package handlers import ( "bytes" "io" "time" "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" ) // CertificationHandler 认证处理器 // 负责处理HTTP请求,参数验证,调用应用服务,返回HTTP响应 type CertificationHandler struct { certAppService certification.CertificationApplicationService esignCallbackService certification.EsignCallbackApplicationService response interfaces.ResponseBuilder validator interfaces.RequestValidator logger *zap.Logger } // NewCertificationHandler 创建认证处理器 func NewCertificationHandler( certAppService certification.CertificationApplicationService, esignCallbackService certification.EsignCallbackApplicationService, response interfaces.ResponseBuilder, validator interfaces.RequestValidator, logger *zap.Logger, ) *CertificationHandler { return &CertificationHandler{ certAppService: certAppService, esignCallbackService: esignCallbackService, response: response, validator: validator, logger: logger, } } // GetCertificationStatus 获取认证状态 // @Summary 获取认证状态 // @Description 获取当前用户的认证状态信息,包括认证进度、当前状态等 // @Tags 企业认证 // @Accept json // @Produce json // @Security Bearer // @Success 200 {object} map[string]interface{} "获取认证状态成功" // @Failure 401 {object} map[string]interface{} "用户未登录" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/certification/status [get] func (h *CertificationHandler) GetCertificationStatus(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { h.response.Unauthorized(c, "用户未登录") return } query := &queries.GetCertificationStatusQuery{ UserID: userID, } result, err := h.certAppService.GetCertificationStatus(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, "获取认证状态成功") } // GetCertificationDetails 获取认证详情 // @Summary 获取认证详情 // @Description 获取当前用户的详细认证信息,包括企业信息、认证记录等 // @Tags 企业认证 // @Accept json // @Produce json // @Security Bearer // @Success 200 {object} map[string]interface{} "获取认证详情成功" // @Failure 401 {object} map[string]interface{} "用户未登录" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/certification/details [get] func (h *CertificationHandler) GetCertificationDetails(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { h.response.Unauthorized(c, "用户未登录") return } query := &queries.GetCertificationDetailsQuery{ UserID: userID, } result, err := h.certAppService.GetCertificationDetails(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, "获取认证详情成功") } // GetCertificationProgress 获取认证进度 // @Summary 获取认证进度 // @Description 获取当前用户的认证进度百分比和下一步操作提示 // @Tags 企业认证 // @Accept json // @Produce json // @Security Bearer // @Success 200 {object} map[string]interface{} "获取认证进度成功" // @Failure 401 {object} map[string]interface{} "用户未登录" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/certification/progress [get] func (h *CertificationHandler) GetCertificationProgress(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { h.response.Unauthorized(c, "用户未登录") return } result, err := h.certAppService.GetCertificationProgress(c.Request.Context(), userID) if err != nil { h.logger.Error("获取认证进度失败", zap.Error(err)) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, result, "获取认证进度成功") } // SubmitEnterpriseInfo 提交企业信息 // @Summary 提交企业信息 // @Description 提交企业四要素信息(企业名称、统一社会信用代码、法定代表人姓名、法定代表人身份证),完成企业信息验证。如果用户没有认证申请,系统会自动创建 // @Tags 企业认证 // @Accept json // @Produce json // @Security Bearer // @Param request body commands.SubmitEnterpriseInfoCommand true "企业信息提交请求" // @Success 200 {object} map[string]interface{} "企业信息提交成功" // @Failure 400 {object} map[string]interface{} "请求参数错误或验证码无效" // @Failure 401 {object} map[string]interface{} "用户未登录" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/certification/submit-enterprise-info [post] func (h *CertificationHandler) SubmitEnterpriseInfo(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { h.response.Unauthorized(c, "用户未登录") return } var cmd commands.SubmitEnterpriseInfoCommand if err := h.validator.BindAndValidate(c, &cmd); err != nil { return } cmd.UserID = userID result, err := h.certAppService.SubmitEnterpriseInfo(c.Request.Context(), &cmd) if err != nil { h.logger.Error("提交企业信息失败", zap.Error(err)) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, result, "企业信息提交成功") } // GetEnterpriseAuthURL 获取企业认证链接 // @Summary 获取企业认证链接 // @Description 获取e签宝企业认证链接,用户可通过该链接完成企业认证 // @Tags 企业认证 // @Accept json // @Produce json // @Security Bearer // @Success 200 {object} map[string]interface{} "获取企业认证链接成功" // @Failure 401 {object} map[string]interface{} "用户未登录" // @Failure 400 {object} map[string]interface{} "企业信息未提交或认证状态异常" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/certification/enterprise-auth-url [get] func (h *CertificationHandler) GetEnterpriseAuthURL(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { h.response.Unauthorized(c, "用户未登录") return } result, err := h.certAppService.GetEnterpriseAuthURL(c.Request.Context(), userID) if err != nil { h.logger.Error("获取企业认证链接失败", zap.Error(err)) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, result, "获取企业认证链接成功") } // ApplyContract 申请合同 // @Summary 申请合同 // @Description 为企业认证用户申请合同,生成合同文档 // @Tags 企业认证 // @Accept json // @Produce json // @Security Bearer // @Success 200 {object} map[string]interface{} "合同申请成功" // @Failure 401 {object} map[string]interface{} "用户未登录" // @Failure 400 {object} map[string]interface{} "企业认证未完成或合同申请失败" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/certification/apply-contract [post] func (h *CertificationHandler) ApplyContract(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { h.response.Unauthorized(c, "用户未登录") return } result, err := h.certAppService.ApplyContract(c.Request.Context(), userID) if err != nil { h.logger.Error("申请合同失败", zap.Error(err)) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, result, "合同申请成功") } // GetContractSignURL 获取合同签署链接 // @Summary 获取合同签署链接 // @Description 获取e签宝合同签署链接,用户可通过该链接完成合同签署 // @Tags 企业认证 // @Accept json // @Produce json // @Security Bearer // @Success 200 {object} map[string]interface{} "获取合同签署链接成功" // @Failure 401 {object} map[string]interface{} "用户未登录" // @Failure 400 {object} map[string]interface{} "合同未申请或签署状态异常" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/certification/contract-sign-url [get] func (h *CertificationHandler) GetContractSignURL(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { h.response.Unauthorized(c, "用户未登录") return } cmd := &commands.GetContractSignURLCommand{ UserID: userID, } result, err := h.certAppService.GetContractSignURL(c.Request.Context(), cmd) if err != nil { h.logger.Error("获取合同签署链接失败", zap.Error(err)) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, result, "获取合同签署链接成功") } // EsignCallback e签宝回调 // @Summary e签宝回调接口 // @Description 接收e签宝认证和签署的回调通知 // @Tags 企业认证 // @Accept json // @Produce json // @Success 200 {object} map[string]interface{} "回调处理成功" // @Failure 400 {object} map[string]interface{} "回调参数错误" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/certification/esign-callback [post] func (h *CertificationHandler) EsignCallback(c *gin.Context) { // 记录请求基本信息 h.logger.Info("收到e签宝回调请求", zap.String("method", c.Request.Method), zap.String("url", c.Request.URL.String()), zap.String("remote_addr", c.ClientIP()), zap.String("user_agent", c.GetHeader("User-Agent")), ) // 记录所有请求头 headers := make(map[string]string) for key, values := range c.Request.Header { if len(values) > 0 { headers[key] = values[0] } } h.logger.Info("回调请求头信息", zap.Any("headers", headers)) // 记录URL查询参数 queryParams := make(map[string]string) for key, values := range c.Request.URL.Query() { if len(values) > 0 { queryParams[key] = values[0] } } if len(queryParams) > 0 { h.logger.Info("回调URL查询参数", zap.Any("query_params", queryParams)) } // 读取并记录请求体 var requestBody interface{} var callbackData map[string]interface{} if c.Request.Body != nil { // 读取请求体 bodyBytes, err := c.GetRawData() if err != nil { h.logger.Error("读取回调请求体失败", zap.Error(err)) h.response.BadRequest(c, "读取请求体失败") return } // 尝试解析为JSON if err := c.ShouldBindJSON(&callbackData); err == nil { requestBody = callbackData } else { // 如果不是JSON,记录原始字符串 requestBody = string(bodyBytes) h.logger.Error("回调请求体不是有效的JSON格式", zap.Error(err)) h.response.BadRequest(c, "请求体格式错误") return } h.logger.Info("回调请求体内容", zap.Any("body", requestBody)) // 重新设置请求体,以便后续处理 c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) } // 记录Content-Type contentType := c.GetHeader("Content-Type") h.logger.Info("回调请求Content-Type", zap.String("content_type", contentType)) // 记录Content-Length contentLength := c.GetHeader("Content-Length") if contentLength != "" { h.logger.Info("回调请求Content-Length", zap.String("content_length", contentLength)) } // 记录时间戳 h.logger.Info("回调请求时间", zap.Time("request_time", time.Now()), zap.String("request_id", c.GetHeader("X-Request-ID")), ) // 记录完整的请求信息摘要 h.logger.Info("e签宝回调完整信息摘要", zap.String("method", c.Request.Method), zap.String("url", c.Request.URL.String()), zap.String("client_ip", c.ClientIP()), zap.String("content_type", contentType), zap.Any("headers", headers), zap.Any("query_params", queryParams), zap.Any("body", requestBody), ) // 处理回调数据 if callbackData != nil { // 构建请求头映射 headers := make(map[string]string) for key, values := range c.Request.Header { if len(values) > 0 { headers[key] = values[0] } } // 构建查询参数映射 queryParams := make(map[string]string) for key, values := range c.Request.URL.Query() { if len(values) > 0 { queryParams[key] = values[0] } } if err := h.esignCallbackService.HandleCallback(c.Request.Context(), callbackData, headers, queryParams); err != nil { h.logger.Error("处理e签宝回调失败", zap.Error(err)) h.response.BadRequest(c, "回调处理失败: "+err.Error()) return } } // 返回成功响应 c.JSON(200, map[string]interface{}{ "code": "200", "msg": "success", }) }