You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

248 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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
}