✨ 新增几大中心功能
This commit is contained in:
@@ -7,6 +7,8 @@ type ApiGroup struct {
|
||||
JwtApi
|
||||
BaseApi
|
||||
SystemApi
|
||||
PublicAuthApi
|
||||
InviteCodeApi
|
||||
CasbinApi
|
||||
SystemApiApi
|
||||
AuthorityApi
|
||||
@@ -41,4 +43,6 @@ var (
|
||||
sysErrorService = service.ServiceGroupApp.SystemServiceGroup.SysErrorService
|
||||
loginLogService = service.ServiceGroupApp.SystemServiceGroup.LoginLogService
|
||||
apiTokenService = service.ServiceGroupApp.SystemServiceGroup.ApiTokenService
|
||||
inviteCodeService = service.ServiceGroupApp.SystemServiceGroup.InviteCodeService
|
||||
publicRegisterService = service.ServiceGroupApp.SystemServiceGroup.PublicRegisterService
|
||||
)
|
||||
|
||||
63
server/api/v1/system/invite_code.go
Normal file
63
server/api/v1/system/invite_code.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"git.echol.cn/loser/Go-Web-Template/server/model/common/response"
|
||||
"git.echol.cn/loser/Go-Web-Template/server/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type InviteCodeApi struct{}
|
||||
|
||||
type inviteCodeCurrentResponse struct {
|
||||
HasUnused bool `json:"hasUnused"`
|
||||
Record interface{} `json:"record,omitempty"`
|
||||
}
|
||||
|
||||
// GenerateInviteCode
|
||||
// @Tags InviteCode
|
||||
// @Summary 生成邀请码(同一时间仅允许一个未使用码)
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=system.InviteCodeGenerated,msg=string} "生成成功"
|
||||
// @Router /user/invite-code/generate [post]
|
||||
func (a *InviteCodeApi) GenerateInviteCode(c *gin.Context) {
|
||||
uid := utils.GetUserID(c)
|
||||
expireHours := inviteCodeService.InviteExpireHours()
|
||||
res, err := inviteCodeService.Generate(uid, expireHours)
|
||||
if err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
response.OkWithData(res, c)
|
||||
}
|
||||
|
||||
// CurrentInviteCode
|
||||
// @Tags InviteCode
|
||||
// @Summary 获取当前未使用邀请码(不返回明文)
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=inviteCodeCurrentResponse,msg=string} "获取成功"
|
||||
// @Router /user/invite-code/current [get]
|
||||
func (a *InviteCodeApi) CurrentInviteCode(c *gin.Context) {
|
||||
uid := utils.GetUserID(c)
|
||||
rec, err := inviteCodeService.GetCurrentUnused(uid)
|
||||
if err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if rec == nil {
|
||||
response.OkWithData(inviteCodeCurrentResponse{HasUnused: false}, c)
|
||||
return
|
||||
}
|
||||
// 仅返回必要字段(不返回 hash)
|
||||
payload := map[string]interface{}{
|
||||
"id": rec.ID,
|
||||
"codeLast4": rec.CodeLast4,
|
||||
"status": rec.Status,
|
||||
"expiresAt": rec.ExpiresAt,
|
||||
"createdAt": rec.CreatedAt.Format(time.RFC3339),
|
||||
}
|
||||
response.OkWithData(inviteCodeCurrentResponse{HasUnused: true, Record: payload}, c)
|
||||
}
|
||||
28
server/api/v1/system/public_auth.go
Normal file
28
server/api/v1/system/public_auth.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/Go-Web-Template/server/model/common/response"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type PublicAuthApi struct{}
|
||||
|
||||
// RegisterStatus
|
||||
// @Tags PublicAuth
|
||||
// @Summary (废弃)获取注册开放状态
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{msg=string} "已废弃"
|
||||
// @Router /public/auth/register/status [get]
|
||||
func (a *PublicAuthApi) RegisterStatus(c *gin.Context) {
|
||||
response.FailWithMessage("该接口已废弃,请使用 GET /public/app/register/status", c)
|
||||
}
|
||||
|
||||
// PublicRegister
|
||||
// @Tags PublicAuth
|
||||
// @Summary (废弃)用户前端注册
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{msg=string} "已废弃"
|
||||
// @Router /public/auth/register [post]
|
||||
func (a *PublicAuthApi) PublicRegister(c *gin.Context) {
|
||||
response.FailWithMessage("该接口已废弃,请使用 POST /public/app/register", c)
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"git.echol.cn/loser/Go-Web-Template/server/global"
|
||||
"git.echol.cn/loser/Go-Web-Template/server/model/common/response"
|
||||
"git.echol.cn/loser/Go-Web-Template/server/model/system"
|
||||
systemReq "git.echol.cn/loser/Go-Web-Template/server/model/system/request"
|
||||
"git.echol.cn/loser/Go-Web-Template/server/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
@@ -33,6 +37,18 @@ func (sysParamsApi *SysParamsApi) CreateSysParams(c *gin.Context) {
|
||||
response.FailWithMessage("创建失败:"+err.Error(), c)
|
||||
return
|
||||
}
|
||||
// write audit (best-effort)
|
||||
operatorID := utils.GetUserID(c)
|
||||
if operatorID > 0 {
|
||||
_ = global.GVA_DB.Create(&system.SysParamChangeLog{
|
||||
ParamID: sysParams.ID,
|
||||
Key: sysParams.Key,
|
||||
Action: system.SysParamChangeActionCreate,
|
||||
OldValue: "",
|
||||
NewValue: sysParams.Value,
|
||||
OperatorUserID: operatorID,
|
||||
}).Error
|
||||
}
|
||||
response.OkWithMessage("创建成功", c)
|
||||
}
|
||||
|
||||
@@ -47,12 +63,26 @@ func (sysParamsApi *SysParamsApi) CreateSysParams(c *gin.Context) {
|
||||
// @Router /sysParams/deleteSysParams [delete]
|
||||
func (sysParamsApi *SysParamsApi) DeleteSysParams(c *gin.Context) {
|
||||
ID := c.Query("ID")
|
||||
// read before delete for audit
|
||||
var before system.SysParams
|
||||
_ = global.GVA_DB.Where("id = ?", ID).First(&before).Error
|
||||
err := sysParamsService.DeleteSysParams(ID)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||
response.FailWithMessage("删除失败:"+err.Error(), c)
|
||||
return
|
||||
}
|
||||
operatorID := utils.GetUserID(c)
|
||||
if operatorID > 0 && before.ID > 0 {
|
||||
_ = global.GVA_DB.Create(&system.SysParamChangeLog{
|
||||
ParamID: before.ID,
|
||||
Key: before.Key,
|
||||
Action: system.SysParamChangeActionDelete,
|
||||
OldValue: before.Value,
|
||||
NewValue: "",
|
||||
OperatorUserID: operatorID,
|
||||
}).Error
|
||||
}
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
|
||||
@@ -91,15 +121,97 @@ func (sysParamsApi *SysParamsApi) UpdateSysParams(c *gin.Context) {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
// read before update for audit
|
||||
var before system.SysParams
|
||||
_ = global.GVA_DB.Where("id = ?", sysParams.ID).First(&before).Error
|
||||
err = sysParamsService.UpdateSysParams(sysParams)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新失败!", zap.Error(err))
|
||||
response.FailWithMessage("更新失败:"+err.Error(), c)
|
||||
return
|
||||
}
|
||||
operatorID := utils.GetUserID(c)
|
||||
if operatorID > 0 && before.ID > 0 {
|
||||
_ = global.GVA_DB.Create(&system.SysParamChangeLog{
|
||||
ParamID: before.ID,
|
||||
Key: before.Key,
|
||||
Action: system.SysParamChangeActionUpdate,
|
||||
OldValue: before.Value,
|
||||
NewValue: sysParams.Value,
|
||||
OperatorUserID: operatorID,
|
||||
}).Error
|
||||
}
|
||||
response.OkWithMessage("更新成功", c)
|
||||
}
|
||||
|
||||
// GetSysParamChangeLogList 分页获取参数变更审计
|
||||
// @Tags SysParams
|
||||
// @Summary 分页获取参数变更审计
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param page query int false "页码" default(1)
|
||||
// @Param pageSize query int false "每页大小" default(10)
|
||||
// @Param key query string false "key(模糊)"
|
||||
// @Param operatorUserId query int false "操作人ID"
|
||||
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "获取成功"
|
||||
// @Router /sysParams/getChangeLogList [get]
|
||||
func (sysParamsApi *SysParamsApi) GetSysParamChangeLogList(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize <= 0 || pageSize > 200 {
|
||||
pageSize = 10
|
||||
}
|
||||
|
||||
key := strings.TrimSpace(c.Query("key"))
|
||||
var operatorID uint
|
||||
if raw := strings.TrimSpace(c.Query("operatorUserId")); raw != "" {
|
||||
if v, err := strconv.Atoi(raw); err == nil && v > 0 {
|
||||
operatorID = uint(v)
|
||||
}
|
||||
}
|
||||
|
||||
db := global.GVA_DB.Model(&system.SysParamChangeLog{})
|
||||
if key != "" {
|
||||
db = db.Where("key LIKE ?", "%"+key+"%")
|
||||
}
|
||||
if operatorID > 0 {
|
||||
db = db.Where("operator_user_id = ?", operatorID)
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := db.Count(&total).Error; err != nil {
|
||||
response.FailWithMessage("获取失败:"+err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
type row struct {
|
||||
system.SysParamChangeLog
|
||||
OperatorName string `json:"operatorName" gorm:"column:operator_name"`
|
||||
}
|
||||
var list []row
|
||||
if err := db.
|
||||
Joins("LEFT JOIN sys_users su ON su.id = sys_param_change_logs.operator_user_id").
|
||||
Select("sys_param_change_logs.*, su.username AS operator_name").
|
||||
Order("sys_param_change_logs.id desc").
|
||||
Limit(pageSize).
|
||||
Offset((page - 1) * pageSize).
|
||||
Scan(&list).Error; err != nil {
|
||||
response.FailWithMessage("获取失败:"+err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: list,
|
||||
Total: total,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
}, "获取成功", c)
|
||||
}
|
||||
|
||||
// FindSysParams 用id查询参数
|
||||
// @Tags SysParams
|
||||
// @Summary 用id查询参数
|
||||
|
||||
Reference in New Issue
Block a user