Files
tyapi-server/internal/infrastructure/http/handlers/certification_handler.go
2025-07-21 15:13:26 +08:00

480 lines
16 KiB
Go

package handlers
import (
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"tyapi-server/internal/application/certification"
"tyapi-server/internal/application/certification/dto/commands"
"tyapi-server/internal/application/certification/dto/queries"
"tyapi-server/internal/shared/interfaces"
"tyapi-server/internal/shared/middleware"
)
// CertificationHandler 认证HTTP处理器
type CertificationHandler struct {
appService certification.CertificationApplicationService
response interfaces.ResponseBuilder
validator interfaces.RequestValidator
logger *zap.Logger
jwtAuth *middleware.JWTAuthMiddleware
}
// NewCertificationHandler 创建认证处理器
func NewCertificationHandler(
appService certification.CertificationApplicationService,
response interfaces.ResponseBuilder,
validator interfaces.RequestValidator,
logger *zap.Logger,
jwtAuth *middleware.JWTAuthMiddleware,
) *CertificationHandler {
return &CertificationHandler{
appService: appService,
response: response,
validator: validator,
logger: logger,
jwtAuth: jwtAuth,
}
}
// ================ 认证申请管理 ================
// CreateCertification 创建认证申请
// @Summary 创建认证申请
// @Description 为用户创建企业认证申请
// @Tags 认证管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body commands.CreateCertificationCommand true "创建认证申请请求"
// @Success 201 {object} responses.CertificationResponse "认证申请创建成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/certifications [post]
func (h *CertificationHandler) CreateCertification(c *gin.Context) {
var cmd commands.CreateCertificationCommand
cmd.UserID = h.getCurrentUserID(c)
if cmd.UserID == "" {
h.response.Unauthorized(c, "用户未登录")
return
}
result, err := h.appService.CreateCertification(c.Request.Context(), &cmd)
if err != nil {
h.logger.Error("创建认证申请失败", zap.Error(err), zap.String("user_id", cmd.UserID))
h.response.BadRequest(c, err.Error())
return
}
h.response.Created(c, result, "认证申请创建成功")
}
// GetCertification 获取认证详情
// @Summary 获取认证详情
// @Description 根据认证ID获取认证详情
// @Tags 认证管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "认证ID"
// @Success 200 {object} responses.CertificationResponse "获取认证详情成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "认证记录不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/certifications/{id} [get]
func (h *CertificationHandler) GetCertification(c *gin.Context) {
userID := h.getCurrentUserID(c)
if userID == "" {
h.response.Unauthorized(c, "用户未登录")
return
}
certificationID := c.Param("id")
if certificationID == "" {
h.response.BadRequest(c, "认证ID不能为空")
return
}
query := &queries.GetCertificationQuery{
CertificationID: certificationID,
UserID: userID,
}
result, err := h.appService.GetCertification(c.Request.Context(), query)
if err != nil {
h.logger.Error("获取认证详情失败", zap.Error(err), zap.String("certification_id", certificationID))
h.response.NotFound(c, "认证记录不存在")
return
}
h.response.Success(c, result, "获取认证详情成功")
}
// ================ 企业信息管理 ================
// SubmitEnterpriseInfo 提交企业信息
// @Summary 提交企业信息
// @Description 提交企业认证所需的企业信息
// @Tags 认证管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path string true "认证ID"
// @Param request body commands.SubmitEnterpriseInfoCommand true "提交企业信息请求"
// @Success 200 {object} responses.CertificationResponse "企业信息提交成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "认证记录不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/certifications/{id}/enterprise-info [post]
func (h *CertificationHandler) SubmitEnterpriseInfo(c *gin.Context) {
userID := h.getCurrentUserID(c)
if userID == "" {
h.response.Unauthorized(c, "用户未登录")
return
}
certificationID := c.Param("id")
if certificationID == "" {
h.response.BadRequest(c, "认证ID不能为空")
return
}
var cmd commands.SubmitEnterpriseInfoCommand
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
cmd.CertificationID = certificationID
cmd.UserID = userID
result, err := h.appService.SubmitEnterpriseInfo(c.Request.Context(), &cmd)
if err != nil {
h.logger.Error("提交企业信息失败", zap.Error(err), zap.String("certification_id", certificationID))
h.response.BadRequest(c, err.Error())
return
}
h.response.Success(c, result, "企业信息提交成功")
}
// ================ 合同管理 ================
// ApplyContract 申请合同签署
// @Summary 申请合同签署
// @Description 申请企业认证合同签署
// @Tags 认证管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body commands.ApplyContractCommand true "申请合同请求"
// @Success 200 {object} responses.ContractSignUrlResponse "合同申请成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "认证记录不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/certifications/apply-contract [post]
func (h *CertificationHandler) ApplyContract(c *gin.Context) {
userID := h.getCurrentUserID(c)
if userID == "" {
h.response.Unauthorized(c, "用户未登录")
return
}
var cmd commands.ApplyContractCommand
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
cmd.UserID = userID
result, err := h.appService.ApplyContract(c.Request.Context(), &cmd)
if err != nil {
h.logger.Error("申请合同失败", zap.Error(err), zap.String("certification_id", cmd.CertificationID))
h.response.BadRequest(c, err.Error())
return
}
h.response.Success(c, result, "合同申请成功")
}
// ================ 重试操作 ================
// RetryOperation 重试操作
// @Summary 重试操作
// @Description 重试失败的企业认证或合同申请操作
// @Tags 认证管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body commands.RetryOperationCommand true "重试操作请求"
// @Success 200 {object} responses.CertificationResponse "重试操作成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 404 {object} map[string]interface{} "认证记录不存在"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/certifications/retry [post]
func (h *CertificationHandler) RetryOperation(c *gin.Context) {
userID := h.getCurrentUserID(c)
if userID == "" {
h.response.Unauthorized(c, "用户未登录")
return
}
var cmd commands.RetryOperationCommand
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
cmd.UserID = userID
result, err := h.appService.RetryOperation(c.Request.Context(), &cmd)
if err != nil {
h.logger.Error("重试操作失败", zap.Error(err), zap.String("certification_id", cmd.CertificationID))
h.response.BadRequest(c, err.Error())
return
}
h.response.Success(c, result, "重试操作成功")
}
// ================ 查询操作 ================
// GetUserCertifications 获取用户认证列表
// @Summary 获取用户认证列表
// @Description 获取当前用户的认证申请列表
// @Tags 认证管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param status query string false "认证状态"
// @Param include_completed query bool false "是否包含已完成"
// @Param include_failed query bool false "是否包含失败"
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Success 200 {object} responses.CertificationListResponse "获取用户认证列表成功"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/certifications/user [get]
func (h *CertificationHandler) GetUserCertifications(c *gin.Context) {
userID := h.getCurrentUserID(c)
if userID == "" {
h.response.Unauthorized(c, "用户未登录")
return
}
var query queries.GetUserCertificationsQuery
if err := h.validator.BindAndValidate(c, &query); err != nil {
return
}
query.UserID = userID
result, err := h.appService.GetUserCertifications(c.Request.Context(), &query)
if err != nil {
h.logger.Error("获取用户认证列表失败", zap.Error(err), zap.String("user_id", userID))
h.response.BadRequest(c, err.Error())
return
}
h.response.Success(c, result, "获取用户认证列表成功")
}
// ListCertifications 获取认证列表(管理员)
// @Summary 获取认证列表
// @Description 管理员获取认证申请列表
// @Tags 认证管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Param sort_by query string false "排序字段"
// @Param sort_order query string false "排序方向" Enums(asc, desc)
// @Param status query string false "认证状态"
// @Param user_id query string false "用户ID"
// @Param company_name query string false "公司名称"
// @Param legal_person_name query string false "法人姓名"
// @Param search_keyword query string false "搜索关键词"
// @Success 200 {object} responses.CertificationListResponse "获取认证列表成功"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 403 {object} map[string]interface{} "权限不足"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/certifications [get]
func (h *CertificationHandler) ListCertifications(c *gin.Context) {
userID := h.getCurrentUserID(c)
if userID == "" {
h.response.Unauthorized(c, "用户未登录")
return
}
var query queries.ListCertificationsQuery
if err := h.validator.BindAndValidate(c, &query); err != nil {
return
}
result, err := h.appService.ListCertifications(c.Request.Context(), &query)
if err != nil {
h.logger.Error("获取认证列表失败", zap.Error(err))
h.response.BadRequest(c, err.Error())
return
}
h.response.Success(c, result, "获取认证列表成功")
}
// GetCertificationStatistics 获取认证统计
// @Summary 获取认证统计
// @Description 获取认证相关的统计数据
// @Tags 认证管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param start_date query string true "开始日期" format(date)
// @Param end_date query string true "结束日期" format(date)
// @Param period query string false "统计周期" Enums(daily, weekly, monthly, yearly) default(daily)
// @Param group_by query []string false "分组字段"
// @Param user_ids query []string false "用户ID列表"
// @Param statuses query []string false "状态列表"
// @Success 200 {object} responses.CertificationStatisticsResponse "获取认证统计成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/certifications/statistics [get]
func (h *CertificationHandler) GetCertificationStatistics(c *gin.Context) {
userID := h.getCurrentUserID(c)
if userID == "" {
h.response.Unauthorized(c, "用户未登录")
return
}
var query queries.GetCertificationStatisticsQuery
if err := h.validator.BindAndValidate(c, &query); err != nil {
return
}
result, err := h.appService.GetCertificationStatistics(c.Request.Context(), &query)
if err != nil {
h.logger.Error("获取认证统计失败", zap.Error(err))
h.response.BadRequest(c, err.Error())
return
}
h.response.Success(c, result, "获取认证统计成功")
}
// ================ 回调处理 ================
// HandleEsignCallback 处理e签宝回调
// @Summary 处理e签宝回调
// @Description 处理e签宝的企业认证和合同签署回调
// @Tags 认证管理
// @Accept json
// @Produce json
// @Param request body commands.EsignCallbackCommand true "e签宝回调数据"
// @Success 200 {object} responses.CallbackResponse "回调处理成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/certifications/callbacks [post]
func (h *CertificationHandler) HandleEsignCallback(c *gin.Context) {
var cmd commands.EsignCallbackCommand
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
result, err := h.appService.HandleEsignCallback(c.Request.Context(), &cmd)
if err != nil {
h.logger.Error("处理e签宝回调失败", zap.Error(err), zap.String("certification_id", cmd.CertificationID))
h.response.BadRequest(c, err.Error())
return
}
h.response.Success(c, result, "回调处理成功")
}
// ================ 管理员操作 ================
// ForceTransitionStatus 强制状态转换(管理员)
// @Summary 强制状态转换
// @Description 管理员强制转换认证状态
// @Tags 认证管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body commands.ForceTransitionStatusCommand true "强制状态转换请求"
// @Success 200 {object} responses.CertificationResponse "状态转换成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 403 {object} map[string]interface{} "权限不足"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/certifications/force-transition [post]
func (h *CertificationHandler) ForceTransitionStatus(c *gin.Context) {
adminID := h.getCurrentUserID(c)
if adminID == "" {
h.response.Unauthorized(c, "用户未登录")
return
}
var cmd commands.ForceTransitionStatusCommand
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
return
}
cmd.AdminID = adminID
result, err := h.appService.ForceTransitionStatus(c.Request.Context(), &cmd)
if err != nil {
h.logger.Error("强制状态转换失败", zap.Error(err), zap.String("certification_id", cmd.CertificationID))
h.response.BadRequest(c, err.Error())
return
}
h.response.Success(c, result, "状态转换成功")
}
// GetSystemMonitoring 获取系统监控数据
// @Summary 获取系统监控数据
// @Description 获取认证系统的监控数据
// @Tags 认证管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param time_range query string false "时间范围" Enums(1h, 6h, 24h, 7d, 30d) default(24h)
// @Param metrics query []string false "监控指标"
// @Success 200 {object} responses.SystemMonitoringResponse "获取系统监控数据成功"
// @Failure 400 {object} map[string]interface{} "请求参数错误"
// @Failure 401 {object} map[string]interface{} "未认证"
// @Failure 403 {object} map[string]interface{} "权限不足"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/certifications/monitoring [get]
func (h *CertificationHandler) GetSystemMonitoring(c *gin.Context) {
userID := h.getCurrentUserID(c)
if userID == "" {
h.response.Unauthorized(c, "用户未登录")
return
}
var query queries.GetSystemMonitoringQuery
if err := h.validator.BindAndValidate(c, &query); err != nil {
return
}
result, err := h.appService.GetSystemMonitoring(c.Request.Context(), &query)
if err != nil {
h.logger.Error("获取系统监控数据失败", zap.Error(err))
h.response.BadRequest(c, err.Error())
return
}
h.response.Success(c, result, "获取系统监控数据成功")
}
// ================ 辅助方法 ================
// getCurrentUserID 获取当前用户ID
func (h *CertificationHandler) getCurrentUserID(c *gin.Context) string {
if userID, exists := c.Get("user_id"); exists {
if id, ok := userID.(string); ok {
return id
}
}
return ""
}