🎉初步完成用户

This commit is contained in:
coward
2024-10-18 17:19:19 +08:00
commit f375118c88
45 changed files with 3302 additions and 0 deletions

20
http/api/admin/base.go Normal file
View File

@@ -0,0 +1,20 @@
package admin
import (
"github.com/gin-gonic/gin"
"website-nav/http/response"
"website-nav/http/vo"
)
// GetCurrentLoginUser
// @description: 获取当前登陆用户
// @param c
// @return *vo.User
func GetCurrentLoginUser(c *gin.Context) *vo.User {
if user, ok := c.Get("user"); ok {
return user.(*vo.User)
}
response.R(c).AuthorizationFailed("暂未登陆")
c.Abort()
return nil
}

111
http/api/admin/login.go Normal file
View File

@@ -0,0 +1,111 @@
package admin
import (
"fmt"
"gitee.ltd/lxh/logger/log"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/mojocn/base64Captcha"
"time"
"website-nav/component"
"website-nav/http/param"
"website-nav/http/response"
"website-nav/http/vo"
"website-nav/service"
"website-nav/utils"
)
type Login struct{}
func LoginAPI() Login {
return Login{}
}
// Captcha
// @description: 获取验证码
// @receiver login
// @param c
func (Login) Captcha(c *gin.Context) {
math := base64Captcha.DriverMath{Height: 120, Width: 480, Fonts: []string{"ApothecaryFont.ttf", "3Dumb.ttf"}}
mathDriver := math.ConvertFonts()
capt := base64Captcha.NewCaptcha(mathDriver, component.Captcha{})
id, base64Str, _, err := capt.Generate()
if err != nil {
response.R(c).FailedWithError(fmt.Errorf("生成验证码失败: %s", err.Error()))
return
}
response.R(c).OkWithData(map[string]any{
"id": id,
"captcha": base64Str,
})
}
// Login
// @description: 登陆
// @receiver login
// @param c
func (Login) Login(c *gin.Context) {
var p param.Login
if err := c.ShouldBind(&p); err != nil {
response.R(c).Validator(err)
return
}
// 验证验证码是否正确
ok := component.Captcha{}.Verify(p.CaptchaId, p.CaptchaCode, true)
if !ok {
response.R(c).FailedWithError("验证码错误")
return
}
// 验证码正确,查询用户信息
user, err := service.User().GetUserByAccount(p.Account)
if err != nil {
response.R(c).FailedWithError("获取用户信息失败")
return
}
// 对比密码
if !utils.Password().ComparePassword(user.Password, p.Password) {
response.R(c).FailedWithError("密码错误")
return
}
secret := component.JWT().GenerateSecret(p.Password, uuid.NewString(), time.Now().Local().String())
// 生成token
token, expireAt, err := component.JWT().GenerateToken(user.Id, secret)
if err != nil {
log.Errorf("用户[%s]生成token失败: %v", user.Account, err.Error())
response.R(c).FailedWithError("登陆失败!")
return
}
c.Writer.Header().Set("X-TOKEN", secret)
response.R(c).OkWithData(map[string]any{
"token": token,
"type": "Bearer",
"expireAt": expireAt,
})
}
// Logout
// @description: 退出登陆
// @receiver LoginApi
// @param c
func (Login) Logout(c *gin.Context) {
loginUser, ok := c.Get("user")
if !ok {
response.R(c).AuthorizationFailed("未登陆")
return
}
if err := component.JWT().Logout(loginUser.(*vo.User).Id); err != nil {
response.R(c).FailedWithError("退出登陆失败")
return
}
response.R(c).OK()
}

185
http/api/admin/user.go Normal file
View File

