647 lines
22 KiB
Go
647 lines
22 KiB
Go
package handlers
|
|
|
|
import (
|
|
"archive/zip"
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"license-manager/internal/api/middleware"
|
|
"license-manager/internal/config"
|
|
"license-manager/internal/models"
|
|
"license-manager/internal/service"
|
|
"license-manager/pkg/i18n"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type AuthorizationCodeHandler struct {
|
|
authCodeService service.AuthorizationCodeService
|
|
}
|
|
|
|
// NewAuthorizationCodeHandler 创建授权码处理器
|
|
func NewAuthorizationCodeHandler(authCodeService service.AuthorizationCodeService) *AuthorizationCodeHandler {
|
|
return &AuthorizationCodeHandler{
|
|
authCodeService: authCodeService,
|
|
}
|
|
}
|
|
|
|
// CreateAuthorizationCode 创建授权码
|
|
// @Summary 创建授权码
|
|
// @Description 创建新的授权码,自动生成授权码字符串。有效期从当天00:00:00开始,到指定天数后的23:59:59结束
|
|
// @Tags 授权码管理
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Param authorization_code body models.AuthorizationCodeCreateRequest true "授权码信息"
|
|
// @Success 200 {object} models.APIResponse{data=models.AuthorizationCodeCreateResponse} "创建成功"
|
|
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
|
|
// @Failure 401 {object} models.ErrorResponse "未认证"
|
|
// @Failure 404 {object} models.ErrorResponse "客户不存在"
|
|
// @Failure 409 {object} models.ErrorResponse "授权码已存在"
|
|
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
|
|
// @Router /api/v1/authorization-codes [post]
|
|
func (h *AuthorizationCodeHandler) CreateAuthorizationCode(c *gin.Context) {
|
|
var req models.AuthorizationCodeCreateRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message + ": " + err.Error(),
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
// 直接传递 gin.Context
|
|
data, err := h.authCodeService.CreateAuthorizationCode(c, &req)
|
|
if err != nil {
|
|
// 错误已经在Service层完全包装好了,直接使用
|
|
var i18nErr *i18n.I18nError
|
|
if errors.As(err, &i18nErr) {
|
|
c.JSON(i18nErr.HttpCode, models.ErrorResponse{
|
|
Code: i18nErr.Code,
|
|
Message: i18nErr.Message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
} else {
|
|
// 兜底:理论上不应该到这里,因为Service层应该返回I18nError
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
lang := middleware.GetLanguage(c)
|
|
successMessage := i18n.GetErrorMessage("000000", lang)
|
|
c.JSON(http.StatusOK, models.APIResponse{
|
|
Code: "000000",
|
|
Message: successMessage,
|
|
Data: data,
|
|
})
|
|
}
|
|
|
|
// GetAuthorizationCodeList 查询授权码列表
|
|
// @Summary 查询授权码列表
|
|
// @Description 分页查询授权码列表,支持筛选和排序
|
|
// @Tags 授权码管理
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Param page query int false "页码,默认1" minimum(1)
|
|
// @Param page_size query int false "每页条数,默认20,最大100" minimum(1) maximum(100)
|
|
// @Param customer_id query string false "客户ID筛选"
|
|
// @Param status query string false "状态筛选" Enums(normal, locked, expired)
|
|
// @Param start_date query string false "创建开始时间"
|
|
// @Param end_date query string false "创建结束时间"
|
|
// @Param sort query string false "排序字段,默认created_at" Enums(created_at, updated_at, code)
|
|
// @Param order query string false "排序方向,默认desc" Enums(asc, desc)
|
|
// @Success 200 {object} models.APIResponse{data=models.AuthorizationCodeListResponse} "查询成功"
|
|
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
|
|
// @Failure 401 {object} models.ErrorResponse "未认证"
|
|
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
|
|
// @Router /api/v1/authorization-codes [get]
|
|
func (h *AuthorizationCodeHandler) GetAuthorizationCodeList(c *gin.Context) {
|
|
var req models.AuthorizationCodeListRequest
|
|
if err := c.ShouldBindQuery(&req); err != nil {
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message + ": " + err.Error(),
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
// 直接传递 gin.Context
|
|
data, err := h.authCodeService.GetAuthorizationCodeList(c, &req)
|
|
if err != nil {
|
|
// 错误已经在Service层完全包装好了,直接使用
|
|
var i18nErr *i18n.I18nError
|
|
if errors.As(err, &i18nErr) {
|
|
c.JSON(i18nErr.HttpCode, models.ErrorResponse{
|
|
Code: i18nErr.Code,
|
|
Message: i18nErr.Message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
} else {
|
|
// 兜底:理论上不应该到这里,因为Service层应该返回I18nError
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
lang := middleware.GetLanguage(c)
|
|
successMessage := i18n.GetErrorMessage("000000", lang)
|
|
c.JSON(http.StatusOK, models.APIResponse{
|
|
Code: "000000",
|
|
Message: successMessage,
|
|
Data: data,
|
|
})
|
|
}
|
|
|
|
// GetAuthorizationCode 获取授权码详情
|
|
// @Summary 获取授权码详情
|
|
// @Description 根据授权码ID获取授权码详细信息
|
|
// @Tags 授权码管理
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Param id path string true "授权码ID"
|
|
// @Success 200 {object} models.APIResponse{data=models.AuthorizationCode} "查询成功"
|
|
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
|
|
// @Failure 401 {object} models.ErrorResponse "未认证"
|
|
// @Failure 404 {object} models.ErrorResponse "授权码不存在"
|
|
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
|
|
// @Router /api/v1/authorization-codes/{id} [get]
|
|
func (h *AuthorizationCodeHandler) GetAuthorizationCode(c *gin.Context) {
|
|
id := c.Param("id")
|
|
if id == "" {
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
// 直接传递 gin.Context
|
|
data, err := h.authCodeService.GetAuthorizationCode(c, id)
|
|
if err != nil {
|
|
// 错误已经在Service层完全包装好了,直接使用
|
|
var i18nErr *i18n.I18nError
|
|
if errors.As(err, &i18nErr) {
|
|
c.JSON(i18nErr.HttpCode, models.ErrorResponse{
|
|
Code: i18nErr.Code,
|
|
Message: i18nErr.Message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
} else {
|
|
// 兜底:理论上不应该到这里,因为Service层应该返回I18nError
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
lang := middleware.GetLanguage(c)
|
|
successMessage := i18n.GetErrorMessage("000000", lang)
|
|
c.JSON(http.StatusOK, models.APIResponse{
|
|
Code: "000000",
|
|
Message: successMessage,
|
|
Data: data,
|
|
})
|
|
}
|
|
|
|
// DownloadAuthorizationFile 下载授权文件
|
|
// @Summary 下载授权文件
|
|
// @Description 下载授权码文件,包含授权码和RSA公钥,供客户端使用
|
|
// @Tags 授权码管理
|
|
// @Accept json
|
|
// @Produce application/zip
|
|
// @Security BearerAuth
|
|
// @Param id path string true "授权码ID"
|
|
// @Success 200 {file} binary "包含授权码文件和RSA公钥的压缩包"
|
|
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
|
|
// @Failure 401 {object} models.ErrorResponse "未认证"
|
|
// @Failure 404 {object} models.ErrorResponse "授权码不存在"
|
|
// @Failure 409 {object} models.ErrorResponse "授权码不可用"
|
|
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
|
|
// @Router /api/v1/authorization-codes/{id}/download [get]
|
|
func (h *AuthorizationCodeHandler) DownloadAuthorizationFile(c *gin.Context) {
|
|
lang := middleware.GetLanguage(c)
|
|
id := c.Param("id")
|
|
if id == "" {
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
ctx := middleware.WithLanguage(c.Request.Context(), c)
|
|
|
|
fileData, fileName, authCode, err := h.authCodeService.GenerateAuthorizationFile(ctx, id)
|
|
if err != nil {
|
|
var i18nErr *i18n.I18nError
|
|
if errors.As(err, &i18nErr) {
|
|
c.JSON(i18nErr.HttpCode, models.ErrorResponse{
|
|
Code: i18nErr.Code,
|
|
Message: i18nErr.Message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
} else {
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
cfg := config.GetConfig()
|
|
if cfg == nil || cfg.License.RSA.PublicKeyPath == "" {
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
publicKeyPath := filepath.Clean(cfg.License.RSA.PublicKeyPath)
|
|
publicKeyData, err := os.ReadFile(publicKeyPath)
|
|
if err != nil {
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
var buffer bytes.Buffer
|
|
zipWriter := zip.NewWriter(&buffer)
|
|
|
|
const zipAuthFileName = "authorization_code.txt"
|
|
authFileWriter, err := zipWriter.Create(zipAuthFileName)
|
|
if err != nil {
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
if _, err := authFileWriter.Write(fileData); err != nil {
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
publicKeyWriter, err := zipWriter.Create("rsa_public_key.pem")
|
|
if err != nil {
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
if _, err := publicKeyWriter.Write(publicKeyData); err != nil {
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
if err := zipWriter.Close(); err != nil {
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
packageFileName := fmt.Sprintf("authorization_package_%s.zip", strings.TrimSpace(authCode))
|
|
if strings.TrimSpace(authCode) == "" {
|
|
baseName := strings.TrimSuffix(fileName, filepath.Ext(fileName))
|
|
packageFileName = fmt.Sprintf("%s_package.zip", baseName)
|
|
}
|
|
|
|
c.Header("Content-Description", "File Transfer")
|
|
c.Header("Content-Type", "application/zip")
|
|
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", packageFileName))
|
|
c.Header("Content-Transfer-Encoding", "binary")
|
|
c.Header("Cache-Control", "must-revalidate")
|
|
c.Header("Pragma", "public")
|
|
c.Data(http.StatusOK, "application/zip", buffer.Bytes())
|
|
}
|
|
|
|
// UpdateAuthorizationCode 更新授权码
|
|
// @Summary 更新授权码
|
|
// @Description 更新授权码信息,所有字段都是可选的,需要指定变更类型和原因
|
|
// @Tags 授权码管理
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Param id path string true "授权码ID"
|
|
// @Param authorization_code body models.AuthorizationCodeUpdateRequest true "授权码信息"
|
|
// @Success 200 {object} models.APIResponse{data=models.AuthorizationCode} "更新成功"
|
|
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
|
|
// @Failure 401 {object} models.ErrorResponse "未认证"
|
|
// @Failure 404 {object} models.ErrorResponse "授权码不存在"
|
|
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
|
|
// @Router /api/v1/authorization-codes/{id} [put]
|
|
func (h *AuthorizationCodeHandler) UpdateAuthorizationCode(c *gin.Context) {
|
|
id := c.Param("id")
|
|
if id == "" {
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
var req models.AuthorizationCodeUpdateRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message + ": " + err.Error(),
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
// 直接传递 gin.Context
|
|
authCode, err := h.authCodeService.UpdateAuthorizationCode(c, id, &req)
|
|
if err != nil {
|
|
// 错误已经在Service层完全包装好了,直接使用
|
|
var i18nErr *i18n.I18nError
|
|
if errors.As(err, &i18nErr) {
|
|
c.JSON(i18nErr.HttpCode, models.ErrorResponse{
|
|
Code: i18nErr.Code,
|
|
Message: i18nErr.Message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
} else {
|
|
// 兜底:理论上不应该到这里,因为Service层应该返回I18nError
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
lang := middleware.GetLanguage(c)
|
|
successMessage := i18n.GetErrorMessage("000000", lang)
|
|
c.JSON(http.StatusOK, models.APIResponse{
|
|
Code: "000000",
|
|
Message: successMessage,
|
|
Data: authCode,
|
|
})
|
|
}
|
|
|
|
// LockUnlockAuthorizationCode 锁定/解锁授权码
|
|
// @Summary 锁定/解锁授权码
|
|
// @Description 锁定或解锁指定的授权码,可以设置锁定原因
|
|
// @Tags 授权码管理
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Param id path string true "授权码ID"
|
|
// @Param lock_request body models.AuthorizationCodeLockRequest true "锁定/解锁信息"
|
|
// @Success 200 {object} models.APIResponse{data=models.AuthorizationCode} "操作成功"
|
|
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
|
|
// @Failure 401 {object} models.ErrorResponse "未认证"
|
|
// @Failure 404 {object} models.ErrorResponse "授权码不存在"
|
|
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
|
|
// @Router /api/v1/authorization-codes/{id}/lock [put]
|
|
func (h *AuthorizationCodeHandler) LockUnlockAuthorizationCode(c *gin.Context) {
|
|
id := c.Param("id")
|
|
if id == "" {
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
var req models.AuthorizationCodeLockRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message + ": " + err.Error(),
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
// 直接传递 gin.Context
|
|
data, err := h.authCodeService.LockUnlockAuthorizationCode(c, id, &req)
|
|
if err != nil {
|
|
// 错误已经在Service层完全包装好了,直接使用
|
|
var i18nErr *i18n.I18nError
|
|
if errors.As(err, &i18nErr) {
|
|
c.JSON(i18nErr.HttpCode, models.ErrorResponse{
|
|
Code: i18nErr.Code,
|
|
Message: i18nErr.Message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
} else {
|
|
// 兜底:理论上不应该到这里,因为Service层应该返回I18nError
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
lang := middleware.GetLanguage(c)
|
|
successMessage := i18n.GetErrorMessage("000000", lang)
|
|
c.JSON(http.StatusOK, models.APIResponse{
|
|
Code: "000000",
|
|
Message: successMessage,
|
|
Data: data,
|
|
})
|
|
}
|
|
|
|
// DeleteAuthorizationCode 删除授权码
|
|
// @Summary 删除授权码
|
|
// @Description 删除指定的授权码(软删除)
|
|
// @Tags 授权码管理
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Param id path string true "授权码ID"
|
|
// @Success 200 {object} models.APIResponse "删除成功"
|
|
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
|
|
// @Failure 401 {object} models.ErrorResponse "未认证"
|
|
// @Failure 404 {object} models.ErrorResponse "授权码不存在"
|
|
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
|
|
// @Router /api/v1/authorization-codes/{id} [delete]
|
|
func (h *AuthorizationCodeHandler) DeleteAuthorizationCode(c *gin.Context) {
|
|
id := c.Param("id")
|
|
if id == "" {
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
// 直接传递 gin.Context
|
|
if err := h.authCodeService.DeleteAuthorizationCode(c, id); err != nil {
|
|
// 错误已经在Service层完全包装好了,直接使用
|
|
var i18nErr *i18n.I18nError
|
|
if errors.As(err, &i18nErr) {
|
|
c.JSON(i18nErr.HttpCode, models.ErrorResponse{
|
|
Code: i18nErr.Code,
|
|
Message: i18nErr.Message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
} else {
|
|
// 兜底:理论上不应该到这里,因为Service层应该返回I18nError
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
lang := middleware.GetLanguage(c)
|
|
successMessage := i18n.GetErrorMessage("000000", lang)
|
|
c.JSON(http.StatusOK, models.APIResponse{
|
|
Code: "000000",
|
|
Message: successMessage,
|
|
Data: nil,
|
|
})
|
|
}
|
|
|
|
// GetAuthorizationChangeList 查询授权变更历史列表
|
|
// @Summary 查询授权变更历史列表
|
|
// @Description 分页查询指定授权码的变更历史,支持筛选
|
|
// @Tags 授权码管理
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Param id path string true "授权码ID"
|
|
// @Param page query int false "页码,默认1" minimum(1)
|
|
// @Param page_size query int false "每页条数,默认20,最大100" minimum(1) maximum(100)
|
|
// @Param change_type query string false "变更类型筛选"
|
|
// @Param operator_id query string false "操作人筛选"
|
|
// @Param start_date query string false "开始时间 (YYYY-MM-DD格式)"
|
|
// @Param end_date query string false "结束时间 (YYYY-MM-DD格式)"
|
|
// @Param sort query string false "排序字段,默认created_at" Enums(created_at, change_type)
|
|
// @Param order query string false "排序方向,默认desc" Enums(asc, desc)
|
|
// @Success 200 {object} models.APIResponse{data=models.AuthorizationChangeListResponse} "查询成功"
|
|
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
|
|
// @Failure 401 {object} models.ErrorResponse "未认证"
|
|
// @Failure 404 {object} models.ErrorResponse "授权码不存在"
|
|
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
|
|
// @Router /api/v1/authorization-codes/{id}/changes [get]
|
|
func (h *AuthorizationCodeHandler) GetAuthorizationChangeList(c *gin.Context) {
|
|
id := c.Param("id")
|
|
if id == "" {
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
var req models.AuthorizationChangeListRequest
|
|
if err := c.ShouldBindQuery(&req); err != nil {
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900001", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message + ": " + err.Error(),
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
return
|
|
}
|
|
|
|
// 直接传递 gin.Context
|
|
data, err := h.authCodeService.GetAuthorizationChangeList(c, id, &req)
|
|
if err != nil {
|
|
// 错误已经在Service层完全包装好了,直接使用
|
|
var i18nErr *i18n.I18nError
|
|
if errors.As(err, &i18nErr) {
|
|
c.JSON(i18nErr.HttpCode, models.ErrorResponse{
|
|
Code: i18nErr.Code,
|
|
Message: i18nErr.Message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
} else {
|
|
// 兜底:理论上不应该到这里,因为Service层应该返回I18nError
|
|
lang := middleware.GetLanguage(c)
|
|
status, errCode, message := i18n.NewI18nErrorResponse("900004", lang)
|
|
c.JSON(status, models.ErrorResponse{
|
|
Code: errCode,
|
|
Message: message,
|
|
Timestamp: time.Now().Format(time.RFC3339),
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
lang := middleware.GetLanguage(c)
|
|
successMessage := i18n.GetErrorMessage("000000", lang)
|
|
c.JSON(http.StatusOK, models.APIResponse{
|
|
Code: "000000",
|
|
Message: successMessage,
|
|
Data: data,
|
|
})
|
|
}
|