This commit is contained in:
2026-06-18 21:16:02 +08:00
parent 9685d34187
commit 3a5a0d0028
36 changed files with 1566 additions and 66 deletions

View File

@@ -0,0 +1,149 @@
package handlers
import (
"strconv"
"strings"
api_app "tyapi-server/internal/application/api"
"tyapi-server/internal/application/api/dto"
"tyapi-server/internal/shared/interfaces"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AdminQueryWhitelistHandler struct {
appService api_app.QueryWhitelistApplicationService
responseBuilder interfaces.ResponseBuilder
validator interfaces.RequestValidator
logger *zap.Logger
}
func NewAdminQueryWhitelistHandler(
appService api_app.QueryWhitelistApplicationService,
responseBuilder interfaces.ResponseBuilder,
validator interfaces.RequestValidator,
logger *zap.Logger,
) *AdminQueryWhitelistHandler {
return &AdminQueryWhitelistHandler{
appService: appService,
responseBuilder: responseBuilder,
validator: validator,
logger: logger,
}
}
func (h *AdminQueryWhitelistHandler) ListEntries(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
filters := map[string]interface{}{}
if userID := strings.TrimSpace(c.Query("user_id")); userID != "" {
filters["user_id"] = userID
}
if status := strings.TrimSpace(c.Query("status")); status != "" {
filters["status"] = status
}
if apiCode := strings.TrimSpace(c.Query("api_code")); apiCode != "" {
filters["api_code"] = apiCode
}
if idCard := strings.TrimSpace(c.Query("id_card")); idCard != "" {
filters["id_card"] = idCard
}
if keyword := strings.TrimSpace(c.Query("keyword")); keyword != "" {
filters["keyword"] = keyword
}
result, err := h.appService.ListEntries(c.Request.Context(), filters, interfaces.ListOptions{
Page: page,
PageSize: pageSize,
})
if err != nil {
h.logger.Error("获取查询白名单列表失败", zap.Error(err))
h.responseBuilder.InternalError(c, "获取查询白名单列表失败")
return
}
h.responseBuilder.Success(c, result, "获取查询白名单列表成功")
}
func (h *AdminQueryWhitelistHandler) GetEntry(c *gin.Context) {
id := c.Param("id")
result, err := h.appService.GetEntry(c.Request.Context(), id)
if err != nil {
h.logger.Error("获取查询白名单详情失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, result, "获取查询白名单详情成功")
}
func (h *AdminQueryWhitelistHandler) CreateEntry(c *gin.Context) {
var req dto.QueryWhitelistEntryRequest
if err := h.validator.BindAndValidate(c, &req); err != nil {
h.responseBuilder.BadRequest(c, "参数校验失败")
return
}
adminUserID := c.GetString("user_id")
result, err := h.appService.CreateEntry(c.Request.Context(), adminUserID, &req)
if err != nil {
h.logger.Error("创建查询白名单失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, result, "创建查询白名单成功")
}
func (h *AdminQueryWhitelistHandler) UpdateEntry(c *gin.Context) {
id := c.Param("id")
var req dto.QueryWhitelistEntryUpdateRequest
if err := h.validator.BindAndValidate(c, &req); err != nil {
h.responseBuilder.BadRequest(c, "参数校验失败")
return
}
adminUserID := c.GetString("user_id")
result, err := h.appService.UpdateEntry(c.Request.Context(), adminUserID, id, &req)
if err != nil {
h.logger.Error("更新查询白名单失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, result, "更新查询白名单成功")
}
func (h *AdminQueryWhitelistHandler) UpdateEntryStatus(c *gin.Context) {
id := c.Param("id")
var req dto.QueryWhitelistStatusRequest
if err := h.validator.BindAndValidate(c, &req); err != nil {
h.responseBuilder.BadRequest(c, "参数校验失败")
return
}
adminUserID := c.GetString("user_id")
result, err := h.appService.UpdateEntryStatus(c.Request.Context(), adminUserID, id, req.Status)
if err != nil {
h.logger.Error("更新查询白名单状态失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, result, "更新查询白名单状态成功")
}
func (h *AdminQueryWhitelistHandler) DeleteEntry(c *gin.Context) {
id := c.Param("id")
if err := h.appService.DeleteEntry(c.Request.Context(), id); err != nil {
h.logger.Error("删除查询白名单失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, nil, "删除查询白名单成功")
}
func (h *AdminQueryWhitelistHandler) ImportLegacyEntries(c *gin.Context) {
adminUserID := c.GetString("user_id")
result, err := h.appService.ImportLegacyEntries(c.Request.Context(), adminUserID)
if err != nil {
h.logger.Error("导入历史硬编码白名单失败", zap.Error(err))
h.responseBuilder.BadRequest(c, err.Error())
return
}
h.responseBuilder.Success(c, result, "导入历史硬编码白名单成功")
}

View File

@@ -76,7 +76,7 @@ type decodedSendCodeData struct {
// @Router /api/v1/users/send-code [post]
func (h *UserHandler) SendCode(c *gin.Context) {
var cmd commands.SendCodeCommand
// 绑定请求包含data字段和可选的captchaVerifyParam字段
if err := c.ShouldBindJSON(&cmd); err != nil {
h.response.BadRequest(c, "请求参数格式错误必须提供data字段")
@@ -113,7 +113,7 @@ func (h *UserHandler) SendCode(c *gin.Context) {
zap.String("scene", decodedData.Scene),
zap.String("client_ip", c.ClientIP()),
zap.Error(err))
// 根据错误类型返回不同的用户友好消息(不暴露技术细节)
userMessage := h.getSignatureErrorMessage(err)
h.response.BadRequest(c, userMessage)
@@ -123,11 +123,11 @@ func (h *UserHandler) SendCode(c *gin.Context) {
// 构建SendCodeCommand用于调用应用服务
serviceCmd := &commands.SendCodeCommand{
Phone: decodedData.Phone,
Scene: decodedData.Scene,
Timestamp: decodedData.Timestamp,
Nonce: decodedData.Nonce,
Signature: decodedData.Signature,
Phone: decodedData.Phone,
Scene: decodedData.Scene,
Timestamp: decodedData.Timestamp,
Nonce: decodedData.Nonce,
Signature: decodedData.Signature,
CaptchaVerifyParam: cmd.CaptchaVerifyParam,
}
@@ -183,7 +183,7 @@ func (h *UserHandler) verifyDecodedSignature(ctx context.Context, data *decodedS
// getSignatureErrorMessage 根据错误类型返回用户友好的错误消息(不暴露技术细节)
func (h *UserHandler) getSignatureErrorMessage(err error) string {
errMsg := err.Error()
// 根据错误消息内容判断错误类型,返回通用的用户友好消息
if strings.Contains(errMsg, "请求已被使用") || strings.Contains(errMsg, "重复提交") {
// 重放攻击:返回通用消息,不暴露具体原因
@@ -197,12 +197,11 @@ func (h *UserHandler) getSignatureErrorMessage(err error) string {
// 签名错误:返回通用消息
return "请求验证失败,请重新操作"
}
// 其他错误:返回通用消息
return "请求验证失败,请重新操作"
}
// Register 用户注册
// @Summary 用户注册
// @Description 使用手机号、密码和验证码进行用户注册,需要确认密码

View File

@@ -0,0 +1,37 @@
package routes
import (
"tyapi-server/internal/infrastructure/http/handlers"
sharedhttp "tyapi-server/internal/shared/http"
"tyapi-server/internal/shared/middleware"
)
type AdminQueryWhitelistRoutes struct {
handler *handlers.AdminQueryWhitelistHandler
admin *middleware.AdminAuthMiddleware
}
func NewAdminQueryWhitelistRoutes(
handler *handlers.AdminQueryWhitelistHandler,
admin *middleware.AdminAuthMiddleware,
) *AdminQueryWhitelistRoutes {
return &AdminQueryWhitelistRoutes{
handler: handler,
admin: admin,
}
}
func (r *AdminQueryWhitelistRoutes) Register(router *sharedhttp.GinRouter) {
engine := router.GetEngine()
group := engine.Group("/api/v1/admin/query-whitelist")
group.Use(r.admin.Handle())
{
group.GET("/entries", r.handler.ListEntries)
group.GET("/entries/:id", r.handler.GetEntry)
group.POST("/entries", r.handler.CreateEntry)
group.PUT("/entries/:id", r.handler.UpdateEntry)
group.PATCH("/entries/:id/status", r.handler.UpdateEntryStatus)
group.DELETE("/entries/:id", r.handler.DeleteEntry)
group.POST("/entries/import-legacy", r.handler.ImportLegacyEntries)
}
}