f
This commit is contained in:
@@ -45,6 +45,9 @@ type CertificationApplicationService interface {
|
||||
// AdminCompleteCertificationWithoutContract 管理员代用户完成认证(暂不关联合同)
|
||||
AdminCompleteCertificationWithoutContract(ctx context.Context, cmd *commands.AdminCompleteCertificationCommand) (*responses.CertificationResponse, error)
|
||||
|
||||
// AdminResetForResignContract 管理员触发重新认证(回退到提交企业信息,保留钱包/API Key/历史合同,不改 is_certified)
|
||||
AdminResetForResignContract(ctx context.Context, cmd *commands.AdminResetForResignContractCommand) (*responses.CertificationResponse, error)
|
||||
|
||||
// AdminListSubmitRecords 管理端分页查询企业信息提交记录
|
||||
AdminListSubmitRecords(ctx context.Context, query *queries.AdminListSubmitRecordsQuery) (*responses.AdminSubmitRecordsListResponse, error)
|
||||
// AdminGetSubmitRecordByID 管理端获取单条提交记录详情
|
||||
|
||||
@@ -1003,6 +1003,48 @@ func (s *CertificationApplicationServiceImpl) AdminCompleteCertificationWithoutC
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// AdminResetForResignContract 管理员触发重新认证(回退到提交企业信息)
|
||||
// 回退到 pending,用户可重新填写企业信息并走完整流程;不改 is_certified,不动钱包/API Key/历史合同
|
||||
func (s *CertificationApplicationServiceImpl) AdminResetForResignContract(
|
||||
ctx context.Context,
|
||||
cmd *commands.AdminResetForResignContractCommand,
|
||||
) (*responses.CertificationResponse, error) {
|
||||
s.logger.Info("管理员触发重新认证",
|
||||
zap.String("admin_id", cmd.AdminID),
|
||||
zap.String("user_id", cmd.UserID),
|
||||
zap.String("reason", cmd.Reason),
|
||||
)
|
||||
|
||||
if strings.TrimSpace(cmd.UserID) == "" {
|
||||
return nil, fmt.Errorf("用户ID不能为空")
|
||||
}
|
||||
if strings.TrimSpace(cmd.Reason) == "" {
|
||||
return nil, fmt.Errorf("请填写操作原因")
|
||||
}
|
||||
|
||||
cert, err := s.aggregateService.LoadCertificationByUserID(ctx, cmd.UserID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("加载认证信息失败: %s", err.Error())
|
||||
}
|
||||
|
||||
if err := cert.ResetForResignContract(cmd.AdminID, fmt.Sprintf("管理员触发重新认证:%s", cmd.Reason)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.aggregateService.SaveCertification(ctx, cert); err != nil {
|
||||
return nil, fmt.Errorf("保存认证信息失败: %s", err.Error())
|
||||
}
|
||||
|
||||
response := s.convertToResponse(cert)
|
||||
s.logger.Info("管理员触发重新认证成功",
|
||||
zap.String("admin_id", cmd.AdminID),
|
||||
zap.String("user_id", cmd.UserID),
|
||||
zap.String("certification_id", cert.ID),
|
||||
zap.String("status", string(cert.Status)),
|
||||
)
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// AdminListSubmitRecords 管理端分页查询企业信息提交记录
|
||||
func (s *CertificationApplicationServiceImpl) AdminListSubmitRecords(
|
||||
ctx context.Context,
|
||||
|
||||
@@ -85,6 +85,13 @@ type AdminCompleteCertificationCommand struct {
|
||||
// 备注信息,用于记录后台操作原因
|
||||
Reason string `json:"reason" validate:"required"`
|
||||
}
|
||||
|
||||
// AdminResetForResignContractCommand 管理员触发用户重新认证(回退到提交企业信息,保留钱包/API Key/历史记录)
|
||||
type AdminResetForResignContractCommand struct {
|
||||
AdminID string `json:"-"`
|
||||
UserID string `json:"user_id" validate:"required"`
|
||||
Reason string `json:"reason" validate:"required,min=2,max=500"`
|
||||
}
|
||||
// ForceTransitionStatusCommand 强制状态转换命令(管理员)
|
||||
type ForceTransitionStatusCommand struct {
|
||||
CertificationID string `json:"certification_id" validate:"required"`
|
||||
|
||||
@@ -552,6 +552,57 @@ func (c *Certification) ResetAfterSignTaskCreateFailed() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResetForResignContract 管理员触发重新认证:回退到 pending,用户可重新填写企业信息并走完整入驻流程
|
||||
// 不改动用户域认证标记、钱包、API Key、历史合同记录
|
||||
func (c *Certification) ResetForResignContract(actorID, reason string) error {
|
||||
switch c.Status {
|
||||
case enums.StatusCompleted, enums.StatusContractSigned, enums.StatusContractApplied,
|
||||
enums.StatusContractRejected, enums.StatusContractExpired,
|
||||
enums.StatusEnterpriseVerified, enums.StatusInfoSubmitted, enums.StatusInfoPendingReview:
|
||||
// 允许从已进入流程的各状态重置,供用户重新填写企业信息
|
||||
default:
|
||||
if c.Status == enums.StatusPending {
|
||||
return fmt.Errorf("当前已是待提交企业信息状态,无需重置")
|
||||
}
|
||||
return fmt.Errorf("当前状态 %s 不允许重新认证", enums.GetStatusName(c.Status))
|
||||
}
|
||||
|
||||
oldStatus := c.Status
|
||||
now := time.Now()
|
||||
|
||||
c.Status = enums.StatusPending
|
||||
c.SignPlatform = ""
|
||||
c.AuthFlowID = ""
|
||||
c.AuthURL = ""
|
||||
c.ContractCode = ""
|
||||
c.ContractFileID = ""
|
||||
c.EsignFlowID = ""
|
||||
c.ContractURL = ""
|
||||
c.ContractSignURL = ""
|
||||
c.InfoSubmittedAt = nil
|
||||
c.EnterpriseVerifiedAt = nil
|
||||
c.ContractAppliedAt = nil
|
||||
c.ContractSignedAt = nil
|
||||
c.CompletedAt = nil
|
||||
c.ContractFileCreatedAt = nil
|
||||
c.RetryCount = 0
|
||||
c.clearFailureInfo()
|
||||
c.updateTransitionAudit(enums.ActorTypeAdmin, actorID)
|
||||
c.UpdatedAt = now
|
||||
|
||||
c.addDomainEvent(&CertificationStatusChangedEvent{
|
||||
CertificationID: c.ID,
|
||||
UserID: c.UserID,
|
||||
FromStatus: oldStatus,
|
||||
ToStatus: enums.StatusPending,
|
||||
Actor: enums.ActorTypeAdmin,
|
||||
ActorID: actorID,
|
||||
Reason: reason,
|
||||
TransitionedAt: now,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetSignPlatform 设置签署平台(选定后锁定)
|
||||
func (c *Certification) SetSignPlatform(platform enums.SignPlatform) error {
|
||||
if !enums.IsValidSignPlatform(platform) {
|
||||
|
||||
@@ -559,6 +559,46 @@ func (h *CertificationHandler) AdminCompleteCertificationWithoutContract(c *gin.
|
||||
h.response.Success(c, result, "代用户完成认证成功")
|
||||
}
|
||||
|
||||
// AdminResetForResignContract 管理员触发重新认证
|
||||
// @Summary 管理员触发重新认证
|
||||
// @Description 将认证回退到 pending,用户可重新填写企业信息并走完整入驻流程;保留钱包、API Key、历史合同与 is_certified
|
||||
// @Tags 认证管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security Bearer
|
||||
// @Param request body commands.AdminResetForResignContractCommand true "管理员重新认证请求"
|
||||
// @Success 200 {object} responses.CertificationResponse "操作成功"
|
||||
// @Failure 400 {object} map[string]interface{} "请求参数错误"
|
||||
// @Failure 401 {object} map[string]interface{} "未认证"
|
||||
// @Failure 403 {object} map[string]interface{} "权限不足"
|
||||
// @Router /api/v1/certifications/admin/reset-for-resign-contract [post]
|
||||
func (h *CertificationHandler) AdminResetForResignContract(c *gin.Context) {
|
||||
adminID := h.getCurrentUserID(c)
|
||||
if adminID == "" {
|
||||
h.response.Unauthorized(c, "用户未登录")
|
||||
return
|
||||
}
|
||||
|
||||
var cmd commands.AdminResetForResignContractCommand
|
||||
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
|
||||
return
|
||||
}
|
||||
cmd.AdminID = adminID
|
||||
|
||||
result, err := h.appService.AdminResetForResignContract(c.Request.Context(), &cmd)
|
||||
if err != nil {
|
||||
h.logger.Error("管理员触发重新认证失败",
|
||||
zap.Error(err),
|
||||
zap.String("admin_id", adminID),
|
||||
zap.String("user_id", cmd.UserID),
|
||||
)
|
||||
h.response.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.response.Success(c, result, "已重置为重新认证,请通知用户前往企业入驻重新填写企业信息")
|
||||
}
|
||||
|
||||
// AdminListSubmitRecords 管理端分页查询企业信息提交记录
|
||||
// @Summary 管理端企业审核列表
|
||||
// @Tags 认证管理
|
||||
|
||||
@@ -90,6 +90,7 @@ func (r *CertificationRoutes) Register(router *http.GinRouter) {
|
||||
adminGroup.Use(r.admin.Handle())
|
||||
{
|
||||
adminGroup.POST("/transition-status", r.handler.AdminTransitionCertificationStatus)
|
||||
adminGroup.POST("/reset-for-resign-contract", r.handler.AdminResetForResignContract)
|
||||
}
|
||||
adminCertGroup := adminGroup.Group("/submit-records")
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user