perf: 通用模块分出认证模块
This commit is contained in:
@@ -1,203 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/config"
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/modules/common/model"
|
||||
"be.ems/src/modules/common/service"
|
||||
systemModelVO "be.ems/src/modules/system/model/vo"
|
||||
systemService "be.ems/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 AccountController 结构体
|
||||
var NewAccount = &AccountController{
|
||||
accountService: service.NewAccount,
|
||||
sysLogLoginService: systemService.NewSysLogLogin,
|
||||
}
|
||||
|
||||
// 账号身份操作处理
|
||||
//
|
||||
// PATH /
|
||||
type AccountController struct {
|
||||
accountService *service.Account // 账号身份操作服务
|
||||
sysLogLoginService *systemService.SysLogLogin // 系统登录访问
|
||||
}
|
||||
|
||||
// Login 系统登录
|
||||
//
|
||||
// POST /login
|
||||
//
|
||||
// @Tags common/authorization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Summary System Login
|
||||
// @Description System Login
|
||||
// @Router /login [post]
|
||||
func (s AccountController) Login(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body model.LoginBody
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(40422, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 当前请求信息
|
||||
ipaddr, location := reqctx.IPAddrLocation(c)
|
||||
os, browser := reqctx.UaOsBrowser(c)
|
||||
|
||||
// 校验验证码 根据错误信息,创建系统访问记录
|
||||
if err := s.accountService.ValidateCaptcha(body.Code, body.UUID); err != nil {
|
||||
msg := fmt.Sprintf("%s code: %s", err.Error(), body.Code)
|
||||
s.sysLogLoginService.Insert(
|
||||
body.Username, constants.STATUS_NO, msg,
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
c.JSON(400, resp.CodeMsg(40012, i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
loginUser, err := s.accountService.ByUsername(body.Username, body.Password)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
// 生成令牌,创建系统访问记录
|
||||
tokenStr := token.Create(&loginUser, [4]string{ipaddr, location, os, browser})
|
||||
if tokenStr == "" {
|
||||
c.JSON(200, resp.Err(nil))
|
||||
return
|
||||
} else {
|
||||
s.accountService.UpdateLoginDateAndIP(loginUser)
|
||||
// 登录成功
|
||||
s.sysLogLoginService.Insert(
|
||||
body.Username, constants.STATUS_YES, "app.common.loginSuccess",
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(map[string]any{
|
||||
"accessToken": tokenStr,
|
||||
"tokenType": strings.TrimRight(constants.HEADER_PREFIX, " "),
|
||||
"expiresIn": (loginUser.ExpireTime - loginUser.LoginTime) / 1000,
|
||||
"userId": loginUser.UserId,
|
||||
}))
|
||||
}
|
||||
|
||||
// Me 登录用户信息
|
||||
//
|
||||
// GET /me
|
||||
//
|
||||
// @Tags common/authorization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Login User Information
|
||||
// @Description Login User Information
|
||||
// @Router /me [get]
|
||||
func (s AccountController) Me(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
info, err := reqctx.LoginUser(c)
|
||||
if err != nil {
|
||||
c.JSON(401, resp.CodeMsg(40003, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 角色权限集合,系统管理员拥有所有权限
|
||||
isSystemUser := config.IsSystemUser(info.UserId)
|
||||
roles, perms := s.accountService.RoleAndMenuPerms(info.UserId, isSystemUser)
|
||||
|
||||
info.User.NickName = i18n.TKey(language, info.User.NickName)
|
||||
info.User.Remark = i18n.TKey(language, info.User.Remark)
|
||||
info.User.Dept.DeptName = i18n.TKey(language, info.User.Dept.DeptName)
|
||||
for ri := range info.User.Roles {
|
||||
info.User.Roles[ri].RoleName = i18n.TKey(language, info.User.Roles[ri].RoleName)
|
||||
}
|
||||
c.JSON(200, resp.OkData(map[string]any{
|
||||
"user": info.User,
|
||||
"roles": roles,
|
||||
"permissions": perms,
|
||||
}))
|
||||
}
|
||||
|
||||
// Router 登录用户路由信息
|
||||
//
|
||||
// GET /router
|
||||
//
|
||||
// @Tags common/authorization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Login User Routing Information
|
||||
// @Description Login User Routing Information
|
||||
// @Router /router [get]
|
||||
func (s AccountController) Router(c *gin.Context) {
|
||||
userId := reqctx.LoginUserToUserID(c)
|
||||
|
||||
// 前端路由,系统管理员拥有所有
|
||||
isSystemUser := config.IsSystemUser(userId)
|
||||
buildMenus := s.accountService.RouteMenus(userId, isSystemUser)
|
||||
|
||||
// 闭包函数处理多语言
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var converI18n func(language string, arr *[]systemModelVO.Router)
|
||||
converI18n = func(language string, arr *[]systemModelVO.Router) {
|
||||
for i := range *arr {
|
||||
(*arr)[i].Meta.Title = i18n.TKey(language, (*arr)[i].Meta.Title)
|
||||
if len((*arr)[i].Children) > 0 {
|
||||
converI18n(language, &(*arr)[i].Children)
|
||||
}
|
||||
}
|
||||
}
|
||||
converI18n(language, &buildMenus)
|
||||
|
||||
c.JSON(200, resp.OkData(buildMenus))
|
||||
}
|
||||
|
||||
// Logout 系统登出
|
||||
//
|
||||
// POST /logout
|
||||
//
|
||||
// @Tags common/authorization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary System Logout
|
||||
// @Description System Logout
|
||||
// @Router /logout [post]
|
||||
func (s AccountController) Logout(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
tokenStr := reqctx.Authorization(c)
|
||||
if tokenStr != "" {
|
||||
// 存在token时记录退出信息
|
||||
userName := token.Remove(tokenStr)
|
||||
if userName != "" {
|
||||
// 当前请求信息
|
||||
ipaddr, location := reqctx.IPAddrLocation(c)
|
||||
os, browser := reqctx.UaOsBrowser(c)
|
||||
// 创建系统访问记录
|
||||
s.sysLogLoginService.Insert(
|
||||
userName, constants.STATUS_YES, "app.common.logoutSuccess",
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkMsg(i18n.TKey(language, "app.common.logoutSuccess")))
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/framework/utils/machine"
|
||||
"be.ems/src/framework/utils/regular"
|
||||
"be.ems/src/modules/common/service"
|
||||
systemService "be.ems/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 BootloaderController 结构体
|
||||
var NewBootloader = &BootloaderController{
|
||||
accountService: service.NewAccount,
|
||||
sysUserService: systemService.NewSysUser,
|
||||
}
|
||||
|
||||
// 系统引导初始化
|
||||
//
|
||||
// PATH /bootloader
|
||||
type BootloaderController struct {
|
||||
accountService *service.Account // 账号身份操作服务
|
||||
sysUserService *systemService.SysUser // 用户信息服务
|
||||
}
|
||||
|
||||
// 首次引导开始
|
||||
//
|
||||
// POST /
|
||||
func (s *BootloaderController) Start(c *gin.Context) {
|
||||
// 是否完成引导
|
||||
launchInfo := machine.LaunchInfo
|
||||
if launchInfo == nil {
|
||||
c.JSON(200, resp.Err(nil))
|
||||
return
|
||||
}
|
||||
if v, ok := launchInfo[constants.LAUNCH_BOOTLOADER]; ok && !v.(bool) {
|
||||
c.JSON(200, resp.ErrMsg("bootloader done"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询用户登录账号
|
||||
sysUser := s.sysUserService.FindById(1)
|
||||
if sysUser.UserId != 1 {
|
||||
c.JSON(200, resp.ErrMsg("not found user data"))
|
||||
return
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
loginUser := token.TokenInfo{
|
||||
UserId: sysUser.UserId,
|
||||
DeptId: sysUser.DeptId,
|
||||
User: sysUser,
|
||||
Permissions: []string{constants.SYS_PERMISSION_SYSTEM},
|
||||
}
|
||||
|
||||
// 当前请求信息
|
||||
ipaddr, location := reqctx.IPAddrLocation(c)
|
||||
os, browser := reqctx.UaOsBrowser(c)
|
||||
|
||||
// 生成令牌,创建系统访问记录
|
||||
tokenStr := token.Create(&loginUser, [4]string{ipaddr, location, os, browser})
|
||||
if tokenStr == "" {
|
||||
c.JSON(200, resp.Err(nil))
|
||||
return
|
||||
} else {
|
||||
s.accountService.UpdateLoginDateAndIP(loginUser)
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(map[string]any{
|
||||
"accessToken": tokenStr,
|
||||
"tokenType": strings.TrimRight(constants.HEADER_PREFIX, " "),
|
||||
"expiresIn": (loginUser.ExpireTime - loginUser.LoginTime) / 1000,
|
||||
"userId": loginUser.UserId,
|
||||
}))
|
||||
}
|
||||
|
||||
// 首次引导完成
|
||||
//
|
||||
// PUT /
|
||||
func (s *BootloaderController) Done(c *gin.Context) {
|
||||
// 是否完成引导
|
||||
launchInfo := machine.LaunchInfo
|
||||
if launchInfo == nil {
|
||||
c.JSON(200, resp.Err(nil))
|
||||
return
|
||||
}
|
||||
if v, ok := launchInfo[constants.LAUNCH_BOOTLOADER]; ok && !v.(bool) {
|
||||
c.JSON(200, resp.ErrMsg("bootloader done"))
|
||||
return
|
||||
}
|
||||
|
||||
// 标记引导完成
|
||||
if err := machine.Bootloader(false); err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 清除授权信息
|
||||
token.Remove(reqctx.Authorization(c))
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
}
|
||||
|
||||
// 引导系统数据重置
|
||||
//
|
||||
// DELETE /
|
||||
func (s *BootloaderController) Reset(c *gin.Context) {
|
||||
// 是否完成引导
|
||||
launchInfo := machine.LaunchInfo
|
||||
if launchInfo == nil {
|
||||
c.JSON(200, resp.Err(nil))
|
||||
return
|
||||
}
|
||||
if v, ok := launchInfo[constants.LAUNCH_BOOTLOADER]; ok && v.(bool) {
|
||||
c.JSON(200, resp.ErrMsg("bootloader not done"))
|
||||
return
|
||||
}
|
||||
|
||||
if err := machine.Reset(); err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 清除授权信息
|
||||
token.Remove(reqctx.Authorization(c))
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
}
|
||||
|
||||
// 账号变更
|
||||
//
|
||||
// PUT /account
|
||||
func (s *BootloaderController) Account(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
UserName string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
if !regular.ValidPassword(body.Password) {
|
||||
// 登录密码至少包含大小写字母、数字、特殊符号,且不少于6位
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "user.errPasswd")))
|
||||
return
|
||||
}
|
||||
|
||||
// 是否完成引导
|
||||
launchInfo := machine.LaunchInfo
|
||||
if launchInfo == nil {
|
||||
c.JSON(200, resp.Err(nil))
|
||||
return
|
||||
}
|
||||
if v, ok := launchInfo[constants.LAUNCH_BOOTLOADER]; ok && !v.(bool) {
|
||||
c.JSON(200, resp.ErrMsg("bootloader done"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询用户登录账号
|
||||
sysUser := s.sysUserService.FindById(2)
|
||||
if sysUser.UserId != 2 {
|
||||
c.JSON(200, resp.ErrMsg("not found user data"))
|
||||
return
|
||||
}
|
||||
sysUser.UserName = body.UserName
|
||||
sysUser.NickName = body.UserName
|
||||
sysUser.Password = body.Password
|
||||
sysUser.UpdateBy = reqctx.LoginUserToUserName(c)
|
||||
rows := s.sysUserService.Update(sysUser)
|
||||
if rows > 0 {
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.Err(nil))
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/config"
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/database/redis"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
systemService "be.ems/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/mojocn/base64Captcha"
|
||||
)
|
||||
|
||||
// 实例化控制层 CaptchaController 结构体
|
||||
var NewCaptcha = &CaptchaController{
|
||||
sysConfigService: systemService.NewSysConfig,
|
||||
}
|
||||
|
||||
// 验证码操作处理
|
||||
//
|
||||
// PATH /
|
||||
type CaptchaController struct {
|
||||
sysConfigService *systemService.SysConfig // 参数配置服务
|
||||
}
|
||||
|
||||
// 获取验证码
|
||||
//
|
||||
// GET /captchaImage
|
||||
//
|
||||
// @Tags common
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Get CAPTCHA
|
||||
// @Description Get CAPTCHA
|
||||
// @Router /captchaImage [get]
|
||||
func (s *CaptchaController) Image(c *gin.Context) {
|
||||
// 从数据库配置获取验证码开关 true开启,false关闭
|
||||
captchaEnabledStr := s.sysConfigService.FindValueByKey("sys.account.captchaEnabled")
|
||||
captchaEnabled := parse.Boolean(captchaEnabledStr)
|
||||
if !captchaEnabled {
|
||||
c.JSON(200, resp.Ok(map[string]any{
|
||||
"captchaEnabled": captchaEnabled,
|
||||
}))
|
||||
return
|
||||
}
|
||||
|
||||
// 生成唯一标识
|
||||
verifyKey := ""
|
||||
data := map[string]any{
|
||||
"captchaEnabled": captchaEnabled,
|
||||
"uuid": "",
|
||||
"img": "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",
|
||||
}
|
||||
|
||||
// 从数据库配置获取验证码类型 math 数值计算 char 字符验证
|
||||
captchaType := s.sysConfigService.FindValueByKey("sys.account.captchaType")
|
||||
if captchaType == constants.CAPTCHA_TYPE_MATH {
|
||||
math := config.Get("mathCaptcha").(map[string]any)
|
||||
driverCaptcha := &base64Captcha.DriverMath{
|
||||
//Height png height in pixel.
|
||||
Height: math["height"].(int),
|
||||
// Width Captcha png width in pixel.
|
||||
Width: math["width"].(int),
|
||||
//NoiseCount text noise count.
|
||||
NoiseCount: math["noise"].(int),
|
||||
//ShowLineOptions := OptionShowHollowLine | OptionShowSlimeLine | OptionShowSineLine .
|
||||
ShowLineOptions: base64Captcha.OptionShowHollowLine,
|
||||
}
|
||||
if math["color"].(bool) {
|
||||
//BgColor captcha image background color (optional)
|
||||
driverCaptcha.BgColor = parse.Color(math["background"].(string))
|
||||
}
|
||||
// 验证码生成
|
||||
id, question, answer := driverCaptcha.GenerateIdQuestionAnswer()
|
||||
// 验证码表达式解析输出
|
||||
item, err := driverCaptcha.DrawCaptcha(question)
|
||||
if err != nil {
|
||||
logger.Infof("Generate Id Question Answer %s %s : %v", captchaType, question, err)
|
||||
} else {
|
||||
data["uuid"] = id
|
||||
data["img"] = item.EncodeB64string()
|
||||
expiration := constants.CAPTCHA_EXPIRATION * time.Second
|
||||
verifyKey = constants.CACHE_CAPTCHA_CODE + ":" + id
|
||||
redis.SetByExpire("", verifyKey, answer, expiration)
|
||||
}
|
||||
}
|
||||
if captchaType == constants.CAPTCHA_TYPE_CHAR {
|
||||
char := config.Get("charCaptcha").(map[string]any)
|
||||
driverCaptcha := &base64Captcha.DriverString{
|
||||
//Height png height in pixel.
|
||||
Height: char["height"].(int),
|
||||
// Width Captcha png width in pixel.
|
||||
Width: char["width"].(int),
|
||||
//NoiseCount text noise count.
|
||||
NoiseCount: char["noise"].(int),
|
||||
//Length random string length.
|
||||
Length: char["size"].(int),
|
||||
//Source is a unicode which is the rand string from.
|
||||
Source: char["chars"].(string),
|
||||
//ShowLineOptions := OptionShowHollowLine | OptionShowSlimeLine | OptionShowSineLine .
|
||||
ShowLineOptions: base64Captcha.OptionShowHollowLine,
|
||||
}
|
||||
if char["color"].(bool) {
|
||||
//BgColor captcha image background color (optional)
|
||||
driverCaptcha.BgColor = parse.Color(char["background"].(string))
|
||||
}
|
||||
// 验证码生成
|
||||
id, question, answer := driverCaptcha.GenerateIdQuestionAnswer()
|
||||
// 验证码表达式解析输出
|
||||
item, err := driverCaptcha.DrawCaptcha(question)
|
||||
if err != nil {
|
||||
logger.Infof("Generate Id Question Answer %s %s : %v", captchaType, question, err)
|
||||
} else {
|
||||
data["uuid"] = id
|
||||
data["img"] = item.EncodeB64string()
|
||||
expiration := constants.CAPTCHA_EXPIRATION * time.Second
|
||||
verifyKey = constants.CACHE_CAPTCHA_CODE + ":" + id
|
||||
redis.SetByExpire("", verifyKey, answer, expiration)
|
||||
}
|
||||
}
|
||||
|
||||
// 本地开发下返回验证码结果,方便接口调试
|
||||
if config.Env() == "local" {
|
||||
text, _ := redis.Get("", verifyKey)
|
||||
data["text"] = text
|
||||
c.JSON(200, resp.Ok(data))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.Ok(data))
|
||||
}
|
||||
@@ -11,22 +11,16 @@ import (
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
commonService "be.ems/src/modules/common/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 CommonController 结构体
|
||||
var NewCommon = &CommonController{
|
||||
commontService: commonService.NewCommont,
|
||||
}
|
||||
var NewCommon = &CommonController{}
|
||||
|
||||
// 通用请求
|
||||
//
|
||||
// PATH /
|
||||
type CommonController struct {
|
||||
commontService *commonService.Commont // 通用请求服务
|
||||
}
|
||||
type CommonController struct{}
|
||||
|
||||
// Hash 哈希编码
|
||||
//
|
||||
@@ -100,29 +94,3 @@ func (s *CommonController) I18n(c *gin.Context) {
|
||||
"errorFields": errorFields,
|
||||
})
|
||||
}
|
||||
|
||||
// 系统的配置信息
|
||||
//
|
||||
// GET /sys-conf
|
||||
//
|
||||
// @Tags common
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Summary Configuration information for the system
|
||||
// @Description Configuration information for the system
|
||||
// @Router /sys-conf [get]
|
||||
func (s CommonController) SysConfig(c *gin.Context) {
|
||||
data := s.commontService.SystemConfigInfo()
|
||||
|
||||
// 闭包函数处理多语言
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
converI18n := func(language string, arr *map[string]string) {
|
||||
for k, v := range *arr {
|
||||
(*arr)[k] = i18n.TKey(language, v)
|
||||
}
|
||||
}
|
||||
converI18n(language, &data)
|
||||
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/regular"
|
||||
"be.ems/src/modules/common/model"
|
||||
"be.ems/src/modules/common/service"
|
||||
systemService "be.ems/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 RegisterController 结构体
|
||||
var NewRegister = &RegisterController{
|
||||
registerService: service.NewRegister,
|
||||
sysLogLoginService: systemService.NewSysLogLogin,
|
||||
}
|
||||
|
||||
// 账号注册操作处理
|
||||
//
|
||||
// PATH /
|
||||
type RegisterController struct {
|
||||
registerService *service.Register // 账号注册操作服务
|
||||
sysLogLoginService *systemService.SysLogLogin // 系统登录访问服务
|
||||
}
|
||||
|
||||
// 账号注册
|
||||
//
|
||||
// GET /register
|
||||
func (s *RegisterController) Register(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body model.RegisterBody
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(40422, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 判断必传参数
|
||||
if !regular.ValidUsername(body.Username) {
|
||||
// 账号不能以数字开头,可包含大写小写字母,数字,且不少于5位
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "register.errUsername")))
|
||||
return
|
||||
}
|
||||
if !regular.ValidPassword(body.Password) {
|
||||
// 登录密码至少包含大小写字母、数字、特殊符号,且不少于6位
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "register.errPasswd")))
|
||||
return
|
||||
}
|
||||
if body.Password != body.ConfirmPassword {
|
||||
// 用户确认输入密码不一致
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "register.errPasswdNotEq")))
|
||||
return
|
||||
}
|
||||
|
||||
// 当前请求信息
|
||||
ipaddr, location := reqctx.IPAddrLocation(c)
|
||||
os, browser := reqctx.UaOsBrowser(c)
|
||||
|
||||
// 校验验证码
|
||||
err := s.registerService.ValidateCaptcha(
|
||||
body.Code,
|
||||
body.UUID,
|
||||
)
|
||||
// 根据错误信息,创建系统访问记录
|
||||
if err != nil {
|
||||
msg := err.Error() + " code: " + body.Code
|
||||
s.sysLogLoginService.Insert(
|
||||
body.Username, constants.STATUS_NO, msg,
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
userId, err := s.registerService.ByUserName(body.Username, body.Password)
|
||||
if err == nil {
|
||||
msg := i18n.TTemplate(language, "register.successMsg", map[string]any{"name": body.Username, "id": userId})
|
||||
s.sysLogLoginService.Insert(
|
||||
body.Username, constants.STATUS_YES, msg,
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
// 注册成功
|
||||
c.JSON(200, resp.OkMsg(i18n.TKey(language, "register.success")))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
}
|
||||
Reference in New Issue
Block a user