@@ -0,0 +1,185 @@
package admin
import (
"encoding/base64"
"errors"
"fmt"
"github.com/gin-gonic/gin"
"website-nav/http/param"
"website-nav/http/response"
"website-nav/http/vo"
"website-nav/model"
"website-nav/service"
"website-nav/utils"
)
type User struct{}
func UserAPI() User {
return User{}
}
// GetLoginUser
// @description: 获取当前登陆用户信息
// @receiver u
// @param c
func (u User) GetLoginUser(c *gin.Context) {
var loginUser *vo.User
if loginUser = GetCurrentLoginUser(c); c.IsAborted() {
return
}
response.R(c).OkWithData(loginUser)
}
// List
// @description: 用户列表
// @receiver u
// @param c
func (u User) List(c *gin.Context) {
var p param.UserList
if err := c.ShouldBind(&p); err != nil {
response.R(c).Validator(err)
return
}
data, total, err := service.User().List(p)
if err != nil {
response.R(c).FailedWithError(err)
return
}
response.R(c).Paginate(data, total, p.Current, p.Size)
}
// Save
// @description: 新增/编辑用户
// @receiver u
// @param c
func (u User) Save(c *gin.Context) {
var p param.SaveUser
if err := c.ShouldBind(&p); err != nil {
response.R(c).Validator(err)
return
}
ent := &model.User{
Base: model.Base{
Id: p.Id,
},
Account: p.Account,
Password: p.Password,
Avatar: p.Avatar,
Nickname: p.Nickname,
Contact: p.Contact,
}
if err := service.User().CreateUser(ent); err != nil {
response.R(c).FailedWithError(err)
return
}
response.R(c).OK()
}
// Delete
// @description: 删除用户
// @receiver u
// @param c
func (u User) Delete(c *gin.Context) {
var id = c.Param("id")
if id == "" || id == "undefined" {
response.R(c).Validator(errors.New("id不能为空"))
return
}
if err := service.User().Delete(id); err != nil {
response.R(c).FailedWithError(err)
return
}
response.R(c).OK()
}
// ChangePassword
// @description: 修改密码
// @receiver u
// @param c
func (u User) ChangePassword(c *gin.Context) {
var p param.ChangePassword
if err := c.ShouldBind(&p); err != nil {
response.R(c).Validator(err)
return
}
user := GetCurrentLoginUser(c)
if user == nil {
response.R(c).FailedWithError("用户信息错误")
return
}
// 判断原密码是否对
if !utils.Password().ComparePassword(user.Password, p.OriginalPassword) {
response.R(c).FailedWithError("原密码错误")
return
}
// 修改密码
if err := service.User().ChangePassword(user.Id, p.NewPassword); err != nil {
response.R(c).FailedWithError(err)
return
}
response.R(c).OK()
}
// ResetPassword
// @description: 重置密码
// @receiver UserApi
// @param c
func (u User) ResetPassword(c *gin.Context) {
var id = c.Param("id")
if id == "" || id == "undefined" {
response.R(c).FailedWithError("id不能为空")
return
}
loginUser := GetCurrentLoginUser(c)
if loginUser == nil {
response.R(c).FailedWithError("用户信息错误")
return
}
// 先查询一下
user, err := service.User().GetUserById(id)
if err != nil {
response.R(c).FailedWithError("获取用户信息失败")
return
}
if user.Account == loginUser.Account {
response.R(c).FailedWithError("当前用户不可重置密码")
return
}
// 修改密码
if err := service.User().ChangePassword(user.Id, "admin123"); err != nil {
response.R(c).FailedWithError(err)
return
}
response.R(c).OK()
}
// GenerateAvatar
// @description: 生成头像
// @receiver UserApi
// @param c
func (u User) GenerateAvatar(c *gin.Context) {
avatar, err := utils.Avatar().GenerateAvatar(false)
if err != nil {
response.R(c).FailedWithError(fmt.Errorf("生成头像失败: %s", err.Error()))
return
}
response.R(c).OkWithData(fmt.Sprintf("data:image/png;base64,%s", base64.StdEncoding.EncodeToString([]byte(avatar))))
}