初始化v1
This commit is contained in:
15
api/hello/hello.go
Normal file
15
api/hello/hello.go
Normal file
@@ -0,0 +1,15 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package hello
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"nl-video-api/api/hello/v1"
|
||||
)
|
||||
|
||||
type IHelloV1 interface {
|
||||
Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error)
|
||||
}
|
||||
12
api/hello/v1/hello.go
Normal file
12
api/hello/v1/hello.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type HelloReq struct {
|
||||
g.Meta `path:"/hello" tags:"Hello" method:"get" summary:"You first hello api"`
|
||||
}
|
||||
type HelloRes struct {
|
||||
g.Meta `mime:"text/html" example:"string"`
|
||||
}
|
||||
80
api/middleware/auth.go
Normal file
80
api/middleware/auth.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"nl-video-api/internal/consts"
|
||||
"nl-video-api/utility/jwt"
|
||||
"nl-video-api/utility/response"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// Auth JWT认证中间件
|
||||
func Auth(r *ghttp.Request) {
|
||||
// 获取Authorization头
|
||||
authHeader := r.Header.Get("Authorization")
|
||||
if authHeader == "" {
|
||||
response.Error(r, response.CodeUnauthorized, "请提供认证令牌")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查Bearer前缀
|
||||
if !strings.HasPrefix(authHeader, "Bearer ") {
|
||||
response.Error(r, response.CodeUnauthorized, "认证令牌格式错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 提取token
|
||||
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
|
||||
if tokenString == "" {
|
||||
response.Error(r, response.CodeUnauthorized, "认证令牌不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 解析token
|
||||
claims, err := jwt.ParseToken(tokenString)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeTokenInvalid, "认证令牌无效")
|
||||
return
|
||||
}
|
||||
|
||||
// 将用户信息存储到上下文
|
||||
r.SetCtxVar("user_id", claims.UserID)
|
||||
r.SetCtxVar("username", claims.Username)
|
||||
r.SetCtxVar("user_type", claims.UserType)
|
||||
|
||||
r.Middleware.Next()
|
||||
}
|
||||
|
||||
// AdminAuth 管理员认证中间件
|
||||
func AdminAuth(r *ghttp.Request) {
|
||||
// 先执行基础认证
|
||||
Auth(r)
|
||||
if r.Response.Status >= 400 {
|
||||
return
|
||||
}
|
||||
|
||||
// 检查用户类型
|
||||
userType := r.GetCtxVar("user_type").String()
|
||||
if userType != consts.UserTypeAdmin {
|
||||
response.Error(r, response.CodeForbidden, "需要管理员权限")
|
||||
return
|
||||
}
|
||||
|
||||
r.Middleware.Next()
|
||||
}
|
||||
|
||||
// OptionalAuth 可选认证中间件(不强制要求登录)
|
||||
func OptionalAuth(r *ghttp.Request) {
|
||||
authHeader := r.Header.Get("Authorization")
|
||||
if authHeader != "" && strings.HasPrefix(authHeader, "Bearer ") {
|
||||
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
|
||||
if claims, err := jwt.ParseToken(tokenString); err == nil {
|
||||
r.SetCtxVar("user_id", claims.UserID)
|
||||
r.SetCtxVar("username", claims.Username)
|
||||
r.SetCtxVar("user_type", claims.UserType)
|
||||
}
|
||||
}
|
||||
|
||||
r.Middleware.Next()
|
||||
}
|
||||
19
api/middleware/cors.go
Normal file
19
api/middleware/cors.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// CORS 跨域处理中间件
|
||||
func CORS(r *ghttp.Request) {
|
||||
// 设置CORS头
|
||||
r.Response.CORSDefault()
|
||||
|
||||
// 处理预检请求
|
||||
if r.Method == "OPTIONS" {
|
||||
r.Response.WriteHeader(200)
|
||||
return
|
||||
}
|
||||
|
||||
r.Middleware.Next()
|
||||
}
|
||||
54
api/middleware/log.go
Normal file
54
api/middleware/log.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// RequestLog 请求日志中间件
|
||||
func RequestLog(r *ghttp.Request) {
|
||||
start := time.Now()
|
||||
|
||||
// 记录请求开始
|
||||
g.Log().Info(r.Context(),
|
||||
"请求开始",
|
||||
"method", r.Method,
|
||||
"uri", r.RequestURI,
|
||||
"ip", r.GetClientIp(),
|
||||
"user_agent", r.Header.Get("User-Agent"),
|
||||
)
|
||||
|
||||
r.Middleware.Next()
|
||||
|
||||
// 记录请求结束
|
||||
duration := time.Since(start)
|
||||
g.Log().Info(r.Context(),
|
||||
"请求结束",
|
||||
"method", r.Method,
|
||||
"uri", r.RequestURI,
|
||||
"status", r.Response.Status,
|
||||
"duration", duration.String(),
|
||||
"ip", r.GetClientIp(),
|
||||
)
|
||||
}
|
||||
|
||||
// ErrorLog 错误日志中间件
|
||||
func ErrorLog(r *ghttp.Request) {
|
||||
r.Middleware.Next()
|
||||
|
||||
// 如果有错误,记录详细信息
|
||||
if r.Response.Status >= 400 {
|
||||
g.Log().Error(r.Context(),
|
||||
"请求错误",
|
||||
"method", r.Method,
|
||||
"uri", r.RequestURI,
|
||||
"status", r.Response.Status,
|
||||
"ip", r.GetClientIp(),
|
||||
"user_agent", r.Header.Get("User-Agent"),
|
||||
"time", gtime.Now().String(),
|
||||
)
|
||||
}
|
||||
}
|
||||
221
api/middleware/permission.go
Normal file
221
api/middleware/permission.go
Normal file
@@ -0,0 +1,221 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"nl-video-api/internal/service/auth"
|
||||
"nl-video-api/utility/jwt"
|
||||
"nl-video-api/utility/response"
|
||||
)
|
||||
|
||||
// PermissionMiddleware 权限验证中间件
|
||||
func PermissionMiddleware(r *ghttp.Request) {
|
||||
// 获取请求路径和方法
|
||||
apiPath := r.URL.Path
|
||||
method := r.Method
|
||||
|
||||
// 跳过不需要权限验证的路径
|
||||
skipPaths := []string{
|
||||
"/api/v1/auth/login",
|
||||
"/api/v1/auth/register",
|
||||
"/api/v1/admin/login",
|
||||
"/api/v1/admin/register",
|
||||
}
|
||||
|
||||
for _, skipPath := range skipPaths {
|
||||
if apiPath == skipPath {
|
||||
r.Middleware.Next()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 获取Token
|
||||
token := r.Header.Get("Authorization")
|
||||
if token == "" {
|
||||
response.Error(r, 1002, "请先登录")
|
||||
return
|
||||
}
|
||||
|
||||
// 移除Bearer前缀
|
||||
if strings.HasPrefix(token, "Bearer ") {
|
||||
token = strings.TrimPrefix(token, "Bearer ")
|
||||
}
|
||||
|
||||
// 验证Token
|
||||
claims, err := jwt.ParseToken(token)
|
||||
if err != nil {
|
||||
response.Error(r, 1003, "Token无效")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取用户ID
|
||||
userId := int(claims.UserID)
|
||||
if userId <= 0 {
|
||||
response.Error(r, 1003, "Token无效")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查API权限
|
||||
hasPermission, err := auth.Permission.CheckApiPermission(r.Context(), userId, apiPath, method)
|
||||
if err != nil {
|
||||
g.Log().Errorf(r.Context(), "权限检查失败: %v", err)
|
||||
response.Error(r, 1004, "权限检查失败")
|
||||
return
|
||||
}
|
||||
|
||||
if !hasPermission {
|
||||
response.Error(r, 1004, "没有访问权限")
|
||||
return
|
||||
}
|
||||
|
||||
// 将用户ID存储到上下文中
|
||||
r.SetCtxVar("user_id", userId)
|
||||
|
||||
r.Middleware.Next()
|
||||
}
|
||||
|
||||
// RolePermissionMiddleware 角色权限验证中间件
|
||||
func RolePermissionMiddleware(requiredRole string) func(r *ghttp.Request) {
|
||||
return func(r *ghttp.Request) {
|
||||
// 获取Token
|
||||
token := r.Header.Get("Authorization")
|
||||
if token == "" {
|
||||
response.Error(r, 1002, "请先登录")
|
||||
return
|
||||
}
|
||||
|
||||
// 移除Bearer前缀
|
||||
if strings.HasPrefix(token, "Bearer ") {
|
||||
token = strings.TrimPrefix(token, "Bearer ")
|
||||
}
|
||||
|
||||
// 验证Token
|
||||
claims, err := jwt.ParseToken(token)
|
||||
if err != nil {
|
||||
response.Error(r, 1003, "Token无效")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取用户角色
|
||||
userRole := claims.UserType
|
||||
if userRole == "" {
|
||||
response.Error(r, 1004, "用户角色信息无效")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查角色权限
|
||||
if userRole != requiredRole && userRole != "super_admin" {
|
||||
response.Error(r, 1004, "没有访问权限")
|
||||
return
|
||||
}
|
||||
|
||||
r.Middleware.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// AdminPermissionMiddleware 管理员权限验证中间件
|
||||
func AdminPermissionMiddleware(r *ghttp.Request) {
|
||||
// 获取Token
|
||||
token := r.Header.Get("Authorization")
|
||||
if token == "" {
|
||||
response.Error(r, 1002, "请先登录")
|
||||
return
|
||||
}
|
||||
|
||||
// 移除Bearer前缀
|
||||
if strings.HasPrefix(token, "Bearer ") {
|
||||
token = strings.TrimPrefix(token, "Bearer ")
|
||||
}
|
||||
|
||||
// 验证Token
|
||||
claims, err := jwt.ParseToken(token)
|
||||
if err != nil {
|
||||
response.Error(r, 1003, "Token无效")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否为管理员Token
|
||||
userType := claims.UserType
|
||||
if userType != "admin" {
|
||||
response.Error(r, 1004, "需要管理员权限")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取管理员ID
|
||||
adminId := int(claims.UserID)
|
||||
if adminId <= 0 {
|
||||
response.Error(r, 1003, "Token无效")
|
||||
return
|
||||
}
|
||||
|
||||
// 将管理员ID存储到上下文中
|
||||
r.SetCtxVar("admin_id", adminId)
|
||||
|
||||
r.Middleware.Next()
|
||||
}
|
||||
|
||||
// CheckPermissionCode 检查权限编码中间件
|
||||
func CheckPermissionCode(permissionCode string) func(r *ghttp.Request) {
|
||||
return func(r *ghttp.Request) {
|
||||
// 获取用户ID
|
||||
userId := r.GetCtxVar("user_id")
|
||||
if userId == nil {
|
||||
response.Error(r, 1002, "请先登录")
|
||||
return
|
||||
}
|
||||
|
||||
userIdInt := userId.Int()
|
||||
if userIdInt <= 0 {
|
||||
response.Error(r, 1002, "用户信息无效")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查权限
|
||||
hasPermission, err := auth.Permission.CheckUserPermission(r.Context(), userIdInt, permissionCode)
|
||||
if err != nil {
|
||||
g.Log().Errorf(r.Context(), "权限检查失败: %v", err)
|
||||
response.Error(r, 1004, "权限检查失败")
|
||||
return
|
||||
}
|
||||
|
||||
if !hasPermission {
|
||||
response.Error(r, 1004, "没有访问权限")
|
||||
return
|
||||
}
|
||||
|
||||
r.Middleware.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// SuperAdminMiddleware 超级管理员权限验证中间件
|
||||
func SuperAdminMiddleware(r *ghttp.Request) {
|
||||
// 获取Token
|
||||
token := r.Header.Get("Authorization")
|
||||
if token == "" {
|
||||
response.Error(r, 1002, "请先登录")
|
||||
return
|
||||
}
|
||||
|
||||
// 移除Bearer前缀
|
||||
if strings.HasPrefix(token, "Bearer ") {
|
||||
token = strings.TrimPrefix(token, "Bearer ")
|
||||
}
|
||||
|
||||
// 验证Token
|
||||
claims, err := jwt.ParseToken(token)
|
||||
if err != nil {
|
||||
response.Error(r, 1003, "Token无效")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否为超级管理员
|
||||
role := claims.UserType
|
||||
if role != "super_admin" {
|
||||
response.Error(r, 1004, "需要超级管理员权限")
|
||||
return
|
||||
}
|
||||
|
||||
r.Middleware.Next()
|
||||
}
|
||||
60
api/middleware/rate_limit.go
Normal file
60
api/middleware/rate_limit.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"nl-video-api/utility/response"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gredis"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// RateLimit 限流中间件
|
||||
func RateLimit(maxRequests int, window time.Duration) func(r *ghttp.Request) {
|
||||
return func(r *ghttp.Request) {
|
||||
var (
|
||||
ctx = r.Context()
|
||||
client = g.Redis()
|
||||
key = fmt.Sprintf("rate_limit:%s", r.GetClientIp())
|
||||
)
|
||||
|
||||
// 获取当前请求次数
|
||||
count, err := client.Get(ctx, key)
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "Redis获取失败:", err)
|
||||
r.Middleware.Next()
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否超过限制
|
||||
if count.Int() >= maxRequests {
|
||||
response.Error(r, response.CodeError, "请求过于频繁,请稍后再试")
|
||||
return
|
||||
}
|
||||
|
||||
// 增加计数
|
||||
if count.Int() == 0 {
|
||||
// 第一次请求,设置过期时间
|
||||
seconds := int64(window.Seconds())
|
||||
client.Set(ctx, key, 1, gredis.SetOption{
|
||||
TTLOption: gredis.TTLOption{EX: &seconds},
|
||||
})
|
||||
} else {
|
||||
// 增加计数
|
||||
client.Incr(ctx, key)
|
||||
}
|
||||
|
||||
r.Middleware.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// APIRateLimit API接口限流(每分钟60次)
|
||||
func APIRateLimit(r *ghttp.Request) {
|
||||
RateLimit(60, time.Minute)(r)
|
||||
}
|
||||
|
||||
// LoginRateLimit 登录接口限流(每分钟5次)
|
||||
func LoginRateLimit(r *ghttp.Request) {
|
||||
RateLimit(5, time.Minute)(r)
|
||||
}
|
||||
160
api/middleware/request_log.go
Normal file
160
api/middleware/request_log.go
Normal file
@@ -0,0 +1,160 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"nl-video-api/utility/logger"
|
||||
)
|
||||
|
||||
// RequestLogger 请求日志中间件
|
||||
func RequestLogger(r *ghttp.Request) {
|
||||
// 记录请求开始时间
|
||||
startTime := time.Now()
|
||||
|
||||
// 获取请求信息
|
||||
method := r.Method
|
||||
uri := r.RequestURI
|
||||
ip := r.GetClientIp()
|
||||
userAgent := r.Header.Get("User-Agent")
|
||||
|
||||
// 读取请求体
|
||||
var requestBody []byte
|
||||
if r.GetBodyString() != "" {
|
||||
requestBody = []byte(r.GetBodyString())
|
||||
}
|
||||
|
||||
// 记录请求开始日志
|
||||
logger.LogInfo(r.Context(), "请求开始 | Method: %s | URI: %s | IP: %s | UserAgent: %s | Body: %s",
|
||||
method, uri, ip, userAgent, string(requestBody))
|
||||
|
||||
// 继续处理请求
|
||||
r.Middleware.Next()
|
||||
|
||||
// 计算请求处理时间
|
||||
duration := time.Since(startTime)
|
||||
|
||||
// 获取响应状态码
|
||||
status := r.Response.Status
|
||||
|
||||
// 获取响应内容(简化处理)
|
||||
responseBody := ""
|
||||
|
||||
// 记录请求完成日志
|
||||
logger.LogInfo(r.Context(), "请求完成 | Method: %s | URI: %s | IP: %s | Status: %d | Duration: %v | Response: %s",
|
||||
method, uri, ip, status, duration, responseBody)
|
||||
|
||||
// 如果是错误状态码,记录错误日志
|
||||
if status >= 400 {
|
||||
logger.LogError(r.Context(), "请求错误 | Method: %s | URI: %s | IP: %s | Status: %d | Duration: %v | Response: %s",
|
||||
method, uri, ip, status, duration, responseBody)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ErrorLogger 错误日志中间件
|
||||
func ErrorLogger(r *ghttp.Request) {
|
||||
// 使用defer捕获panic
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
// 记录panic错误
|
||||
logger.LogPanic(r.Context(), "请求panic | Method: %s | URI: %s | IP: %s | Error: %v",
|
||||
r.Method, r.RequestURI, r.GetClientIp(), err)
|
||||
|
||||
// 返回统一错误响应
|
||||
r.Response.WriteJsonExit(g.Map{
|
||||
"code": 5000,
|
||||
"msg": "服务器内部错误",
|
||||
"result": nil,
|
||||
})
|
||||
}
|
||||
}()
|
||||
|
||||
// 继续处理请求
|
||||
r.Middleware.Next()
|
||||
}
|
||||
|
||||
// BusinessLogger 业务日志记录器
|
||||
func LogBusinessOperation(ctx context.Context, module string, operation string, userId interface{}, params interface{}, result interface{}, err error) {
|
||||
fields := g.Map{
|
||||
"module": module,
|
||||
"operation": operation,
|
||||
"user_id": userId,
|
||||
"params": gconv.String(params),
|
||||
"result": gconv.String(result),
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fields["error"] = err.Error()
|
||||
logger.LogWithFields(ctx, "error", "error", "业务操作失败", fields)
|
||||
} else {
|
||||
logger.LogWithFields(ctx, "log", "info", "业务操作成功", fields)
|
||||
}
|
||||
}
|
||||
|
||||
// AuthLogger 认证日志记录器
|
||||
func LogAuthOperation(ctx context.Context, operation string, username string, ip string, userAgent string, success bool, err error) {
|
||||
fields := g.Map{
|
||||
"operation": operation,
|
||||
"username": username,
|
||||
"ip": ip,
|
||||
"user_agent": userAgent,
|
||||
"success": success,
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fields["error"] = err.Error()
|
||||
logger.LogWithFields(ctx, "error", "error", "认证操作失败", fields)
|
||||
} else {
|
||||
logger.LogWithFields(ctx, "log", "info", "认证操作成功", fields)
|
||||
}
|
||||
}
|
||||
|
||||
// APILogger API调用日志记录器
|
||||
func LogAPICall(ctx context.Context, api string, method string, params interface{}, response interface{}, duration time.Duration, err error) {
|
||||
fields := g.Map{
|
||||
"api": api,
|
||||
"method": method,
|
||||
"params": gconv.String(params),
|
||||
"response": gconv.String(response),
|
||||
"duration": duration.String(),
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fields["error"] = err.Error()
|
||||
logger.LogWithFields(ctx, "error", "error", "API调用失败", fields)
|
||||
} else {
|
||||
logger.LogWithFields(ctx, "log", "info", "API调用成功", fields)
|
||||
}
|
||||
}
|
||||
|
||||
// ValidationLogger 参数验证日志记录器
|
||||
func LogValidationError(ctx context.Context, field string, value interface{}, rule string, message string) {
|
||||
fields := g.Map{
|
||||
"field": field,
|
||||
"value": gconv.String(value),
|
||||
"rule": rule,
|
||||
"message": message,
|
||||
}
|
||||
|
||||
logger.LogWithFields(ctx, "error", "warn", "参数验证失败", fields)
|
||||
}
|
||||
|
||||
// PerformanceLogger 性能日志记录器
|
||||
func LogPerformance(ctx context.Context, operation string, duration time.Duration, threshold time.Duration) {
|
||||
fields := g.Map{
|
||||
"operation": operation,
|
||||
"duration": duration.String(),
|
||||
"threshold": threshold.String(),
|
||||
"slow": duration > threshold,
|
||||
}
|
||||
|
||||
if duration > threshold {
|
||||
logger.LogWithFields(ctx, "error", "warn", "慢操作检测", fields)
|
||||
} else {
|
||||
logger.LogWithFields(ctx, "log", "debug", "性能监控", fields)
|
||||
}
|
||||
}
|
||||
74
api/middleware/response.go
Normal file
74
api/middleware/response.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"nl-video-api/utility/response"
|
||||
)
|
||||
|
||||
// ResponseHandler 全局响应处理中间件
|
||||
// 确保所有响应都返回HTTP 200状态码,错误信息通过code和message字段传递
|
||||
func ResponseHandler(r *ghttp.Request) {
|
||||
// 设置默认响应头
|
||||
r.Response.Header().Set("Content-Type", "application/json")
|
||||
|
||||
// 继续执行后续中间件和处理函数
|
||||
r.Middleware.Next()
|
||||
|
||||
// 检查响应状态码,如果不是200,则转换为统一格式
|
||||
if r.Response.Status != 200 {
|
||||
// 获取原始状态码
|
||||
originalStatus := r.Response.Status
|
||||
|
||||
// 根据HTTP状态码映射到业务错误码
|
||||
var businessCode int
|
||||
var message string
|
||||
|
||||
switch originalStatus {
|
||||
case 400:
|
||||
businessCode = response.CodeInvalidParam
|
||||
message = "请求参数错误"
|
||||
case 401:
|
||||
businessCode = response.CodeUnauthorized
|
||||
message = "未授权访问"
|
||||
case 403:
|
||||
businessCode = response.CodeForbidden
|
||||
message = "权限不足"
|
||||
case 404:
|
||||
businessCode = response.CodeNotFound
|
||||
message = "资源不存在"
|
||||
case 500:
|
||||
businessCode = response.CodeServerError
|
||||
message = "服务器内部错误"
|
||||
default:
|
||||
businessCode = response.CodeError
|
||||
message = "请求处理失败"
|
||||
}
|
||||
|
||||
// 清空原有响应内容
|
||||
r.Response.ClearBuffer()
|
||||
|
||||
// 返回统一格式的错误响应,HTTP状态码为200
|
||||
response.Error(r, businessCode, message)
|
||||
}
|
||||
}
|
||||
|
||||
// ErrorHandler 错误处理中间件
|
||||
// 捕获panic和其他未处理的错误,统一返回格式
|
||||
func ErrorHandler(r *ghttp.Request) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
// 记录错误日志
|
||||
g.Log().Errorf(r.Context(), "Panic recovered: %v", err)
|
||||
|
||||
// 清空响应缓冲区
|
||||
r.Response.ClearBuffer()
|
||||
|
||||
// 返回统一格式的错误响应
|
||||
response.Error(r, response.CodeServerError, "系统内部错误")
|
||||
}
|
||||
}()
|
||||
|
||||
// 继续执行后续中间件和处理函数
|
||||
r.Middleware.Next()
|
||||
}
|
||||
42
api/v1/admin.go
Normal file
42
api/v1/admin.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// AdminGroup 管理员路由组
|
||||
func AdminGroup(group *ghttp.RouterGroup) {
|
||||
// 管理员评论管理路由
|
||||
// AdminCommentRoutes(group) // TODO: 待实现
|
||||
|
||||
// 管理员轮播图管理路由
|
||||
BannerAdminRoutes(group)
|
||||
|
||||
// 管理员支付订单管理路由
|
||||
PaymentOrderAdminRoutes(group)
|
||||
|
||||
// VIP等级管理路由
|
||||
VipLevelAdminRoutes(group)
|
||||
|
||||
// 附件管理路由
|
||||
AttachmentAdminRoutes(group)
|
||||
|
||||
// 系统配置管理路由
|
||||
ConfigAdminRoutes(group)
|
||||
|
||||
// 日志管理路由
|
||||
LogAdminRoutes(group)
|
||||
|
||||
// 用户收藏管理路由
|
||||
// UserCollectAdminRoutes(group) // TODO: 待实现
|
||||
|
||||
// 用户观看历史管理路由
|
||||
// UserWatchHistoryAdminRoutes(group) // TODO: 待实现
|
||||
}
|
||||
|
||||
// AdminAuthMiddleware 管理员认证中间件
|
||||
func AdminAuthMiddleware(r *ghttp.Request) {
|
||||
// 这里应该实现管理员认证逻辑
|
||||
// 暂时跳过,后续实现
|
||||
r.Middleware.Next()
|
||||
}
|
||||
301
api/v1/attachment.go
Normal file
301
api/v1/attachment.go
Normal file
@@ -0,0 +1,301 @@
|
||||
package v1
|
||||
|
||||
// 附件管理相关请求和响应结构
|
||||
|
||||
// AttachmentUploadReq 上传附件请求
|
||||
type AttachmentUploadReq struct {
|
||||
Type string `json:"type" v:"required|in:image,video,audio,document#附件类型不能为空|附件类型只能为image,video,audio,document"`
|
||||
Category string `json:"category" v:"required|length:1,50#分类不能为空|分类长度为1-50个字符"`
|
||||
Description string `json:"description" v:"max:200#描述长度不能超过200个字符"`
|
||||
}
|
||||
|
||||
// AttachmentUploadRes 上传附件响应
|
||||
type AttachmentUploadRes struct {
|
||||
Id uint `json:"id"`
|
||||
Filename string `json:"filename"`
|
||||
Url string `json:"url"`
|
||||
Size int64 `json:"size"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// AttachmentListReq 获取附件列表请求
|
||||
type AttachmentListReq struct {
|
||||
Page int `json:"page" v:"min:1#页码必须大于0"`
|
||||
Size int `json:"size" v:"min:1|max:100#每页数量必须大于0|每页数量不能超过100"`
|
||||
Type string `json:"type" v:"in:,image,video,audio,document#附件类型只能为image,video,audio,document"`
|
||||
Category string `json:"category" v:"max:50#分类长度不能超过50个字符"`
|
||||
Keyword string `json:"keyword" v:"max:50#关键词长度不能超过50个字符"`
|
||||
StartDate string `json:"start_date" v:"date#开始日期格式不正确"`
|
||||
EndDate string `json:"end_date" v:"date#结束日期格式不正确"`
|
||||
MinSize int64 `json:"min_size" v:"min:0#最小文件大小不能小于0"`
|
||||
MaxSize int64 `json:"max_size" v:"min:0#最大文件大小不能小于0"`
|
||||
UserId uint `json:"user_id" v:"min:0#用户ID不能小于0"`
|
||||
}
|
||||
|
||||
// AttachmentListRes 获取附件列表响应
|
||||
type AttachmentListRes struct {
|
||||
List []AttachmentItem `json:"list"`
|
||||
Total int `json:"total"`
|
||||
Page int `json:"page"`
|
||||
Size int `json:"size"`
|
||||
}
|
||||
|
||||
// AttachmentItem 附件列表项
|
||||
type AttachmentItem struct {
|
||||
Id uint `json:"id"`
|
||||
Filename string `json:"filename"`
|
||||
OriginalName string `json:"original_name"`
|
||||
Url string `json:"url"`
|
||||
Size int64 `json:"size"`
|
||||
Type string `json:"type"`
|
||||
Category string `json:"category"`
|
||||
Description string `json:"description"`
|
||||
UserId uint `json:"user_id"`
|
||||
Username string `json:"username"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// AttachmentDetailReq 获取附件详情请求
|
||||
type AttachmentDetailReq struct {
|
||||
Id uint `json:"id" v:"required|min:1#附件ID不能为空"`
|
||||
}
|
||||
|
||||
// AttachmentDetailRes 获取附件详情响应
|
||||
type AttachmentDetailRes struct {
|
||||
Attachment AttachmentDetail `json:"attachment"`
|
||||
}
|
||||
|
||||
// AttachmentDetail 附件详情
|
||||
type AttachmentDetail struct {
|
||||
Id uint `json:"id"`
|
||||
Filename string `json:"filename"`
|
||||
OriginalName string `json:"original_name"`
|
||||
Url string `json:"url"`
|
||||
Size int64 `json:"size"`
|
||||
Type string `json:"type"`
|
||||
Category string `json:"category"`
|
||||
Description string `json:"description"`
|
||||
UserId uint `json:"user_id"`
|
||||
Username string `json:"username"`
|
||||
DownloadCount int `json:"download_count"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// AttachmentUpdateReq 更新附件请求
|
||||
type AttachmentUpdateReq struct {
|
||||
Id uint `json:"id" v:"required|min:1#附件ID不能为空"`
|
||||
Category string `json:"category" v:"required|length:1,50#分类不能为空|分类长度为1-50个字符"`
|
||||
Description string `json:"description" v:"max:200#描述长度不能超过200个字符"`
|
||||
}
|
||||
|
||||
// AttachmentDeleteReq 删除附件请求
|
||||
type AttachmentDeleteReq struct {
|
||||
Id uint `json:"id" v:"required|min:1#附件ID不能为空"`
|
||||
}
|
||||
|
||||
// AttachmentBatchDeleteReq 批量删除附件请求
|
||||
type AttachmentBatchDeleteReq struct {
|
||||
Ids []uint `json:"ids" v:"required|min:1#附件ID列表不能为空"`
|
||||
}
|
||||
|
||||
// AttachmentDownloadReq 下载附件请求
|
||||
type AttachmentDownloadReq struct {
|
||||
Id uint `json:"id" v:"required|min:1#附件ID不能为空"`
|
||||
}
|
||||
|
||||
// AttachmentDownloadRes 下载附件响应
|
||||
type AttachmentDownloadRes struct {
|
||||
Url string `json:"url"`
|
||||
Filename string `json:"filename"`
|
||||
}
|
||||
|
||||
// AttachmentCategoryListReq 获取附件分类列表请求
|
||||
type AttachmentCategoryListReq struct {
|
||||
Type string `json:"type" v:"in:,image,video,audio,document#附件类型只能为image,video,audio,document"`
|
||||
}
|
||||
|
||||
// AttachmentCategoryListRes 获取附件分类列表响应
|
||||
type AttachmentCategoryListRes struct {
|
||||
Categories []AttachmentCategoryItem `json:"categories"`
|
||||
}
|
||||
|
||||
// AttachmentCategoryItem 附件分类项
|
||||
type AttachmentCategoryItem struct {
|
||||
Category string `json:"category"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
// AttachmentStatisticsReq 获取附件统计请求
|
||||
type AttachmentStatisticsReq struct {
|
||||
StartDate string `json:"start_date" v:"date#开始日期格式不正确"`
|
||||
EndDate string `json:"end_date" v:"date#结束日期格式不正确"`
|
||||
Type string `json:"type" v:"in:,image,video,audio,document#附件类型只能为image,video,audio,document"`
|
||||
}
|
||||
|
||||
// AttachmentStatisticsRes 获取附件统计响应
|
||||
type AttachmentStatisticsRes struct {
|
||||
TotalCount int `json:"total_count"` // 总附件数
|
||||
TotalSize int64 `json:"total_size"` // 总文件大小
|
||||
TypeStats []AttachmentTypeStatItem `json:"type_stats"` // 类型统计
|
||||
CategoryStats []AttachmentCategoryStatItem `json:"category_stats"` // 分类统计
|
||||
UploadChart []AttachmentUploadChartItem `json:"upload_chart"` // 上传图表数据
|
||||
SizeChart []AttachmentSizeChartItem `json:"size_chart"` // 大小图表数据
|
||||
PopularFiles []AttachmentPopularItem `json:"popular_files"` // 热门文件
|
||||
RecentUploads []AttachmentRecentItem `json:"recent_uploads"` // 最近上传
|
||||
}
|
||||
|
||||
// AttachmentTypeStatItem 附件类型统计项
|
||||
type AttachmentTypeStatItem struct {
|
||||
Type string `json:"type"`
|
||||
Count int `json:"count"`
|
||||
Size int64 `json:"size"`
|
||||
Percentage string `json:"percentage"`
|
||||
}
|
||||
|
||||
// AttachmentCategoryStatItem 附件分类统计项
|
||||
type AttachmentCategoryStatItem struct {
|
||||
Category string `json:"category"`
|
||||
Count int `json:"count"`
|
||||
Size int64 `json:"size"`
|
||||
Percentage string `json:"percentage"`
|
||||
}
|
||||
|
||||
// AttachmentUploadChartItem 附件上传图表项
|
||||
type AttachmentUploadChartItem struct {
|
||||
Date string `json:"date"`
|
||||
Count int `json:"count"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
// AttachmentSizeChartItem 附件大小图表项
|
||||
type AttachmentSizeChartItem struct {
|
||||
SizeRange string `json:"size_range"` // 大小范围,如 "0-1MB", "1-10MB"
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
// AttachmentPopularItem 热门附件项
|
||||
type AttachmentPopularItem struct {
|
||||
Id uint `json:"id"`
|
||||
Filename string `json:"filename"`
|
||||
Type string `json:"type"`
|
||||
Size int64 `json:"size"`
|
||||
DownloadCount int `json:"download_count"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// AttachmentRecentItem 最近上传附件项
|
||||
type AttachmentRecentItem struct {
|
||||
Id uint `json:"id"`
|
||||
Filename string `json:"filename"`
|
||||
OriginalName string `json:"original_name"`
|
||||
Type string `json:"type"`
|
||||
Size int64 `json:"size"`
|
||||
UserId uint `json:"user_id"`
|
||||
Username string `json:"username"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// AttachmentCleanupReq 清理附件请求
|
||||
type AttachmentCleanupReq struct {
|
||||
Type string `json:"type" v:"in:,image,video,audio,document#附件类型只能为image,video,audio,document"`
|
||||
Days int `json:"days" v:"min:1#天数必须大于0"`
|
||||
MinSize int64 `json:"min_size" v:"min:0#最小文件大小不能小于0"`
|
||||
MaxSize int64 `json:"max_size" v:"min:0#最大文件大小不能小于0"`
|
||||
Unused bool `json:"unused"` // 是否只清理未使用的附件
|
||||
DryRun bool `json:"dry_run"` // 是否只是预览,不实际删除
|
||||
}
|
||||
|
||||
// AttachmentCleanupRes 清理附件响应
|
||||
type AttachmentCleanupRes struct {
|
||||
DeletedCount int `json:"deleted_count"` // 删除数量
|
||||
DeletedSize int64 `json:"deleted_size"` // 删除大小
|
||||
DeletedFiles []string `json:"deleted_files"` // 删除的文件列表
|
||||
}
|
||||
|
||||
// AttachmentMoveReq 移动附件请求
|
||||
type AttachmentMoveReq struct {
|
||||
Ids []uint `json:"ids" v:"required|min:1#附件ID列表不能为空"`
|
||||
NewCategory string `json:"new_category" v:"required|length:1,50#新分类不能为空|新分类长度为1-50个字符"`
|
||||
}
|
||||
|
||||
// AttachmentCopyReq 复制附件请求
|
||||
type AttachmentCopyReq struct {
|
||||
Id uint `json:"id" v:"required|min:1#附件ID不能为空"`
|
||||
NewCategory string `json:"new_category" v:"length:1,50#新分类长度为1-50个字符"`
|
||||
Description string `json:"description" v:"max:200#描述长度不能超过200个字符"`
|
||||
}
|
||||
|
||||
// AttachmentCopyRes 复制附件响应
|
||||
type AttachmentCopyRes struct {
|
||||
Id uint `json:"id"`
|
||||
Filename string `json:"filename"`
|
||||
Url string `json:"url"`
|
||||
}
|
||||
|
||||
// AttachmentRenameReq 重命名附件请求
|
||||
type AttachmentRenameReq struct {
|
||||
Id uint `json:"id" v:"required|min:1#附件ID不能为空"`
|
||||
Filename string `json:"filename" v:"required|length:1,100#文件名不能为空|文件名长度为1-100个字符"`
|
||||
}
|
||||
|
||||
// AttachmentSearchReq 搜索附件请求
|
||||
type AttachmentSearchReq struct {
|
||||
Query string `json:"query" v:"required|length:1,100#搜索关键词不能为空|搜索关键词长度为1-100个字符"`
|
||||
Type string `json:"type" v:"in:,image,video,audio,document#附件类型只能为image,video,audio,document"`
|
||||
Category string `json:"category" v:"max:50#分类长度不能超过50个字符"`
|
||||
Page int `json:"page" v:"min:1#页码必须大于0"`
|
||||
Size int `json:"size" v:"min:1|max:100#每页数量必须大于0|每页数量不能超过100"`
|
||||
}
|
||||
|
||||
// AttachmentSearchRes 搜索附件响应
|
||||
type AttachmentSearchRes struct {
|
||||
List []AttachmentItem `json:"list"`
|
||||
Total int `json:"total"`
|
||||
Page int `json:"page"`
|
||||
Size int `json:"size"`
|
||||
}
|
||||
|
||||
// AttachmentExportReq 导出附件请求
|
||||
type AttachmentExportReq struct {
|
||||
Type string `json:"type" v:"in:,image,video,audio,document#附件类型只能为image,video,audio,document"`
|
||||
Category string `json:"category" v:"max:50#分类长度不能超过50个字符"`
|
||||
StartDate string `json:"start_date" v:"date#开始日期格式不正确"`
|
||||
EndDate string `json:"end_date" v:"date#结束日期格式不正确"`
|
||||
}
|
||||
|
||||
// AttachmentExportRes 导出附件响应
|
||||
type AttachmentExportRes struct {
|
||||
FileUrl string `json:"file_url"` // 导出文件URL
|
||||
}
|
||||
|
||||
// AttachmentUserListReq 获取用户附件列表请求(用户端)
|
||||
type AttachmentUserListReq struct {
|
||||
Page int `json:"page" v:"min:1#页码必须大于0"`
|
||||
Size int `json:"size" v:"min:1|max:50#每页数量必须大于0|每页数量不能超过50"`
|
||||
Type string `json:"type" v:"in:,image,video,audio,document#附件类型只能为image,video,audio,document"`
|
||||
Category string `json:"category" v:"max:50#分类长度不能超过50个字符"`
|
||||
Keyword string `json:"keyword" v:"max:50#关键词长度不能超过50个字符"`
|
||||
}
|
||||
|
||||
// AttachmentUserListRes 获取用户附件列表响应(用户端)
|
||||
type AttachmentUserListRes struct {
|
||||
List []AttachmentUserItem `json:"list"`
|
||||
Total int `json:"total"`
|
||||
Page int `json:"page"`
|
||||
Size int `json:"size"`
|
||||
}
|
||||
|
||||
// AttachmentUserItem 用户附件列表项
|
||||
type AttachmentUserItem struct {
|
||||
Id uint `json:"id"`
|
||||
Filename string `json:"filename"`
|
||||
OriginalName string `json:"original_name"`
|
||||
Url string `json:"url"`
|
||||
Size int64 `json:"size"`
|
||||
Type string `json:"type"`
|
||||
Category string `json:"category"`
|
||||
Description string `json:"description"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
19
api/v1/attachment_routes.go
Normal file
19
api/v1/attachment_routes.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// AttachmentUserRoutes 用户附件管理路由
|
||||
// 注意:这个文件不应该导入controller包,避免循环导入
|
||||
// 路由注册应该在cmd包中进行
|
||||
func AttachmentUserRoutes(group *ghttp.RouterGroup) {
|
||||
// 路由注册逻辑移动到cmd包中
|
||||
}
|
||||
|
||||
// AttachmentAdminRoutes 管理员附件管理路由
|
||||
// 注意:这个文件不应该导入controller包,避免循环导入
|
||||
// 路由注册应该在cmd包中进行
|
||||
func AttachmentAdminRoutes(group *ghttp.RouterGroup) {
|
||||
// 路由注册逻辑移动到cmd包中
|
||||
}
|
||||
43
api/v1/auth.go
Normal file
43
api/v1/auth.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"nl-video-api/api/middleware"
|
||||
"nl-video-api/internal/controller/auth"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// AuthGroup 认证路由组
|
||||
func AuthGroup(group *ghttp.RouterGroup) {
|
||||
// 用户认证相关路由 (无需认证)
|
||||
group.Group("/auth", func(group *ghttp.RouterGroup) {
|
||||
// 应用CORS中间件
|
||||
group.Middleware(middleware.CORS)
|
||||
|
||||
// 用户登录
|
||||
group.POST("/login", auth.Auth.Login)
|
||||
|
||||
// 用户注册
|
||||
group.POST("/register", auth.Auth.Register)
|
||||
})
|
||||
|
||||
// 用户认证后的路由 (需要认证)
|
||||
group.Group("/auth", func(group *ghttp.RouterGroup) {
|
||||
// 应用中间件
|
||||
group.Middleware(middleware.CORS)
|
||||
group.Middleware(middleware.Auth) // 用户认证中间件
|
||||
group.Middleware(middleware.RequestLog)
|
||||
|
||||
// 获取用户信息
|
||||
group.GET("/profile", auth.Auth.Profile)
|
||||
|
||||
// 更新用户信息
|
||||
group.POST("/profile", auth.Auth.UpdateProfile)
|
||||
|
||||
// 用户登出
|
||||
group.POST("/logout", auth.Auth.Logout)
|
||||
|
||||
// 刷新Token
|
||||
group.POST("/refresh", auth.Auth.RefreshToken)
|
||||
})
|
||||
}
|
||||
172
api/v1/banner.go
Normal file
172
api/v1/banner.go
Normal file
@@ -0,0 +1,172 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// BannerListReq 轮播图列表请求
|
||||
type BannerListReq struct {
|
||||
g.Meta `path:"/banner/list" method:"get" summary:"轮播图列表" tags:"轮播图管理"`
|
||||
Position int `json:"position" v:"min:0#位置必须大于等于0" dc:"位置(0:全部,1:首页,2:分类页,3:详情页)" default:"0"`
|
||||
Status int `json:"status" v:"in:-1,0,1#状态值错误" dc:"状态(-1:全部,0:禁用,1:启用)" default:"-1"`
|
||||
Page int `json:"page" v:"min:1#页码必须大于0" dc:"页码" default:"1"`
|
||||
Size int `json:"size" v:"min:1|max:100#每页数量必须大于0|每页数量不能超过100" dc:"每页数量" default:"10"`
|
||||
}
|
||||
|
||||
// BannerListRes 轮播图列表响应
|
||||
type BannerListRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
List []BannerItem `json:"list" dc:"轮播图列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Page int `json:"page" dc:"当前页"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
}
|
||||
|
||||
// BannerItem 轮播图项目
|
||||
type BannerItem struct {
|
||||
Id uint `json:"id" dc:"轮播图ID"`
|
||||
Title string `json:"title" dc:"标题"`
|
||||
Image string `json:"image" dc:"图片地址"`
|
||||
Link string `json:"link" dc:"链接地址"`
|
||||
Position int `json:"position" dc:"位置"`
|
||||
Sort int `json:"sort" dc:"排序"`
|
||||
Status int `json:"status" dc:"状态"`
|
||||
StartTime string `json:"start_time" dc:"开始时间"`
|
||||
EndTime string `json:"end_time" dc:"结束时间"`
|
||||
ClickCount int `json:"click_count" dc:"点击次数"`
|
||||
Description string `json:"description" dc:"描述"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
}
|
||||
|
||||
// AdminBannerCreateReq 管理员创建轮播图请求
|
||||
type AdminBannerCreateReq struct {
|
||||
g.Meta `path:"/admin/banner/create" method:"post" summary:"创建轮播图" tags:"轮播图管理"`
|
||||
Title string `json:"title" v:"required|length:1,100#标题不能为空|标题长度为1-100字符" dc:"标题"`
|
||||
Image string `json:"image" v:"required|url#图片地址不能为空|图片地址格式错误" dc:"图片地址"`
|
||||
Link string `json:"link" v:"url#链接地址格式错误" dc:"链接地址"`
|
||||
Position int `json:"position" v:"required|in:1,2,3#位置不能为空|位置值错误" dc:"位置(1:首页,2:分类页,3:详情页)"`
|
||||
Sort int `json:"sort" v:"min:0#排序必须大于等于0" dc:"排序" default:"0"`
|
||||
Status int `json:"status" v:"in:0,1#状态值错误" dc:"状态(0:禁用,1:启用)" default:"1"`
|
||||
StartTime string `json:"start_time" v:"datetime#开始时间格式错误" dc:"开始时间"`
|
||||
EndTime string `json:"end_time" v:"datetime#结束时间格式错误" dc:"结束时间"`
|
||||
Description string `json:"description" v:"length:0,500#描述长度不能超过500字符" dc:"描述"`
|
||||
}
|
||||
|
||||
// AdminBannerCreateRes 管理员创建轮播图响应
|
||||
type AdminBannerCreateRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
Id uint `json:"id" dc:"轮播图ID"`
|
||||
}
|
||||
|
||||
// AdminBannerUpdateReq 管理员更新轮播图请求
|
||||
type AdminBannerUpdateReq struct {
|
||||
g.Meta `path:"/admin/banner/update" method:"post" summary:"更新轮播图" tags:"轮播图管理"`
|
||||
Id uint `json:"id" v:"required|min:1#轮播图ID不能为空|轮播图ID必须大于0" dc:"轮播图ID"`
|
||||
Title string `json:"title" v:"required|length:1,100#标题不能为空|标题长度为1-100字符" dc:"标题"`
|
||||
Image string `json:"image" v:"required|url#图片地址不能为空|图片地址格式错误" dc:"图片地址"`
|
||||
Link string `json:"link" v:"url#链接地址格式错误" dc:"链接地址"`
|
||||
Position int `json:"position" v:"required|in:1,2,3#位置不能为空|位置值错误" dc:"位置(1:首页,2:分类页,3:详情页)"`
|
||||
Sort int `json:"sort" v:"min:0#排序必须大于等于0" dc:"排序"`
|
||||
Status int `json:"status" v:"in:0,1#状态值错误" dc:"状态(0:禁用,1:启用)"`
|
||||
StartTime string `json:"start_time" v:"datetime#开始时间格式错误" dc:"开始时间"`
|
||||
EndTime string `json:"end_time" v:"datetime#结束时间格式错误" dc:"结束时间"`
|
||||
Description string `json:"description" v:"length:0,500#描述长度不能超过500字符" dc:"描述"`
|
||||
}
|
||||
|
||||
// AdminBannerUpdateRes 管理员更新轮播图响应
|
||||
type AdminBannerUpdateRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// AdminBannerDeleteReq 管理员删除轮播图请求
|
||||
type AdminBannerDeleteReq struct {
|
||||
g.Meta `path:"/admin/banner/delete" method:"post" summary:"删除轮播图" tags:"轮播图管理"`
|
||||
Id uint `json:"id" v:"required|min:1#轮播图ID不能为空|轮播图ID必须大于0" dc:"轮播图ID"`
|
||||
}
|
||||
|
||||
// AdminBannerDeleteRes 管理员删除轮播图响应
|
||||
type AdminBannerDeleteRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// AdminBannerDetailReq 管理员轮播图详情请求
|
||||
type AdminBannerDetailReq struct {
|
||||
g.Meta `path:"/admin/banner/detail" method:"get" summary:"轮播图详情" tags:"轮播图管理"`
|
||||
Id uint `json:"id" v:"required|min:1#轮播图ID不能为空|轮播图ID必须大于0" dc:"轮播图ID"`
|
||||
}
|
||||
|
||||
// AdminBannerDetailRes 管理员轮播图详情响应
|
||||
type AdminBannerDetailRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
Banner BannerItem `json:"banner" dc:"轮播图详情"`
|
||||
}
|
||||
|
||||
// AdminBannerListReq 管理员轮播图列表请求
|
||||
type AdminBannerListReq struct {
|
||||
g.Meta `path:"/admin/banner/list" method:"get" summary:"管理员轮播图列表" tags:"轮播图管理"`
|
||||
Position int `json:"position" v:"min:0#位置必须大于等于0" dc:"位置(0:全部,1:首页,2:分类页,3:详情页)" default:"0"`
|
||||
Status int `json:"status" v:"in:-1,0,1#状态值错误" dc:"状态(-1:全部,0:禁用,1:启用)" default:"-1"`
|
||||
Keyword string `json:"keyword" dc:"关键词搜索"`
|
||||
Page int `json:"page" v:"min:1#页码必须大于0" dc:"页码" default:"1"`
|
||||
Size int `json:"size" v:"min:1|max:100#每页数量必须大于0|每页数量不能超过100" dc:"每页数量" default:"10"`
|
||||
}
|
||||
|
||||
// AdminBannerListRes 管理员轮播图列表响应
|
||||
type AdminBannerListRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
List []AdminBannerItem `json:"list" dc:"轮播图列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Page int `json:"page" dc:"当前页"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
}
|
||||
|
||||
// AdminBannerItem 管理员轮播图项目
|
||||
type AdminBannerItem struct {
|
||||
Id uint `json:"id" dc:"轮播图ID"`
|
||||
Title string `json:"title" dc:"标题"`
|
||||
Image string `json:"image" dc:"图片地址"`
|
||||
Link string `json:"link" dc:"链接地址"`
|
||||
Position int `json:"position" dc:"位置"`
|
||||
Sort int `json:"sort" dc:"排序"`
|
||||
Status int `json:"status" dc:"状态"`
|
||||
StartTime string `json:"start_time" dc:"开始时间"`
|
||||
EndTime string `json:"end_time" dc:"结束时间"`
|
||||
ClickCount int `json:"click_count" dc:"点击次数"`
|
||||
Description string `json:"description" dc:"描述"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" dc:"更新时间"`
|
||||
}
|
||||
|
||||
// AdminBannerUpdateStatusReq 管理员更新轮播图状态请求
|
||||
type AdminBannerUpdateStatusReq struct {
|
||||
g.Meta `path:"/admin/banner/status" method:"post" summary:"更新轮播图状态" tags:"轮播图管理"`
|
||||
Id uint `json:"id" v:"required|min:1#轮播图ID不能为空|轮播图ID必须大于0" dc:"轮播图ID"`
|
||||
Status int `json:"status" v:"required|in:0,1#状态不能为空|状态值错误" dc:"状态(0:禁用,1:启用)"`
|
||||
}
|
||||
|
||||
// AdminBannerUpdateStatusRes 管理员更新轮播图状态响应
|
||||
type AdminBannerUpdateStatusRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// AdminBannerBatchDeleteReq 管理员批量删除轮播图请求
|
||||
type AdminBannerBatchDeleteReq struct {
|
||||
g.Meta `path:"/admin/banner/batch-delete" method:"post" summary:"批量删除轮播图" tags:"轮播图管理"`
|
||||
Ids []uint `json:"ids" v:"required|length:1,100#轮播图ID列表不能为空|最多选择100条记录" dc:"轮播图ID列表"`
|
||||
}
|
||||
|
||||
// AdminBannerBatchDeleteRes 管理员批量删除轮播图响应
|
||||
type AdminBannerBatchDeleteRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// BannerClickReq 轮播图点击请求
|
||||
type BannerClickReq struct {
|
||||
g.Meta `path:"/banner/click" method:"post" summary:"轮播图点击" tags:"轮播图管理"`
|
||||
Id uint `json:"id" v:"required|min:1#轮播图ID不能为空|轮播图ID必须大于0" dc:"轮播图ID"`
|
||||
}
|
||||
|
||||
// BannerClickRes 轮播图点击响应
|
||||
type BannerClickRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
19
api/v1/banner_routes.go
Normal file
19
api/v1/banner_routes.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// BannerUserRoutes 用户轮播图路由
|
||||
// 注意:这个文件不应该导入controller包,避免循环导入
|
||||
// 路由注册应该在cmd包中进行
|
||||
func BannerUserRoutes(group *ghttp.RouterGroup) {
|
||||
// 路由注册逻辑移动到cmd包中
|
||||
}
|
||||
|
||||
// BannerAdminRoutes 管理员轮播图路由
|
||||
// 注意:这个文件不应该导入controller包,避免循环导入
|
||||
// 路由注册应该在cmd包中进行
|
||||
func BannerAdminRoutes(group *ghttp.RouterGroup) {
|
||||
// 路由注册逻辑移动到cmd包中
|
||||
}
|
||||
156
api/v1/comment.go
Normal file
156
api/v1/comment.go
Normal file
@@ -0,0 +1,156 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// CommentAddReq 添加评论请求
|
||||
type CommentAddReq struct {
|
||||
g.Meta `path:"/comment/add" method:"post" summary:"添加评论" tags:"评论管理"`
|
||||
MovieId int `json:"movie_id" v:"required|min:1#影片ID不能为空|影片ID必须大于0" dc:"影片ID"`
|
||||
ParentId int `json:"parent_id" v:"min:0#父评论ID必须大于等于0" dc:"父评论ID" default:"0"`
|
||||
Content string `json:"content" v:"required|length:1,500#评论内容不能为空|评论内容长度为1-500字符" dc:"评论内容"`
|
||||
}
|
||||
|
||||
// CommentAddRes 添加评论响应
|
||||
type CommentAddRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
Id uint `json:"id" dc:"评论ID"`
|
||||
}
|
||||
|
||||
// CommentListReq 评论列表请求
|
||||
type CommentListReq struct {
|
||||
g.Meta `path:"/comment/list" method:"get" summary:"评论列表" tags:"评论管理"`
|
||||
MovieId int `json:"movie_id" v:"required|min:1#影片ID不能为空|影片ID必须大于0" dc:"影片ID"`
|
||||
ParentId int `json:"parent_id" v:"min:0#父评论ID必须大于等于0" dc:"父评论ID" default:"0"`
|
||||
Page int `json:"page" v:"min:1#页码必须大于0" dc:"页码" default:"1"`
|
||||
Size int `json:"size" v:"min:1|max:100#每页数量必须大于0|每页数量不能超过100" dc:"每页数量" default:"10"`
|
||||
}
|
||||
|
||||
// CommentListRes 评论列表响应
|
||||
type CommentListRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
List []CommentItem `json:"list" dc:"评论列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Page int `json:"page" dc:"当前页"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
}
|
||||
|
||||
// CommentItem 评论项目
|
||||
type CommentItem struct {
|
||||
Id uint `json:"id" dc:"评论ID"`
|
||||
UserId int `json:"user_id" dc:"用户ID"`
|
||||
Username string `json:"username" dc:"用户名"`
|
||||
UserAvatar string `json:"user_avatar" dc:"用户头像"`
|
||||
MovieId int `json:"movie_id" dc:"影片ID"`
|
||||
ParentId int `json:"parent_id" dc:"父评论ID"`
|
||||
Content string `json:"content" dc:"评论内容"`
|
||||
LikeCount int `json:"like_count" dc:"点赞数"`
|
||||
IsLiked bool `json:"is_liked" dc:"是否已点赞"`
|
||||
Status int `json:"status" dc:"状态"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
Replies []CommentItem `json:"replies,omitempty" dc:"回复列表"`
|
||||
}
|
||||
|
||||
// CommentDeleteReq 删除评论请求
|
||||
type CommentDeleteReq struct {
|
||||
g.Meta `path:"/comment/delete" method:"post" summary:"删除评论" tags:"评论管理"`
|
||||
Id uint `json:"id" v:"required|min:1#评论ID不能为空|评论ID必须大于0" dc:"评论ID"`
|
||||
}
|
||||
|
||||
// CommentDeleteRes 删除评论响应
|
||||
type CommentDeleteRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// CommentLikeReq 点赞评论请求
|
||||
type CommentLikeReq struct {
|
||||
g.Meta `path:"/comment/like" method:"post" summary:"点赞评论" tags:"评论管理"`
|
||||
Id uint `json:"id" v:"required|min:1#评论ID不能为空|评论ID必须大于0" dc:"评论ID"`
|
||||
}
|
||||
|
||||
// CommentLikeRes 点赞评论响应
|
||||
type CommentLikeRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// CommentUnlikeReq 取消点赞请求
|
||||
type CommentUnlikeReq struct {
|
||||
g.Meta `path:"/comment/unlike" method:"post" summary:"取消点赞" tags:"评论管理"`
|
||||
Id uint `json:"id" v:"required|min:1#评论ID不能为空|评论ID必须大于0" dc:"评论ID"`
|
||||
}
|
||||
|
||||
// CommentUnlikeRes 取消点赞响应
|
||||
type CommentUnlikeRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// CommentReportReq 举报评论请求
|
||||
type CommentReportReq struct {
|
||||
g.Meta `path:"/comment/report" method:"post" summary:"举报评论" tags:"评论管理"`
|
||||
Id uint `json:"id" v:"required|min:1#评论ID不能为空|评论ID必须大于0" dc:"评论ID"`
|
||||
Reason string `json:"reason" v:"required|length:1,200#举报原因不能为空|举报原因长度为1-200字符" dc:"举报原因"`
|
||||
}
|
||||
|
||||
// CommentReportRes 举报评论响应
|
||||
type CommentReportRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// AdminCommentListReq 管理员评论列表请求
|
||||
type AdminCommentListReq struct {
|
||||
g.Meta `path:"/admin/comment/list" method:"get" summary:"管理员评论列表" tags:"评论管理"`
|
||||
MovieId int `json:"movie_id" v:"min:0#影片ID必须大于等于0" dc:"影片ID"`
|
||||
UserId int `json:"user_id" v:"min:0#用户ID必须大于等于0" dc:"用户ID"`
|
||||
Status int `json:"status" v:"in:-1,0,1,2#状态值错误" dc:"状态(-1:全部,0:待审核,1:已通过,2:已拒绝)" default:"-1"`
|
||||
Keyword string `json:"keyword" dc:"关键词搜索"`
|
||||
Page int `json:"page" v:"min:1#页码必须大于0" dc:"页码" default:"1"`
|
||||
Size int `json:"size" v:"min:1|max:100#每页数量必须大于0|每页数量不能超过100" dc:"每页数量" default:"10"`
|
||||
}
|
||||
|
||||
// AdminCommentListRes 管理员评论列表响应
|
||||
type AdminCommentListRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
List []AdminCommentItem `json:"list" dc:"评论列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Page int `json:"page" dc:"当前页"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
}
|
||||
|
||||
// AdminCommentItem 管理员评论项目
|
||||
type AdminCommentItem struct {
|
||||
Id uint `json:"id" dc:"评论ID"`
|
||||
UserId int `json:"user_id" dc:"用户ID"`
|
||||
Username string `json:"username" dc:"用户名"`
|
||||
MovieId int `json:"movie_id" dc:"影片ID"`
|
||||
MovieName string `json:"movie_name" dc:"影片名称"`
|
||||
ParentId int `json:"parent_id" dc:"父评论ID"`
|
||||
Content string `json:"content" dc:"评论内容"`
|
||||
LikeCount int `json:"like_count" dc:"点赞数"`
|
||||
Status int `json:"status" dc:"状态"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" dc:"更新时间"`
|
||||
}
|
||||
|
||||
// AdminCommentUpdateStatusReq 管理员更新评论状态请求
|
||||
type AdminCommentUpdateStatusReq struct {
|
||||
g.Meta `path:"/admin/comment/status" method:"post" summary:"更新评论状态" tags:"评论管理"`
|
||||
Id uint `json:"id" v:"required|min:1#评论ID不能为空|评论ID必须大于0" dc:"评论ID"`
|
||||
Status int `json:"status" v:"required|in:0,1,2#状态不能为空|状态值错误" dc:"状态(0:待审核,1:已通过,2:已拒绝)"`
|
||||
}
|
||||
|
||||
// AdminCommentUpdateStatusRes 管理员更新评论状态响应
|
||||
type AdminCommentUpdateStatusRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// AdminCommentBatchDeleteReq 管理员批量删除评论请求
|
||||
type AdminCommentBatchDeleteReq struct {
|
||||
g.Meta `path:"/admin/comment/batch-delete" method:"post" summary:"批量删除评论" tags:"评论管理"`
|
||||
Ids []uint `json:"ids" v:"required|length:1,100#评论ID列表不能为空|最多选择100条记录" dc:"评论ID列表"`
|
||||
}
|
||||
|
||||
// AdminCommentBatchDeleteRes 管理员批量删除评论响应
|
||||
type AdminCommentBatchDeleteRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
28
api/v1/comment_routes.go
Normal file
28
api/v1/comment_routes.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// CommentUserRoutes 用户评论路由
|
||||
func CommentUserRoutes(group *ghttp.RouterGroup) {
|
||||
// TODO: 需要实现middleware和user controller
|
||||
// group.Middleware(middleware.AuthMiddleware)
|
||||
// group.POST("/comment/create", middleware.AuthMiddleware, user.Comment.Create)
|
||||
// group.GET("/comment/list", middleware.AuthMiddleware, user.Comment.GetList)
|
||||
|
||||
// 评论点赞
|
||||
// group.POST("/comment/like", user.Comment.Like)
|
||||
|
||||
// 评论举报
|
||||
// group.POST("/comment/report", user.Comment.Report)
|
||||
}
|
||||
|
||||
// CommentAdminRoutes 管理员评论路由
|
||||
func CommentAdminRoutes(group *ghttp.RouterGroup) {
|
||||
// TODO: 需要实现admin controller
|
||||
// group.GET("/admin/comment/list", admin.Comment.GetList)
|
||||
// group.POST("/admin/comment/delete", admin.Comment.Delete)
|
||||
// group.POST("/admin/comment/batch-delete", admin.Comment.BatchDelete)
|
||||
// group.POST("/admin/comment/update-status", admin.Comment.UpdateStatus)
|
||||
}
|
||||
313
api/v1/config.go
Normal file
313
api/v1/config.go
Normal file
@@ -0,0 +1,313 @@
|
||||
package v1
|
||||
|
||||
import "github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
// ===== 系统配置管理相关结构 =====
|
||||
|
||||
// ConfigListReq 获取配置列表请求
|
||||
type ConfigListReq struct {
|
||||
g.Meta `path:"/config/list" method:"get" summary:"获取配置列表" tags:"系统配置管理"`
|
||||
Page int `json:"page" dc:"页码,默认1"`
|
||||
Size int `json:"size" dc:"每页数量,默认10"`
|
||||
Group string `json:"group" dc:"配置分组"`
|
||||
Keyword string `json:"keyword" dc:"搜索关键词"`
|
||||
Status int `json:"status" dc:"状态:0-禁用,1-启用"`
|
||||
}
|
||||
|
||||
// ConfigListRes 获取配置列表响应
|
||||
type ConfigListRes struct {
|
||||
List []ConfigItem `json:"list" dc:"配置列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Page int `json:"page" dc:"当前页码"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
}
|
||||
|
||||
// ConfigItem 配置项
|
||||
type ConfigItem struct {
|
||||
Id uint `json:"id" dc:"配置ID"`
|
||||
Name string `json:"name" dc:"配置名称"`
|
||||
Key string `json:"key" dc:"配置键"`
|
||||
Value string `json:"value" dc:"配置值"`
|
||||
Group string `json:"group" dc:"配置分组"`
|
||||
Type string `json:"type" dc:"配置类型"`
|
||||
Description string `json:"description" dc:"配置描述"`
|
||||
Sort int `json:"sort" dc:"排序"`
|
||||
Status int `json:"status" dc:"状态:0-禁用,1-启用"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" dc:"更新时间"`
|
||||
}
|
||||
|
||||
// ConfigDetailReq 获取配置详情请求
|
||||
type ConfigDetailReq struct {
|
||||
g.Meta `path:"/config/detail" method:"get" summary:"获取配置详情" tags:"系统配置管理"`
|
||||
Id uint `json:"id" v:"required|min:1#请输入配置ID|配置ID不能为空" dc:"配置ID"`
|
||||
}
|
||||
|
||||
// ConfigDetailRes 获取配置详情响应
|
||||
type ConfigDetailRes struct {
|
||||
Config ConfigDetail `json:"config" dc:"配置详情"`
|
||||
}
|
||||
|
||||
// ConfigDetail 配置详情
|
||||
type ConfigDetail struct {
|
||||
Id uint `json:"id" dc:"配置ID"`
|
||||
Name string `json:"name" dc:"配置名称"`
|
||||
Key string `json:"key" dc:"配置键"`
|
||||
Value string `json:"value" dc:"配置值"`
|
||||
Group string `json:"group" dc:"配置分组"`
|
||||
Type string `json:"type" dc:"配置类型"`
|
||||
Description string `json:"description" dc:"配置描述"`
|
||||
Sort int `json:"sort" dc:"排序"`
|
||||
Status int `json:"status" dc:"状态:0-禁用,1-启用"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" dc:"更新时间"`
|
||||
}
|
||||
|
||||
// ConfigCreateReq 创建配置请求
|
||||
type ConfigCreateReq struct {
|
||||
g.Meta `path:"/config/create" method:"post" summary:"创建配置" tags:"系统配置管理"`
|
||||
Name string `json:"name" v:"required|length:1,100#请输入配置名称|配置名称长度为1-100个字符" dc:"配置名称"`
|
||||
Key string `json:"key" v:"required|length:1,100#请输入配置键|配置键长度为1-100个字符" dc:"配置键"`
|
||||
Value string `json:"value" dc:"配置值"`
|
||||
Group string `json:"group" v:"required|length:1,50#请输入配置分组|配置分组长度为1-50个字符" dc:"配置分组"`
|
||||
Type string `json:"type" v:"required|in:string,int,float,bool,json#请选择配置类型|配置类型必须为string,int,float,bool,json之一" dc:"配置类型"`
|
||||
Description string `json:"description" dc:"配置描述"`
|
||||
Sort int `json:"sort" dc:"排序"`
|
||||
Status int `json:"status" v:"in:0,1#状态值错误" dc:"状态:0-禁用,1-启用"`
|
||||
}
|
||||
|
||||
// ConfigUpdateReq 更新配置请求
|
||||
type ConfigUpdateReq struct {
|
||||
g.Meta `path:"/config/update" method:"post" summary:"更新配置" tags:"系统配置管理"`
|
||||
Id uint `json:"id" v:"required|min:1#请输入配置ID|配置ID不能为空" dc:"配置ID"`
|
||||
Name string `json:"name" v:"required|length:1,100#请输入配置名称|配置名称长度为1-100个字符" dc:"配置名称"`
|
||||
Value string `json:"value" dc:"配置值"`
|
||||
Group string `json:"group" v:"required|length:1,50#请输入配置分组|配置分组长度为1-50个字符" dc:"配置分组"`
|
||||
Type string `json:"type" v:"required|in:string,int,float,bool,json#请选择配置类型|配置类型必须为string,int,float,bool,json之一" dc:"配置类型"`
|
||||
Description string `json:"description" dc:"配置描述"`
|
||||
Sort int `json:"sort" dc:"排序"`
|
||||
Status int `json:"status" v:"in:0,1#状态值错误" dc:"状态:0-禁用,1-启用"`
|
||||
}
|
||||
|
||||
// ConfigDeleteReq 删除配置请求
|
||||
type ConfigDeleteReq struct {
|
||||
g.Meta `path:"/config/delete" method:"post" summary:"删除配置" tags:"系统配置管理"`
|
||||
Id uint `json:"id" v:"required|min:1#请输入配置ID|配置ID不能为空" dc:"配置ID"`
|
||||
}
|
||||
|
||||
// ConfigBatchDeleteReq 批量删除配置请求
|
||||
type ConfigBatchDeleteReq struct {
|
||||
g.Meta `path:"/config/batch-delete" method:"post" summary:"批量删除配置" tags:"系统配置管理"`
|
||||
Ids []uint `json:"ids" v:"required|length:1,100#请选择要删除的配置|最多选择100个配置" dc:"配置ID列表"`
|
||||
}
|
||||
|
||||
// ConfigGetByKeyReq 根据键获取配置请求
|
||||
type ConfigGetByKeyReq struct {
|
||||
g.Meta `path:"/config/get-by-key" method:"get" summary:"根据键获取配置" tags:"系统配置管理"`
|
||||
Key string `json:"key" v:"required#请输入配置键" dc:"配置键"`
|
||||
}
|
||||
|
||||
// ConfigGetByKeyRes 根据键获取配置响应
|
||||
type ConfigGetByKeyRes struct {
|
||||
Value string `json:"value" dc:"配置值"`
|
||||
}
|
||||
|
||||
// ConfigGetByGroupReq 根据分组获取配置请求
|
||||
type ConfigGetByGroupReq struct {
|
||||
g.Meta `path:"/config/get-by-group" method:"get" summary:"根据分组获取配置" tags:"系统配置管理"`
|
||||
Group string `json:"group" v:"required#请输入配置分组" dc:"配置分组"`
|
||||
}
|
||||
|
||||
// ConfigGetByGroupRes 根据分组获取配置响应
|
||||
type ConfigGetByGroupRes struct {
|
||||
Configs []ConfigGroupItem `json:"configs" dc:"配置列表"`
|
||||
}
|
||||
|
||||
// ConfigGroupItem 分组配置项
|
||||
type ConfigGroupItem struct {
|
||||
Key string `json:"key" dc:"配置键"`
|
||||
Value string `json:"value" dc:"配置值"`
|
||||
Name string `json:"name" dc:"配置名称"`
|
||||
Type string `json:"type" dc:"配置类型"`
|
||||
Description string `json:"description" dc:"配置描述"`
|
||||
}
|
||||
|
||||
// ConfigSetReq 设置配置请求
|
||||
type ConfigSetReq struct {
|
||||
g.Meta `path:"/config/set" method:"post" summary:"设置配置" tags:"系统配置管理"`
|
||||
Key string `json:"key" v:"required#请输入配置键" dc:"配置键"`
|
||||
Value string `json:"value" dc:"配置值"`
|
||||
}
|
||||
|
||||
// ConfigBatchSetReq 批量设置配置请求
|
||||
type ConfigBatchSetReq struct {
|
||||
g.Meta `path:"/config/batch-set" method:"post" summary:"批量设置配置" tags:"系统配置管理"`
|
||||
Configs []ConfigSetItem `json:"configs" v:"required|length:1,100#请输入配置列表|最多设置100个配置" dc:"配置列表"`
|
||||
}
|
||||
|
||||
// ConfigSetItem 设置配置项
|
||||
type ConfigSetItem struct {
|
||||
Key string `json:"key" v:"required#请输入配置键" dc:"配置键"`
|
||||
Value string `json:"value" dc:"配置值"`
|
||||
}
|
||||
|
||||
// ConfigGroupListReq 获取配置分组列表请求
|
||||
type ConfigGroupListReq struct {
|
||||
g.Meta `path:"/config/group/list" method:"get" summary:"获取配置分组列表" tags:"系统配置管理"`
|
||||
}
|
||||
|
||||
// ConfigGroupListRes 获取配置分组列表响应
|
||||
type ConfigGroupListRes struct {
|
||||
Groups []ConfigGroupStatItem `json:"groups" dc:"分组列表"`
|
||||
}
|
||||
|
||||
// ConfigGroupStatItem 配置分组统计项
|
||||
type ConfigGroupStatItem struct {
|
||||
Group string `json:"group" dc:"分组名称"`
|
||||
Count int `json:"count" dc:"配置数量"`
|
||||
Description string `json:"description" dc:"分组描述"`
|
||||
}
|
||||
|
||||
// ConfigExportReq 导出配置请求
|
||||
type ConfigExportReq struct {
|
||||
g.Meta `path:"/config/export" method:"get" summary:"导出配置" tags:"系统配置管理"`
|
||||
Group string `json:"group" dc:"配置分组,为空则导出全部"`
|
||||
Format string `json:"format" v:"in:json,yaml,ini#导出格式错误" dc:"导出格式:json,yaml,ini"`
|
||||
}
|
||||
|
||||
// ConfigExportRes 导出配置响应
|
||||
type ConfigExportRes struct {
|
||||
Content string `json:"content" dc:"导出内容"`
|
||||
Filename string `json:"filename" dc:"文件名"`
|
||||
}
|
||||
|
||||
// ConfigImportReq 导入配置请求
|
||||
type ConfigImportReq struct {
|
||||
g.Meta `path:"/config/import" method:"post" summary:"导入配置" tags:"系统配置管理"`
|
||||
Content string `json:"content" v:"required#请输入导入内容" dc:"导入内容"`
|
||||
Format string `json:"format" v:"required|in:json,yaml,ini#请选择导入格式|导入格式必须为json,yaml,ini之一" dc:"导入格式"`
|
||||
Group string `json:"group" dc:"目标分组,为空则使用原分组"`
|
||||
Mode string `json:"mode" v:"in:merge,replace#导入模式错误" dc:"导入模式:merge-合并,replace-替换"`
|
||||
}
|
||||
|
||||
// ConfigImportRes 导入配置响应
|
||||
type ConfigImportRes struct {
|
||||
Success int `json:"success" dc:"成功导入数量"`
|
||||
Failed int `json:"failed" dc:"失败数量"`
|
||||
Total int `json:"total" dc:"总数量"`
|
||||
}
|
||||
|
||||
// ConfigCacheReq 缓存配置请求
|
||||
type ConfigCacheReq struct {
|
||||
g.Meta `path:"/config/cache" method:"post" summary:"缓存配置" tags:"系统配置管理"`
|
||||
Group string `json:"group" dc:"配置分组,为空则缓存全部"`
|
||||
}
|
||||
|
||||
// ConfigClearCacheReq 清除配置缓存请求
|
||||
type ConfigClearCacheReq struct {
|
||||
g.Meta `path:"/config/clear-cache" method:"post" summary:"清除配置缓存" tags:"系统配置管理"`
|
||||
Group string `json:"group" dc:"配置分组,为空则清除全部"`
|
||||
}
|
||||
|
||||
// ConfigValidateReq 验证配置请求
|
||||
type ConfigValidateReq struct {
|
||||
g.Meta `path:"/config/validate" method:"post" summary:"验证配置" tags:"系统配置管理"`
|
||||
Key string `json:"key" v:"required#请输入配置键" dc:"配置键"`
|
||||
Value string `json:"value" dc:"配置值"`
|
||||
Type string `json:"type" v:"required|in:string,int,float,bool,json#请选择配置类型|配置类型必须为string,int,float,bool,json之一" dc:"配置类型"`
|
||||
}
|
||||
|
||||
// ConfigValidateRes 验证配置响应
|
||||
type ConfigValidateRes struct {
|
||||
Valid bool `json:"valid" dc:"是否有效"`
|
||||
Message string `json:"message" dc:"验证消息"`
|
||||
}
|
||||
|
||||
// ConfigBackupReq 备份配置请求
|
||||
type ConfigBackupReq struct {
|
||||
g.Meta `path:"/config/backup" method:"post" summary:"备份配置" tags:"系统配置管理"`
|
||||
Name string `json:"name" v:"required|length:1,100#请输入备份名称|备份名称长度为1-100个字符" dc:"备份名称"`
|
||||
Group string `json:"group" dc:"配置分组,为空则备份全部"`
|
||||
}
|
||||
|
||||
// ConfigBackupRes 备份配置响应
|
||||
type ConfigBackupRes struct {
|
||||
BackupId string `json:"backup_id" dc:"备份ID"`
|
||||
Filename string `json:"filename" dc:"备份文件名"`
|
||||
}
|
||||
|
||||
// ConfigRestoreReq 恢复配置请求
|
||||
type ConfigRestoreReq struct {
|
||||
g.Meta `path:"/config/restore" method:"post" summary:"恢复配置" tags:"系统配置管理"`
|
||||
BackupId string `json:"backup_id" v:"required#请输入备份ID" dc:"备份ID"`
|
||||
Mode string `json:"mode" v:"in:merge,replace#恢复模式错误" dc:"恢复模式:merge-合并,replace-替换"`
|
||||
}
|
||||
|
||||
// ConfigRestoreRes 恢复配置响应
|
||||
type ConfigRestoreRes struct {
|
||||
Success int `json:"success" dc:"成功恢复数量"`
|
||||
Failed int `json:"failed" dc:"失败数量"`
|
||||
Total int `json:"total" dc:"总数量"`
|
||||
}
|
||||
|
||||
// ConfigHistoryReq 获取配置历史请求
|
||||
type ConfigHistoryReq struct {
|
||||
g.Meta `path:"/config/history" method:"get" summary:"获取配置历史" tags:"系统配置管理"`
|
||||
Key string `json:"key" v:"required#请输入配置键" dc:"配置键"`
|
||||
Page int `json:"page" dc:"页码,默认1"`
|
||||
Size int `json:"size" dc:"每页数量,默认10"`
|
||||
}
|
||||
|
||||
// ConfigHistoryRes 获取配置历史响应
|
||||
type ConfigHistoryRes struct {
|
||||
List []ConfigHistoryItem `json:"list" dc:"历史列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Page int `json:"page" dc:"当前页码"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
}
|
||||
|
||||
// ConfigHistoryItem 配置历史项
|
||||
type ConfigHistoryItem struct {
|
||||
Id uint `json:"id" dc:"历史ID"`
|
||||
Key string `json:"key" dc:"配置键"`
|
||||
OldValue string `json:"old_value" dc:"旧值"`
|
||||
NewValue string `json:"new_value" dc:"新值"`
|
||||
Operation string `json:"operation" dc:"操作类型"`
|
||||
UserId uint `json:"user_id" dc:"操作用户ID"`
|
||||
Username string `json:"username" dc:"操作用户名"`
|
||||
CreatedAt string `json:"created_at" dc:"操作时间"`
|
||||
}
|
||||
|
||||
// ===== 用户端配置相关结构 =====
|
||||
|
||||
// ConfigUserGetReq 用户获取配置请求
|
||||
type ConfigUserGetReq struct {
|
||||
g.Meta `path:"/config/get" method:"get" summary:"获取配置" tags:"用户配置"`
|
||||
Key string `json:"key" v:"required#请输入配置键" dc:"配置键"`
|
||||
}
|
||||
|
||||
// ConfigUserGetRes 用户获取配置响应
|
||||
type ConfigUserGetRes struct {
|
||||
Value string `json:"value" dc:"配置值"`
|
||||
}
|
||||
|
||||
// ConfigUserGetGroupReq 用户获取分组配置请求
|
||||
type ConfigUserGetGroupReq struct {
|
||||
g.Meta `path:"/config/group" method:"get" summary:"获取分组配置" tags:"用户配置"`
|
||||
Group string `json:"group" v:"required#请输入配置分组" dc:"配置分组"`
|
||||
}
|
||||
|
||||
// ConfigUserGetGroupRes 用户获取分组配置响应
|
||||
type ConfigUserGetGroupRes struct {
|
||||
Configs map[string]string `json:"configs" dc:"配置键值对"`
|
||||
}
|
||||
|
||||
// ConfigUserGetPublicReq 用户获取公开配置请求
|
||||
type ConfigUserGetPublicReq struct {
|
||||
g.Meta `path:"/config/public" method:"get" summary:"获取公开配置" tags:"用户配置"`
|
||||
}
|
||||
|
||||
// ConfigUserGetPublicRes 用户获取公开配置响应
|
||||
type ConfigUserGetPublicRes struct {
|
||||
Configs map[string]interface{} `json:"configs" dc:"公开配置"`
|
||||
}
|
||||
19
api/v1/config_routes.go
Normal file
19
api/v1/config_routes.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// ConfigUserRoutes 用户配置路由
|
||||
// 注意:这个文件不应该导入controller包,避免循环导入
|
||||
// 路由注册应该在cmd包中进行
|
||||
func ConfigUserRoutes(group *ghttp.RouterGroup) {
|
||||
// 路由注册逻辑移动到cmd包中
|
||||
}
|
||||
|
||||
// ConfigAdminRoutes 管理员配置路由
|
||||
// 注意:这个文件不应该导入controller包,避免循环导入
|
||||
// 路由注册应该在cmd包中进行
|
||||
func ConfigAdminRoutes(group *ghttp.RouterGroup) {
|
||||
// 路由注册逻辑移动到cmd包中
|
||||
}
|
||||
473
api/v1/log.go
Normal file
473
api/v1/log.go
Normal file
@@ -0,0 +1,473 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// ===== 管理员日志管理 =====
|
||||
|
||||
// AdminLogListReq 管理员日志列表请求
|
||||
type AdminLogListReq struct {
|
||||
g.Meta `path:"/admin-log/list" method:"get" tags:"管理员日志" summary:"获取管理员日志列表"`
|
||||
Page int `json:"page" v:"min:1" dc:"页码,默认1"`
|
||||
Size int `json:"size" v:"min:1|max:100" dc:"每页数量,默认10"`
|
||||
AdminId int `json:"admin_id" dc:"管理员ID"`
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Action string `json:"action" dc:"操作类型"`
|
||||
Status int `json:"status" dc:"状态:1成功,0失败"`
|
||||
StartTime string `json:"start_time" dc:"开始时间"`
|
||||
EndTime string `json:"end_time" dc:"结束时间"`
|
||||
Keyword string `json:"keyword" dc:"关键词搜索"`
|
||||
}
|
||||
|
||||
// AdminLogListRes 管理员日志列表响应
|
||||
type AdminLogListRes struct {
|
||||
List []AdminLogItem `json:"list" dc:"日志列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Page int `json:"page" dc:"当前页"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
}
|
||||
|
||||
// AdminLogItem 管理员日志项
|
||||
type AdminLogItem struct {
|
||||
Id int `json:"id" dc:"日志ID"`
|
||||
AdminId int `json:"admin_id" dc:"管理员ID"`
|
||||
AdminName string `json:"admin_name" dc:"管理员名称"`
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Action string `json:"action" dc:"操作类型"`
|
||||
Description string `json:"description" dc:"操作描述"`
|
||||
RequestData string `json:"request_data" dc:"请求数据"`
|
||||
ResponseData string `json:"response_data" dc:"响应数据"`
|
||||
Ip string `json:"ip" dc:"IP地址"`
|
||||
UserAgent string `json:"user_agent" dc:"用户代理"`
|
||||
Status int `json:"status" dc:"状态:1成功,0失败"`
|
||||
ErrorMsg string `json:"error_msg" dc:"错误信息"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
}
|
||||
|
||||
// AdminLogDetailReq 管理员日志详情请求
|
||||
type AdminLogDetailReq struct {
|
||||
g.Meta `path:"/admin-log/detail" method:"get" tags:"管理员日志" summary:"获取管理员日志详情"`
|
||||
Id int `json:"id" v:"required|min:1" dc:"日志ID"`
|
||||
}
|
||||
|
||||
// AdminLogDetailRes 管理员日志详情响应
|
||||
type AdminLogDetailRes struct {
|
||||
Log AdminLogDetail `json:"log" dc:"日志详情"`
|
||||
}
|
||||
|
||||
// AdminLogDetail 管理员日志详情
|
||||
type AdminLogDetail struct {
|
||||
Id int `json:"id" dc:"日志ID"`
|
||||
AdminId int `json:"admin_id" dc:"管理员ID"`
|
||||
AdminName string `json:"admin_name" dc:"管理员名称"`
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Action string `json:"action" dc:"操作类型"`
|
||||
Description string `json:"description" dc:"操作描述"`
|
||||
RequestData string `json:"request_data" dc:"请求数据"`
|
||||
ResponseData string `json:"response_data" dc:"响应数据"`
|
||||
Ip string `json:"ip" dc:"IP地址"`
|
||||
UserAgent string `json:"user_agent" dc:"用户代理"`
|
||||
Status int `json:"status" dc:"状态:1成功,0失败"`
|
||||
ErrorMsg string `json:"error_msg" dc:"错误信息"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
}
|
||||
|
||||
// AdminLogDeleteReq 删除管理员日志请求
|
||||
type AdminLogDeleteReq struct {
|
||||
g.Meta `path:"/admin-log/delete" method:"post" tags:"管理员日志" summary:"删除管理员日志"`
|
||||
Id int `json:"id" v:"required|min:1" dc:"日志ID"`
|
||||
}
|
||||
|
||||
// AdminLogDeleteRes 删除管理员日志响应
|
||||
type AdminLogDeleteRes struct {
|
||||
Message string `json:"message" dc:"操作结果"`
|
||||
}
|
||||
|
||||
// AdminLogBatchDeleteReq 批量删除管理员日志请求
|
||||
type AdminLogBatchDeleteReq struct {
|
||||
g.Meta `path:"/admin-log/batch-delete" method:"post" tags:"管理员日志" summary:"批量删除管理员日志"`
|
||||
Ids []int `json:"ids" v:"required" dc:"日志ID列表"`
|
||||
}
|
||||
|
||||
// AdminLogBatchDeleteRes 批量删除管理员日志响应
|
||||
type AdminLogBatchDeleteRes struct {
|
||||
Message string `json:"message" dc:"操作结果"`
|
||||
}
|
||||
|
||||
// AdminLogClearReq 清空管理员日志请求
|
||||
type AdminLogClearReq struct {
|
||||
g.Meta `path:"/admin-log/clear" method:"post" tags:"管理员日志" summary:"清空管理员日志"`
|
||||
Days int `json:"days" dc:"保留天数,0表示全部清空"`
|
||||
AdminId int `json:"admin_id" dc:"管理员ID,0表示所有管理员"`
|
||||
Module string `json:"module" dc:"模块名称,空表示所有模块"`
|
||||
}
|
||||
|
||||
// AdminLogClearRes 清空管理员日志响应
|
||||
type AdminLogClearRes struct {
|
||||
Message string `json:"message" dc:"操作结果"`
|
||||
Count int `json:"count" dc:"清空数量"`
|
||||
}
|
||||
|
||||
// AdminLogExportReq 导出管理员日志请求
|
||||
type AdminLogExportReq struct {
|
||||
g.Meta `path:"/admin-log/export" method:"get" tags:"管理员日志" summary:"导出管理员日志"`
|
||||
AdminId int `json:"admin_id" dc:"管理员ID"`
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Action string `json:"action" dc:"操作类型"`
|
||||
Status int `json:"status" dc:"状态:1成功,0失败"`
|
||||
StartTime string `json:"start_time" dc:"开始时间"`
|
||||
EndTime string `json:"end_time" dc:"结束时间"`
|
||||
Format string `json:"format" dc:"导出格式:excel,csv,json"`
|
||||
}
|
||||
|
||||
// AdminLogExportRes 导出管理员日志响应
|
||||
type AdminLogExportRes struct {
|
||||
Content string `json:"content" dc:"导出内容"`
|
||||
Filename string `json:"filename" dc:"文件名"`
|
||||
}
|
||||
|
||||
// AdminLogStatsReq 管理员日志统计请求
|
||||
type AdminLogStatsReq struct {
|
||||
g.Meta `path:"/admin-log/stats" method:"get" tags:"管理员日志" summary:"获取管理员日志统计"`
|
||||
AdminId int `json:"admin_id" dc:"管理员ID"`
|
||||
StartTime string `json:"start_time" dc:"开始时间"`
|
||||
EndTime string `json:"end_time" dc:"结束时间"`
|
||||
Type string `json:"type" dc:"统计类型:day,week,month"`
|
||||
}
|
||||
|
||||
// AdminLogStatsRes 管理员日志统计响应
|
||||
type AdminLogStatsRes struct {
|
||||
Stats AdminLogStatsData `json:"stats" dc:"统计数据"`
|
||||
}
|
||||
|
||||
// AdminLogStatsData 管理员日志统计数据
|
||||
type AdminLogStatsData struct {
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Success int `json:"success" dc:"成功数"`
|
||||
Failed int `json:"failed" dc:"失败数"`
|
||||
SuccessRate float64 `json:"success_rate" dc:"成功率"`
|
||||
ModuleStats []AdminLogModuleStats `json:"module_stats" dc:"模块统计"`
|
||||
ActionStats []AdminLogActionStats `json:"action_stats" dc:"操作统计"`
|
||||
TimeStats []AdminLogTimeStats `json:"time_stats" dc:"时间统计"`
|
||||
AdminStats []AdminLogAdminStats `json:"admin_stats" dc:"管理员统计"`
|
||||
}
|
||||
|
||||
// AdminLogModuleStats 模块统计
|
||||
type AdminLogModuleStats struct {
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Count int `json:"count" dc:"数量"`
|
||||
}
|
||||
|
||||
// AdminLogActionStats 操作统计
|
||||
type AdminLogActionStats struct {
|
||||
Action string `json:"action" dc:"操作类型"`
|
||||
Count int `json:"count" dc:"数量"`
|
||||
}
|
||||
|
||||
// AdminLogTimeStats 时间统计
|
||||
type AdminLogTimeStats struct {
|
||||
Time string `json:"time" dc:"时间"`
|
||||
Count int `json:"count" dc:"数量"`
|
||||
}
|
||||
|
||||
// AdminLogAdminStats 管理员统计
|
||||
type AdminLogAdminStats struct {
|
||||
AdminId int `json:"admin_id" dc:"管理员ID"`
|
||||
AdminName string `json:"admin_name" dc:"管理员名称"`
|
||||
Count int `json:"count" dc:"数量"`
|
||||
}
|
||||
|
||||
// ===== 用户日志管理 =====
|
||||
|
||||
// UserLogListReq 用户日志列表请求
|
||||
type UserLogListReq struct {
|
||||
g.Meta `path:"/user-log/list" method:"get" tags:"用户日志" summary:"获取用户日志列表"`
|
||||
Page int `json:"page" v:"min:1" dc:"页码,默认1"`
|
||||
Size int `json:"size" v:"min:1|max:100" dc:"每页数量,默认10"`
|
||||
UserId int `json:"user_id" dc:"用户ID"`
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Action string `json:"action" dc:"操作类型"`
|
||||
Status int `json:"status" dc:"状态:1成功,0失败"`
|
||||
StartTime string `json:"start_time" dc:"开始时间"`
|
||||
EndTime string `json:"end_time" dc:"结束时间"`
|
||||
Keyword string `json:"keyword" dc:"关键词搜索"`
|
||||
}
|
||||
|
||||
// UserLogListRes 用户日志列表响应
|
||||
type UserLogListRes struct {
|
||||
List []UserLogItem `json:"list" dc:"日志列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Page int `json:"page" dc:"当前页"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
}
|
||||
|
||||
// UserLogItem 用户日志项
|
||||
type UserLogItem struct {
|
||||
Id int `json:"id" dc:"日志ID"`
|
||||
UserId int `json:"user_id" dc:"用户ID"`
|
||||
Username string `json:"username" dc:"用户名"`
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Action string `json:"action" dc:"操作类型"`
|
||||
Description string `json:"description" dc:"操作描述"`
|
||||
RequestData string `json:"request_data" dc:"请求数据"`
|
||||
ResponseData string `json:"response_data" dc:"响应数据"`
|
||||
Ip string `json:"ip" dc:"IP地址"`
|
||||
UserAgent string `json:"user_agent" dc:"用户代理"`
|
||||
Status int `json:"status" dc:"状态:1成功,0失败"`
|
||||
ErrorMsg string `json:"error_msg" dc:"错误信息"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
}
|
||||
|
||||
// UserLogDetailReq 用户日志详情请求
|
||||
type UserLogDetailReq struct {
|
||||
g.Meta `path:"/user-log/detail" method:"get" tags:"用户日志" summary:"获取用户日志详情"`
|
||||
Id int `json:"id" v:"required|min:1" dc:"日志ID"`
|
||||
}
|
||||
|
||||
// UserLogDetailRes 用户日志详情响应
|
||||
type UserLogDetailRes struct {
|
||||
Log UserLogDetail `json:"log" dc:"日志详情"`
|
||||
}
|
||||
|
||||
// UserLogDetail 用户日志详情
|
||||
type UserLogDetail struct {
|
||||
Id int `json:"id" dc:"日志ID"`
|
||||
UserId int `json:"user_id" dc:"用户ID"`
|
||||
Username string `json:"username" dc:"用户名"`
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Action string `json:"action" dc:"操作类型"`
|
||||
Description string `json:"description" dc:"操作描述"`
|
||||
RequestData string `json:"request_data" dc:"请求数据"`
|
||||
ResponseData string `json:"response_data" dc:"响应数据"`
|
||||
Ip string `json:"ip" dc:"IP地址"`
|
||||
UserAgent string `json:"user_agent" dc:"用户代理"`
|
||||
Status int `json:"status" dc:"状态:1成功,0失败"`
|
||||
ErrorMsg string `json:"error_msg" dc:"错误信息"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
}
|
||||
|
||||
// UserLogDeleteReq 删除用户日志请求
|
||||
type UserLogDeleteReq struct {
|
||||
g.Meta `path:"/user-log/delete" method:"post" tags:"用户日志" summary:"删除用户日志"`
|
||||
Id int `json:"id" v:"required|min:1" dc:"日志ID"`
|
||||
}
|
||||
|
||||
// UserLogDeleteRes 删除用户日志响应
|
||||
type UserLogDeleteRes struct {
|
||||
Message string `json:"message" dc:"操作结果"`
|
||||
}
|
||||
|
||||
// UserLogBatchDeleteReq 批量删除用户日志请求
|
||||
type UserLogBatchDeleteReq struct {
|
||||
g.Meta `path:"/user-log/batch-delete" method:"post" tags:"用户日志" summary:"批量删除用户日志"`
|
||||
Ids []int `json:"ids" v:"required" dc:"日志ID列表"`
|
||||
}
|
||||
|
||||
// UserLogBatchDeleteRes 批量删除用户日志响应
|
||||
type UserLogBatchDeleteRes struct {
|
||||
Message string `json:"message" dc:"操作结果"`
|
||||
}
|
||||
|
||||
// UserLogClearReq 清空用户日志请求
|
||||
type UserLogClearReq struct {
|
||||
g.Meta `path:"/user-log/clear" method:"post" tags:"用户日志" summary:"清空用户日志"`
|
||||
Days int `json:"days" dc:"保留天数,0表示全部清空"`
|
||||
UserId int `json:"user_id" dc:"用户ID,0表示所有用户"`
|
||||
Module string `json:"module" dc:"模块名称,空表示所有模块"`
|
||||
}
|
||||
|
||||
// UserLogClearRes 清空用户日志响应
|
||||
type UserLogClearRes struct {
|
||||
Message string `json:"message" dc:"操作结果"`
|
||||
Count int `json:"count" dc:"清空数量"`
|
||||
}
|
||||
|
||||
// UserLogExportReq 导出用户日志请求
|
||||
type UserLogExportReq struct {
|
||||
g.Meta `path:"/user-log/export" method:"get" tags:"用户日志" summary:"导出用户日志"`
|
||||
UserId int `json:"user_id" dc:"用户ID"`
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Action string `json:"action" dc:"操作类型"`
|
||||
Status int `json:"status" dc:"状态:1成功,0失败"`
|
||||
StartTime string `json:"start_time" dc:"开始时间"`
|
||||
EndTime string `json:"end_time" dc:"结束时间"`
|
||||
Format string `json:"format" dc:"导出格式:excel,csv,json"`
|
||||
}
|
||||
|
||||
// UserLogExportRes 导出用户日志响应
|
||||
type UserLogExportRes struct {
|
||||
Content string `json:"content" dc:"导出内容"`
|
||||
Filename string `json:"filename" dc:"文件名"`
|
||||
}
|
||||
|
||||
// UserLogStatsReq 用户日志统计请求
|
||||
type UserLogStatsReq struct {
|
||||
g.Meta `path:"/user-log/stats" method:"get" tags:"用户日志" summary:"获取用户日志统计"`
|
||||
UserId int `json:"user_id" dc:"用户ID"`
|
||||
StartTime string `json:"start_time" dc:"开始时间"`
|
||||
EndTime string `json:"end_time" dc:"结束时间"`
|
||||
Type string `json:"type" dc:"统计类型:day,week,month"`
|
||||
}
|
||||
|
||||
// UserLogStatsRes 用户日志统计响应
|
||||
type UserLogStatsRes struct {
|
||||
Stats UserLogStatsData `json:"stats" dc:"统计数据"`
|
||||
}
|
||||
|
||||
// UserLogStatsData 用户日志统计数据
|
||||
type UserLogStatsData struct {
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Success int `json:"success" dc:"成功数"`
|
||||
Failed int `json:"failed" dc:"失败数"`
|
||||
SuccessRate float64 `json:"success_rate" dc:"成功率"`
|
||||
ModuleStats []UserLogModuleStats `json:"module_stats" dc:"模块统计"`
|
||||
ActionStats []UserLogActionStats `json:"action_stats" dc:"操作统计"`
|
||||
TimeStats []UserLogTimeStats `json:"time_stats" dc:"时间统计"`
|
||||
UserStats []UserLogUserStats `json:"user_stats" dc:"用户统计"`
|
||||
}
|
||||
|
||||
// UserLogModuleStats 模块统计
|
||||
type UserLogModuleStats struct {
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Count int `json:"count" dc:"数量"`
|
||||
}
|
||||
|
||||
// UserLogActionStats 操作统计
|
||||
type UserLogActionStats struct {
|
||||
Action string `json:"action" dc:"操作类型"`
|
||||
Count int `json:"count" dc:"数量"`
|
||||
}
|
||||
|
||||
// UserLogTimeStats 时间统计
|
||||
type UserLogTimeStats struct {
|
||||
Time string `json:"time" dc:"时间"`
|
||||
Count int `json:"count" dc:"数量"`
|
||||
}
|
||||
|
||||
// UserLogUserStats 用户统计
|
||||
type UserLogUserStats struct {
|
||||
UserId int `json:"user_id" dc:"用户ID"`
|
||||
Username string `json:"username" dc:"用户名"`
|
||||
Count int `json:"count" dc:"数量"`
|
||||
}
|
||||
|
||||
// ===== 用户端日志查询 =====
|
||||
|
||||
// UserMyLogListReq 用户查看自己的日志列表请求
|
||||
type UserMyLogListReq struct {
|
||||
g.Meta `path:"/my-log/list" method:"get" tags:"用户日志" summary:"获取我的日志列表"`
|
||||
Page int `json:"page" v:"min:1" dc:"页码,默认1"`
|
||||
Size int `json:"size" v:"min:1|max:100" dc:"每页数量,默认10"`
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Action string `json:"action" dc:"操作类型"`
|
||||
StartTime string `json:"start_time" dc:"开始时间"`
|
||||
EndTime string `json:"end_time" dc:"结束时间"`
|
||||
}
|
||||
|
||||
// UserMyLogListRes 用户查看自己的日志列表响应
|
||||
type UserMyLogListRes struct {
|
||||
List []UserMyLogItem `json:"list" dc:"日志列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Page int `json:"page" dc:"当前页"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
}
|
||||
|
||||
// UserMyLogItem 用户日志项
|
||||
type UserMyLogItem struct {
|
||||
Id int `json:"id" dc:"日志ID"`
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Action string `json:"action" dc:"操作类型"`
|
||||
Description string `json:"description" dc:"操作描述"`
|
||||
Status int `json:"status" dc:"状态:1成功,0失败"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
}
|
||||
|
||||
// UserMyLogDetailReq 用户查看自己的日志详情请求
|
||||
type UserMyLogDetailReq struct {
|
||||
g.Meta `path:"/my-log/detail" method:"get" tags:"用户日志" summary:"获取我的日志详情"`
|
||||
Id int `json:"id" v:"required|min:1" dc:"日志ID"`
|
||||
}
|
||||
|
||||
// UserMyLogDetailRes 用户查看自己的日志详情响应
|
||||
type UserMyLogDetailRes struct {
|
||||
Log UserMyLogDetail `json:"log" dc:"日志详情"`
|
||||
}
|
||||
|
||||
// UserMyLogDetail 用户日志详情
|
||||
type UserMyLogDetail struct {
|
||||
Id int `json:"id" dc:"日志ID"`
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Action string `json:"action" dc:"操作类型"`
|
||||
Description string `json:"description" dc:"操作描述"`
|
||||
Status int `json:"status" dc:"状态:1成功,0失败"`
|
||||
ErrorMsg string `json:"error_msg" dc:"错误信息"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
}
|
||||
|
||||
// ===== 系统日志管理 =====
|
||||
|
||||
// SystemLogListReq 系统日志列表请求
|
||||
type SystemLogListReq struct {
|
||||
g.Meta `path:"/system-log/list" method:"get" tags:"系统日志" summary:"获取系统日志列表"`
|
||||
Page int `json:"page" v:"min:1" dc:"页码,默认1"`
|
||||
Size int `json:"size" v:"min:1|max:100" dc:"每页数量,默认10"`
|
||||
Level string `json:"level" dc:"日志级别:debug,info,warn,error"`
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
StartTime string `json:"start_time" dc:"开始时间"`
|
||||
EndTime string `json:"end_time" dc:"结束时间"`
|
||||
Keyword string `json:"keyword" dc:"关键词搜索"`
|
||||
}
|
||||
|
||||
// SystemLogListRes 系统日志列表响应
|
||||
type SystemLogListRes struct {
|
||||
List []SystemLogItem `json:"list" dc:"日志列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Page int `json:"page" dc:"当前页"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
}
|
||||
|
||||
// SystemLogItem 系统日志项
|
||||
type SystemLogItem struct {
|
||||
Id int `json:"id" dc:"日志ID"`
|
||||
Level string `json:"level" dc:"日志级别"`
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Message string `json:"message" dc:"日志消息"`
|
||||
Context string `json:"context" dc:"上下文信息"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
}
|
||||
|
||||
// SystemLogDetailReq 系统日志详情请求
|
||||
type SystemLogDetailReq struct {
|
||||
g.Meta `path:"/system-log/detail" method:"get" tags:"系统日志" summary:"获取系统日志详情"`
|
||||
Id int `json:"id" v:"required|min:1" dc:"日志ID"`
|
||||
}
|
||||
|
||||
// SystemLogDetailRes 系统日志详情响应
|
||||
type SystemLogDetailRes struct {
|
||||
Log SystemLogDetail `json:"log" dc:"日志详情"`
|
||||
}
|
||||
|
||||
// SystemLogDetail 系统日志详情
|
||||
type SystemLogDetail struct {
|
||||
Id int `json:"id" dc:"日志ID"`
|
||||
Level string `json:"level" dc:"日志级别"`
|
||||
Module string `json:"module" dc:"模块名称"`
|
||||
Message string `json:"message" dc:"日志消息"`
|
||||
Context string `json:"context" dc:"上下文信息"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
}
|
||||
|
||||
// SystemLogClearReq 清空系统日志请求
|
||||
type SystemLogClearReq struct {
|
||||
g.Meta `path:"/system-log/clear" method:"post" tags:"系统日志" summary:"清空系统日志"`
|
||||
Days int `json:"days" dc:"保留天数,0表示全部清空"`
|
||||
Level string `json:"level" dc:"日志级别,空表示所有级别"`
|
||||
Module string `json:"module" dc:"模块名称,空表示所有模块"`
|
||||
}
|
||||
|
||||
// SystemLogClearRes 清空系统日志响应
|
||||
type SystemLogClearRes struct {
|
||||
Message string `json:"message" dc:"操作结果"`
|
||||
Count int `json:"count" dc:"清空数量"`
|
||||
}
|
||||
19
api/v1/log_routes.go
Normal file
19
api/v1/log_routes.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// LogUserRoutes 用户日志路由
|
||||
// 注意:这个文件不应该导入controller包,避免循环导入
|
||||
// 路由注册应该在cmd包中进行
|
||||
func LogUserRoutes(group *ghttp.RouterGroup) {
|
||||
// 路由注册逻辑移动到cmd包中
|
||||
}
|
||||
|
||||
// LogAdminRoutes 管理员日志路由
|
||||
// 注意:这个文件不应该导入controller包,避免循环导入
|
||||
// 路由注册应该在cmd包中进行
|
||||
func LogAdminRoutes(group *ghttp.RouterGroup) {
|
||||
// 路由注册逻辑移动到cmd包中
|
||||
}
|
||||
65
api/v1/movie.go
Normal file
65
api/v1/movie.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"nl-video-api/internal/controller/movie"
|
||||
)
|
||||
|
||||
// MovieGroup 影片管理路由组
|
||||
func MovieGroup(group *ghttp.RouterGroup) {
|
||||
group.Middleware(AuthMiddleware) // 需要认证
|
||||
|
||||
// 影片管理路由
|
||||
group.Group("/movies", func(group *ghttp.RouterGroup) {
|
||||
// 基础CRUD操作
|
||||
group.GET("/", movie.Movie.GetList) // 获取影片列表
|
||||
group.POST("/", movie.Movie.Create) // 创建影片
|
||||
group.GET("/{id}", movie.Movie.GetById) // 获取影片详情
|
||||
group.POST("/update", movie.Movie.Update) // 更新影片
|
||||
group.POST("/delete/{id}", movie.Movie.Delete) // 删除影片
|
||||
|
||||
// 搜索和筛选
|
||||
group.GET("/search", movie.Movie.Search) // 搜索影片
|
||||
group.GET("/category/{category_id}", movie.Movie.GetByCategory) // 按分类获取
|
||||
|
||||
// 特殊列表
|
||||
group.GET("/hot", movie.Movie.GetHot) // 获取热门影片
|
||||
group.GET("/recommend", movie.Movie.GetRecommend) // 获取推荐影片
|
||||
group.GET("/new", movie.Movie.GetNew) // 获取最新影片
|
||||
|
||||
// 批量操作
|
||||
group.POST("/batch-update", movie.Movie.BatchUpdate) // 批量更新状态
|
||||
|
||||
// 文件上传
|
||||
group.POST("/upload/video", movie.Movie.UploadVideo) // 上传视频
|
||||
group.POST("/upload/poster", movie.Movie.UploadPoster) // 上传封面
|
||||
})
|
||||
|
||||
// 集数管理路由
|
||||
group.Group("/episodes", func(group *ghttp.RouterGroup) {
|
||||
// 基础CRUD操作
|
||||
group.POST("/", movie.Episode.Create) // 创建集数
|
||||
group.GET("/{id}", movie.Episode.GetById) // 获取集数详情
|
||||
group.POST("/update", movie.Episode.Update) // 更新集数
|
||||
group.POST("/delete/{id}", movie.Episode.Delete) // 删除集数
|
||||
|
||||
// 按影片获取集数
|
||||
group.GET("/movie/{movie_id}", movie.Episode.GetByMovieId) // 获取影片的所有集数
|
||||
|
||||
// 批量操作
|
||||
group.POST("/batch", movie.Episode.BatchCreate) // 批量创建集数
|
||||
group.POST("/batch-status", movie.Episode.BatchUpdateStatus) // 批量更新状态
|
||||
|
||||
// 文件上传和处理
|
||||
group.POST("/upload/video", movie.Episode.UploadVideo) // 上传集数视频
|
||||
group.POST("/thumbnail", movie.Episode.GenerateThumbnail) // 生成缩略图
|
||||
group.GET("/video/info", movie.Episode.GetVideoInfo) // 获取视频信息
|
||||
})
|
||||
}
|
||||
|
||||
// AuthMiddleware 认证中间件(这里引用已存在的中间件)
|
||||
var AuthMiddleware = func(r *ghttp.Request) {
|
||||
// 这里应该引用已存在的认证中间件
|
||||
// 暂时跳过认证检查,实际项目中需要实现
|
||||
r.Middleware.Next()
|
||||
}
|
||||
230
api/v1/payment_order.go
Normal file
230
api/v1/payment_order.go
Normal file
@@ -0,0 +1,230 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// PaymentOrderCreateReq 创建支付订单请求
|
||||
type PaymentOrderCreateReq struct {
|
||||
g.Meta `path:"/payment/create" method:"post" summary:"创建支付订单" tags:"支付订单管理"`
|
||||
VipLevelId uint `json:"vip_level_id" v:"required|min:1#VIP等级ID不能为空|VIP等级ID必须大于0" dc:"VIP等级ID"`
|
||||
PaymentType int `json:"payment_type" v:"required|in:1,2,3#支付方式不能为空|支付方式错误" dc:"支付方式(1:支付宝,2:微信,3:余额)"`
|
||||
CouponId uint `json:"coupon_id" v:"min:0#优惠券ID必须大于等于0" dc:"优惠券ID" default:"0"`
|
||||
Remark string `json:"remark" v:"length:0,200#备注长度不能超过200字符" dc:"备注"`
|
||||
}
|
||||
|
||||
// PaymentOrderCreateRes 创建支付订单响应
|
||||
type PaymentOrderCreateRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
OrderNo string `json:"order_no" dc:"订单号"`
|
||||
PaymentNo string `json:"payment_no" dc:"支付单号"`
|
||||
PayUrl string `json:"pay_url" dc:"支付链接"`
|
||||
Amount string `json:"amount" dc:"支付金额"`
|
||||
}
|
||||
|
||||
// PaymentOrderListReq 支付订单列表请求
|
||||
type PaymentOrderListReq struct {
|
||||
g.Meta `path:"/payment/list" method:"get" summary:"支付订单列表" tags:"支付订单管理"`
|
||||
Status int `json:"status" v:"in:-1,0,1,2,3#状态值错误" dc:"状态(-1:全部,0:待支付,1:已支付,2:已取消,3:已退款)" default:"-1"`
|
||||
Page int `json:"page" v:"min:1#页码必须大于0" dc:"页码" default:"1"`
|
||||
Size int `json:"size" v:"min:1|max:100#每页数量必须大于0|每页数量不能超过100" dc:"每页数量" default:"10"`
|
||||
}
|
||||
|
||||
// PaymentOrderListRes 支付订单列表响应
|
||||
type PaymentOrderListRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
List []PaymentOrderItem `json:"list" dc:"订单列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Page int `json:"page" dc:"当前页"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
}
|
||||
|
||||
// PaymentOrderItem 支付订单项目
|
||||
type PaymentOrderItem struct {
|
||||
Id uint `json:"id" dc:"订单ID"`
|
||||
OrderNo string `json:"order_no" dc:"订单号"`
|
||||
PaymentNo string `json:"payment_no" dc:"支付单号"`
|
||||
VipLevelName string `json:"vip_level_name" dc:"VIP等级名称"`
|
||||
OriginalPrice string `json:"original_price" dc:"原价"`
|
||||
CouponAmount string `json:"coupon_amount" dc:"优惠金额"`
|
||||
ActualAmount string `json:"actual_amount" dc:"实付金额"`
|
||||
PaymentType int `json:"payment_type" dc:"支付方式"`
|
||||
Status int `json:"status" dc:"订单状态"`
|
||||
PaidAt string `json:"paid_at" dc:"支付时间"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
Remark string `json:"remark" dc:"备注"`
|
||||
}
|
||||
|
||||
// PaymentOrderDetailReq 支付订单详情请求
|
||||
type PaymentOrderDetailReq struct {
|
||||
g.Meta `path:"/payment/detail" method:"get" summary:"支付订单详情" tags:"支付订单管理"`
|
||||
OrderNo string `json:"order_no" v:"required#订单号不能为空" dc:"订单号"`
|
||||
}
|
||||
|
||||
// PaymentOrderDetailRes 支付订单详情响应
|
||||
type PaymentOrderDetailRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
Order PaymentOrderDetail `json:"order" dc:"订单详情"`
|
||||
}
|
||||
|
||||
// PaymentOrderDetail 支付订单详情
|
||||
type PaymentOrderDetail struct {
|
||||
Id uint `json:"id" dc:"订单ID"`
|
||||
OrderNo string `json:"order_no" dc:"订单号"`
|
||||
PaymentNo string `json:"payment_no" dc:"支付单号"`
|
||||
VipLevelId uint `json:"vip_level_id" dc:"VIP等级ID"`
|
||||
VipLevelName string `json:"vip_level_name" dc:"VIP等级名称"`
|
||||
Duration int `json:"duration" dc:"时长(天)"`
|
||||
OriginalPrice string `json:"original_price" dc:"原价"`
|
||||
CouponId uint `json:"coupon_id" dc:"优惠券ID"`
|
||||
CouponAmount string `json:"coupon_amount" dc:"优惠金额"`
|
||||
ActualAmount string `json:"actual_amount" dc:"实付金额"`
|
||||
PaymentType int `json:"payment_type" dc:"支付方式"`
|
||||
Status int `json:"status" dc:"订单状态"`
|
||||
PaidAt string `json:"paid_at" dc:"支付时间"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" dc:"更新时间"`
|
||||
Remark string `json:"remark" dc:"备注"`
|
||||
}
|
||||
|
||||
// PaymentOrderCancelReq 取消支付订单请求
|
||||
type PaymentOrderCancelReq struct {
|
||||
g.Meta `path:"/payment/cancel" method:"post" summary:"取消支付订单" tags:"支付订单管理"`
|
||||
OrderNo string `json:"order_no" v:"required#订单号不能为空" dc:"订单号"`
|
||||
}
|
||||
|
||||
// PaymentOrderCancelRes 取消支付订单响应
|
||||
type PaymentOrderCancelRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// PaymentCallbackReq 支付回调请求
|
||||
type PaymentCallbackReq struct {
|
||||
g.Meta `path:"/payment/callback" method:"post" summary:"支付回调" tags:"支付订单管理"`
|
||||
OrderNo string `json:"order_no" v:"required#订单号不能为空" dc:"订单号"`
|
||||
PaymentNo string `json:"payment_no" v:"required#支付单号不能为空" dc:"支付单号"`
|
||||
Amount string `json:"amount" v:"required#支付金额不能为空" dc:"支付金额"`
|
||||
Status int `json:"status" v:"required|in:1,2#支付状态不能为空|支付状态错误" dc:"支付状态(1:成功,2:失败)"`
|
||||
TradeNo string `json:"trade_no" dc:"第三方交易号"`
|
||||
}
|
||||
|
||||
// PaymentCallbackRes 支付回调响应
|
||||
type PaymentCallbackRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// AdminPaymentOrderListReq 管理员支付订单列表请求
|
||||
type AdminPaymentOrderListReq struct {
|
||||
g.Meta `path:"/admin/payment/list" method:"get" summary:"管理员支付订单列表" tags:"支付订单管理"`
|
||||
UserId uint `json:"user_id" v:"min:0#用户ID必须大于等于0" dc:"用户ID" default:"0"`
|
||||
Status int `json:"status" v:"in:-1,0,1,2,3#状态值错误" dc:"状态(-1:全部,0:待支付,1:已支付,2:已取消,3:已退款)" default:"-1"`
|
||||
PaymentType int `json:"payment_type" v:"in:-1,1,2,3#支付方式错误" dc:"支付方式(-1:全部,1:支付宝,2:微信,3:余额)" default:"-1"`
|
||||
StartDate string `json:"start_date" v:"date#开始日期格式错误" dc:"开始日期"`
|
||||
EndDate string `json:"end_date" v:"date#结束日期格式错误" dc:"结束日期"`
|
||||
Keyword string `json:"keyword" dc:"关键词搜索(订单号/用户名)"`
|
||||
Page int `json:"page" v:"min:1#页码必须大于0" dc:"页码" default:"1"`
|
||||
Size int `json:"size" v:"min:1|max:100#每页数量必须大于0|每页数量不能超过100" dc:"每页数量" default:"10"`
|
||||
}
|
||||
|
||||
// AdminPaymentOrderListRes 管理员支付订单列表响应
|
||||
type AdminPaymentOrderListRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
List []AdminPaymentOrderItem `json:"list" dc:"订单列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Page int `json:"page" dc:"当前页"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
}
|
||||
|
||||
// AdminPaymentOrderItem 管理员支付订单项目
|
||||
type AdminPaymentOrderItem struct {
|
||||
Id uint `json:"id" dc:"订单ID"`
|
||||
OrderNo string `json:"order_no" dc:"订单号"`
|
||||
PaymentNo string `json:"payment_no" dc:"支付单号"`
|
||||
UserId uint `json:"user_id" dc:"用户ID"`
|
||||
Username string `json:"username" dc:"用户名"`
|
||||
VipLevelName string `json:"vip_level_name" dc:"VIP等级名称"`
|
||||
OriginalPrice string `json:"original_price" dc:"原价"`
|
||||
CouponAmount string `json:"coupon_amount" dc:"优惠金额"`
|
||||
ActualAmount string `json:"actual_amount" dc:"实付金额"`
|
||||
PaymentType int `json:"payment_type" dc:"支付方式"`
|
||||
Status int `json:"status" dc:"订单状态"`
|
||||
PaidAt string `json:"paid_at" dc:"支付时间"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
Remark string `json:"remark" dc:"备注"`
|
||||
}
|
||||
|
||||
// AdminPaymentOrderDetailReq 管理员支付订单详情请求
|
||||
type AdminPaymentOrderDetailReq struct {
|
||||
g.Meta `path:"/admin/payment/detail" method:"get" summary:"管理员支付订单详情" tags:"支付订单管理"`
|
||||
Id uint `json:"id" v:"required|min:1#订单ID不能为空|订单ID必须大于0" dc:"订单ID"`
|
||||
}
|
||||
|
||||
// AdminPaymentOrderDetailRes 管理员支付订单详情响应
|
||||
type AdminPaymentOrderDetailRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
Order AdminPaymentOrderDetail `json:"order" dc:"订单详情"`
|
||||
}
|
||||
|
||||
// AdminPaymentOrderDetail 管理员支付订单详情
|
||||
type AdminPaymentOrderDetail struct {
|
||||
Id uint `json:"id" dc:"订单ID"`
|
||||
OrderNo string `json:"order_no" dc:"订单号"`
|
||||
PaymentNo string `json:"payment_no" dc:"支付单号"`
|
||||
UserId uint `json:"user_id" dc:"用户ID"`
|
||||
Username string `json:"username" dc:"用户名"`
|
||||
VipLevelId uint `json:"vip_level_id" dc:"VIP等级ID"`
|
||||
VipLevelName string `json:"vip_level_name" dc:"VIP等级名称"`
|
||||
Duration int `json:"duration" dc:"时长(天)"`
|
||||
OriginalPrice string `json:"original_price" dc:"原价"`
|
||||
CouponId uint `json:"coupon_id" dc:"优惠券ID"`
|
||||
CouponAmount string `json:"coupon_amount" dc:"优惠金额"`
|
||||
ActualAmount string `json:"actual_amount" dc:"实付金额"`
|
||||
PaymentType int `json:"payment_type" dc:"支付方式"`
|
||||
Status int `json:"status" dc:"订单状态"`
|
||||
TradeNo string `json:"trade_no" dc:"第三方交易号"`
|
||||
PaidAt string `json:"paid_at" dc:"支付时间"`
|
||||
CreatedAt string `json:"created_at" dc:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" dc:"更新时间"`
|
||||
Remark string `json:"remark" dc:"备注"`
|
||||
}
|
||||
|
||||
// AdminPaymentOrderRefundReq 管理员订单退款请求
|
||||
type AdminPaymentOrderRefundReq struct {
|
||||
g.Meta `path:"/admin/payment/refund" method:"post" summary:"订单退款" tags:"支付订单管理"`
|
||||
Id uint `json:"id" v:"required|min:1#订单ID不能为空|订单ID必须大于0" dc:"订单ID"`
|
||||
RefundType int `json:"refund_type" v:"required|in:1,2#退款类型不能为空|退款类型错误" dc:"退款类型(1:全额退款,2:部分退款)"`
|
||||
Amount string `json:"amount" v:"required-if:refund_type,2#部分退款时金额不能为空" dc:"退款金额"`
|
||||
Reason string `json:"reason" v:"required|length:1,200#退款原因不能为空|退款原因长度为1-200字符" dc:"退款原因"`
|
||||
}
|
||||
|
||||
// AdminPaymentOrderRefundRes 管理员订单退款响应
|
||||
type AdminPaymentOrderRefundRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// PaymentStatisticsReq 支付统计请求
|
||||
type PaymentStatisticsReq struct {
|
||||
g.Meta `path:"/admin/payment/statistics" method:"get" summary:"支付统计" tags:"支付订单管理"`
|
||||
StartDate string `json:"start_date" v:"date#开始日期格式错误" dc:"开始日期"`
|
||||
EndDate string `json:"end_date" v:"date#结束日期格式错误" dc:"结束日期"`
|
||||
Type string `json:"type" v:"in:day,week,month#统计类型错误" dc:"统计类型(day:按天,week:按周,month:按月)" default:"day"`
|
||||
}
|
||||
|
||||
// PaymentStatisticsRes 支付统计响应
|
||||
type PaymentStatisticsRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
TotalCount int `json:"total_count" dc:"总订单数"`
|
||||
TotalAmount string `json:"total_amount" dc:"总金额"`
|
||||
PaidCount int `json:"paid_count" dc:"已支付订单数"`
|
||||
PaidAmount string `json:"paid_amount" dc:"已支付金额"`
|
||||
RefundCount int `json:"refund_count" dc:"退款订单数"`
|
||||
RefundAmount string `json:"refund_amount" dc:"退款金额"`
|
||||
ChartData []PaymentStatisticsItem `json:"chart_data" dc:"图表数据"`
|
||||
}
|
||||
|
||||
// PaymentStatisticsItem 支付统计项目
|
||||
type PaymentStatisticsItem struct {
|
||||
Date string `json:"date" dc:"日期"`
|
||||
Count int `json:"count" dc:"订单数"`
|
||||
Amount string `json:"amount" dc:"金额"`
|
||||
}
|
||||
19
api/v1/payment_order_routes.go
Normal file
19
api/v1/payment_order_routes.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// PaymentOrderUserRoutes 用户支付订单路由
|
||||
// 注意:这个文件不应该导入controller包,避免循环导入
|
||||
// 路由注册应该在cmd包中进行
|
||||
func PaymentOrderUserRoutes(group *ghttp.RouterGroup) {
|
||||
// 路由注册逻辑移动到cmd包中
|
||||
}
|
||||
|
||||
// PaymentOrderAdminRoutes 管理员支付订单路由
|
||||
// 注意:这个文件不应该导入controller包,避免循环导入
|
||||
// 路由注册应该在cmd包中进行
|
||||
func PaymentOrderAdminRoutes(group *ghttp.RouterGroup) {
|
||||
// 路由注册逻辑移动到cmd包中
|
||||
}
|
||||
64
api/v1/user_collect.go
Normal file
64
api/v1/user_collect.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// UserCollectAddReq 添加收藏请求
|
||||
type UserCollectAddReq struct {
|
||||
g.Meta `path:"/user/collect/add" method:"post" summary:"添加收藏" tags:"用户收藏"`
|
||||
MovieId int `json:"movie_id" v:"required|min:1#影片ID不能为空|影片ID必须大于0" dc:"影片ID"`
|
||||
}
|
||||
|
||||
// UserCollectAddRes 添加收藏响应
|
||||
type UserCollectAddRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// UserCollectRemoveReq 取消收藏请求
|
||||
type UserCollectRemoveReq struct {
|
||||
g.Meta `path:"/user/collect/remove" method:"post" summary:"取消收藏" tags:"用户收藏"`
|
||||
MovieId int `json:"movie_id" v:"required|min:1#影片ID不能为空|影片ID必须大于0" dc:"影片ID"`
|
||||
}
|
||||
|
||||
// UserCollectRemoveRes 取消收藏响应
|
||||
type UserCollectRemoveRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// UserCollectListReq 收藏列表请求
|
||||
type UserCollectListReq struct {
|
||||
g.Meta `path:"/user/collect/list" method:"get" summary:"收藏列表" tags:"用户收藏"`
|
||||
Page int `json:"page" v:"min:1#页码必须大于0" dc:"页码" default:"1"`
|
||||
Size int `json:"size" v:"min:1|max:100#每页数量必须大于0|每页数量不能超过100" dc:"每页数量" default:"10"`
|
||||
}
|
||||
|
||||
// UserCollectListRes 收藏列表响应
|
||||
type UserCollectListRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
List []UserCollectItem `json:"list" dc:"收藏列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Page int `json:"page" dc:"当前页"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
}
|
||||
|
||||
// UserCollectItem 收藏项目
|
||||
type UserCollectItem struct {
|
||||
Id uint `json:"id" dc:"收藏ID"`
|
||||
MovieId int `json:"movie_id" dc:"影片ID"`
|
||||
MovieName string `json:"movie_name" dc:"影片名称"`
|
||||
MovieCover string `json:"movie_cover" dc:"影片封面"`
|
||||
CreatedAt string `json:"created_at" dc:"收藏时间"`
|
||||
}
|
||||
|
||||
// UserCollectCheckReq 检查收藏状态请求
|
||||
type UserCollectCheckReq struct {
|
||||
g.Meta `path:"/user/collect/check" method:"get" summary:"检查收藏状态" tags:"用户收藏"`
|
||||
MovieId int `json:"movie_id" v:"required|min:1#影片ID不能为空|影片ID必须大于0" dc:"影片ID"`
|
||||
}
|
||||
|
||||
// UserCollectCheckRes 检查收藏状态响应
|
||||
type UserCollectCheckRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
IsCollected bool `json:"is_collected" dc:"是否已收藏"`
|
||||
}
|
||||
30
api/v1/user_collect_routes.go
Normal file
30
api/v1/user_collect_routes.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"nl-video-api/api/middleware"
|
||||
"nl-video-api/internal/controller/user"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// UserCollectGroup 用户收藏路由组
|
||||
func UserCollectGroup(group *ghttp.RouterGroup) {
|
||||
group.Group("/user/collect", func(group *ghttp.RouterGroup) {
|
||||
// 应用中间件
|
||||
group.Middleware(middleware.CORS)
|
||||
group.Middleware(middleware.Auth) // 用户认证中间件
|
||||
group.Middleware(middleware.RequestLog)
|
||||
|
||||
// 添加收藏
|
||||
group.POST("/add", user.UserCollect.Add)
|
||||
|
||||
// 取消收藏
|
||||
group.POST("/remove", user.UserCollect.Remove)
|
||||
|
||||
// 收藏列表
|
||||
group.GET("/list", user.UserCollect.List)
|
||||
|
||||
// 检查收藏状态
|
||||
group.GET("/check", user.UserCollect.Check)
|
||||
})
|
||||
}
|
||||
80
api/v1/user_watch_history.go
Normal file
80
api/v1/user_watch_history.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// UserWatchHistoryAddReq 添加观看历史请求
|
||||
type UserWatchHistoryAddReq struct {
|
||||
g.Meta `path:"/user/history/add" method:"post" summary:"添加观看历史" tags:"观看历史"`
|
||||
MovieId int `json:"movie_id" v:"required|min:1#影片ID不能为空|影片ID必须大于0" dc:"影片ID"`
|
||||
EpisodeId int `json:"episode_id" v:"min:0#剧集ID必须大于等于0" dc:"剧集ID"`
|
||||
Progress int `json:"progress" v:"min:0|max:100#观看进度必须在0-100之间" dc:"观看进度(百分比)" default:"0"`
|
||||
}
|
||||
|
||||
// UserWatchHistoryAddRes 添加观看历史响应
|
||||
type UserWatchHistoryAddRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// UserWatchHistoryListReq 观看历史列表请求
|
||||
type UserWatchHistoryListReq struct {
|
||||
g.Meta `path:"/user/history/list" method:"get" summary:"观看历史列表" tags:"观看历史"`
|
||||
Page int `json:"page" v:"min:1#页码必须大于0" dc:"页码" default:"1"`
|
||||
Size int `json:"size" v:"min:1|max:100#每页数量必须大于0|每页数量不能超过100" dc:"每页数量" default:"10"`
|
||||
}
|
||||
|
||||
// UserWatchHistoryListRes 观看历史列表响应
|
||||
type UserWatchHistoryListRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
List []UserWatchHistoryItem `json:"list" dc:"观看历史列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
Page int `json:"page" dc:"当前页"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
}
|
||||
|
||||
// UserWatchHistoryItem 观看历史项目
|
||||
type UserWatchHistoryItem struct {
|
||||
Id uint `json:"id" dc:"历史记录ID"`
|
||||
MovieId int `json:"movie_id" dc:"影片ID"`
|
||||
MovieName string `json:"movie_name" dc:"影片名称"`
|
||||
MovieCover string `json:"movie_cover" dc:"影片封面"`
|
||||
EpisodeId int `json:"episode_id" dc:"剧集ID"`
|
||||
EpisodeName string `json:"episode_name" dc:"剧集名称"`
|
||||
Progress int `json:"progress" dc:"观看进度"`
|
||||
WatchedAt string `json:"watched_at" dc:"观看时间"`
|
||||
}
|
||||
|
||||
// UserWatchHistoryDeleteReq 删除观看历史请求
|
||||
type UserWatchHistoryDeleteReq struct {
|
||||
g.Meta `path:"/user/history/delete" method:"post" summary:"删除观看历史" tags:"观看历史"`
|
||||
Id uint `json:"id" v:"required|min:1#历史记录ID不能为空|历史记录ID必须大于0" dc:"历史记录ID"`
|
||||
}
|
||||
|
||||
// UserWatchHistoryDeleteRes 删除观看历史响应
|
||||
type UserWatchHistoryDeleteRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// UserWatchHistoryClearReq 清空观看历史请求
|
||||
type UserWatchHistoryClearReq struct {
|
||||
g.Meta `path:"/user/history/clear" method:"post" summary:"清空观看历史" tags:"观看历史"`
|
||||
}
|
||||
|
||||
// UserWatchHistoryClearRes 清空观看历史响应
|
||||
type UserWatchHistoryClearRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
}
|
||||
|
||||
// UserWatchHistoryGetReq 获取观看进度请求
|
||||
type UserWatchHistoryGetReq struct {
|
||||
g.Meta `path:"/user/history/get" method:"get" summary:"获取观看进度" tags:"观看历史"`
|
||||
MovieId int `json:"movie_id" v:"required|min:1#影片ID不能为空|影片ID必须大于0" dc:"影片ID"`
|
||||
EpisodeId int `json:"episode_id" v:"min:0#剧集ID必须大于等于0" dc:"剧集ID"`
|
||||
}
|
||||
|
||||
// UserWatchHistoryGetRes 获取观看进度响应
|
||||
type UserWatchHistoryGetRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
Progress int `json:"progress" dc:"观看进度"`
|
||||
}
|
||||
33
api/v1/user_watch_history_routes.go
Normal file
33
api/v1/user_watch_history_routes.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"nl-video-api/api/middleware"
|
||||
"nl-video-api/internal/controller/user"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// UserWatchHistoryGroup 用户观看历史路由组
|
||||
func UserWatchHistoryGroup(group *ghttp.RouterGroup) {
|
||||
group.Group("/user/history", func(group *ghttp.RouterGroup) {
|
||||
// 应用中间件
|
||||
group.Middleware(middleware.CORS)
|
||||
group.Middleware(middleware.Auth) // 用户认证中间件
|
||||
group.Middleware(middleware.RequestLog)
|
||||
|
||||
// 添加观看历史
|
||||
group.POST("/add", user.UserWatchHistory.Add)
|
||||
|
||||
// 观看历史列表
|
||||
group.GET("/list", user.UserWatchHistory.List)
|
||||
|
||||
// 删除观看历史
|
||||
group.POST("/delete", user.UserWatchHistory.Delete)
|
||||
|
||||
// 清空观看历史
|
||||
group.POST("/clear", user.UserWatchHistory.Clear)
|
||||
|
||||
// 获取观看进度
|
||||
group.GET("/get", user.UserWatchHistory.Get)
|
||||
})
|
||||
}
|
||||
227
api/v1/vip_level.go
Normal file
227
api/v1/vip_level.go
Normal file
@@ -0,0 +1,227 @@
|
||||
package v1
|
||||
|
||||
// VIP等级管理相关请求和响应结构
|
||||
|
||||
// VipLevelCreateReq 创建VIP等级请求
|
||||
type VipLevelCreateReq struct {
|
||||
Name string `json:"name" v:"required|length:1,50#VIP等级名称不能为空|VIP等级名称长度为1-50个字符"`
|
||||
Level int `json:"level" v:"required|min:1#VIP等级不能为空|VIP等级必须大于0"`
|
||||
Duration int `json:"duration" v:"required|min:1#有效期不能为空|有效期必须大于0天"`
|
||||
Price string `json:"price" v:"required|regex:^\\d+(\\.\\d{1,2})?$#价格不能为空|价格格式不正确"`
|
||||
Description string `json:"description" v:"max:500#描述长度不能超过500个字符"`
|
||||
Features string `json:"features" v:"max:1000#特权描述长度不能超过1000个字符"`
|
||||
Sort int `json:"sort" v:"min:0#排序值不能小于0"`
|
||||
Status int `json:"status" v:"in:0,1#状态值只能为0或1"`
|
||||
}
|
||||
|
||||
// VipLevelCreateRes 创建VIP等级响应
|
||||
type VipLevelCreateRes struct {
|
||||
Id uint `json:"id"`
|
||||
}
|
||||
|
||||
// VipLevelUpdateReq 更新VIP等级请求
|
||||
type VipLevelUpdateReq struct {
|
||||
Id uint `json:"id" v:"required|min:1#VIP等级ID不能为空"`
|
||||
Name string `json:"name" v:"required|length:1,50#VIP等级名称不能为空|VIP等级名称长度为1-50个字符"`
|
||||
Level int `json:"level" v:"required|min:1#VIP等级不能为空|VIP等级必须大于0"`
|
||||
Duration int `json:"duration" v:"required|min:1#有效期不能为空|有效期必须大于0天"`
|
||||
Price string `json:"price" v:"required|regex:^\\d+(\\.\\d{1,2})?$#价格不能为空|价格格式不正确"`
|
||||
Description string `json:"description" v:"max:500#描述长度不能超过500个字符"`
|
||||
Features string `json:"features" v:"max:1000#特权描述长度不能超过1000个字符"`
|
||||
Sort int `json:"sort" v:"min:0#排序值不能小于0"`
|
||||
Status int `json:"status" v:"in:0,1#状态值只能为0或1"`
|
||||
}
|
||||
|
||||
// VipLevelListReq 获取VIP等级列表请求
|
||||
type VipLevelListReq struct {
|
||||
Page int `json:"page" v:"min:1#页码必须大于0"`
|
||||
Size int `json:"size" v:"min:1|max:100#每页数量必须大于0|每页数量不能超过100"`
|
||||
Status int `json:"status" v:"in:-1,0,1#状态值只能为-1,0,1"`
|
||||
Keyword string `json:"keyword" v:"max:50#关键词长度不能超过50个字符"`
|
||||
MinPrice string `json:"min_price" v:"regex:^\\d*(\\.\\d{1,2})?$#最低价格格式不正确"`
|
||||
MaxPrice string `json:"max_price" v:"regex:^\\d*(\\.\\d{1,2})?$#最高价格格式不正确"`
|
||||
}
|
||||
|
||||
// VipLevelListRes 获取VIP等级列表响应
|
||||
type VipLevelListRes struct {
|
||||
List []VipLevelItem `json:"list"`
|
||||
Total int `json:"total"`
|
||||
Page int `json:"page"`
|
||||
Size int `json:"size"`
|
||||
}
|
||||
|
||||
// VipLevelItem VIP等级列表项
|
||||
type VipLevelItem struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Level int `json:"level"`
|
||||
Duration int `json:"duration"`
|
||||
Price string `json:"price"`
|
||||
Description string `json:"description"`
|
||||
Features string `json:"features"`
|
||||
Sort int `json:"sort"`
|
||||
Status int `json:"status"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// VipLevelDetailReq 获取VIP等级详情请求
|
||||
type VipLevelDetailReq struct {
|
||||
Id uint `json:"id" v:"required|min:1#VIP等级ID不能为空"`
|
||||
}
|
||||
|
||||
// VipLevelDetailRes 获取VIP等级详情响应
|
||||
type VipLevelDetailRes struct {
|
||||
VipLevel VipLevelDetail `json:"vip_level"`
|
||||
}
|
||||
|
||||
// VipLevelDetail VIP等级详情
|
||||
type VipLevelDetail struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Level int `json:"level"`
|
||||
Duration int `json:"duration"`
|
||||
Price string `json:"price"`
|
||||
Description string `json:"description"`
|
||||
Features string `json:"features"`
|
||||
Sort int `json:"sort"`
|
||||
Status int `json:"status"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// VipLevelDeleteReq 删除VIP等级请求
|
||||
type VipLevelDeleteReq struct {
|
||||
Id uint `json:"id" v:"required|min:1#VIP等级ID不能为空"`
|
||||
}
|
||||
|
||||
// VipLevelStatusReq 更新VIP等级状态请求
|
||||
type VipLevelStatusReq struct {
|
||||
Id uint `json:"id" v:"required|min:1#VIP等级ID不能为空"`
|
||||
Status int `json:"status" v:"in:0,1#状态值只能为0或1"`
|
||||
}
|
||||
|
||||
// VipLevelBatchStatusReq 批量更新VIP等级状态请求
|
||||
type VipLevelBatchStatusReq struct {
|
||||
Ids []uint `json:"ids" v:"required|min:1#VIP等级ID列表不能为空"`
|
||||
Status int `json:"status" v:"in:0,1#状态值只能为0或1"`
|
||||
}
|
||||
|
||||
// VipLevelSortReq 更新VIP等级排序请求
|
||||
type VipLevelSortReq struct {
|
||||
Id uint `json:"id" v:"required|min:1#VIP等级ID不能为空"`
|
||||
Sort int `json:"sort" v:"min:0#排序值不能小于0"`
|
||||
}
|
||||
|
||||
// VipLevelBatchSortReq 批量更新VIP等级排序请求
|
||||
type VipLevelBatchSortReq struct {
|
||||
Items []VipLevelSortItem `json:"items" v:"required|min:1#排序项目不能为空"`
|
||||
}
|
||||
|
||||
// VipLevelSortItem 排序项目
|
||||
type VipLevelSortItem struct {
|
||||
Id uint `json:"id" v:"required|min:1#VIP等级ID不能为空"`
|
||||
Sort int `json:"sort" v:"min:0#排序值不能小于0"`
|
||||
}
|
||||
|
||||
// VipLevelActiveListReq 获取有效VIP等级列表请求(用户端)
|
||||
type VipLevelActiveListReq struct {
|
||||
// 无需参数,直接获取所有有效的VIP等级
|
||||
}
|
||||
|
||||
// VipLevelActiveListRes 获取有效VIP等级列表响应(用户端)
|
||||
type VipLevelActiveListRes struct {
|
||||
List []VipLevelActiveItem `json:"list"`
|
||||
}
|
||||
|
||||
// VipLevelActiveItem 有效VIP等级项(用户端)
|
||||
type VipLevelActiveItem struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Level int `json:"level"`
|
||||
Duration int `json:"duration"`
|
||||
Price string `json:"price"`
|
||||
Description string `json:"description"`
|
||||
Features string `json:"features"`
|
||||
IsRecommend bool `json:"is_recommend"` // 是否推荐
|
||||
}
|
||||
|
||||
// VipLevelStatisticsReq 获取VIP等级统计请求
|
||||
type VipLevelStatisticsReq struct {
|
||||
StartDate string `json:"start_date" v:"date#开始日期格式不正确"`
|
||||
EndDate string `json:"end_date" v:"date#结束日期格式不正确"`
|
||||
}
|
||||
|
||||
// VipLevelStatisticsRes 获取VIP等级统计响应
|
||||
type VipLevelStatisticsRes struct {
|
||||
TotalLevels int `json:"total_levels"` // 总等级数
|
||||
ActiveLevels int `json:"active_levels"` // 有效等级数
|
||||
TotalSales string `json:"total_sales"` // 总销售额
|
||||
TotalOrders int `json:"total_orders"` // 总订单数
|
||||
LevelStats []VipLevelStatItem `json:"level_stats"` // 各等级统计
|
||||
SalesChart []VipLevelSalesChartItem `json:"sales_chart"` // 销售图表数据
|
||||
PopularLevels []VipLevelPopularItem `json:"popular_levels"` // 热门等级
|
||||
}
|
||||
|
||||
// VipLevelStatItem VIP等级统计项
|
||||
type VipLevelStatItem struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Level int `json:"level"`
|
||||
OrderCount int `json:"order_count"` // 订单数量
|
||||
SalesAmount string `json:"sales_amount"` // 销售金额
|
||||
UserCount int `json:"user_count"` // 用户数量
|
||||
}
|
||||
|
||||
// VipLevelSalesChartItem VIP等级销售图表项
|
||||
type VipLevelSalesChartItem struct {
|
||||
Date string `json:"date"` // 日期
|
||||
Amount string `json:"amount"` // 销售金额
|
||||
Count int `json:"count"` // 订单数量
|
||||
}
|
||||
|
||||
// VipLevelPopularItem 热门VIP等级项
|
||||
type VipLevelPopularItem struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Level int `json:"level"`
|
||||
Price string `json:"price"`
|
||||
OrderCount int `json:"order_count"`
|
||||
Percentage string `json:"percentage"` // 占比
|
||||
}
|
||||
|
||||
// VipLevelCopyReq 复制VIP等级请求
|
||||
type VipLevelCopyReq struct {
|
||||
SourceId uint `json:"source_id" v:"required|min:1#源VIP等级ID不能为空"`
|
||||
Name string `json:"name" v:"required|length:1,50#VIP等级名称不能为空|VIP等级名称长度为1-50个字符"`
|
||||
Level int `json:"level" v:"required|min:1#VIP等级不能为空|VIP等级必须大于0"`
|
||||
}
|
||||
|
||||
// VipLevelCopyRes 复制VIP等级响应
|
||||
type VipLevelCopyRes struct {
|
||||
Id uint `json:"id"`
|
||||
}
|
||||
|
||||
// VipLevelExportReq 导出VIP等级请求
|
||||
type VipLevelExportReq struct {
|
||||
Status int `json:"status" v:"in:-1,0,1#状态值只能为-1,0,1"`
|
||||
StartDate string `json:"start_date" v:"date#开始日期格式不正确"`
|
||||
EndDate string `json:"end_date" v:"date#结束日期格式不正确"`
|
||||
}
|
||||
|
||||
// VipLevelExportRes 导出VIP等级响应
|
||||
type VipLevelExportRes struct {
|
||||
FileUrl string `json:"file_url"` // 导出文件URL
|
||||
}
|
||||
|
||||
// VipLevelImportReq 导入VIP等级请求
|
||||
type VipLevelImportReq struct {
|
||||
FileUrl string `json:"file_url" v:"required|url#文件URL不能为空|文件URL格式不正确"`
|
||||
}
|
||||
|
||||
// VipLevelImportRes 导入VIP等级响应
|
||||
type VipLevelImportRes struct {
|
||||
SuccessCount int `json:"success_count"` // 成功导入数量
|
||||
FailCount int `json:"fail_count"` // 失败数量
|
||||
FailReasons []string `json:"fail_reasons"` // 失败原因
|
||||
}
|
||||
19
api/v1/vip_level_routes.go
Normal file
19
api/v1/vip_level_routes.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// VipLevelUserRoutes 用户VIP等级路由
|
||||
// 注意:这个文件不应该导入controller包,避免循环导入
|
||||
// 路由注册应该在cmd包中进行
|
||||
func VipLevelUserRoutes(group *ghttp.RouterGroup) {
|
||||
// 路由注册逻辑移动到cmd包中
|
||||
}
|
||||
|
||||
// VipLevelAdminRoutes 管理员VIP等级路由
|
||||
// 注意:这个文件不应该导入controller包,避免循环导入
|
||||
// 路由注册应该在cmd包中进行
|
||||
func VipLevelAdminRoutes(group *ghttp.RouterGroup) {
|
||||
// 路由注册逻辑移动到cmd包中
|
||||
}
|
||||
Reference in New Issue
Block a user