Go+Vue3开发博客系统(五)
本文最后更新于 2024-08-19,文章内容距离上一次更新已经过去了很久啦,可能已经过时了,请谨慎参考喵。
前情提要
JWT鉴权配置
首先安装依赖:
go get github.com/dgrijalva/jwt-go
下一步在 /config.yaml
中添加配置:
# 系统配置
system:
# 运行地址:本地
host: "0.0.0.0"
# 端口
port: 5001
# 启动环境:debug/release
env: debug
# logger 日志配置
logger:
# 日志等级
level: info
# 日志前缀
prefix: '[goblog-admin]'
# 日志文件路径
director: logger
# 显示行号
show_line: true
# 是否打印在控制台
log_in_console: true
# MySQL 配置
mysql:
# 监听地址
host: 127.0.0.1
# 端口
port: 3306
# 数据库名称
db_name: goblogtest
# 链接数据库用户名
username: goblogtest
# 链接数据库密码
password: goblogtest
# 日志等级
log_level: dev
# 字符集设置
charset: utf8mb4
# 最大连接数
maxIdle: 50
# 最大连接时间
maxOpen: 150
# Redis 配置
redis:
# redis 访问地址
address: 127.0.0.1:6379
# redis 连接密码
password:
# 数据库(默认为0,第一个)
db: 0
# JWT token 配置
token:
# 请求头
headers: Bearer
# 过期时间
expireTime: 24
# 密钥
secret: goblog-admin
# 签名
issuer: admin
下一步在 /config/config.go
中定义结构体:
// 读取配置文件
// @author DaBaiLuoBo
package config
import (
"gopkg.in/yaml.v2"
"io/ioutil"
)
// config 总配置文件
type config struct {
System system `yaml:"system"`
Logger logger `yaml:"logger"`
Mysql mysql `yaml:"mysql"`
Redis redis `yaml:"redis"`
Token token `yaml:"token"`
}
// 系统配置
type system struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
Env string `yaml:"env"`
}
// logger 日志配置
type logger struct {
Level string `yaml:"level"`
Prefix string `yaml:"prefix"`
Director string `yaml:"director"`
ShowLine bool `yaml:"show_line"`
LogInConsole bool `yaml:"log_in_console"`
}
// MySQL 配置
type mysql struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
DbName string `yaml:"db_name"`
Username string `yaml:"username"`
Password string `yaml:"password"`
LogLevel string `yaml:"log_level"`
Charset string `yaml:"charset"`
MaxIdle int `yaml:"maxIdle"`
MaxOpen int `yaml:"maxOpen"`
}
// Redis 配置
type redis struct {
Address string `yaml:"address"`
Password string `yaml:"password"`
Db int `yaml:"db"`
}
// JWT token 配置
type token struct {
Headers string `yaml:"headers"`
ExpireTime int `yaml:"expireTime"`
Secret string `yaml:"secret"`
Issuer string `yaml:"issuer"`
}
var Config *config
// init 初始化配置
func init() {
yamlFile, err := ioutil.ReadFile("./config.yaml") // 注意这里的路径,是和根目录同级
// 如果为空,直接返回错误内容
if err != nil {
return
}
// 接收配置文件,存入 Config 中
yaml.Unmarshal(yamlFile, &Config)
}
在 /main.go
中打印测试一下配置是否正确:
// 测试打印 token 配置
global.Log.Infof("Token 配置:%s:%d:%s:%s", config.Config.Token.Headers, config.Config.Token.ExpireTime, config.Config.Token.Secret, config.Config.Token.Issuer)
启动测试一下:
可以看到,有一个参数是不对的,修改一下配置文件 /config/config.go
中的过期时间:
ExpireTime int `yaml:"expireTime"`
这里插一嘴,最好将
/config.yaml
和/config/config.go
中的相关参数名称更换为驼峰命名,请尽量减少下划线的使用
我已经更改完毕了 /config.yaml
:
# 系统配置
system:
# 运行地址:本地
host: "0.0.0.0"
# 端口
port: 5001
# 启动环境:debug/release
env: debug
# logger 日志配置
logger:
# 日志等级
level: info
# 日志前缀
prefix: '[goblog-admin]'
# 日志文件路径
director: logger
# 显示行号
showLine: true
# 是否打印在控制台
logInConsole: true
# MySQL 配置
mysql:
# 监听地址
host: 127.0.0.1
# 端口
port: 3306
# 数据库名称
dbName: goblogtest
# 链接数据库用户名
username: goblogtest
# 链接数据库密码
password: goblogtest
# 日志等级
logLevel: dev
# 字符集设置
charset: utf8mb4
# 最大连接数
maxIdle: 50
# 最大连接时间
maxOpen: 150
# Redis 配置
redis:
# redis 访问地址
address: 127.0.0.1:6379
# redis 连接密码
password:
# 数据库(默认为0,第一个)
db: 0
# JWT token 配置
token:
# 请求头
headers: Bearer
# 过期时间
expireTime: 24
# 密钥
secret: goblog-admin
# 签名
issuer: admin
/config/config.go
:
// 读取配置文件
// @author DaBaiLuoBo
package config
import (
"gopkg.in/yaml.v2"
"io/ioutil"
)
// config 总配置文件
type config struct {
System system `yaml:"system"`
Logger logger `yaml:"logger"`
Mysql mysql `yaml:"mysql"`
Redis redis `yaml:"redis"`
Token token `yaml:"token"`
}
// 系统配置
type system struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
Env string `yaml:"env"`
}
// logger 日志配置
type logger struct {
Level string `yaml:"level"`
Prefix string `yaml:"prefix"`
Director string `yaml:"director"`
ShowLine bool `yaml:"showLine"`
LogInConsole bool `yaml:"logInConsole"`
}
// MySQL 配置
type mysql struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
DbName string `yaml:"dbName"`
Username string `yaml:"username"`
Password string `yaml:"password"`
LogLevel string `yaml:"logLevel"`
Charset string `yaml:"charset"`
MaxIdle int `yaml:"maxIdle"`
MaxOpen int `yaml:"maxOpen"`
}
// Redis 配置
type redis struct {
Address string `yaml:"address"`
Password string `yaml:"password"`
Db int `yaml:"db"`
}
// JWT token 配置
type token struct {
Headers string `yaml:"headers"`
ExpireTime int `yaml:"expireTime"`
Secret string `yaml:"secret"`
Issuer string `yaml:"issuer"`
}
var Config *config
// init 初始化配置
func init() {
yamlFile, err := ioutil.ReadFile("./config.yaml") // 注意这里的路径,是和根目录同级
// 如果为空,直接返回错误内容
if err != nil {
return
}
// 接收配置文件,存入 Config 中
yaml.Unmarshal(yamlFile, &Config)
}
再测试一下:
现在没什么问题了
Token生成
第一步还是先定义生成token所需要的一个结构体 /model/sysAdmin.go
:
为什么还是在用户模型里呢?这是因为 token 的生成是根据登录用户的特征去生成的
// 系统用户相关模型
// @author DaBaiLuoBo
package model
import "goblog-admin/utils"
// SysAdmin 用户模型对象
type SysAdmin struct {
ID uint `gorm:"column:id;comment:'主键';primaryKey;NOT NULL" json:"id"` // ID
Username string `gorm:"column:username;varchar(64);comment:'用户账号';NOT NULL" json:"username"` // 用户账号
Password string `gorm:"column:password;varchar(64);comment:'密码';NOT NULL" json:"password"` // 密码
Nickname string `gorm:"column:nickname;varchar(64);comment:'昵称'" json:"nickname"` // 昵称
Status int `gorm:"column:status;default:1;comment:'账号启用状态:1-启用;2-禁用';NOT NULL" json:"status"` // 账号启用状态:1-启用;2-禁用
Icon string `gorm:"column:icon;varchar(500);comment:'头像'" json:"icon"` // 头像
Sex int `gorm:"column:sex;default:1;comment:'性别:1-男;2-女';NOT NULL" json:"sex"` // 性别:1-男;2-女
Email string `gorm:"column:email;varchar(64);comment:'邮箱'" json:"email"` // 邮箱
Phone string `gorm:"column:phone;varchar(64);comment:'手机号'" json:"phone"` // 手机号
Note string `gorm:"column:note;varchar(500);comment:'备注信息'" json:"note"` // 备注信息
CreateTime utils.HTime `gorm:"column:create_time;comment:'创建时间';NOT NULL" json:"createTime"` // 创建时间
}
func (SysAdmin) TableName() string {
return "sys_admin"
}
// AddSysAdminDto 新增用户参数对象
type AddSysAdminDto struct {
RoleId uint `validate:"required"` // 角色ID(不是用户ID)
Username string `validate:"required"` // 用户名(账号)
Password string `validate:"required"` // 密码
Nickname string `validate:"required"` // 昵称
Sex int // 性别:1-男;2-女
Phone string `validate:"required"` // 手机号
Email string `validate:"required"` // 邮箱
Note string // 备注信息
Status int `validate:"required"` // 账号启用状态:1-启用;2-禁用
}
// SysAdminInfo 根据ID查询用户
type SysAdminInfo struct {
ID uint `json:"id"` // ID
RoleId uint `json:"roleId"` // 角色ID(不是用户ID)
Username string `json:"username"` // 用户名(账号)
Nickname string `json:"nickname"` // 昵称
Sex int `json:"sex"` // 性别:1-男;2-女
Phone string `json:"phone"` // 手机号
Email string `json:"email"` // 邮箱
Note string `json:"note"` // 备注信息
Status int `json:"status"` // 账号启用状态:1-启用;2-禁用
}
// UpdateSysAdminDto 修改用户信息
type UpdateSysAdminDto struct {
ID uint // ID
RoleId uint `validate:"required"` // 角色ID(不是用户ID)
Username string `validate:"required"` // 用户名(账号)
Nickname string `validate:"required"` // 昵称
Sex int // 性别:1-男;2-女
Phone string `validate:"required"` // 手机号
Email string `validate:"required"` // 邮箱
Note string // 备注信息
Status int `validate:"required"` // 账号启用状态:1-启用;2-禁用
}
// SysAdminIdDto 用户ID参数
type SysAdminIdDto struct {
ID uint `json:"id"` // ID
}
// UpdateSysAdminStatusDto 设置启用状态参数
type UpdateSysAdminStatusDto struct {
ID uint // ID
Status int // 账号启用状态:1-启用;2-禁用
}
// ResetSysAdminPasswordDto 重置密码参数对象
type ResetSysAdminPasswordDto struct {
ID uint // ID
Password string // 密码
}
// SysAdminVo 用户参数对象
type SysAdminVo struct {
ID uint `json:"id"` // ID
Username string `json:"username"` // 用户名(账号)
Nickname string `json:"nickname"` // 昵称
Status int `json:"status"` // 账号启用状态:1-启用;2-禁用
Icon string `json:"icon"` // 头像
Sex int `json:"sex"` // 性别:1-男;2-女
Email string `json:"email"` // 邮箱
Phone string `json:"phone"` // 手机号
Note string `json:"note"` // 备注信息
RoleName string `json:"roleName"` // 备注名称
CreateTime utils.HTime `json:"createTime"` // 创建时间
}
// JwtAdmin 鉴权用户结构体
type JwtAdmin struct {
ID uint `json:"id"` // ID
Username string `json:"username"` // 用户名(账号)
Nickname string `json:"nickname"` // 昵称
Status int `json:"status"` // 账号启用状态:1-启用;2-禁用
Icon string `json:"icon"` // 头像
Email string `json:"email"` // 邮箱
Phone string `json:"phone"` // 手机号
Note string `json:"note"` // 备注信息
ExpireTime int64 `json:"expireTime"` // 过期时间
}
创建一个核心组件 /core/jwt.go
:
// JWT 用户鉴权
// @author DaBaiLuoBo
package core
import (
"github.com/dgrijalva/jwt-go"
"goblog-admin/config"
"goblog-admin/model"
"time"
)
// userStdClaims 结构体
type userStdClaims struct {
model.JwtAdmin
jwt.StandardClaims
}
var (
TokenExpireDuration = time.Duration(config.Config.Token.ExpireTime) * time.Hour // token 过期时间
Secret = []byte(config.Config.Token.Secret) // token 密钥
Issuer = config.Config.Token.Issuer // token 签发人
ErrAbsent = "Token is absent" // 令牌不存在
ErrInvalid = "Token is invalid" // 令牌无效
)
// GenerateTokenByAdmin 根据用户信息生成 token
func GenerateTokenByAdmin(sysAdmin model.SysAdmin) (string, error) {
var jwtAdmin = model.JwtAdmin{
ID: sysAdmin.ID,
Username: sysAdmin.Username,
Nickname: sysAdmin.Nickname,
Status: sysAdmin.Status,
Icon: sysAdmin.Icon,
Email: sysAdmin.Email,
Phone: sysAdmin.Phone,
Note: sysAdmin.Note,
ExpireTime: time.Now().Add(TokenExpireDuration).Unix(),
}
c := userStdClaims{
jwtAdmin,
jwt.StandardClaims{
ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(),
Issuer: Issuer,
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
return token.SignedString(Secret)
}
这样token生成工具就写好了,下一节来测试
登录以及测试Token
第一步还是一样,先在 /model/sysAdmin.go
中定义结构体:
// 系统用户相关模型
// @author DaBaiLuoBo
package model
import "goblog-admin/utils"
// SysAdmin 用户模型对象
type SysAdmin struct {
ID uint `gorm:"column:id;comment:'主键';primaryKey;NOT NULL" json:"id"` // ID
Username string `gorm:"column:username;varchar(64);comment:'用户账号';NOT NULL" json:"username"` // 用户账号
Password string `gorm:"column:password;varchar(64);comment:'密码';NOT NULL" json:"password"` // 密码
Nickname string `gorm:"column:nickname;varchar(64);comment:'昵称'" json:"nickname"` // 昵称
Status int `gorm:"column:status;default:1;comment:'账号启用状态:1-启用;2-禁用';NOT NULL" json:"status"` // 账号启用状态:1-启用;2-禁用
Icon string `gorm:"column:icon;varchar(500);comment:'头像'" json:"icon"` // 头像
Sex int `gorm:"column:sex;default:1;comment:'性别:1-男;2-女';NOT NULL" json:"sex"` // 性别:1-男;2-女
Email string `gorm:"column:email;varchar(64);comment:'邮箱'" json:"email"` // 邮箱
Phone string `gorm:"column:phone;varchar(64);comment:'手机号'" json:"phone"` // 手机号
Note string `gorm:"column:note;varchar(500);comment:'备注信息'" json:"note"` // 备注信息
CreateTime utils.HTime `gorm:"column:create_time;comment:'创建时间';NOT NULL" json:"createTime"` // 创建时间
}
func (SysAdmin) TableName() string {
return "sys_admin"
}
// AddSysAdminDto 新增用户参数对象
type AddSysAdminDto struct {
RoleId uint `validate:"required"` // 角色ID(不是用户ID)
Username string `validate:"required"` // 用户名(账号)
Password string `validate:"required"` // 密码
Nickname string `validate:"required"` // 昵称
Sex int // 性别:1-男;2-女
Phone string `validate:"required"` // 手机号
Email string `validate:"required"` // 邮箱
Note string // 备注信息
Status int `validate:"required"` // 账号启用状态:1-启用;2-禁用
}
// SysAdminInfo 根据ID查询用户
type SysAdminInfo struct {
ID uint `json:"id"` // ID
RoleId uint `json:"roleId"` // 角色ID(不是用户ID)
Username string `json:"username"` // 用户名(账号)
Nickname string `json:"nickname"` // 昵称
Sex int `json:"sex"` // 性别:1-男;2-女
Phone string `json:"phone"` // 手机号
Email string `json:"email"` // 邮箱
Note string `json:"note"` // 备注信息
Status int `json:"status"` // 账号启用状态:1-启用;2-禁用
}
// UpdateSysAdminDto 修改用户信息
type UpdateSysAdminDto struct {
ID uint // ID
RoleId uint `validate:"required"` // 角色ID(不是用户ID)
Username string `validate:"required"` // 用户名(账号)
Nickname string `validate:"required"` // 昵称
Sex int // 性别:1-男;2-女
Phone string `validate:"required"` // 手机号
Email string `validate:"required"` // 邮箱
Note string // 备注信息
Status int `validate:"required"` // 账号启用状态:1-启用;2-禁用
}
// SysAdminIdDto 用户ID参数
type SysAdminIdDto struct {
ID uint `json:"id"` // ID
}
// UpdateSysAdminStatusDto 设置启用状态参数
type UpdateSysAdminStatusDto struct {
ID uint // ID
Status int // 账号启用状态:1-启用;2-禁用
}
// ResetSysAdminPasswordDto 重置密码参数对象
type ResetSysAdminPasswordDto struct {
ID uint // ID
Password string // 密码
}
// SysAdminVo 用户参数对象
type SysAdminVo struct {
ID uint `json:"id"` // ID
Username string `json:"username"` // 用户名(账号)
Nickname string `json:"nickname"` // 昵称
Status int `json:"status"` // 账号启用状态:1-启用;2-禁用
Icon string `json:"icon"` // 头像
Sex int `json:"sex"` // 性别:1-男;2-女
Email string `json:"email"` // 邮箱
Phone string `json:"phone"` // 手机号
Note string `json:"note"` // 备注信息
RoleName string `json:"roleName"` // 备注名称
CreateTime utils.HTime `json:"createTime"` // 创建时间
}
// JwtAdmin 鉴权用户结构体
type JwtAdmin struct {
ID uint `json:"id"` // ID
Username string `json:"username"` // 用户名(账号)
Nickname string `json:"nickname"` // 昵称
Status int `json:"status"` // 账号启用状态:1-启用;2-禁用
Icon string `json:"icon"` // 头像
Email string `json:"email"` // 邮箱
Phone string `json:"phone"` // 手机号
Note string `json:"note"` // 备注信息
ExpireTime int64 `json:"expireTime"` // 过期时间
}
// LoginDto 登录结构体参数
type LoginDto struct {
Username string `json:"username" validate:"required"` // 用户名(账号)
Password string `json:"password" validate:"required"` // 密码
}
再创建一个定义系统常量的组件 /constant/constant.go
:
// 系统常量定义
// @author DaBaiLuoBo
package constant
const (
NormalStatus = 1 // 状态启用
StatusDisable = 2 // 状态停用
)
回到 /api/sysAdmin.go
来写登录方法:
// 系统用户相关接口
// @author DaBaiLuoBo
package api
import (
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"goblog-admin/constant"
"goblog-admin/core"
"goblog-admin/global"
"goblog-admin/model"
"goblog-admin/result"
"goblog-admin/utils"
"strconv"
"time"
)
// CreateSysAdmin 新增用户
// @Summary 新增用户
// @Tags 用户相关接口
// @Produce json
// @Description 新增用户
// @Param data body model.AddSysAdminDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysAdmin/add [post]
func CreateSysAdmin(c *gin.Context) {
var dto model.AddSysAdminDto
_ = c.BindJSON(&dto)
// 对必填参数进行一个校验
err := validator.New().Struct(dto)
if err != nil {
result.Failed(c, int(result.ApiCode.MissParameter), result.ApiCode.GetMessage(result.ApiCode.MissParameter))
return
}
// 查询用户名是否重复
sysAdminByUsername := GetSysAdminByUsername(dto.Username)
if sysAdminByUsername.ID > 0 {
result.Failed(c, int(result.ApiCode.UsernameAlreadyExists), result.ApiCode.GetMessage(result.ApiCode.UsernameAlreadyExists))
return
}
// 新增用户
sysAdmin := model.SysAdmin{
Username: dto.Username,
Nickname: dto.Nickname,
Password: utils.EncryptionMd5(dto.Password), // 使用加密工具类加密密码
Phone: dto.Phone,
Email: dto.Email,
Sex: dto.Sex,
Note: dto.Note,
Status: dto.Status,
CreateTime: utils.HTime{Time: time.Now()},
}
core.Db.Create(&sysAdmin)
// 新增用户与角色关系表信息
sysAdminExists := GetSysAdminByUsername(dto.Username)
var sysAdminRole model.SysAdminRole
sysAdminRole.AdminId = sysAdminExists.ID // 用户ID
sysAdminRole.RoleId = dto.RoleId // 角色ID
core.Db.Create(&sysAdminRole)
result.Success(c, true)
}
// GetSysAdmin 根据ID查询用户
// @Summary 根据ID查询用户
// @Tags 用户相关接口
// @Produce json
// @Description 根据ID查询用户
// @Param id query int true "用户ID"
// @Success 200 {object} result.Result
// @router /api/sysAdmin/info [get]
func GetSysAdmin(c *gin.Context) {
Id, _ := strconv.Atoi(c.Query("id"))
// 定义返回的结构体
var sysAdminInfo model.SysAdminInfo
core.Db.Table("sys_admin").
Select("sys_admin.*", "sys_admin_role.role_id").
Joins("LEFT JOIN sys_admin_role ON sys_admin.id = sys_admin_role.admin_id").
Joins("LEFT JOIN sys_role ON sys_admin_role.role_id = sys_role.id").
First(&sysAdminInfo, Id)
result.Success(c, sysAdminInfo)
}
// UpdateSysAdmin 修改用户信息
// @Summary 修改用户信息
// @Tags 用户相关接口
// @Produce json
// @Description 修改用户信息
// @Param data body model.UpdateSysAdminDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysAdmin/update [put]
func UpdateSysAdmin(c *gin.Context) {
var dto model.UpdateSysAdminDto
_ = c.BindJSON(&dto)
// 对必填参数进行一个校验
err := validator.New().Struct(dto)
if err != nil {
result.Failed(c, int(result.ApiCode.MissParameter), result.ApiCode.GetMessage(result.ApiCode.MissParameter))
return
}
// 先查询用户信息
var sysAdmin model.SysAdmin
core.Db.First(&sysAdmin, dto.ID)
// 再修改用户信息
if dto.Username != "" {
sysAdmin.Username = dto.Username
}
if dto.Nickname != "" {
sysAdmin.Nickname = dto.Nickname
}
if dto.Phone != "" {
sysAdmin.Phone = dto.Phone
}
if dto.Email != "" {
sysAdmin.Email = dto.Email
}
if dto.Note != "" {
sysAdmin.Note = dto.Note
}
sysAdmin.Status = dto.Status
sysAdmin.Sex = dto.Sex
core.Db.Save(&sysAdmin)
// 删除之前绑定的角色再分配新的角色(角色与用户关系表)
var sysAdminRole model.SysAdminRole
core.Db.Where("admin_id = ?", dto.ID).Delete(&model.SysAdminRole{})
sysAdminRole.AdminId = dto.ID
sysAdminRole.RoleId = dto.RoleId
core.Db.Create(&sysAdminRole)
result.Success(c, true)
}
// DeleteSysAdmin 根据ID删除用户
// @Summary 根据ID删除用户
// @Tags 用户相关接口
// @Produce json
// @Description 根据ID删除用户
// @Param data body model.SysAdminIdDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysAdmin/delete [delete]
func DeleteSysAdmin(c *gin.Context) {
var dto model.SysAdminIdDto
_ = c.BindJSON(&dto)
core.Db.Delete(&model.SysAdmin{}, dto.ID)
// 再查询关系表,并删除
core.Db.Where("admin_id = ?", dto.ID).Delete(&model.SysAdminRole{})
result.Success(c, true)
}
// UpdateSysAdminStatus 设置用户启用状态
// @Summary 设置用户启用状态
// @Tags 用户相关接口
// @Produce json
// @Description 设置用户启用状态
// @Param data body model.UpdateSysAdminStatusDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysAdmin/updateStatus [put]
func UpdateSysAdminStatus(c *gin.Context) {
var dto model.UpdateSysAdminStatusDto
_ = c.BindJSON(&dto)
var sysAdmin model.SysAdmin
core.Db.First(&sysAdmin, dto.ID)
sysAdmin.Status = dto.Status
core.Db.Save(&sysAdmin)
result.Success(c, true)
}
// ResetSysAdminPassword 重置用户密码
// @Summary 重置用户密码
// @Tags 用户相关接口
// @Produce json
// @Description 重置用户密码
// @Param data body model.ResetSysAdminPasswordDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysAdmin/resetPassword [put]
func ResetSysAdminPassword(c *gin.Context) {
var dto model.ResetSysAdminPasswordDto
_ = c.BindJSON(&dto)
var sysAdmin model.SysAdmin
core.Db.First(&sysAdmin, dto.ID)
sysAdmin.Password = utils.EncryptionMd5(dto.Password)
core.Db.Save(&sysAdmin)
result.Success(c, true)
}
// GetSysAdminList 分页查询用户列表
// @Summary 分页查询用户列表
// @Tags 用户相关接口
// @Produce json
// @Description 分页查询用户列表
// @Param pageNum query int false "分页数"
// @Param pageSize query int false "每页数"
// @Param username query string false "用户名称"
// @Param status query string false "账号启用状态:1-启用;2-禁用"
// @Param beginTime query string false "开始时间"
// @Param endTime query string false "结束时间"
// @Success 200 {object} result.Result
// @router /api/sysAdmin/list [get]
func GetSysAdminList(c *gin.Context) {
PageNum, _ := strconv.Atoi(c.Query("pageNum"))
PageSize, _ := strconv.Atoi(c.Query("pageSize"))
Username := c.Query("username")
Status := c.Query("status")
BeginTime := c.Query("beginTime")
EndTime := c.Query("endTime")
if PageSize < 1 {
PageSize = 10
}
if PageNum < 1 {
PageNum = 1
}
var sysAdminVo []model.SysAdminVo
var count int64
curDb := core.Db.Table("sys_admin").
Select("sys_admin.*, sys_role.role_name").
Joins("LEFT JOIN sys_admin_role ON sys_admin.id = sys_admin_role.admin_id").
Joins("LEFT JOIN sys_role ON sys_role.id = sys_admin_role.role_id")
if Username != "" {
curDb = curDb.Where("sys_admin.username = ?", Username)
}
if BeginTime != "" && EndTime != "" {
curDb = curDb.Where("sys_admin.create_time BETWEEN ? AND ?", BeginTime, EndTime)
}
if Status != "" {
curDb = curDb.Where("sys_admin.status = ?", Status)
}
curDb.Count(&count).Limit(PageSize).Offset((PageNum - 1) * PageSize).Order("sys_admin.create_time DESC").Find(&sysAdminVo)
result.Success(c, map[string]interface{}{"total": count, "pageSize": PageSize, "pageNum": PageNum, "list": sysAdminVo})
}
// Login 用户登录接口
// @Summary 用户登录接口
// @Tags 用户相关接口
// @Produce json
// @Description 用户登录接口
// @Param data body model.LoginDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysAdmin/login [post]
func Login(c *gin.Context) {
// 绑定 JSON 参数
var dto model.LoginDto
_ = c.BindJSON(&dto)
// 对必填参数进行一个校验
err := validator.New().Struct(dto)
if err != nil {
result.Failed(c, int(result.ApiCode.MissParameter), result.ApiCode.GetMessage(result.ApiCode.MissParameter))
return
}
// 查询用户信息
sysAdmin := GetSysAdminByUsername(dto.Username)
if sysAdmin.Status == constant.StatusDisable {
result.Failed(c, int(result.ApiCode.StatusDisable), result.ApiCode.GetMessage(result.ApiCode.StatusDisable))
return
}
// 用户存在
if sysAdmin.ID > 0 {
// 校验密码是否正确
if sysAdmin.Password != utils.EncryptionMd5(dto.Password) {
result.Failed(c, int(result.ApiCode.PasswordNotTrue), result.ApiCode.GetMessage(result.ApiCode.PasswordNotTrue))
return
}
// 生成 token
token, _ := core.GenerateTokenByAdmin(sysAdmin)
global.Log.Infof("用户 token:%s", token)
// 组装用户信息 todo
// 用户左侧菜单列表数据 todo
// 用户权限列表 todo
// 返回信息 todo
result.Success(c, map[string]any{"token": token})
} else { // 用户不存在
result.Failed(c, int(result.ApiCode.SysAdminIsNotExists), result.ApiCode.GetMessage(result.ApiCode.SysAdminIsNotExists))
return
}
}
// GetSysAdminByUsername 根据用户名称查询用户
func GetSysAdminByUsername(username string) (sysAdmin model.SysAdmin) {
core.Db.Where("username = ?", username).First(&sysAdmin)
return sysAdmin
}
再定义一下新加的 code 码 /result/code.go
:
// 状态码/状态信息
// @author DaiBaiLuoBo
package result
// Codes 定义状态
type Codes struct {
Message map[uint]string
Success uint
Failed uint
SysMenuIsExist uint
DelSysMenuFailed uint
DelSysChildMenuFailed uint
RoleAlreadyExists uint
DelSysRoleFailed uint
MissParameter uint
UsernameAlreadyExists uint
StatusDisable uint
SysAdminIsNotExists uint
PasswordNotTrue uint
}
// ApiCode 状态码
var ApiCode = &Codes{
Success: 200,
Failed: 501,
SysMenuIsExist: 600,
DelSysMenuFailed: 601,
DelSysChildMenuFailed: 602,
RoleAlreadyExists: 603,
DelSysRoleFailed: 604,
MissParameter: 605,
UsernameAlreadyExists: 606,
StatusDisable: 607,
SysAdminIsNotExists: 608,
PasswordNotTrue: 609,
}
// 状态信息初始化
func init() {
ApiCode.Message = map[uint]string{
ApiCode.Success: "成功",
ApiCode.Failed: "失败",
ApiCode.SysMenuIsExist: "菜单名称已存在,请重新输入",
ApiCode.DelSysMenuFailed: "菜单已分配,不能删除",
ApiCode.DelSysChildMenuFailed: "该菜单存在子菜单,不能删除",
ApiCode.RoleAlreadyExists: "角色名或角色Key已存在,请重新输入",
ApiCode.DelSysRoleFailed: "角色已分配,不能删除",
ApiCode.MissParameter: "缺少必填参数",
ApiCode.UsernameAlreadyExists: "用户名称已存在,请重新输入",
ApiCode.StatusDisable: "该账户已被禁用,请联系管理员",
ApiCode.SysAdminIsNotExists: "用户不存在,请先注册",
ApiCode.PasswordNotTrue: "密码错误,请重新输入",
}
}
// GetMessage 供给外部调用状态信息
func (c *Codes) GetMessage(code uint) string {
message, ok := c.Message[code]
// 如果不 ok,返回空,ok 则返回 message
if !ok {
return ""
}
return message
}
下一步加入路由 /router/router.go
:
router.POST("/api/sysAdmin/login", api.Login)
最后初始化swag,测试一下:
ok,没什么问题喵~
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 OrdisBlog
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果