From 6190a8853a4231e7277dae3e2ed9c98f6673c2e9 Mon Sep 17 00:00:00 2001 From: mei Date: Sun, 5 Apr 2026 10:36:22 +0800 Subject: [PATCH] feat: v2(Incomplete,very early version) --- api/account/account.go | 62 ++++++++ api/rule/rule.go | 62 ++++++++ api/user/tool.go | 81 ++++++++++ api/user/user.go | 103 +++++++++++++ configs/config.go | 52 +------ data.db | Bin 0 -> 49152 bytes docker-compose.yml | 4 +- docs/bilibili-config.md | 17 ++ docs/email-config.md | 3 + drivers/bilibili/api.go | 30 ++++ drivers/bilibili/bilibili.go | 44 ++++++ drivers/bilibili/model.go | 9 ++ drivers/bilibili/tool.go | 134 ++++++++++++++++ drivers/dingtalk/dingtalk.go | 5 + drivers/dingtalk/model.go | 6 + drivers/dingtalk/tool.go | 20 +++ drivers/email/email.go | 20 +++ drivers/email/model.go | 15 ++ drivers/email/tool.go | 116 ++++++++++++++ drivers/github/github.go | 42 +++++ drivers/github/model.go | 10 ++ drivers/github/tool.go | 57 +++++++ drivers/onebot/model.go | 11 ++ drivers/onebot/onebot.go | 42 +++++ drivers/onebot/tool.go | 47 ++++++ go.mod | 33 ++-- go.sum | 64 +++++--- handler/db/db.go | 16 ++ internal/base/base.go | 29 ---- internal/frontend/frontend.go | 19 --- internal/reminder/reminder.go | 23 --- internal/reminder/timer.go | 52 ------- internal/sender/bilibili.go | 283 ---------------------------------- internal/sender/email.go | 99 ------------ internal/sender/gitub.go | 36 ----- internal/sender/onebot.go | 43 ------ main.go | 136 ++++------------ model/account.go | 9 ++ model/rule.go | 11 ++ model/timer.go | 9 ++ model/user.go | 43 ++++++ 41 files changed, 1131 insertions(+), 766 deletions(-) create mode 100644 api/account/account.go create mode 100644 api/rule/rule.go create mode 100644 api/user/tool.go create mode 100644 api/user/user.go create mode 100644 data.db create mode 100644 docs/bilibili-config.md create mode 100644 docs/email-config.md create mode 100644 drivers/bilibili/api.go create mode 100644 drivers/bilibili/bilibili.go create mode 100644 drivers/bilibili/model.go create mode 100644 drivers/bilibili/tool.go create mode 100644 drivers/dingtalk/dingtalk.go create mode 100644 drivers/dingtalk/model.go create mode 100644 drivers/dingtalk/tool.go create mode 100644 drivers/email/email.go create mode 100644 drivers/email/model.go create mode 100644 drivers/email/tool.go create mode 100644 drivers/github/github.go create mode 100644 drivers/github/model.go create mode 100644 drivers/github/tool.go create mode 100644 drivers/onebot/model.go create mode 100644 drivers/onebot/onebot.go create mode 100644 drivers/onebot/tool.go create mode 100644 handler/db/db.go delete mode 100644 internal/base/base.go delete mode 100644 internal/frontend/frontend.go delete mode 100644 internal/reminder/reminder.go delete mode 100644 internal/reminder/timer.go delete mode 100644 internal/sender/bilibili.go delete mode 100644 internal/sender/email.go delete mode 100644 internal/sender/gitub.go delete mode 100644 internal/sender/onebot.go create mode 100644 model/account.go create mode 100644 model/rule.go create mode 100644 model/timer.go create mode 100644 model/user.go diff --git a/api/account/account.go b/api/account/account.go new file mode 100644 index 0000000..471b5f6 --- /dev/null +++ b/api/account/account.go @@ -0,0 +1,62 @@ +package account + +import ( + "github.com/gin-gonic/gin" + "github.com/ssdomei232/goodBaby/api/user" + "github.com/ssdomei232/goodBaby/handler/db" + "github.com/ssdomei232/goodBaby/model" +) + +// 添加账号 +func HandleAddAccount(c *gin.Context) { + gormDB, err := db.GetGormDB() + if err != nil { + c.JSON(500, gin.H{"code": 500, "data": "服务器内部错误"}) + return + } + + userInfo, err := user.GetUserInfoByGinCtx(c) + if err != nil { + c.JSON(401, gin.H{"code": 401, "data": "获取用户信息失败"}) + return + } + + var newAccount model.Account + if err := c.BindJSON(&newAccount); err != nil { + c.JSON(400, gin.H{"code": 400, "data": "输入参数错误"}) + return + } + + newAccount.UID = userInfo.ID + result := gormDB.Create(&newAccount) + if result.Error != nil { + c.JSON(500, gin.H{"code": 500, "data": "添加账号失败"}) + return + } + + c.JSON(200, gin.H{"code": 200, "data": "添加账号成功"}) +} + +// 获取用户的所有账号 +func HandleGetAllAccounts(c *gin.Context) { + gormDB, err := db.GetGormDB() + if err != nil { + c.JSON(500, gin.H{"code": 500, "data": "服务器内部错误"}) + return + } + + userInfo, err := user.GetUserInfoByGinCtx(c) + if err != nil { + c.JSON(401, gin.H{"code": 401, "data": "获取用户信息失败"}) + return + } + + var accounts []model.Account + result := gormDB.Where("uid = ?", userInfo.ID).Find(&accounts) + if result.Error != nil { + c.JSON(500, gin.H{"code": 500, "data": "获取账号失败"}) + return + } + + c.JSON(200, gin.H{"code": 200, "data": accounts}) +} diff --git a/api/rule/rule.go b/api/rule/rule.go new file mode 100644 index 0000000..0ec682d --- /dev/null +++ b/api/rule/rule.go @@ -0,0 +1,62 @@ +package rule + +import ( + "github.com/gin-gonic/gin" + "github.com/ssdomei232/goodBaby/api/user" + "github.com/ssdomei232/goodBaby/handler/db" + "github.com/ssdomei232/goodBaby/model" +) + +// 获取用户的所有规则 +func HandleGetAllRules(c *gin.Context) { + gormDB, err := db.GetGormDB() + if err != nil { + c.JSON(500, gin.H{"code": 500, "data": "获取规则失败"}) + return + } + + userInfo, err := user.GetUserInfoByGinCtx(c) + if err != nil { + c.JSON(401, gin.H{"code": 401, "data": "获取用户信息失败"}) + return + } + + var rules []model.Rule + result := gormDB.Where("uid = ?", userInfo.ID).Find(&rules) + if result.Error != nil { + c.JSON(500, gin.H{"code": 500, "data": "获取规则失败"}) + return + } + + c.JSON(200, gin.H{"code": 200, "data": rules}) +} + +// 创建新规则 +func HandleCreateRule(c *gin.Context) { + gormDB, err := db.GetGormDB() + if err != nil { + c.JSON(500, gin.H{"code": 500, "data": "服务器内部错误"}) + return + } + + userInfo, err := user.GetUserInfoByGinCtx(c) + if err != nil { + c.JSON(401, gin.H{"code": 401, "data": "获取用户信息失败"}) + return + } + + var newRule model.Rule + if err := c.BindJSON(&newRule); err != nil { + c.JSON(400, gin.H{"code": 400, "data": "输入参数错误"}) + return + } + + newRule.UID = userInfo.ID + result := gormDB.Create(&newRule) + if result.Error != nil { + c.JSON(500, gin.H{"code": 500, "data": "创建规则失败"}) + return + } + + c.JSON(200, gin.H{"code": 200, "data": "规则创建成功"}) +} diff --git a/api/user/tool.go b/api/user/tool.go new file mode 100644 index 0000000..d9d10a7 --- /dev/null +++ b/api/user/tool.go @@ -0,0 +1,81 @@ +package user + +import ( + "github.com/gin-contrib/sessions" + "github.com/gin-gonic/gin" + "github.com/ssdomei232/goodBaby/handler/db" + "github.com/ssdomei232/goodBaby/model" + "golang.org/x/crypto/bcrypt" +) + +// 加密密码 +func encryptPassword(password string) (string, error) { + hashedID, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + if err != nil { + return "", err + } + return string(hashedID), nil +} + +// 验证密码 +func verifyPassword(hashedPassword, inputPassword string) error { + return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(inputPassword)) +} + +func createUser(u *model.User) error { + gormDB, err := db.GetGormDB() + if err != nil { + return err + } + + hashedPassword, err := encryptPassword(u.Password) + if err != nil { + return err + } + u.Password = hashedPassword + + result := gormDB.Create(u) + return result.Error +} + +// 校验密码 +func verifyUser(u *model.User) error { + gormDB, err := db.GetGormDB() + if err != nil { + return err + } + + var hashedPassword string + result := gormDB.Where("username = ?", u.Username).First(&model.User{}).Select("password").Scan(&hashedPassword) + if result.Error != nil { + return result.Error + } + + return verifyPassword(hashedPassword, u.Password) +} + +// 通过用户名获取用户信息 +func GetUserInfo(username string) (*model.User, error) { + gormDB, err := db.GetGormDB() + if err != nil { + return nil, err + } + + var user model.User + result := gormDB.Where("username = ?", username).First(&user) + if result.Error != nil { + return nil, result.Error + } + return &user, nil +} + +// 通过 gin.Context 获取用户信息 +func GetUserInfoByGinCtx(c *gin.Context) (userInfo *model.User, err error) { + session := sessions.Default(c) + username := session.Get("username") + userInfo, err = GetUserInfo(username.(string)) + if err != nil { + return nil, err + } + return userInfo, nil +} diff --git a/api/user/user.go b/api/user/user.go new file mode 100644 index 0000000..146f6af --- /dev/null +++ b/api/user/user.go @@ -0,0 +1,103 @@ +package user + +import ( + "github.com/gin-contrib/sessions" + "github.com/gin-gonic/gin" + "github.com/ssdomei232/goodBaby/configs" + "github.com/ssdomei232/goodBaby/model" +) + +// 处理注册请求,配置文件中可设置禁用注册 +func HandleRegistry(c *gin.Context) { + var user model.User + var err error + + config, err := configs.GetConfig() + if err != nil { + c.JSON(500, gin.H{"code": 500, "data": "获取配置文件失败"}) + return + } + + if !config.EnableRegistry { + c.JSON(403, gin.H{"code": 403, "data": "注册功能已关闭"}) + return + } + + err = c.BindJSON(&user) + if err != nil { + c.JSON(400, gin.H{"code": 400, "data": "输入错误"}) + return + } + + if err = user.IsValid(); err != nil { + c.JSON(400, gin.H{"code": 400, "data": err.Error()}) + return + } + + if isExist := user.IsExist(); isExist { + c.JSON(400, gin.H{"code": 400, "data": "用户名已存在"}) + return + } + + if err = createUser(&user); err != nil { + c.JSON(500, gin.H{"code": 500, "data": "注册失败"}) + return + } + + session := sessions.Default(c) + session.Set("username", user.Username) + session.Save() + + c.JSON(200, gin.H{"code": 200, "data": "注册成功"}) +} + +// 处理登录请求 +func HandleLogin(c *gin.Context) { + var user model.User + var err error + + err = c.BindJSON(&user) + if err != nil { + c.JSON(400, gin.H{"code": 400, "data": "输入错误"}) + return + } + + if err = user.IsValid(); err != nil { + c.JSON(400, gin.H{"code": 400, "data": err.Error()}) + } + + if err = verifyUser(&user); err != nil { + c.JSON(400, gin.H{"code": 400, "data": "用户名或密码错误"}) + return + } + + session := sessions.Default(c) + session.Set("username", user.Username) + session.Save() + + c.JSON(200, gin.H{"code": 200, "data": "登录成功"}) +} + +// 处理获取用户信息请求 +func HandleGetUserInfo(c *gin.Context) { + userInfo, err := GetUserInfoByGinCtx(c) + if err != nil { + c.JSON(500, gin.H{"code": 500, "data": "获取用户信息失败"}) + return + } + c.JSON(200, gin.H{"code": 200, "data": userInfo}) +} + +// 认证中间件 +func AuthMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + session := sessions.Default(c) + username := session.Get("username") + if username == nil { + c.JSON(401, gin.H{"code": 401, "data": "未登录"}) + c.Abort() + return + } + c.Next() + } +} diff --git a/configs/config.go b/configs/config.go index ae0e815..42550fc 100644 --- a/configs/config.go +++ b/configs/config.go @@ -5,52 +5,14 @@ import ( "os" ) +// type DingtalkBot struct { +// AccessToken string `json:"access_token"` +// Secret string `json:"secret"` +// } + type Config struct { - SignalSecret string `json:"signal_secret"` - Debug bool `json:"debug"` - DisconnectDuration int `json:"disconnect_duration"` // Hours - BiliMsg string `json:"bili_msg"` - Basic Basic `json:"basic"` - MailConfig MailConfig `json:"mail_config"` - GithubConfig GithubConfig `json:"github_config"` - DingtalkBot DingtalkBot `json:"dingtalk_bot"` - OneBotConfig OneBotConfig `json:"onebot_config"` -} - -type MailConfig struct { - Host string `json:"host"` - Port int `json:"port"` - User string `json:"user"` - Password string `json:"pass"` - MailList []string `json:"mail_list"` - MailTitle string `json:"mail_title"` - MailContent string `json:"mail_content"` -} - -type GithubConfig struct { - Owner string `json:"owner"` - Repos []string `json:"repos"` - Token string `json:"token"` -} - -type Basic struct { - Name string `json:"name"` - Age int `json:"age"` - NickName string `json:"nickname"` - QQNumber string `json:"qq_number"` - CauseStop string `json:"cause_stop"` -} - -type DingtalkBot struct { - AccessToken string `json:"access_token"` - Secret string `json:"secret"` -} - -type OneBotConfig struct { - URL string `json:"url"` // 例如 "http://localhost:5700" - Token string `json:"token"` - SendGroups []int `json:"send_groups"` - Msg string `json:"msg"` + EnableRegistry bool `json:"enable_registry"` + TimeoutDurationHours int `json:"timeout_duration_hours"` } // Get config from json file diff --git a/data.db b/data.db new file mode 100644 index 0000000000000000000000000000000000000000..7848f5c4c06172cc9faac1b54a838a9e35cefb89 GIT binary patch literal 49152 zcmeI(&1=(O9Ki9!c75+UUqcUtST8FZ%FvsLb|Yx9>$ci~10lpV8*yE_H7UN_I&b?k zymej+m8D18?fhSM$JW0v#^ZWu056`o;s^i=GW~aMj`TAXD zMp0Gek*+I>k`^T+N<@@PqUfSTMHz1D@ZgL(t=xXMm(6}wlBq*w`b##FIZPd9KBm7- zf5?7Mf65)?4$ionE(8!j009ILKmY**CJOXlT#0L%roPvF>t);S_S&{5cj=|NQEnJ| zqr6x(^rCDl>a(e2(Pc+cXsTqIo4=3 zo1LEPk2ky4j$KSPjOUHu&SuBmbhgY_UdKId^xy6tU$R=SESKvW`cq?LHh3<*yxv%; z)WoAN8?{C$RVryQ?SZB$j@z=|czbQ}@7=U|en+00J;-qQVpB`1J)oL&YK9io64;TFGGLv zhI|$Fn=&$)6>>K<8k21Mr+}JW+X@oSKRJ5EUCZ-cce>&&8YX)1i=&y*a@;N7YHyok zQBNHDx$80QVg9u79AvJ!FsKu&k(f3&r*6o2kKPW?-s{y! z1+pThXzr_$`<45h`yme45I_I{1Q0*~0R#|0009ILK;S|MB;pY*A=h*yW08Dfurwka zjT92Y#Vd&^afMti6MX-RMgMFFAb 0 { - log.Printf("第 %d 次重试发送邮件给 %s", i, address) - } - - err := sendMailMsg(address, msg, title) - if err == nil { - // 发送成功 - fmt.Printf("邮件成功发送给 %s\n", address) - return - } - - lastErr = err - log.Printf("发送邮件给 %s 失败: %v", address, err) - - // 如果不是最后一次重试,则等待后重试 - if i < maxRetries { - time.Sleep(retryDelay * time.Duration(i+1)) // 递增延迟 - } - } - - // 所有重试都失败 - log.Printf("发送邮件给 %s 经过 %d 次重试后仍然失败: %v", address, maxRetries, lastErr) -} - -func sendMailMsg(address string, msg string, title string) error { - config, err := configs.GetConfig() - if err != nil { - return fmt.Errorf("获取配置文件失败: %v", err) - } - - client, err := mail.NewClient( - config.MailConfig.Host, - mail.WithPort(config.MailConfig.Port), - mail.WithSSL(), - mail.WithUsername(config.MailConfig.User), - mail.WithPassword(config.MailConfig.Password), - mail.WithSMTPAuth(mail.SMTPAuthPlain), - ) - if err != nil { - return fmt.Errorf("创建邮件客户端失败: %v", err) - } - - // 创建邮件 - message := mail.NewMsg() - if err := message.From(config.MailConfig.User); err != nil { - return fmt.Errorf("设置发件人失败: %v", err) - } - - if err := message.To(address); err != nil { - return fmt.Errorf("设置收件人失败: %v", err) - } - - message.Subject(title) - message.SetBodyString(mail.TypeTextPlain, msg) - - // 发送邮件 - if err := client.DialAndSend(message); err != nil { - return fmt.Errorf("发送邮件失败: %v", err) - } - - return nil -} diff --git a/internal/sender/gitub.go b/internal/sender/gitub.go deleted file mode 100644 index 8528107..0000000 --- a/internal/sender/gitub.go +++ /dev/null @@ -1,36 +0,0 @@ -package sender - -import ( - "log" - "time" - - "github.com/ssdomei232/goodBaby/configs" - "github.com/ssdomei232/goodBaby/pkg/github" -) - -// 将repos设置为public -func Github() { - config, err := configs.GetConfig() - if err != nil { - log.Fatalln(err) - } - - for _, repo := range config.GithubConfig.Repos { - maxRetries := 10 - for attempt := range maxRetries { - err := github.MakeRepositoryPublic(config.GithubConfig.Owner, repo, config.GithubConfig.Token) - if err == nil { - break - } - - log.Printf("尝试设置仓库 %s 为公开失败 (尝试 %d/%d): %v", repo, attempt+1, maxRetries, err) - - // 如果不是最后一次尝试,则等待一段时间后重试 - if attempt < maxRetries-1 { - time.Sleep(time.Duration(attempt+1) * time.Second) // 逐步增加等待时间 - } else { - log.Printf("设置仓库 %s 为公开最终失败", repo) - } - } - } -} diff --git a/internal/sender/onebot.go b/internal/sender/onebot.go deleted file mode 100644 index afe5df6..0000000 --- a/internal/sender/onebot.go +++ /dev/null @@ -1,43 +0,0 @@ -package sender - -import ( - "fmt" - "log" - "strconv" - - "github.com/ssdomei232/goodBaby/configs" - "github.com/ssdomei232/goodBaby/internal/base" - napcat "github.com/ssdomei232/napcat-http-go-sdk" -) - -func SendOneBot() { - config, err := configs.GetConfig() - if err != nil { - log.Printf("获取配置文件失败: %v", err) - return - } - - stopMsg := fmt.Sprintf("%s\n\n%s\n\n本消息由自动程序发送", base.GetBasicInfo(), config.OneBotConfig.Msg) - - for _, groupId := range config.OneBotConfig.SendGroups { - sendOneBotMsg(groupId, stopMsg) - } -} - -// 发送一条消息到OneBot -func sendOneBotMsg(groupID int, msg string) { - config, err := configs.GetConfig() - if err != nil { - log.Printf("获取配置文件失败: %v", err) - return - } - - client := napcat.NewClient(config.OneBotConfig.Token, config.OneBotConfig.URL) - - err = client.SendGroupMsg(strconv.Itoa(groupID), msg) - if err != nil { - log.Printf("发送消息到OneBot失败: %v", err) - } else { - log.Printf("成功发送消息到OneBot群 %d", groupID) - } -} diff --git a/main.go b/main.go index 4d54bea..ae91925 100644 --- a/main.go +++ b/main.go @@ -1,121 +1,47 @@ package main import ( - "embed" - "io/fs" - "log" - "net/http" - "time" + "crypto/rand" + "fmt" - "github.com/CuteReimu/bilibili/v2" + "github.com/gin-contrib/sessions" + "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" - "github.com/robfig/cron/v3" - "github.com/ssdomei232/goodBaby/configs" - "github.com/ssdomei232/goodBaby/internal/frontend" - "github.com/ssdomei232/goodBaby/internal/reminder" - "github.com/ssdomei232/goodBaby/internal/sender" + "github.com/ssdomei232/goodBaby/api/account" + "github.com/ssdomei232/goodBaby/api/rule" + "github.com/ssdomei232/goodBaby/api/user" ) -//go:embed static/* -var staticFiles embed.FS - -//go:embed templates/* -var templateFiles embed.FS - -var timer *time.Timer -var duration time.Duration -var biliClient *bilibili.Client -var cookieCheckTimer *time.Ticker - -func init() { - // 1. 加载配置文件 - config, err := configs.GetConfig() - if err != nil { - log.Printf("获取配置文件失败: %v", err) - } - - if config.Debug { - duration = time.Duration(config.DisconnectDuration) * time.Second - } else { - duration = time.Duration(config.DisconnectDuration) * time.Hour - } - - // 2. 检查并创建tmp目录 - if err := sender.EnsureTmpDirectory(); err != nil { - log.Printf("创建tmp目录失败: %v", err) - } - - // 3. 初始化哔哩哔哩和定时器 - biliClient = bilibili.New() - sender.InitBilibili(biliClient) - sender.StartCookieChecker(cookieCheckTimer, biliClient) // Check Bilibili cookie - - reminder.InitTimerManager(duration) - timer = time.NewTimer(duration) - go func() { - <-timer.C - trigger(config) - }() -} - -// 触发器 -func trigger(config configs.Config) { - go sender.SendOneBot() - go sender.SendMail() - go sender.Github() - if !config.Debug { - go sender.SendBili(biliClient) - } -} - func main() { - config, err := configs.GetConfig() - if err != nil { - log.Printf("获取配置文件失败: %v", err) - } - // 定时任务 - reminder.Reminder() - c := cron.New() - if config.Debug { - c.AddFunc("@every 1s", reminder.Reminder) - } else { - c.AddFunc("@every 1h", reminder.Reminder) - } - c.Start() - - // 前端/后端 r := gin.Default() - templFS, _ := fs.Sub(templateFiles, "templates") - r.SetHTMLTemplate(frontend.LoadTemplates(templFS)) - staticFS, _ := fs.Sub(staticFiles, "static") - r.StaticFS("/static", http.FS(staticFS)) + store := cookie.NewStore(generateRandomKey(32)) + r.Use(sessions.Sessions("goodbaby-session", store)) + + v1 := r.Group("/api/v1") + { + v1.POST("/user/registry", user.HandleRegistry) + v1.POST("/user/login", user.HandleLogin) + } + + // 需要认证的路由组 + authorized := v1.Group("/") + authorized.Use(user.AuthMiddleware()) + { + authorized.GET("/user/info", user.HandleGetUserInfo) + authorized.GET("/rules", rule.HandleGetAllRules) + authorized.POST("/rules", rule.HandleCreateRule) + authorized.GET("/accounts", account.HandleGetAllAccounts) + authorized.POST("/accounts", account.HandleAddAccount) + } - r.GET("/", frontend.IndexPage) - r.GET("/signal", handleSignal) - r.GET("/timer/status", reminder.HandleTimerStatus) r.Run(":8088") } -// Handle Signal -func handleSignal(c *gin.Context) { - config, err := configs.GetConfig() +func generateRandomKey(length int) []byte { + key := make([]byte, length) + _, err := rand.Read(key) if err != nil { - log.Printf("获取配置文件失败: %v", err) + panic(fmt.Sprintf("无法生成随机密钥: %v", err)) } - - secret := c.Query("secret") - if secret != config.SignalSecret { - c.JSON(403, gin.H{ - "code": 403, - "message": "secret error", - }) - return - } - timer.Reset(duration) - reminder.GlobalTimerManager.Reset() - c.JSON(200, gin.H{ - "code": 200, - "message": "ok", - }) - log.Println("触发信号") + return key } diff --git a/model/account.go b/model/account.go new file mode 100644 index 0000000..3ae8dfa --- /dev/null +++ b/model/account.go @@ -0,0 +1,9 @@ +package model + +type Account struct { + ID uint `gorm:"primaryKey" json:"id"` + UID uint `json:"uid"` + Name string `json:"name"` // 账号名称 + Type string `json:"type"` // 账号类型,如 "bilibili" + Config string `json:"config"` // 存储账号相关配置,如cookie等 +} diff --git a/model/rule.go b/model/rule.go new file mode 100644 index 0000000..f4fc049 --- /dev/null +++ b/model/rule.go @@ -0,0 +1,11 @@ +package model + +type Rule struct { + ID uint `json:"id" gorm:"primaryKey"` + UID uint `json:"uid"` + TimerID uint `json:"timer_id"` + Name string `json:"name"` + AccountID uint `json:"account_id"` + Type string `json:"type"` + ConfigJson string `json:"config_json"` +} diff --git a/model/timer.go b/model/timer.go new file mode 100644 index 0000000..cd2d338 --- /dev/null +++ b/model/timer.go @@ -0,0 +1,9 @@ +package model + +type Timer struct { + ID uint `gorm:"primaryKey" json:"id"` + UID uint `json:"uid"` + Name string `json:"name"` + SignDerationSeconds int64 `json:"sign_deration_seconds"` + LastSign int64 `json:"last_sign"` +} diff --git a/model/user.go b/model/user.go new file mode 100644 index 0000000..e54ed32 --- /dev/null +++ b/model/user.go @@ -0,0 +1,43 @@ +package model + +import ( + "fmt" + + "github.com/ssdomei232/goodBaby/handler/db" +) + +type User struct { + ID uint `json:"id" gorm:"primaryKey"` + CreateAt int64 `json:"create_at"` + Username string `json:"username"` + Password string `json:"-"` + DingTalkConfig *string `json:"dingtalk_config"` +} + +func (u *User) IsValid() error { + if u.Username == "" || u.Password == "" { + return fmt.Errorf("用户名或密码不能为空") + } + if len(u.Username) > 32 || len(u.Username) < 2 { + return fmt.Errorf("用户名过长或过短") + } + if len(u.Password) > 64 || len(u.Password) < 6 { + return fmt.Errorf("密码过长或过短") + } + return nil +} + +func (u *User) IsExist() bool { + db, err := db.GetGormDB() + if err != nil { + return false + } + + var count int64 + result := db.Where("username = ?", u.Username).Count(&count) + if result.Error != nil { + return false + } + + return count > 0 +}