|
|
package web
|
|
|
|
|
|
import (
|
|
|
// "fmt"
|
|
|
"goskeleton/app/global/consts"
|
|
|
"goskeleton/app/global/variable"
|
|
|
"goskeleton/app/model"
|
|
|
"goskeleton/app/service/users/curd"
|
|
|
userstoken "goskeleton/app/service/users/token"
|
|
|
"goskeleton/app/utils/response"
|
|
|
rsa "goskeleton/app/utils/rsa"
|
|
|
"time"
|
|
|
"net/http"
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
)
|
|
|
|
|
|
type Users struct {
|
|
|
}
|
|
|
|
|
|
// 1.用户注册
|
|
|
func (u *Users) Register(context *gin.Context) {
|
|
|
// 由于本项目骨架已经将表单验证器的字段(成员)绑定在上下文,因此可以按照 GetString()、context.GetBool()、GetFloat64()等快捷获取需要的数据类型,注意:相关键名规则: 前缀+验证器结构体中的 json 标签
|
|
|
// 注意:在 ginskeleton 中获取表单参数验证器中的数字键(字段),请统一使用 GetFloat64(),其它获取数字键(字段)的函数无效,例如:GetInt()、GetInt64()等
|
|
|
// 当然也可以通过gin框架的上下文原始方法获取,例如: context.PostForm("user_name") 获取,这样获取的数据格式为文本,需要自己继续转换
|
|
|
userName := context.GetString(consts.ValidatorPrefix + "user_name")
|
|
|
pass := context.GetString(consts.ValidatorPrefix + "pass")
|
|
|
// userIp := context.ClientIP()
|
|
|
// if curd.CreateUserCurdFactory().Register(userName, pass, userIp) {
|
|
|
if curd.CreateUserCurdFactory().Register(userName, pass) {
|
|
|
response.Success(context, consts.CurdStatusOkMsg, "")
|
|
|
} else {
|
|
|
response.Fail(context, consts.CurdRegisterFailCode, consts.CurdRegisterFailMsg, "")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 2.用户登录
|
|
|
func (u *Users) Login(c *gin.Context) {
|
|
|
userName := c.GetString(consts.ValidatorPrefix + "user_name")
|
|
|
pass := c.GetString(consts.ValidatorPrefix + "pass")
|
|
|
// 密码解密
|
|
|
pass = string(u.DecryptPassword(userName,pass))
|
|
|
|
|
|
// phone := context.GetString(consts.ValidatorPrefix + "phone")
|
|
|
userModelFact := model.CreateUserFactory("")
|
|
|
userModel := userModelFact.Login(userName, pass)
|
|
|
|
|
|
if userModel != nil {
|
|
|
userTokenFactory := userstoken.CreateUserFactory()
|
|
|
if userToken, err := userTokenFactory.GenerateToken( userModel.Id,userName, variable.ConfigYml.GetInt64("Token.JwtTokenCreatedExpireAt")); err == nil {
|
|
|
if userTokenFactory.RecordLoginToken(userModel.Id,userToken) { // 记录用户登录记录,不必要,但会将token存入Redis,懒得改了
|
|
|
data := gin.H{
|
|
|
"userId": userModel.Id,
|
|
|
// "user_name": userName,
|
|
|
// "realName": userModel.RealName,
|
|
|
// "phone": phone,
|
|
|
"token": userToken,
|
|
|
"updated_at": time.Now().Format(variable.DateFormat),
|
|
|
}
|
|
|
response.Success(c, consts.CurdStatusOkMsg, data)
|
|
|
// go userModel.UpdateUserloginInfo( userModel.Id)
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
response.Fail(c, consts.CurdLoginFailCode, consts.CurdLoginFailMsg, "")
|
|
|
}
|
|
|
|
|
|
// 刷新用户token
|
|
|
func (u *Users) RefreshToken(context *gin.Context) {
|
|
|
oldToken := context.GetString(consts.ValidatorPrefix + "token")
|
|
|
if newToken, ok := userstoken.CreateUserFactory().RefreshToken(oldToken); ok {
|
|
|
res := gin.H{
|
|
|
"token": newToken,
|
|
|
}
|
|
|
response.Success(context, consts.CurdStatusOkMsg, res)
|
|
|
} else {
|
|
|
response.Fail(context, consts.CurdRefreshTokenFailCode, consts.CurdRefreshTokenFailMsg, "")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 后面是 curd 部分,自带版本中为了降低初学者学习难度,使用了最简单的方式操作 增、删、改、查
|
|
|
// 在开发企业实际项目中,建议使用我们提供的一整套 curd 快速操作模式
|
|
|
// 参考地址:https://gitee.com/daitougege/GinSkeleton/blob/master/docs/concise.md
|
|
|
// 您也可以参考 Admin 项目地址:https://gitee.com/daitougege/gin-skeleton-admin-backend/ 中, app/model/ 提供的示例语法
|
|
|
|
|
|
//3.用户查询(show)
|
|
|
func (u *Users) Info(c *gin.Context) {
|
|
|
userName := c.GetString(consts.ValidatorPrefix + "user_name")
|
|
|
// page := context.GetFloat64(consts.ValidatorPrefix + "page")
|
|
|
// limit := context.GetFloat64(consts.ValidatorPrefix + "limit")
|
|
|
// limitStart := (page - 1) * limit
|
|
|
res := model.CreateUserFactory("").Info(userName)
|
|
|
if res.UserName != ""{
|
|
|
response.Success(c, consts.CurdStatusOkMsg, gin.H{"id":res.Id,"user_name":res.UserName})
|
|
|
} else {
|
|
|
response.Fail(c, consts.CurdSelectFailCode, consts.CurdSelectFailMsg, "")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//4.用户新增(store)
|
|
|
// func (u *Users) Store(context *gin.Context) {
|
|
|
// userName := context.GetString(consts.ValidatorPrefix + "user_name")
|
|
|
// pass := context.GetString(consts.ValidatorPrefix + "pass")
|
|
|
// realName := context.GetString(consts.ValidatorPrefix + "real_name")
|
|
|
// phone := context.GetString(consts.ValidatorPrefix + "phone")
|
|
|
// remark := context.GetString(consts.ValidatorPrefix + "remark")
|
|
|
|
|
|
// if curd.CreateUserCurdFactory().Store(userName, pass, realName, phone, remark) {
|
|
|
// response.Success(context, consts.CurdStatusOkMsg, "")
|
|
|
// } else {
|
|
|
// response.Fail(context, consts.CurdCreatFailCode, consts.CurdCreatFailMsg, "")
|
|
|
// }
|
|
|
// }
|
|
|
|
|
|
//5.用户更新(update)
|
|
|
func (u *Users) NameUpdate(c *gin.Context) {
|
|
|
//表单参数验证中的int、int16、int32 、int64、float32、float64等数字键(字段),请统一使用 GetFloat64() 获取,其他函数无效
|
|
|
userId := c.GetFloat64(consts.ValidatorPrefix + "id")
|
|
|
userName := c.GetString(consts.ValidatorPrefix + "user_name")
|
|
|
// pass := context.GetString(consts.ValidatorPrefix + "pass")
|
|
|
// realName := context.GetString(consts.ValidatorPrefix + "real_name")
|
|
|
// phone := context.GetString(consts.ValidatorPrefix + "phone")
|
|
|
// remark := context.GetString(consts.ValidatorPrefix + "remark")
|
|
|
// userIp := context.ClientIP()
|
|
|
|
|
|
// 检查正在修改的用户名是否被其他人使用
|
|
|
if model.CreateUserFactory("").UpdateDataCheckUserNameIsUsed(int(userId), userName) > 0 {
|
|
|
response.Fail(c, consts.CurdUpdateFailCode, consts.CurdUpdateFailMsg+", "+userName+" 已经被其他人使用", "")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
//注意:这里没有实现更加精细的权限控制逻辑,例如:超级管理管理员可以更新全部用户数据,普通用户只能修改自己的数据。目前只是验证了token有效、合法之后就可以进行后续操作
|
|
|
// 实际使用请根据真是业务实现权限控制逻辑、再进行数据库操作
|
|
|
// if len(pass)>0{
|
|
|
// if !curd.CreateUserCurdFactory().UpdatePassword(int(userId),pass) {
|
|
|
// response.Fail(context, consts.CurdUpdatePassFailCode, consts.CurdUpdatePassFailMsg, "")
|
|
|
// }
|
|
|
// }
|
|
|
if curd.CreateUserCurdFactory().NameUpdate(int(userId), userName) {
|
|
|
response.Success(c, consts.CurdStatusOkMsg, "")
|
|
|
} else {
|
|
|
response.Fail(c, consts.CurdUpdateFailCode, consts.CurdUpdateFailMsg, "")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func (u *Users) PasswordUpdate(c *gin.Context) {
|
|
|
//表单参数验证中的int、int16、int32 、int64、float32、float64等数字键(字段),请统一使用 GetFloat64() 获取,其他函数无效
|
|
|
userId := c.GetFloat64(consts.ValidatorPrefix + "id")
|
|
|
userName :=c.GetString(consts.ValidatorPrefix + "user_name")
|
|
|
// userName := context.GetString(consts.ValidatorPrefix + "user_name")
|
|
|
oldpass := c.GetString(consts.ValidatorPrefix + "oldpass")
|
|
|
newpass := c.GetString(consts.ValidatorPrefix + "newpass")
|
|
|
// 密码解密
|
|
|
oldpass = string(u.DecryptPassword(userName, oldpass))
|
|
|
newpass = string(u.DecryptPassword(userName, newpass))
|
|
|
|
|
|
//注意:这里没有实现更加精细的权限控制逻辑,例如:超级管理管理员可以更新全部用户数据,普通用户只能修改自己的数据。目前只是验证了token有效、合法之后就可以进行后续操作
|
|
|
// 实际使用请根据真是业务实现权限控制逻辑、再进行数据库操作
|
|
|
userModelFact := model.CreateUserFactory("")
|
|
|
userModel := userModelFact.UpdatePassword(int(userId),userName, oldpass,newpass)
|
|
|
|
|
|
if userModel != nil {
|
|
|
response.Success(c, consts.CurdStatusOkMsg, "")
|
|
|
// go userModel.UpdateUserloginInfo( userModel.Id)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
response.Fail(c, consts.CurdUpdateFailCode, consts.CurdUpdateFailMsg, "")
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
//6.删除记录
|
|
|
func (u *Users) Destroy(context *gin.Context) {
|
|
|
//表单参数验证中的int、int16、int32 、int64、float32、float64等数字键(字段),请统一使用 GetFloat64() 获取,其他函数无效
|
|
|
userId := context.GetFloat64(consts.ValidatorPrefix + "id")
|
|
|
pass :=context.GetString(consts.ValidatorPrefix + "pass")
|
|
|
userName:=context.GetString(consts.ValidatorPrefix + "user_name")
|
|
|
// 密码解密
|
|
|
pass = string(u.DecryptPassword(userName, pass))
|
|
|
if model.CreateUserFactory("").Destroy(int(userId),userName,pass) {
|
|
|
response.Success(context, consts.CurdStatusOkMsg, "")
|
|
|
} else {
|
|
|
response.Fail(context, consts.CurdDeleteFailCode, consts.CurdDeleteFailMsg, "")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func (u *Users) Logout(c *gin.Context) {
|
|
|
//表单参数验证中的int、int16、int32 、int64、float32、float64等数字键(字段),请统一使用 GetFloat64() 获取,其他函数无效
|
|
|
id := c.GetFloat64(consts.ValidatorPrefix + "id")
|
|
|
userName:=c.GetString(consts.ValidatorPrefix + "user_name")
|
|
|
if model.CreateUserFactory("").Logout(int(id),userName) {
|
|
|
response.Success(c, consts.CurdStatusOkMsg, "")
|
|
|
} else {
|
|
|
response.Fail(c, consts.CurdLogoutFailCode, consts.CurdDeleteFailMsg, "")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 返回user_name对应的公钥;如果不存在,会重新创建并存储后返回新的公钥
|
|
|
func (u *Users)PublicKey(c *gin.Context){
|
|
|
userName:=c.GetString(consts.ValidatorPrefix+"user_name")
|
|
|
key := model.CreateUserFactory("").PublicKey(userName)
|
|
|
// fmt.Println("public key: ",string(key))
|
|
|
if key!=nil{
|
|
|
// response.Success(c,consts.CurdStatusOkMsg,gin.H{"PublicKey":key})
|
|
|
c.Data(http.StatusOK, "application/x-pem-file", key)
|
|
|
}else{
|
|
|
response.Fail(c,consts.CurdPublicKeyFailCode,consts.CurdPublicKeyFailMsg,"")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 密码解密
|
|
|
func (u *Users)DecryptPassword(userName, pass string) []byte {
|
|
|
if pass == "" {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// 获取私钥
|
|
|
key := model.CreateUserFactory("").PrivateKey(userName)
|
|
|
if key == nil {
|
|
|
variable.ZapLog.Error("私钥获取失败")
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// 解析私钥
|
|
|
privateKey, err := rsa.ParsePrivateKeyFromPEM(key)
|
|
|
if err != nil {
|
|
|
variable.ZapLog.Error("私钥解析失败,"+err.Error())
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// Base64 解码密码
|
|
|
encryptedPassword, err := rsa.DecodeBase64(pass)
|
|
|
if err != nil {
|
|
|
variable.ZapLog.Error("密码Base64解码失败")
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// 使用私钥解密密码
|
|
|
decryptedBytes, err := rsa.DecryptWithPrivateKey(privateKey, encryptedPassword)
|
|
|
if err != nil {
|
|
|
variable.ZapLog.Error("密码使用私钥解密失败")
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
return decryptedBytes
|
|
|
} |