package handlers import ( "io" "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 认证处理器 type CertificationHandler struct { appService certification.CertificationApplicationService response interfaces.ResponseBuilder logger *zap.Logger } // NewCertificationHandler 创建认证处理器 func NewCertificationHandler( appService certification.CertificationApplicationService, response interfaces.ResponseBuilder, logger *zap.Logger, ) *CertificationHandler { return &CertificationHandler{ appService: appService, response: response, logger: logger, } } // CreateCertification 创建认证申请 // @Summary 创建认证申请 // @Description 为用户创建新的企业认证申请 // @Tags 企业认证 // @Accept json // @Produce json // @Security Bearer // @Success 200 {object} responses.CertificationResponse "认证申请创建成功" // @Failure 401 {object} map[string]interface{} "未认证" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/certification [post] func (h *CertificationHandler) CreateCertification(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { h.response.Unauthorized(c, "用户未认证") return } cmd := &commands.CreateCertificationCommand{UserID: userID} result, err := h.appService.CreateCertification(c.Request.Context(), cmd) if err != nil { h.logger.Error("创建认证申请失败", zap.String("user_id", userID), zap.Error(err), ) h.response.InternalError(c, "创建认证申请失败") return } h.response.Success(c, result, "认证申请创建成功") } // UploadBusinessLicense 上传营业执照并同步OCR识别 // @Summary 上传营业执照并同步OCR识别 // @Description 上传营业执照文件,立即进行OCR识别并返回结果 // @Tags 企业认证 // @Accept multipart/form-data // @Produce json // @Param file formData file true "营业执照文件" // @Security Bearer // @Success 200 {object} responses.UploadLicenseResponse "上传成功" // @Failure 400 {object} map[string]interface{} "请求参数错误" // @Failure 401 {object} map[string]interface{} "未授权" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/certification/upload-license [post] func (h *CertificationHandler) UploadBusinessLicense(c *gin.Context) { // 获取当前用户ID userID, exists := c.Get("user_id") if !exists { h.response.Unauthorized(c, "用户未认证") return } // 获取上传的文件 file, err := c.FormFile("file") if err != nil { h.response.BadRequest(c, "文件上传失败") return } // 读取文件内容 openedFile, err := file.Open() if err != nil { h.response.BadRequest(c, "无法读取文件") return } defer openedFile.Close() fileBytes, err := io.ReadAll(openedFile) if err != nil { h.response.BadRequest(c, "文件读取失败") return } // 调用应用服务 response, err := h.appService.UploadBusinessLicense(c.Request.Context(), userID.(string), fileBytes, file.Filename) if err != nil { h.logger.Error("营业执照上传失败", zap.Error(err)) h.response.InternalError(c, "营业执照上传失败") return } h.response.Success(c, response, "营业执照上传成功") } // GetCertificationStatus 获取认证状态 // @Summary 获取认证状态 // @Description 获取当前用户的认证申请状态 // @Tags 企业认证 // @Accept json // @Produce json // @Security Bearer // @Success 200 {object} responses.CertificationResponse "获取认证状态成功" // @Failure 400 {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.appService.GetCertificationStatus(c.Request.Context(), query) if err != nil { h.logger.Error("获取认证状态失败", zap.String("user_id", userID), zap.Error(err), ) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, result, "获取认证状态成功") } // GetProgressStats 获取进度统计 // @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/stats [get] func (h *CertificationHandler) GetProgressStats(c *gin.Context) { // 这里应该实现获取进度统计的逻辑 // 暂时返回空数据 h.response.Success(c, map[string]interface{}{ "total_applications": 0, "pending": 0, "in_progress": 0, "completed": 0, "rejected": 0, }, "获取进度统计成功") } // GetCertificationProgress 获取认证进度 // @Summary 获取认证进度 // @Description 获取当前用户的认证申请详细进度信息 // @Tags 企业认证 // @Accept json // @Produce json // @Security Bearer // @Success 200 {object} map[string]interface{} "获取认证进度成功" // @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/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.appService.GetCertificationProgress(c.Request.Context(), userID) if err != nil { h.logger.Error("获取认证进度失败", zap.String("user_id", userID), 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} responses.CertificationResponse "企业信息提交成功" // @Failure 400 {object} map[string]interface{} "请求参数错误" // @Failure 401 {object} map[string]interface{} "未认证" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/certification/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 := c.ShouldBindJSON(&cmd); err != nil { h.logger.Error("参数绑定失败", zap.Error(err)) h.response.BadRequest(c, "请求参数格式错误") return } cmd.UserID = userID result, err := h.appService.SubmitEnterpriseInfo(c.Request.Context(), &cmd) if err != nil { h.logger.Error("提交企业信息失败", zap.String("user_id", userID), zap.Error(err), ) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, result, "企业信息提交成功") } // InitiateFaceVerify 发起人脸验证 // @Summary 发起人脸验证 // @Description 发起企业法人人脸验证流程 // @Tags 企业认证 // @Accept json // @Produce json // @Security Bearer // @Param request body commands.InitiateFaceVerifyCommand true "人脸验证请求" // @Success 200 {object} responses.FaceVerifyResponse "人脸验证发起成功" // @Failure 400 {object} map[string]interface{} "请求参数错误" // @Failure 401 {object} map[string]interface{} "未认证" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/certification/face-verify [post] func (h *CertificationHandler) InitiateFaceVerify(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { h.response.Unauthorized(c, "用户未认证") return } var cmd commands.InitiateFaceVerifyCommand if err := c.ShouldBindJSON(&cmd); err != nil { h.logger.Error("参数绑定失败", zap.Error(err)) h.response.BadRequest(c, "请求参数格式错误") return } // 根据用户ID获取认证申请 query := &queries.GetCertificationStatusQuery{UserID: userID} certification, err := h.appService.GetCertificationStatus(c.Request.Context(), query) if err != nil { h.logger.Error("获取认证申请失败", zap.String("user_id", userID), zap.Error(err), ) h.response.BadRequest(c, err.Error()) return } // 如果用户没有认证申请,返回错误 if certification.ID == "" { h.response.BadRequest(c, "用户尚未创建认证申请") return } cmd.CertificationID = certification.ID result, err := h.appService.InitiateFaceVerify(c.Request.Context(), &cmd) if err != nil { h.logger.Error("发起人脸验证失败", zap.String("certification_id", certification.ID), zap.String("user_id", userID), 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} responses.CertificationResponse "合同申请成功" // @Failure 400 {object} map[string]interface{} "请求参数错误" // @Failure 401 {object} map[string]interface{} "未认证" // @Failure 500 {object} map[string]interface{} "服务器内部错误" // @Router /api/v1/certification/contract [post] func (h *CertificationHandler) ApplyContract(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { h.response.Unauthorized(c, "用户未认证") return } result, err := h.appService.ApplyContract(c.Request.Context(), userID) if err != nil { h.logger.Error("申请合同失败", zap.String("user_id", userID), 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} 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/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.appService.GetCertificationDetails(c.Request.Context(), query) if err != nil { h.logger.Error("获取认证详情失败", zap.String("user_id", userID), zap.Error(err), ) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, result, "获取认证详情成功") } // RetryStep 重试步骤 // @Summary 重试认证步骤 // @Description 重新执行指定的认证步骤 // @Tags 企业认证 // @Accept json // @Produce json // @Security Bearer // @Param step path string 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/retry/{step} [post] func (h *CertificationHandler) RetryStep(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { h.response.Unauthorized(c, "用户未认证") return } step := c.Param("step") if step == "" { h.response.BadRequest(c, "步骤名称不能为空") return } var result interface{} var err error switch step { case "face_verify": result, err = h.appService.RetryFaceVerify(c.Request.Context(), userID) case "contract_sign": result, err = h.appService.RetryContractSign(c.Request.Context(), userID) default: h.response.BadRequest(c, "不支持的步骤类型") return } if err != nil { h.logger.Error("重试认证步骤失败", zap.String("user_id", userID), zap.String("step", step), zap.Error(err), ) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, result, "认证步骤重试成功") } // GetLicenseOCRResult 获取营业执照OCR识别结果 // @Summary 获取营业执照OCR识别结果 // @Description 根据上传记录ID获取OCR识别结果 // @Tags 企业认证 // @Accept json // @Produce json // @Security Bearer // @Param record_id path string true "上传记录ID" // @Success 200 {object} responses.UploadLicenseResponse "获取OCR结果成功" // @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/certification/license/{record_id}/ocr-result [get] func (h *CertificationHandler) GetLicenseOCRResult(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { h.response.Unauthorized(c, "用户未认证") return } recordID := c.Param("record_id") if recordID == "" { h.response.BadRequest(c, "上传记录ID不能为空") return } result, err := h.appService.GetLicenseOCRResult(c.Request.Context(), recordID) if err != nil { h.logger.Error("获取OCR结果失败", zap.String("user_id", userID), zap.String("record_id", recordID), zap.Error(err), ) h.response.BadRequest(c, err.Error()) return } h.response.Success(c, result, "获取OCR结果成功") }