Files
tyapi-server/internal/infrastructure/http/handlers/certification_handler.go
2025-07-13 16:36:20 +08:00

473 lines
14 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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结果成功")
}