Browse Source

应用管理修改,应用用户注册添加

huangyan 10 months ago
parent
commit
9fb4b01c79

+ 54 - 0
app/controller/appUser.go

@@ -0,0 +1,54 @@
+package controller
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/go-playground/validator/v10"
+	"project_management/app/e"
+	"project_management/app/model"
+	"project_management/app/services"
+)
+
+var AppUser services.AppUser = &model.AppUser{}
+
+// RegistApply 注册app用户
+func RegistApply(c *gin.Context) {
+	var appuser model.AppUserRegist
+	if err := c.ShouldBindJSON(&appuser); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	if !model.IsRegist(appuser.AppID) {
+		e.ResponseWithMsg(c, e.TheSystemCannotBeRegistered, e.TheSystemCannotBeRegistered.GetMsg())
+		return
+	}
+	user := AppUser.RegistAppUser(appuser)
+	if user == e.SUCCESS {
+		e.ResponseWithMsg(c, e.SUCCESS, e.SUCCESS.GetMsg())
+		return
+	}
+	e.ResponseWithMsg(c, user, user.GetMsg())
+}
+
+// AddAppUser 添加用户
+func AddAppUser(c *gin.Context) {
+	var appuser model.AppUser
+	if err := c.ShouldBindJSON(&appuser); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	validate := validator.New()
+	if err := validate.Struct(appuser); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, err.Error())
+		return
+	}
+	user := AppUser.AddAppUser(appuser)
+	if user == e.SUCCESS {
+		e.ResponseWithMsg(c, e.SUCCESS, e.SUCCESS.GetMsg())
+		return
+	}
+	e.ResponseWithMsg(c, user, user.GetMsg())
+}
+
+func GetAppUserList(c *gin.Context) {
+
+}

+ 121 - 3
app/controller/apply.go

@@ -11,11 +11,70 @@ import (
 
 var Apply services.Apply = &model.Apply{}
 
+// GetApplyList 用户获取自己的应用列表
 func GetApplyList(c *gin.Context) {
+	var params unity.QueryPageParams
+	var apply model.Apply
+	if err := c.ShouldBindJSON(&params); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	queryCond := "app_name like ?"
+	params.Query = "%" + params.Query + "%"
+	uId, _ := unity.GetUId(c)
+	apply.UserId = uId
+	result, total, err := Apply.GetApplyList(params, apply, queryCond)
+	if err != nil {
+		e.ResponseWithMsg(c, e.PaginationFailed, e.PaginationFailed.GetMsg())
+		return
+	} else {
+		e.ResPonsePage(c, result, total, params)
+		return
+	}
+}
+
+// GetApplyState 根据状态筛选
+func GetApplyState(c *gin.Context) {
+	var params unity.QueryPageParams
+	var apply model.Apply
+	if err := c.ShouldBindJSON(&params); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	queryCond := "app_name like ?"
+	params.Query = "%" + params.Query + "%"
+	uId, _ := unity.GetUId(c)
+	apply.UserId = uId
+	result, total, err := Apply.GetApplyList(params, apply, queryCond)
+	if err != nil {
+		e.ResponseWithMsg(c, e.PaginationFailed, e.PaginationFailed.GetMsg())
+		return
+	} else {
+		e.ResPonsePage(c, result, total, params)
+		return
+	}
+}
 
+// AdminApplyList 管理员获取所有应用列表
+func AdminApplyList(c *gin.Context) {
+	var params unity.QueryPageParams
+	if err := c.ShouldBindJSON(&params); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	queryCond := "app_name like ?"
+	params.Query = "%" + params.Query + "%"
+	result, total, err := unity.PaginateWithCondition(params, model.Apply{}, queryCond)
+	if err != nil {
+		e.ResponseWithMsg(c, e.PaginationFailed, e.PaginationFailed.GetMsg())
+		return
+	} else {
+		e.ResPonsePage(c, result, total, params)
+		return
+	}
 }
 
-// AddApply 添加应用
+// AddApply 用户添加应用
 func AddApply(c *gin.Context) {
 	var apply model.Apply
 	if err := c.ShouldBindJSON(&apply); err != nil {
@@ -24,7 +83,7 @@ func AddApply(c *gin.Context) {
 	}
 	validate := validator.New()
 	if err := validate.Struct(apply); err != nil {
-		e.ResponseWithMsg(c, e.ERROR, err.Error())
+		e.ResponseWithMsg(c, e.ERROR, "请检查必填项")
 		return
 	}
 	// 生成应用ID
@@ -32,6 +91,65 @@ func AddApply(c *gin.Context) {
 	for model.AppIdISRepeat(id) {
 		id = unity.RandomAppID()
 	}
+	//获取当前用户ID
+	uId, username := unity.GetUId(c)
+	apply.UserId = uId
 	apply.AppID = id
-	Apply.AddApply(apply)
+	apply.UserName = username
+	addApply := Apply.AddApply(apply)
+	if addApply != e.SUCCESS {
+		e.ResponseWithMsg(c, addApply, addApply.GetMsg())
+		return
+	} else {
+		e.ResponseSuccess(c, nil)
+	}
+}
+
+// UserUpdateApply 用户更新应用
+func UserUpdateApply(c *gin.Context) {
+	var apply model.Apply
+	if err := c.ShouldBindJSON(&apply); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	id, _ := unity.GetUId(c)
+	apply.UserId = id
+	updateApply := Apply.UserUpdateApply(apply)
+	if updateApply != e.SUCCESS {
+		e.ResponseWithMsg(c, updateApply, updateApply.GetMsg())
+		return
+	}
+	e.ResponseSuccess(c, nil)
+}
+
+// GetApplyByAPPID 用户获取应用详情
+func GetApplyByAPPID(c *gin.Context) {
+	appid := c.Query("appid")
+	validate := validator.New()
+	if err := validate.Var(appid, "required"); err != nil {
+		e.ResponseWithMsg(c, e.ERROR, err.Error())
+		return
+	}
+	apply, err := Apply.GetApplyById(appid)
+	if err != nil {
+		e.ResponseWithMsg(c, e.ERROR, "当前应用不可用")
+		return
+	}
+	e.ResponseSuccess(c, apply)
+}
+
+// GetApplyByName 未登录状态下的模糊查询获取应用
+func GetApplyByName(c *gin.Context) {
+	appname := c.Query("appname")
+	validate := validator.New()
+	if err := validate.Var(appname, "required"); err != nil {
+		e.ResponseWithMsg(c, e.ERROR, err.Error())
+		return
+	}
+	apply, err := Apply.QueryApplyByAppName(appname)
+	if err != nil {
+		e.ResponseWithMsg(c, e.ERROR, "未查找到相关应用")
+		return
+	}
+	e.ResponseSuccess(c, apply)
 }

+ 28 - 0
app/controller/capabilities.go

@@ -0,0 +1,28 @@
+package controller
+
+import (
+	"github.com/gin-gonic/gin"
+	"project_management/app/e"
+	"project_management/app/model"
+	"project_management/app/services"
+	"project_management/unity"
+)
+
+var Capabilities services.Capabilities = &model.Capabilities{}
+
+// GetCapabilities 获取所有能力
+func GetCapabilities(c *gin.Context) {
+	var params unity.QueryPageParams
+	if err := c.ShouldBindQuery(&params); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	queryCond := "cap_name like ?"
+	params.Query = "%" + params.Query + "%"
+	result, total, err := Capabilities.GetCapabilitiesList(params, model.Capabilities{}, queryCond)
+	if err != nil {
+		e.ResponseWithMsg(c, e.PaginationFailed, e.PaginationFailed.GetMsg())
+		return
+	}
+	e.ResPonsePage(c, result, total, params)
+}

+ 51 - 0
app/controller/user.go

@@ -0,0 +1,51 @@
+package controller
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/go-playground/validator/v10"
+	"project_management/app/e"
+	"project_management/app/model"
+	"project_management/app/services"
+	"project_management/utils"
+)
+
+var User services.User = &model.User{}
+
+// SendCode 发送验证码登录
+func SendCode(c *gin.Context) {
+	phone := c.PostForm("phone")
+	validate := validator.New()
+	err := validate.Var(phone, "required,min=11,max=11")
+	if err != nil {
+		e.ResponseWithMsg(c, e.ThePhoneNumberIsWrong, e.ThePhoneNumberIsWrong.GetMsg())
+		return
+	}
+	sendModel := utils.SendModel(phone)
+	if sendModel != e.SUCCESS {
+		e.ResponseWithMsg(c, sendModel, sendModel.GetMsg())
+		return
+	} else {
+		e.ResponseSuccess(c, "发送成功")
+	}
+}
+
+// Login 登录
+func Login(c *gin.Context) {
+	var userRegit model.UserRegist
+	if err := c.ShouldBind(&userRegit); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	validate := validator.New()
+	if err := validate.Struct(userRegit); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, err.Error())
+		return
+	}
+	token, rescode := User.Login(userRegit)
+	if rescode != "" {
+		e.ResponseWithMsg(c, e.ERROR, rescode)
+		return
+	} else {
+		e.ResponseSuccess(c, token)
+	}
+}

