diff --git a/app/apiException/apiException.go b/app/apiException/apiException.go index e8ee71a..fbde788 100644 --- a/app/apiException/apiException.go +++ b/app/apiException/apiException.go @@ -31,6 +31,8 @@ var ( NotPermission = NewError(200510, log.LevelInfo, "该用户无权限") ActivityNotFound = NewError(200511, log.LevelInfo, "活动不存在") AnnouncementNotFound = NewError(200512, log.LevelInfo, "公告不存在") + AdminKeyError = NewError(200513, log.LevelInfo, "管理员注册密钥错误") + AdminAlreadyExisted = NewError(200514, log.LevelInfo, "管理员账号已存在") NotInit = NewError(200404, log.LevelWarn, http.StatusText(http.StatusNotFound)) NotFound = NewError(200404, log.LevelWarn, http.StatusText(http.StatusNotFound)) diff --git a/app/controllers/adminController/create.go b/app/controllers/adminController/create.go new file mode 100644 index 0000000..2ded1e9 --- /dev/null +++ b/app/controllers/adminController/create.go @@ -0,0 +1,54 @@ +package adminController + +import ( + "errors" + + "4u-go/app/apiException" + "4u-go/app/models" + "4u-go/app/services/adminService" + "4u-go/app/utils" + "4u-go/config/config" + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +type createAdminByKeyData struct { + Username string `json:"username" binding:"required"` + Password string `json:"password" binding:"required"` + Key string `json:"key" binding:"required"` +} + +// CreateAdminByKey 通过密钥创建普通管理员 +func CreateAdminByKey(c *gin.Context) { + var data createAdminByKeyData + err := c.ShouldBindJSON(&data) + if err != nil { + apiException.AbortWithException(c, apiException.ParamError, err) + return + } + + key := config.Config.GetString("admin.key") + if data.Key != key { + apiException.AbortWithException(c, apiException.AdminKeyError, err) + return + } + + _, err = adminService.GetUserByUsername(data.Username) + if err == nil { + apiException.AbortWithException(c, apiException.AdminAlreadyExisted, err) + return + } else if !errors.Is(err, gorm.ErrRecordNotFound) { + apiException.AbortWithException(c, apiException.ServerError, err) + return + } + + _, err = adminService.CreateAdminUser(data.Username, data.Password, models.ForU, "") + if err != nil { + apiException.AbortWithException(c, apiException.ServerError, err) + return + } + utils.JsonSuccessResponse(c, gin.H{ + "username": data.Username, + "password": data.Password, + }) +} diff --git a/app/models/collection.go b/app/models/collection.go deleted file mode 100644 index bde7a23..0000000 --- a/app/models/collection.go +++ /dev/null @@ -1,12 +0,0 @@ -package models - -import "time" - -// Collection 收藏的结构体 -type Collection struct { - ID uint `json:"id"` // 收藏编号 - UserID int `json:"user_id"` // 用户编号 - Type uint8 `json:"type"` // 收藏类型 1-公告 2-问答 3-网站 - ObjID int `json:"obj_id"` // 对象编号 - CreateAt time.Time `json:"create_at"` // 收藏时间 -} diff --git a/app/models/user.go b/app/models/user.go index 4f3e0a6..e734d78 100644 --- a/app/models/user.go +++ b/app/models/user.go @@ -10,7 +10,7 @@ type User struct { Type UserType `json:"type"` // 用户类型 Password string `json:"password"` // 密码 (只有管理员有密码) WechatOpenID string `json:"wechat_open_id"` // 微信 OpenID - Collage string `json:"collage"` // 学院 + College string `json:"college"` // 学院 Class string `json:"class"` // 班级 PhoneNum string `json:"phone_num"` // 手机号码 CreateTime time.Time `json:"create_time"` // 记录创建时间 @@ -21,9 +21,9 @@ type UserType uint // 用户类型常量 const ( - Undergraduate UserType = 0 - Postgraduate UserType = 1 - ForU UserType = 2 // 普通工作人员 - CollageAdmin UserType = 3 // 学院管理员 - SuperAdmin UserType = 4 + Undergraduate UserType = 0 // 本科生 + Postgraduate UserType = 1 // 研究生 + CollageAdmin UserType = 2 // 学院管理员 + ForU UserType = 3 // ForU工作人员 + SuperAdmin UserType = 4 // 超级管理员 ) diff --git a/app/services/adminService/create.go b/app/services/adminService/create.go new file mode 100644 index 0000000..91ef44a --- /dev/null +++ b/app/services/adminService/create.go @@ -0,0 +1,30 @@ +package adminService + +import ( + "crypto/sha256" + "encoding/hex" + "fmt" + "time" + + "4u-go/app/models" + "4u-go/config/database" +) + +// CreateAdminUser 创建管理员用户 +func CreateAdminUser(username string, password string, userType models.UserType, college string) (*models.User, error) { + h := sha256.New() + if _, err := h.Write([]byte(password)); err != nil { + return nil, fmt.Errorf("failed to hash password: %w", err) + } + pass := hex.EncodeToString(h.Sum(nil)) + user := &models.User{ + Type: userType, + StudentID: username, + Password: pass, + College: college, + CreateTime: time.Now(), + } + res := database.DB.Create(&user) + + return user, res.Error +} diff --git a/app/services/adminService/get.go b/app/services/adminService/get.go new file mode 100644 index 0000000..93fe789 --- /dev/null +++ b/app/services/adminService/get.go @@ -0,0 +1,13 @@ +package adminService + +import ( + "4u-go/app/models" + "4u-go/config/database" +) + +// GetUserByUsername 通过用户名获取用户 +func GetUserByUsername(username string) (*models.User, error) { + user := &models.User{} + res := database.DB.Where("student_id = ?", username).First(user) + return user, res.Error +} diff --git a/config.example.yaml b/config.example.yaml index ceb36cf..34dec25 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -28,6 +28,9 @@ wechat: # 微信小程序相关配置 (切记不能泄漏,不能为空) user: host: +admin: + key: # 管理员密钥 + log: development: true # 是否开启开发模式 true: 开启 false: 关闭 disableCaller: false # 是否禁用调用方 diff --git a/config/database/migrations.go b/config/database/migrations.go index 6f1249a..7b00964 100755 --- a/config/database/migrations.go +++ b/config/database/migrations.go @@ -13,6 +13,5 @@ func autoMigrate(db *gorm.DB) error { &models.Activity{}, &models.LostAndFoundRecord{}, &models.Website{}, - &models.Collection{}, ) } diff --git a/config/router/router.go b/config/router/router.go index a70a213..9c1431f 100644 --- a/config/router/router.go +++ b/config/router/router.go @@ -2,6 +2,7 @@ package router import ( "4u-go/app/controllers/activityController" + "4u-go/app/controllers/adminController" "4u-go/app/controllers/announcementController" "4u-go/app/controllers/userController" "4u-go/app/midwares" @@ -24,6 +25,11 @@ func Init(r *gin.Engine) { user.POST("/login/session", userController.AuthBySession) } + admin := api.Group("/admin") + { + admin.POST("/create/key", adminController.CreateAdminByKey) + } + activity := api.Group("/activity") { activity.GET("", activityController.GetActivityList)