temp
This commit is contained in:
@@ -12,21 +12,11 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// StateTransition 状态转换规则
|
||||
type StateTransition struct {
|
||||
From enums.CertificationStatus
|
||||
To enums.CertificationStatus
|
||||
Action string
|
||||
AllowUser bool // 是否允许用户操作
|
||||
AllowAdmin bool // 是否允许管理员操作
|
||||
RequiresValidation bool // 是否需要额外验证
|
||||
}
|
||||
|
||||
// CertificationStateMachine 认证状态机
|
||||
type CertificationStateMachine struct {
|
||||
transitions map[enums.CertificationStatus][]StateTransition
|
||||
certRepo repositories.CertificationRepository
|
||||
logger *zap.Logger
|
||||
stateManager *CertificationStateManager
|
||||
certRepo repositories.CertificationRepository
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// NewCertificationStateMachine 创建认证状态机
|
||||
@@ -34,41 +24,10 @@ func NewCertificationStateMachine(
|
||||
certRepo repositories.CertificationRepository,
|
||||
logger *zap.Logger,
|
||||
) *CertificationStateMachine {
|
||||
sm := &CertificationStateMachine{
|
||||
transitions: make(map[enums.CertificationStatus][]StateTransition),
|
||||
certRepo: certRepo,
|
||||
logger: logger,
|
||||
}
|
||||
|
||||
// 初始化状态转换规则
|
||||
sm.initializeTransitions()
|
||||
return sm
|
||||
}
|
||||
|
||||
// initializeTransitions 初始化状态转换规则
|
||||
func (sm *CertificationStateMachine) initializeTransitions() {
|
||||
transitions := []StateTransition{
|
||||
// 正常流程转换
|
||||
{enums.StatusPending, enums.StatusInfoSubmitted, "submit_info", true, false, true},
|
||||
{enums.StatusInfoSubmitted, enums.StatusFaceVerified, "face_verify", true, false, true},
|
||||
{enums.StatusFaceVerified, enums.StatusContractApplied, "apply_contract", true, false, false},
|
||||
{enums.StatusContractApplied, enums.StatusContractPending, "system_process", false, false, false},
|
||||
{enums.StatusContractPending, enums.StatusContractApproved, "admin_approve", false, true, true},
|
||||
{enums.StatusContractApproved, enums.StatusContractSigned, "user_sign", true, false, true},
|
||||
{enums.StatusContractSigned, enums.StatusCompleted, "system_complete", false, false, false},
|
||||
|
||||
// 失败和重试转换
|
||||
{enums.StatusInfoSubmitted, enums.StatusFaceFailed, "face_fail", false, false, false},
|
||||
{enums.StatusFaceFailed, enums.StatusFaceVerified, "retry_face", true, false, true},
|
||||
{enums.StatusContractPending, enums.StatusRejected, "admin_reject", false, true, true},
|
||||
{enums.StatusRejected, enums.StatusInfoSubmitted, "restart_process", true, false, false},
|
||||
{enums.StatusContractApproved, enums.StatusSignFailed, "sign_fail", false, false, false},
|
||||
{enums.StatusSignFailed, enums.StatusContractSigned, "retry_sign", true, false, true},
|
||||
}
|
||||
|
||||
// 构建状态转换映射
|
||||
for _, transition := range transitions {
|
||||
sm.transitions[transition.From] = append(sm.transitions[transition.From], transition)
|
||||
return &CertificationStateMachine{
|
||||
stateManager: NewCertificationStateManager(),
|
||||
certRepo: certRepo,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,27 +38,7 @@ func (sm *CertificationStateMachine) CanTransition(
|
||||
isUser bool,
|
||||
isAdmin bool,
|
||||
) (bool, string) {
|
||||
validTransitions, exists := sm.transitions[from]
|
||||
if !exists {
|
||||
return false, "当前状态不支持任何转换"
|
||||
}
|
||||
|
||||
for _, transition := range validTransitions {
|
||||
if transition.To == to {
|
||||
if isUser && !transition.AllowUser {
|
||||
return false, "用户不允许执行此操作"
|
||||
}
|
||||
if isAdmin && !transition.AllowAdmin {
|
||||
return false, "管理员不允许执行此操作"
|
||||
}
|
||||
if !isUser && !isAdmin && (transition.AllowUser || transition.AllowAdmin) {
|
||||
return false, "此操作需要用户或管理员权限"
|
||||
}
|
||||
return true, ""
|
||||
}
|
||||
}
|
||||
|
||||
return false, "不支持的状态转换"
|
||||
return sm.stateManager.CanTransition(from, to, isUser, isAdmin)
|
||||
}
|
||||
|
||||
// TransitionTo 执行状态转换
|
||||
@@ -123,11 +62,6 @@ func (sm *CertificationStateMachine) TransitionTo(
|
||||
return fmt.Errorf("状态转换失败: %s", reason)
|
||||
}
|
||||
|
||||
// 执行状态转换前的验证
|
||||
if err := sm.validateTransition(ctx, &cert, targetStatus, metadata); err != nil {
|
||||
return fmt.Errorf("状态转换验证失败: %w", err)
|
||||
}
|
||||
|
||||
// 更新状态和时间戳
|
||||
oldStatus := cert.Status
|
||||
cert.Status = targetStatus
|
||||
@@ -154,20 +88,23 @@ func (sm *CertificationStateMachine) TransitionTo(
|
||||
|
||||
// updateTimestamp 更新对应的时间戳字段
|
||||
func (sm *CertificationStateMachine) updateTimestamp(cert *entities.Certification, status enums.CertificationStatus) {
|
||||
stateConfig := sm.stateManager.GetStateConfig(status)
|
||||
if stateConfig == nil || stateConfig.TimestampField == "" {
|
||||
return
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
switch status {
|
||||
case enums.StatusInfoSubmitted:
|
||||
switch stateConfig.TimestampField {
|
||||
case "InfoSubmittedAt":
|
||||
cert.InfoSubmittedAt = &now
|
||||
case enums.StatusFaceVerified:
|
||||
cert.FaceVerifiedAt = &now
|
||||
case enums.StatusContractApplied:
|
||||
case "EnterpriseVerifiedAt":
|
||||
cert.EnterpriseVerifiedAt = &now
|
||||
case "ContractAppliedAt":
|
||||
cert.ContractAppliedAt = &now
|
||||
case enums.StatusContractApproved:
|
||||
cert.ContractApprovedAt = &now
|
||||
case enums.StatusContractSigned:
|
||||
case "ContractSignedAt":
|
||||
cert.ContractSignedAt = &now
|
||||
case enums.StatusCompleted:
|
||||
case "CompletedAt":
|
||||
cert.CompletedAt = &now
|
||||
}
|
||||
}
|
||||
@@ -179,25 +116,6 @@ func (sm *CertificationStateMachine) updateCertificationFields(
|
||||
metadata map[string]interface{},
|
||||
) {
|
||||
switch status {
|
||||
case enums.StatusContractApproved:
|
||||
if adminID, ok := metadata["admin_id"].(string); ok {
|
||||
cert.AdminID = &adminID
|
||||
}
|
||||
if approvalNotes, ok := metadata["approval_notes"].(string); ok {
|
||||
cert.ApprovalNotes = approvalNotes
|
||||
}
|
||||
if signingURL, ok := metadata["signing_url"].(string); ok {
|
||||
cert.SigningURL = signingURL
|
||||
}
|
||||
|
||||
case enums.StatusRejected:
|
||||
if adminID, ok := metadata["admin_id"].(string); ok {
|
||||
cert.AdminID = &adminID
|
||||
}
|
||||
if rejectReason, ok := metadata["reject_reason"].(string); ok {
|
||||
cert.RejectReason = rejectReason
|
||||
}
|
||||
|
||||
case enums.StatusContractSigned:
|
||||
if contractURL, ok := metadata["contract_url"].(string); ok {
|
||||
cert.ContractURL = contractURL
|
||||
@@ -205,66 +123,13 @@ func (sm *CertificationStateMachine) updateCertificationFields(
|
||||
}
|
||||
}
|
||||
|
||||
// validateTransition 验证状态转换的有效性
|
||||
func (sm *CertificationStateMachine) validateTransition(
|
||||
ctx context.Context,
|
||||
cert *entities.Certification,
|
||||
targetStatus enums.CertificationStatus,
|
||||
metadata map[string]interface{},
|
||||
) error {
|
||||
switch targetStatus {
|
||||
case enums.StatusInfoSubmitted:
|
||||
// 验证企业信息是否完整
|
||||
// 这里应该检查用户是否有企业信息,通过用户域的企业服务验证
|
||||
// 暂时跳过验证,由应用服务层协调
|
||||
break
|
||||
|
||||
case enums.StatusFaceVerified:
|
||||
// 验证人脸识别是否成功
|
||||
// 这里可以添加人脸识别结果的验证逻辑
|
||||
|
||||
case enums.StatusContractApproved:
|
||||
// 验证管理员审核信息
|
||||
if metadata["signing_url"] == nil || metadata["signing_url"].(string) == "" {
|
||||
return fmt.Errorf("缺少合同签署链接")
|
||||
}
|
||||
|
||||
case enums.StatusRejected:
|
||||
// 验证拒绝原因
|
||||
if metadata["reject_reason"] == nil || metadata["reject_reason"].(string) == "" {
|
||||
return fmt.Errorf("缺少拒绝原因")
|
||||
}
|
||||
|
||||
case enums.StatusContractSigned:
|
||||
// 验证合同签署信息
|
||||
if cert.SigningURL == "" {
|
||||
return fmt.Errorf("缺少合同签署链接")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetValidNextStatuses 获取当前状态可以转换到的下一个状态列表
|
||||
func (sm *CertificationStateMachine) GetValidNextStatuses(
|
||||
currentStatus enums.CertificationStatus,
|
||||
isUser bool,
|
||||
isAdmin bool,
|
||||
) []enums.CertificationStatus {
|
||||
var validStatuses []enums.CertificationStatus
|
||||
|
||||
transitions, exists := sm.transitions[currentStatus]
|
||||
if !exists {
|
||||
return validStatuses
|
||||
}
|
||||
|
||||
for _, transition := range transitions {
|
||||
if (isUser && transition.AllowUser) || (isAdmin && transition.AllowAdmin) {
|
||||
validStatuses = append(validStatuses, transition.To)
|
||||
}
|
||||
}
|
||||
|
||||
return validStatuses
|
||||
return sm.stateManager.GetNextValidStatuses(currentStatus)
|
||||
}
|
||||
|
||||
// GetTransitionAction 获取状态转换对应的操作名称
|
||||
@@ -272,20 +137,49 @@ func (sm *CertificationStateMachine) GetTransitionAction(
|
||||
from enums.CertificationStatus,
|
||||
to enums.CertificationStatus,
|
||||
) string {
|
||||
transitions, exists := sm.transitions[from]
|
||||
if !exists {
|
||||
return ""
|
||||
}
|
||||
|
||||
transitions := sm.stateManager.GetTransitionConfigs(from)
|
||||
for _, transition := range transitions {
|
||||
if transition.To == to {
|
||||
return transition.Action
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetTransitionActionName 获取状态转换对应的操作中文名称
|
||||
func (sm *CertificationStateMachine) GetTransitionActionName(
|
||||
from enums.CertificationStatus,
|
||||
to enums.CertificationStatus,
|
||||
) string {
|
||||
transitions := sm.stateManager.GetTransitionConfigs(from)
|
||||
for _, transition := range transitions {
|
||||
if transition.To == to {
|
||||
return transition.ActionName
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetStateConfig 获取状态配置
|
||||
func (sm *CertificationStateMachine) GetStateConfig(status enums.CertificationStatus) *StateConfig {
|
||||
return sm.stateManager.GetStateConfig(status)
|
||||
}
|
||||
|
||||
// GetProgressPercentage 获取进度百分比
|
||||
func (sm *CertificationStateMachine) GetProgressPercentage(status enums.CertificationStatus) int {
|
||||
return sm.stateManager.GetProgressPercentage(status)
|
||||
}
|
||||
|
||||
// IsUserActionRequired 检查是否需要用户操作
|
||||
func (sm *CertificationStateMachine) IsUserActionRequired(status enums.CertificationStatus) bool {
|
||||
return sm.stateManager.IsUserActionRequired(status)
|
||||
}
|
||||
|
||||
// IsAdminActionRequired 检查是否需要管理员操作
|
||||
func (sm *CertificationStateMachine) IsAdminActionRequired(status enums.CertificationStatus) bool {
|
||||
return sm.stateManager.IsAdminActionRequired(status)
|
||||
}
|
||||
|
||||
// GetTransitionHistory 获取状态转换历史
|
||||
func (sm *CertificationStateMachine) GetTransitionHistory(ctx context.Context, certificationID string) ([]map[string]interface{}, error) {
|
||||
cert, err := sm.certRepo.GetByID(ctx, certificationID)
|
||||
@@ -315,12 +209,12 @@ func (sm *CertificationStateMachine) GetTransitionHistory(ctx context.Context, c
|
||||
})
|
||||
}
|
||||
|
||||
if cert.FaceVerifiedAt != nil {
|
||||
if cert.EnterpriseVerifiedAt != nil {
|
||||
history = append(history, map[string]interface{}{
|
||||
"status": string(enums.StatusFaceVerified),
|
||||
"timestamp": *cert.FaceVerifiedAt,
|
||||
"action": "face_verify",
|
||||
"performer": "system",
|
||||
"status": string(enums.StatusEnterpriseVerified),
|
||||
"timestamp": *cert.EnterpriseVerifiedAt,
|
||||
"action": "enterprise_verify",
|
||||
"performer": "user",
|
||||
"metadata": map[string]interface{}{},
|
||||
})
|
||||
}
|
||||
@@ -335,27 +229,6 @@ func (sm *CertificationStateMachine) GetTransitionHistory(ctx context.Context, c
|
||||
})
|
||||
}
|
||||
|
||||
if cert.ContractApprovedAt != nil {
|
||||
metadata := map[string]interface{}{}
|
||||
if cert.AdminID != nil {
|
||||
metadata["admin_id"] = *cert.AdminID
|
||||
}
|
||||
if cert.ApprovalNotes != "" {
|
||||
metadata["approval_notes"] = cert.ApprovalNotes
|
||||
}
|
||||
if cert.SigningURL != "" {
|
||||
metadata["signing_url"] = cert.SigningURL
|
||||
}
|
||||
|
||||
history = append(history, map[string]interface{}{
|
||||
"status": string(enums.StatusContractApproved),
|
||||
"timestamp": *cert.ContractApprovedAt,
|
||||
"action": "admin_approve",
|
||||
"performer": "admin",
|
||||
"metadata": metadata,
|
||||
})
|
||||
}
|
||||
|
||||
if cert.ContractSignedAt != nil {
|
||||
metadata := map[string]interface{}{}
|
||||
if cert.ContractURL != "" {
|
||||
@@ -365,7 +238,7 @@ func (sm *CertificationStateMachine) GetTransitionHistory(ctx context.Context, c
|
||||
history = append(history, map[string]interface{}{
|
||||
"status": string(enums.StatusContractSigned),
|
||||
"timestamp": *cert.ContractSignedAt,
|
||||
"action": "user_sign",
|
||||
"action": "sign_contract",
|
||||
"performer": "user",
|
||||
"metadata": metadata,
|
||||
})
|
||||
@@ -375,7 +248,7 @@ func (sm *CertificationStateMachine) GetTransitionHistory(ctx context.Context, c
|
||||
history = append(history, map[string]interface{}{
|
||||
"status": string(enums.StatusCompleted),
|
||||
"timestamp": *cert.CompletedAt,
|
||||
"action": "system_complete",
|
||||
"action": "complete",
|
||||
"performer": "system",
|
||||
"metadata": map[string]interface{}{},
|
||||
})
|
||||
@@ -383,66 +256,3 @@ func (sm *CertificationStateMachine) GetTransitionHistory(ctx context.Context, c
|
||||
|
||||
return history, nil
|
||||
}
|
||||
|
||||
// ValidateCertificationFlow 验证认证流程的完整性
|
||||
func (sm *CertificationStateMachine) ValidateCertificationFlow(ctx context.Context, certificationID string) (map[string]interface{}, error) {
|
||||
cert, err := sm.certRepo.GetByID(ctx, certificationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取认证记录失败: %w", err)
|
||||
}
|
||||
|
||||
validation := map[string]interface{}{
|
||||
"certification_id": certificationID,
|
||||
"current_status": cert.Status,
|
||||
"is_valid": true,
|
||||
"issues": []string{},
|
||||
"warnings": []string{},
|
||||
}
|
||||
|
||||
// 检查必要的时间节点
|
||||
if cert.Status != enums.StatusPending {
|
||||
if cert.InfoSubmittedAt == nil {
|
||||
validation["is_valid"] = false
|
||||
validation["issues"] = append(validation["issues"].([]string), "缺少企业信息提交时间")
|
||||
}
|
||||
}
|
||||
|
||||
if cert.Status == enums.StatusFaceVerified || cert.Status == enums.StatusContractApplied ||
|
||||
cert.Status == enums.StatusContractPending || cert.Status == enums.StatusContractApproved ||
|
||||
cert.Status == enums.StatusContractSigned || cert.Status == enums.StatusCompleted {
|
||||
if cert.FaceVerifiedAt == nil {
|
||||
validation["is_valid"] = false
|
||||
validation["issues"] = append(validation["issues"].([]string), "缺少人脸识别完成时间")
|
||||
}
|
||||
}
|
||||
|
||||
if cert.Status == enums.StatusContractApproved || cert.Status == enums.StatusContractSigned ||
|
||||
cert.Status == enums.StatusCompleted {
|
||||
if cert.ContractApprovedAt == nil {
|
||||
validation["is_valid"] = false
|
||||
validation["issues"] = append(validation["issues"].([]string), "缺少合同审核时间")
|
||||
}
|
||||
if cert.SigningURL == "" {
|
||||
validation["warnings"] = append(validation["warnings"].([]string), "缺少合同签署链接")
|
||||
}
|
||||
}
|
||||
|
||||
if cert.Status == enums.StatusContractSigned || cert.Status == enums.StatusCompleted {
|
||||
if cert.ContractSignedAt == nil {
|
||||
validation["is_valid"] = false
|
||||
validation["issues"] = append(validation["issues"].([]string), "缺少合同签署时间")
|
||||
}
|
||||
if cert.ContractURL == "" {
|
||||
validation["warnings"] = append(validation["warnings"].([]string), "缺少合同文件链接")
|
||||
}
|
||||
}
|
||||
|
||||
if cert.Status == enums.StatusCompleted {
|
||||
if cert.CompletedAt == nil {
|
||||
validation["is_valid"] = false
|
||||
validation["issues"] = append(validation["issues"].([]string), "缺少认证完成时间")
|
||||
}
|
||||
}
|
||||
|
||||
return validation, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user