+ 12 - 6
app/e/code_msg.go

@@ -28,6 +28,9 @@ const (
 	HasSend
 	TheUserIsEmpty
 	Repeat
+	AddAppUserFail
+	RegistrationFailed
+	TheSystemCannotBeRegistered
 )
 
 var MsgFlags = map[Rescode]string{
@@ -40,7 +43,7 @@ var MsgFlags = map[Rescode]string{
 	UPDATEFAIL:                    "更新失败",
 	Theuseralreadyexists:          "用户已存在",
 	JSONParsingFailed:             "json解析失败",
-	ThePhoneNumberIsWrong:         "手机号错误",
+	ThePhoneNumberIsWrong:         "手机号格式错误",
 	HasSend:                       "验证码已发送",
 	AlreadyExists:                 "手机号已存在",
 	AccountExists:                 "账号已存在",
@@ -48,11 +51,14 @@ var MsgFlags = map[Rescode]string{
 	TheVerificationCodeWasNotSent: "验证码未发送",
 	AnExceptionOccursWhenSendingAnSMSVerificationCode: "发送短信验证码出现异常",
 	ThePasswordIsWrongOrThePhoneNumberIsIncorrect:     "手机号或者密码错误",
-	TokenIsInvalid: "Token 无效",
-	TokenIsExpired: "Token 过期",
-	TokenIsFaild:   "Token 生成失败",
-	TheUserIsEmpty: "用户为空",
-	Repeat:         "应用名重复",
+	TokenIsInvalid:              "Token 无效",
+	TokenIsExpired:              "Token 过期",
+	TokenIsFaild:                "Token 生成失败",
+	TheUserIsEmpty:              "用户为空",
+	Repeat:                      "应用名重复",
+	AddAppUserFail:              "添加用户失败",
+	RegistrationFailed:          "注册失败",
+	TheSystemCannotBeRegistered: "该系统未开放注册",
 }
 
 func (c Rescode) GetMsg() string {

+ 4 - 1
app/middleware/login_middleware.go

@@ -5,6 +5,7 @@ import (
 	"github.com/gin-gonic/gin"
 	"project_management/app/e"
 	"project_management/nats"
+	"strings"
 	"time"
 )
 
@@ -17,9 +18,11 @@ type UserResponse struct {
 func LoginMiddleware() gin.HandlerFunc {
 	return func(c *gin.Context) {
 		header := c.GetHeader("Authorization")
-		request, err := nats.Nats.Request("login_token_validation", []byte(header), 3*time.Second)
+		split := strings.Split(header, ":")
+		request, err := nats.Nats.Request("login_token_validation", []byte(split[1]), 3*time.Second)
 		if err != nil {
 			e.ResponseWithMsg(c, e.TokenIsInvalid, e.TokenIsInvalid.GetMsg())
+			c.Abort()
 		} else {
 			var response UserResponse
 			sonic.Unmarshal(request.Data, &response)

+ 28 - 0
app/middleware/logon_middeware.go

@@ -0,0 +1,28 @@
+package middlewares
+
+import (
+	"github.com/gin-gonic/gin"
+	"project_management/app/e"
+	"project_management/utils"
+	"strings"
+)
+
+func LogonMiddeware() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		header := c.GetHeader("Authorization")
+		split := strings.Split(header, ":")
+		if header == "" {
+			e.ResponseWithMsg(c, e.TokenIsInvalid, e.TokenIsInvalid.GetMsg())
+			c.Abort()
+		} else {
+			_, err := utils.ParseToken(split[1])
+			if err != nil {
+				e.ResponseWithMsg(c, e.TokenIsInvalid, err.Error())
+				c.Abort()
+			} else {
+				c.Next()
+			}
+		}
+
+	}
+}

+ 90 - 0
app/model/appUser.go

@@ -0,0 +1,90 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"project_management/app/e"
+	"project_management/global"
+	"project_management/unity"
+	"project_management/utils"
+	"time"
+)
+
+type AppUser struct {
+	gorm.Model
+	Username      string `gorm:"type:varchar(50);index:username_name,unique" json:"username" validate:"required" min:"3" max:"50"` // 用户名
+	Phone         string `gorm:"type:varchar(50);" json:"phone" min:"11" max:"11"`                                                 // 手机号
+	Nickname      string `gorm:"type:varchar(50);" json:"nickname"`                                                                // 昵称
+	Password      string `gorm:"type:varchar(50);" json:"password" validate:"required"`                                            // 密码
+	LastLoginTime string `gorm:"type:datetime;" json:"last_login_time"`                                                            // 最后登录时间
+	State         int    `gorm:"type:int;" json:"state"`                                                                           // 状态 0:正常 1:禁用
+	AppID         string `gorm:"type:varchar(50);" json:"app_id" validate:"required"`                                              // 应用id
+	RegistMethod  int    `gorm:"type:int;" json:"regist_method"`                                                                   // 注册方式 1 短信登录 2 微信登录 3 系统添加
+}
+type AppUserRegist struct {
+	Username     string `gorm:"type:varchar(50);index:username_name,unique" json:"username" validate:"required" min:"3" max:"50"` // 用户名
+	Phone        string `gorm:"type:varchar(50);" json:"phone" validate:"required" min:"11" max:"11"`                             // 手机号
+	Nickname     string `gorm:"type:varchar(50);" json:"nickname"`                                                                // 昵称
+	Password     string `gorm:"type:varchar(50);" json:"password" validate:"required" min:"6" max:"20"`                           // 密码
+	AppID        string `gorm:"type:varchar(50);not null;unique" json:"app_id" validate:"required"`                               // 应用id
+	Code         string `json:"code" validate:"required" min:"6" max:"6"`                                                         // 验证码
+	RegistMethod int    `gorm:"type:int;" json:"regist_method"`                                                                   // 注册方式 1 短信登录 2 微信登录 3 系统添加
+}
+
+// RegistAppUser 注册用户
+func (a AppUser) RegistAppUser(appUser AppUserRegist) e.Rescode {
+	//TODO implement me
+	tx := global.DBLink.Select("phone").Where("phone = ?", appUser.Phone).First(&a)
+	ctx := context.Background()
+	result, err := global.Rdb.Get(ctx, appUser.Phone).Result()
+	if err != nil {
+		return e.TheVerificationCodeWasNotSent
+	} else if result != appUser.Code {
+		return e.CodeIsError
+	}
+	if tx.RowsAffected == 0 {
+		a.AppID = appUser.AppID
+		a.State = 0
+		a.Phone = appUser.Phone
+		a.Username = appUser.Username
+		a.Nickname = "游客" + unity.RandomId()
+		md5 := utils.MD5(appUser.Password)
+		a.Password = md5
+		a.LastLoginTime = time.Now().Format("2006-01-02 15:04:05")
+		a.RegistMethod = appUser.RegistMethod
+		tableName := "appUser_" + appUser.AppID
+		//验证表是否已经创建,没有则创建
+		table := global.DBLink.Migrator().HasTable(tableName)
+		if !table {
+			global.DBLink.Table(tableName).AutoMigrate(&AppUser{})
+		}
+		db := global.DBLink.Table(tableName).Create(&a)
+		if db.Error != nil {
+			return e.RegistrationFailed
+		}
+		return e.SUCCESS
+	}
+	return e.AlreadyExists
+}
+
+// AddAppUser 添加用户
+func (a AppUser) AddAppUser(appUser AppUser) e.Rescode {
+	//TODO implement me
+	//验证表是否已经创建,没有则创建
+	tableName := "appUser_" + appUser.AppID
+	table := global.DBLink.Migrator().HasTable(tableName)
+	if !table {
+		global.DBLink.Table(tableName).AutoMigrate(&AppUser{})
+	}
+	a.AppID = appUser.AppID
+	a.State = 0
+	a.Nickname = appUser.Nickname
+	a.Username = appUser.Username
+	a.Password = utils.MD5(appUser.Password)
+	a.LastLoginTime = time.Now().Format("2006-01-02 15:04:05")
+	a.RegistMethod = 3
+	if err := global.DBLink.Table(tableName).Create(&a).Error; err != nil {
+		return e.AddAppUserFail
+	}
+	return e.SUCCESS
+}

+ 118 - 7
app/model/apply.go

@@ -4,24 +4,120 @@ import (
 	"gorm.io/gorm"
 	"project_management/app/e"
 	"project_management/global"
+	"project_management/unity"
 	"strings"
 	"time"
 )
 
 type Apply struct {
 	gorm.Model
-	AppID             string    `gorm:"type:varchar(50);not null;unique" json:"app_id"`                                              // 应用id
-	AppName           string    `gorm:"type:varchar(50);index:idx_name,unique" json:"app_name" validate:"required" min:"3" max:"20"` // 应用名称
-	AppDescription    string    `gorm:"type:varchar(50);not null;unique" json:"app_description" validate:"required"`                 // 应用描述
-	CertificationTime time.Time `gorm:"type:datetime;not null;unique" json:"certification_time"`                                     // 认证到期时间
-	State             int       `gorm:"type:int;not null;unique" json:"state"`                                                       // 状态 0 正常 1 停用 2 过期 3 禁用
+	AppID                  string    `gorm:"type:varchar(50);not null;unique" json:"app_id"`                                              // 应用id
+	UserId                 int       `gorm:"type:int;" json:"user_id"`                                                                    // 用户id
+	UserName               string    `gorm:"type:varchar(50);" json:"user_name"`                                                          // 用户名
+	AppName                string    `gorm:"type:varchar(50);index:idx_name,unique" json:"app_name" validate:"required" min:"3" max:"20"` // 应用名称
+	AppDescription         string    `gorm:"type:varchar(50);" json:"app_description" validate:"required"`                                // 应用描述
+	CertificationTime      time.Time `gorm:"type:datetime;" json:"certification_time"`                                                    // 认证到期时间
+	State                  int       `gorm:"type:int;" json:"state"`                                                                      // 状态 1 正常 2 停用 3 过期 4 禁用
+	Icon                   string    `gorm:"type:varchar(50);" json:"icon"`                                                               // 应用图标
+	StartupDiagram         string    `gorm:"type:varchar(50);" json:"startup_diagram"`                                                    // 启动图
+	LoginMode              int       `gorm:"type:int;" json:"login_mode"`                                                                 // 登录模式 1 公开注册 2禁止注册
+	LoginMethod            int       `gorm:"type:int;" json:"login_method"`                                                               // 登录方式 1 短信登录 2 微信登录
+	BackgroundImage        string    `gorm:"type:varchar(50);" json:"background_image"`                                                   // 背景图
+	BackgroundImageObscure int       `gorm:"type:int;" json:"background_image_obscure"`                                                   // 背景图模糊度
+}
+
+func (a Apply) QueryApplyByAppName(appName string) ([]Apply, error) {
+	//TODO implement me
+	var app []Apply
+	tx := global.DBLink.
+		Select("app_name", "icon", "app_description", "app_id", "user_name").
+		Where("app_name like ?", "%"+appName+"%").
+		Find(&app)
+	if tx.Error != nil {
+		return nil, tx.Error
+	}
+	return app, nil
+}
+
+func (a Apply) GetApplyById(appid string) (Apply, error) {
+	//TODO implement me
+	tx := global.DBLink.
+		Select("app_name", "icon", "app_description", "app_id", "user_name").
+		Where("app_id=?", appid).
+		Where("state=?", 1).
+		First(&a)
+	if tx.Error != nil {
+		return Apply{}, tx.Error
+	}
+	if tx.RowsAffected > 0 {
+		return a, nil
+	}
+	return Apply{}, nil
+}
+
+func (a Apply) UserUpdateApply(apply Apply) e.Rescode {
+	//TODO implement me
+	tx := global.DBLink.Where("id=?", apply.ID).Where("user_id=?", apply.UserId).Updates(&apply)
+	if tx.Error != nil {
+		return e.ERROR
+	}
+	if tx.RowsAffected > 0 {
+		return e.SUCCESS
+	}
+	return e.ERROR
+}
+
+func (a Apply) GetApplyList(params unity.QueryPageParams, apply Apply, queryCond string) (result []Apply, total int64, err error) {
+	var count int64
+	if params.Query != "%%" && params.State != "" {
+		if err = global.DBLink.Model(apply).Where(queryCond, params.Query).Where("user_id=?", apply.UserId).Count(&count).Error; err != nil {
+			return nil, 0, err
+		}
+		// 计算查询的偏移量,并设置每次查询的记录数量
+		offset := (params.Page - 1) * params.Size
+		// 执行分页查询,包括偏移量设置、限制查询数量、排序及应用额外查询条件
+		if err = global.DBLink.Offset(offset).Limit(params.Size).Order(params.Desc).Where(queryCond, params.Query).Where("user_id=?", apply.UserId).Find(&result).Error; err != nil {
+			return nil, 0, err
+		}
+	} else if params.State != "" && params.Query == "%%" {
+		if err = global.DBLink.Model(apply).Where("state=?", params.State).Where("user_id=?", apply.UserId).Count(&count).Error; err != nil {
+			return nil, 0, err
+		}
+		// 计算查询的偏移量,并设置每次查询的记录数量
+		offset := (params.Page - 1) * params.Size
+		// 执行分页查询,包括偏移量设置、限制查询数量、排序及应用额外查询条件
+		if err = global.DBLink.Offset(offset).Limit(params.Size).Order(params.Desc).Where("state=?", params.State).Where("user_id=?", apply.UserId).Find(&result).Error; err != nil {
+			return nil, 0, err
+		}
+	} else if params.State != "" && params.Query != "%%" {
+		if err = global.DBLink.Model(apply).Where(queryCond, params.Query).Where("state=?", params.State).Where("user_id=?", apply.UserId).Count(&count).Error; err != nil {
+			return nil, 0, err
+		}
+		// 计算查询的偏移量,并设置每次查询的记录数量
+		offset := (params.Page - 1) * params.Size
+		// 执行分页查询,包括偏移量设置、限制查询数量、排序及应用额外查询条件
+		if err = global.DBLink.Offset(offset).Limit(params.Size).Order(params.Desc).Where(queryCond, params.Query).Where("state=?", params.State).Where("user_id=?", apply.UserId).Find(&result).Error; err != nil {
+			return nil, 0, err
+		}
+	} else {
+		if err = global.DBLink.Model(apply).Where("user_id=?", apply.UserId).Count(&count).Error; err != nil {
+			return nil, 0, err
+		}
+		// 计算查询的偏移量,并设置每次查询的记录数量
+		offset := (params.Page - 1) * params.Size
+		// 执行分页查询,包括偏移量设置、限制查询数量、排序及应用额外查询条件
+		if err = global.DBLink.Where("user_id=?", apply.UserId).Offset(offset).Limit(params.Size).Order(params.Desc).Find(&result).Error; err != nil {
+			return nil, 0, err
+		}
+	}
+	return result, count, nil
 }
 
 func (a Apply) AddApply(apply Apply) e.Rescode {
 	//TODO implement me
 	//默认每一应用有一年免费时间
-	apply.CertificationTime = apply.CreatedAt.Add(time.Hour * 24 * 365)
-	apply.State = 0
+	apply.CertificationTime = time.Now().Add(time.Hour * 24 * 365)
+	apply.State = 1
 	tx := global.DBLink.Create(&apply)
 	if tx.Error != nil {
 		errMsg := tx.Error.Error()
@@ -34,6 +130,8 @@ func (a Apply) AddApply(apply Apply) e.Rescode {
 	}
 	return e.SUCCESS
 }
+
+// AppIdISRepeat 检查id是否重复
 func AppIdISRepeat(id string) bool {
 	tx := global.DBLink.Where("app_id = ?", id).First(&Apply{})
 	if tx.RowsAffected > 0 {
@@ -41,3 +139,16 @@ func AppIdISRepeat(id string) bool {
 	}
 	return false
 }
+
+// IsRegist 判断是否可以注册
+func IsRegist(appid string) bool {
+	tx := global.DBLink.Model(&Apply{}).
+		Select("login_mode", "app_id").
+		Where("app_id=?", appid).
+		Where("state=?", 1).
+		Where("login_mode=?", 1)
+	if tx.RowsAffected > 0 {
+		return true
+	}
+	return false
+}

+ 31 - 0
app/model/capabilities.go

@@ -0,0 +1,31 @@
+package model
+
+import (
+	"gorm.io/gorm"
+	"project_management/app/e"
+	"project_management/unity"
+)
+
+type Capabilities struct {
+	gorm.Model
+	CapName string `gorm:"type:varchar(50);" json:"cap_name"` // 应用名
+	CpaType string `gorm:"type:varchar(50);" json:"cap_type"` // 应用类型
+	Image   string `gorm:"type:varchar(50);" json:"image"`    // 应用图标
+	CapId   string `gorm:"type:varchar(50);" json:"cap_id"`   // 应用id
+	Price   int    `gorm:"type:int;" json:"price"`
+}
+
+func (c Capabilities) AddCapabilities(capabilities Capabilities) e.Rescode {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (c Capabilities) GetCapabilitiesList(params unity.QueryPageParams, capabilities Capabilities, queryCond interface{}) (result []Capabilities, total int64, err error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (c Capabilities) GetCapabilitiesById(id string) (Capabilities, error) {
+	//TODO implement me
+	panic("implement me")
+}

+ 43 - 0
app/model/user.go

@@ -0,0 +1,43 @@
+package model
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"project_management/global"
+	"project_management/utils"
+)
+
+type User struct {
+	gorm.Model
+	Phone string `gorm:"type:varchar(50);" json:"phone" validate:"required" min:"11" max:"11"`
+}
+type UserRegist struct {
+	Phone string `json:"phone" validate:"required" min:"11" max:"11"`
+	Code  string `json:"code" validate:"required" min:"6" max:"6"`
+}
+
+func (u User) Login(user UserRegist) (string, string) {
+	//TODO implement me
+	tx := global.DBLink.Where("phone = ?", user.Phone).First(&u)
+	ctx := context.Background()
+	result, err := global.Rdb.Get(ctx, user.Phone).Result()
+	if err != nil {
+		return "", "验证验证码失败请联系管理员"
+	} else if result != user.Code {
+		return "", "验证码错误"
+	}
+	token, err := utils.CreateToken(u.ID, u.Phone, "user")
+	token = "interior:" + token
+	if err != nil {
+		return "", "创建令牌失败"
+	}
+	if tx.RowsAffected == 0 {
+		u.Phone = user.Phone
+		create := global.DBLink.Create(&u)
+		if create.Error != nil {
+			return "", "登录失败"
+		}
+		return token, ""
+	}
+	return token, ""
+}

+ 11 - 0
app/router.go

@@ -2,10 +2,21 @@ package app
 
 import (
 	"github.com/gin-gonic/gin"
+	middlewares "project_management/app/middleware"
+	"project_management/app/routers"
 	"project_management/global"
 )
 
 func InitRouter() error {
 	engine := gin.New()
+	engine.Use(middlewares.Cors())
+	routers.UserRouter(engine)
+	//外部用户登录
+	engine.Use(middlewares.LogonMiddeware())
+	routers.AppUserRouter(engine)
+	routers.ApplyNotLogin(engine)
+	//管理员登录
+	engine.Use(middlewares.LoginMiddleware())
+	routers.ApplyRouter(engine)
 	return engine.Run(global.ServerSetting.Port)
 }

+ 13 - 0
app/routers/appUser.go

@@ -0,0 +1,13 @@
+package routers
+
+import (
+	"github.com/gin-gonic/gin"
+	"project_management/app/controller"
+)
+
+func AppUserRouter(r *gin.Engine) {
+	group := r.Group("/api")
+	group.POST("/regist", controller.RegistApply)
+	group.POST("/appuser", controller.AddAppUser)
+
+}

+ 14 - 0
app/routers/apply.go

@@ -0,0 +1,14 @@
+package routers
+
+import (
+	"github.com/gin-gonic/gin"
+	"project_management/app/controller"
+)
+
+func ApplyRouter(r *gin.Engine) {
+	group := r.Group("/api")
+	group.POST("/apply", controller.AddApply)
+	group.POST("/applyall", controller.GetApplyList)
+	group.POST("/applystate", controller.GetApplyState)
+	group.PUT("/apply", controller.UserUpdateApply)
+}

+ 12 - 0
app/routers/applynotlogin.go

@@ -0,0 +1,12 @@
+package routers
+
+import (
+	"github.com/gin-gonic/gin"
+	"project_management/app/controller"
+)
+
+func ApplyNotLogin(r *gin.Engine) {
+	group := r.Group("/api")
+	group.GET("/applyname", controller.GetApplyByName)
+	group.GET("/apply", controller.GetApplyByAPPID)
+}

+ 12 - 0
app/routers/user.go

@@ -0,0 +1,12 @@
+package routers
+
+import (
+	"github.com/gin-gonic/gin"
+	"project_management/app/controller"
+)
+
+func UserRouter(r *gin.Engine) {
+	group := r.Group("/api")
+	group.POST("/user/sendcode", controller.SendCode)
+	group.POST("/user/login", controller.Login)
+}

+ 11 - 0
app/services/appUser.go

@@ -0,0 +1,11 @@
+package services
+
+import (
+	"project_management/app/e"
+	"project_management/app/model"
+)
+
+type AppUser interface {
+	AddAppUser(appUser model.AppUser) e.Rescode
+	RegistAppUser(appUser model.AppUserRegist) e.Rescode
+}

+ 5 - 0
app/services/apply.go

@@ -3,8 +3,13 @@ package services
 import (
 	"project_management/app/e"
 	"project_management/app/model"
+	"project_management/unity"
 )
 
 type Apply interface {
 	AddApply(apply model.Apply) e.Rescode
+	GetApplyList(params unity.QueryPageParams, apply model.Apply, queryCond string) (result []model.Apply, total int64, err error)
+	UserUpdateApply(apply model.Apply) e.Rescode
+	GetApplyById(appid string) (model.Apply, error)
+	QueryApplyByAppName(appName string) ([]model.Apply, error)
 }

+ 13 - 0
app/services/capabilities.go

@@ -0,0 +1,13 @@
+package services
+
+import (
+	"project_management/app/e"
+	"project_management/app/model"
+	"project_management/unity"
+)
+
+type Capabilities interface {
+	AddCapabilities(capabilities model.Capabilities) e.Rescode
+	GetCapabilitiesList(params unity.QueryPageParams, capabilities model.Capabilities, queryCond interface{}) (result []model.Capabilities, total int64, err error)
+	GetCapabilitiesById(id string) (model.Capabilities, error)
+}

+ 9 - 0
app/services/user.go

@@ -0,0 +1,9 @@
+package services
+
+import (
+	"project_management/app/model"
+)
+
+type User interface {
+	Login(user model.UserRegist) (string, string)
+}

+ 1 - 1
configs/config.yaml

@@ -35,7 +35,7 @@ subMail:
   appid: "97173"
   signature: "f639a60e41ee0554921d89884f5ff87e"
 redis:
-  addr: "192.168.0.100:6379"
+  addr: "192.168.11.33:6379"
   password: ""
   db: 0
 nats:

+ 12 - 0
database/createNewTable.go

@@ -0,0 +1,12 @@
+package database
+
+import (
+	"gorm.io/gorm"
+	"project_management/app/model"
+)
+
+// CreateNewTable 动态创建新表
+func CreateNewTable(db *gorm.DB, tableName string) {
+	db.Table(tableName).AutoMigrate(&model.AppUser{})
+
+}

+ 2 - 0
database/migrate.go

@@ -8,5 +8,7 @@ import (
 func Migrate(db *gorm.DB) {
 	db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(
 		model.Apply{},
+		model.User{},
+		model.Capabilities{},
 	)
 }

+ 4 - 1
go.mod

@@ -3,6 +3,7 @@ module project_management
 go 1.21
 
 require (
+	github.com/bytedance/sonic v1.11.6
 	github.com/gin-gonic/gin v1.10.0
 	github.com/go-playground/locales v0.14.1
 	github.com/go-playground/universal-translator v0.18.1
@@ -17,7 +18,6 @@ require (
 )
 
 require (
-	github.com/bytedance/sonic v1.11.6 // indirect
 	github.com/bytedance/sonic/loader v0.1.1 // indirect
 	github.com/cespare/xxhash/v2 v2.1.2 // indirect
 	github.com/cloudwego/base64x v0.1.4 // indirect
@@ -26,8 +26,11 @@ require (
 	github.com/fsnotify/fsnotify v1.7.0 // indirect
 	github.com/gabriel-vasile/mimetype v1.4.3 // indirect
 	github.com/gin-contrib/sse v0.1.0 // indirect
+	github.com/go-resty/resty/v2 v2.13.1 // indirect
 	github.com/go-sql-driver/mysql v1.7.0 // indirect
 	github.com/goccy/go-json v0.10.2 // indirect
+	github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
+	github.com/google/uuid v1.6.0 // indirect
 	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect

+ 46 - 0
go.sum

@@ -34,13 +34,19 @@ github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4
 github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
 github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
 github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
+github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g=
+github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0=
 github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
 github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
 github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
 github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
+github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
 github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
 github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
@@ -123,6 +129,7 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
 github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
 github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
 github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
 go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
 go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
@@ -132,18 +139,57 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
 golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
 golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
 golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
 golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
 golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
 golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
 golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
 golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
 golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
+golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
 golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
 google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

+ 7 - 4
main.go

@@ -5,6 +5,7 @@ import (
 	"project_management/app"
 	"project_management/database"
 	"project_management/global"
+	"project_management/nats"
 	"project_management/simple_zap"
 	"project_management/unity"
 )
@@ -25,13 +26,15 @@ func init() {
 		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "注册本地化失败")
 	}
 	//nats
-	//nats.SetupNats()
+	nats.SetupNats()
+	//redis
+	global.SetupRedisLink()
 }
 
-// @title 面板开发
+// @title 项目管理
 // @version 1.0
-// @description 面板开发
-// @Host 127.0.0.1:8081
+// @description 项目管理
+// @Host 127.0.0.1:9999
 // @BasePath /api
 //
 //go:generate swag init --parseDependency --parseDepth=6

+ 4 - 3
unity/getuid.go

@@ -4,13 +4,14 @@ import (
 	"github.com/gin-gonic/gin"
 )
 
-func GetUId(c *gin.Context) int {
+func GetUId(c *gin.Context) (int, string) {
 	//mustGet := c.MustGet("user")
 	value, exists := c.Get("user")
 	if exists {
 		users := value.(map[string]interface{})
 		id := int(users["ID"].(float64))
-		return id
+		name := users["username"].(string)
+		return id, name
 	}
-	return 0
+	return 0, ""
 }

+ 1 - 2
unity/randomId.go

@@ -9,8 +9,7 @@ import (
 func RandomId() string {
 	const letterBytes = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 	rand.Seed(time.Now().UnixNano())
-
-	b := make([]byte, 32)
+	b := make([]byte, 8)
 	for i := range b {
 		b[i] = letterBytes[rand.Intn(len(letterBytes))]
 	}

+ 1 - 0
unity/unity.go

@@ -15,6 +15,7 @@ type QueryPageParams struct {
 	Size  int    `json:"size" form:"size"`
 	Query string `json:"query" form:"query"`
 	Desc  string `json:"desc" form:"desc"`
+	State string `json:"state" form:"state"`
 }
 
 // Paginate 使用给定的DB连接执行分页查询

+ 47 - 0
utils/create_code.go

@@ -0,0 +1,47 @@
+package utils
+
+import (
+	"context"
+	"fmt"
+	"go.uber.org/zap"
+	"math/rand"
+	"project_management/app/e"
+	"project_management/global"
+	"time"
+)
+
+func CreatCode() string {
+	const chars = "0123456789"
+	result := make([]byte, 6)
+	rand.Seed(time.Now().UnixNano())
+	for i := range result {
+		index := rand.Intn(len(chars))
+		result[i] = chars[index]
+	}
+	return string(result)
+}
+
+func SendModel(phone string) e.Rescode {
+	ctx := context.Background()
+	ss := NewSMS(global.SubMailSetting.Appid, global.SubMailSetting.Signature)
+	result, err := global.Rdb.Exists(ctx, phone).Result()
+	if result == 1 {
+		fmt.Println("验证码已经发送", zap.Error(err))
+		return e.HasSend
+	}
+	if err != nil {
+		fmt.Println("redis查询出现异常", zap.Error(err))
+		return e.TheSystemIsAbnormal
+	}
+	code := CreatCode()
+	content := fmt.Sprintf("【宝智达物联智控平台】您的短信验证码:%s,请在5分钟内输入", code)
+	res, err := ss.Send(phone, content)
+	if err != nil || res.Status != SUCCESS {
+		fmt.Println("发送短信验证码出现异常", zap.Any("res", res), zap.Error(err))
+		return e.AnExceptionOccursWhenSendingAnSMSVerificationCode
+	} else {
+		//验证码装入redis并且设置过期时间
+		err = global.Rdb.Set(ctx, phone, code, 300*time.Second).Err()
+		return e.SUCCESS
+	}
+}

+ 59 - 0
utils/create_token.go

@@ -0,0 +1,59 @@
+package utils
+
+import (
+	"errors"
+	"github.com/golang-jwt/jwt/v4"
+	"project_management/global"
+	"time"
+)
+
+type MyClaims struct {
+	UserId   uint   `json:"user_id"`
+	UserName string `json:"user_name"`
+	Role     string `json:"role"`
+	jwt.RegisteredClaims
+}
+
+const TokenExpireDuration = time.Hour * 999999
+
+func CreateToken(userId uint, userName, role string) (string, error) {
+	claims := MyClaims{
+		UserId:   userId,
+		UserName: userName,
+		Role:     role,
+		RegisteredClaims: jwt.RegisteredClaims{
+			ExpiresAt: jwt.NewNumericDate(time.Now().Add(TokenExpireDuration)),
+			Issuer:    global.JwtSetting.Issuer,
+		},
+	}
+	var mySerect = []byte(global.JwtSetting.Secret)
+	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+	return token.SignedString(mySerect)
+}
+func ParseToken(tokenStr string) (*MyClaims, error) {
+	// 使用全局配置中的密钥对token进行解析。
+	var mySecret = []byte(global.JwtSetting.Secret)
+
+	// 尝试解析并验证JWT令牌。
+	claims := new(MyClaims)
+	token, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (interface{}, error) {
+		return mySecret, nil
+	})
+
+	if err != nil {
+		if errors.Is(err, jwt.ErrSignatureInvalid) || errors.Is(err, jwt.ErrInvalidKey) {
+			return nil, errors.New("无效的签名或密钥")
+		} else if ve, ok := err.(*jwt.ValidationError); ok && ve.Errors&jwt.ValidationErrorExpired != 0 {
+			return nil, errors.New("令牌已过期")
+		}
+		return nil, errors.New("令牌解析失败")
+	}
+
+	// 验证令牌是否有效。
+	if !token.Valid {
+		return nil, errors.New("无效的令牌")
+	}
+
+	// 如果令牌有效,则返回解析出的声明信息。
+	return claims, nil
+}

+ 13 - 0
utils/md5.go

@@ -0,0 +1,13 @@
+package utils
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+)
+
+func MD5(password string) string {
+	bytes := []byte(password)
+	sum := md5.Sum(bytes)
+	toString := hex.EncodeToString(sum[:])
+	return toString
+}

+ 55 - 0
utils/sms.go

@@ -0,0 +1,55 @@
+package utils
+
+import (
+	"encoding/json"
+	"github.com/go-resty/resty/v2"
+)
+
+const (
+	SUCCESS = "success"
+)
+
+type SMS struct {
+	Appid     string
+	Signature string
+}
+
+func NewSMS(appid, signature string) *SMS {
+	return &SMS{
+		Appid:     appid,
+		Signature: signature,
+	}
+}
+
+type SendRes struct {
+	Status  string `json:"status"`
+	Send_id string `json:"send_id"`
+	Fee     int    `json:"fee"`
+	Msg     string `json:"msg"`
+	Code    int    `json:"code"`
+}
+
+// Send 短信发送
+func (t *SMS) Send(to, content string) (SendRes, error) {
+	client := resty.New()
+	resp, err := client.R().
+		SetHeader("Content-Type", "application/x-www-form-urlencoded").
+		SetFormData(map[string]string{
+			"appid":     t.Appid,
+			"signature": t.Signature,
+			"to":        to,
+			"content":   content,
+		}).
+		SetResult(&SendRes{}).
+		Post("https://api-v4.mysubmail.com/sms/send.json")
+
+	if err != nil {
+		return SendRes{}, err
+	}
+
+	temp := SendRes{}
+	if err = json.Unmarshal(resp.Body(), &temp); err != nil {
+		return SendRes{}, err
+	}
+	return temp, nil
+}

+ 63 - 0
utils/time.go

@@ -0,0 +1,63 @@
+package utils
+
+import (
+	"database/sql/driver"
+	"fmt"
+	"time"
+)
+
+const timeFormat = "2006-01-02 15:04:05"
+const timezone = "Asia/Shanghai"
+
+// 全局定义
+type Time time.Time
+
+func (t Time) MarshalJSON() ([]byte, error) {
+	b := make([]byte, 0, len(timeFormat)+2)
+	if time.Time(t).IsZero() {
+		b = append(b, '"')
+		b = append(b, '"')
+		return b, nil
+	}
+
+	b = append(b, '"')
+	b = time.Time(t).AppendFormat(b, timeFormat)
+	b = append(b, '"')
+	return b, nil
+}
+
+func (t *Time) UnmarshalJSON(data []byte) (err error) {
+	now, err := time.ParseInLocation(`"`+timeFormat+`"`, string(data), time.Local)
+	*t = Time(now)
+	return
+}
+
+func (t Time) String() string {
+	if time.Time(t).IsZero() {
+		return ""
+	}
+	return time.Time(t).Format(timeFormat)
+}
+
+func (t Time) Local() time.Time {
+	loc, _ := time.LoadLocation(timezone)
+	return time.Time(t).In(loc)
+}
+
+func (t Time) Value() (driver.Value, error) {
+	var zeroTime time.Time
+	var ti = time.Time(t)
+	if ti.UnixNano() == zeroTime.UnixNano() {
+		return nil, nil
+	}
+	return ti, nil
+}
+
+func (t *Time) Scan(v interface{}) error {
+	value, ok := v.(time.Time)
+	if ok {
+		*t = Time(value)
+		return nil
+	}
+	return fmt.Errorf("can not convert %v to timestamp", v)
+}