package state_machine import ( "fmt" "tyapi-server/internal/domains/certification/enums" ) // StateConfig 状态配置 type StateConfig struct { Status enums.CertificationStatus `json:"status"` Name string `json:"name"` ProgressPercentage int `json:"progress_percentage"` IsUserActionRequired bool `json:"is_user_action_required"` IsSystemAction bool `json:"is_system_action"` TimestampField string `json:"timestamp_field,omitempty"` Description string `json:"description"` NextValidStatuses []enums.CertificationStatus `json:"next_valid_statuses"` AllowedActors []enums.ActorType `json:"allowed_actors"` } // StateTransitionRule 状态转换规则 type StateTransitionRule struct { FromStatus enums.CertificationStatus `json:"from_status"` ToStatus enums.CertificationStatus `json:"to_status"` TransitionName string `json:"transition_name"` AllowedActors []enums.ActorType `json:"allowed_actors"` RequiresValidation bool `json:"requires_validation"` Description string `json:"description"` BusinessRules []string `json:"business_rules"` } // StateConfigManager 状态配置管理器 type StateConfigManager struct { stateConfigs map[enums.CertificationStatus]*StateConfig transitionRules map[string]*StateTransitionRule // key: "from_status->to_status" actorPermissions map[enums.ActorType][]string // actor允许的操作 } // NewStateConfigManager 创建状态配置管理器 func NewStateConfigManager() *StateConfigManager { manager := &StateConfigManager{ stateConfigs: make(map[enums.CertificationStatus]*StateConfig), transitionRules: make(map[string]*StateTransitionRule), actorPermissions: make(map[enums.ActorType][]string), } manager.initializeStateConfigs() manager.initializeTransitionRules() manager.initializeActorPermissions() return manager } // initializeStateConfigs 初始化状态配置 func (m *StateConfigManager) initializeStateConfigs() { configs := []*StateConfig{ { Status: enums.StatusPending, Name: "待认证", ProgressPercentage: 0, IsUserActionRequired: true, IsSystemAction: false, Description: "等待用户提交企业信息", NextValidStatuses: []enums.CertificationStatus{enums.StatusInfoSubmitted}, AllowedActors: []enums.ActorType{enums.ActorTypeUser}, }, { Status: enums.StatusInfoSubmitted, Name: "已提交企业信息", ProgressPercentage: 25, IsUserActionRequired: false, IsSystemAction: true, TimestampField: "InfoSubmittedAt", Description: "企业信息已提交,等待e签宝验证", NextValidStatuses: []enums.CertificationStatus{enums.StatusEnterpriseVerified, enums.StatusInfoRejected}, AllowedActors: []enums.ActorType{enums.ActorTypeEsign, enums.ActorTypeSystem}, }, { Status: enums.StatusEnterpriseVerified, Name: "已企业认证", ProgressPercentage: 50, IsUserActionRequired: true, IsSystemAction: false, TimestampField: "EnterpriseVerifiedAt", Description: "企业认证完成,用户可申请合同", NextValidStatuses: []enums.CertificationStatus{enums.StatusContractApplied}, AllowedActors: []enums.ActorType{enums.ActorTypeUser}, }, { Status: enums.StatusContractApplied, Name: "已申请签署合同", ProgressPercentage: 75, IsUserActionRequired: true, IsSystemAction: true, TimestampField: "ContractAppliedAt", Description: "合同已生成,等待用户签署", NextValidStatuses: []enums.CertificationStatus{enums.StatusContractSigned, enums.StatusContractRejected, enums.StatusContractExpired}, AllowedActors: []enums.ActorType{enums.ActorTypeEsign, enums.ActorTypeSystem}, }, { Status: enums.StatusContractSigned, Name: "认证完成", ProgressPercentage: 100, IsUserActionRequired: false, IsSystemAction: false, TimestampField: "ContractSignedAt", Description: "认证流程已完成", NextValidStatuses: []enums.CertificationStatus{}, AllowedActors: []enums.ActorType{}, }, // 失败状态 { Status: enums.StatusInfoRejected, Name: "企业信息被拒绝", ProgressPercentage: 25, IsUserActionRequired: true, IsSystemAction: false, Description: "企业信息验证失败,需要重新提交", NextValidStatuses: []enums.CertificationStatus{enums.StatusInfoSubmitted}, AllowedActors: []enums.ActorType{enums.ActorTypeUser}, }, { Status: enums.StatusContractRejected, Name: "合同被拒签", ProgressPercentage: 75, IsUserActionRequired: true, IsSystemAction: false, Description: "用户拒绝签署合同", NextValidStatuses: []enums.CertificationStatus{enums.StatusEnterpriseVerified}, AllowedActors: []enums.ActorType{enums.ActorTypeUser, enums.ActorTypeSystem}, }, { Status: enums.StatusContractExpired, Name: "合同签署超时", ProgressPercentage: 75, IsUserActionRequired: true, IsSystemAction: false, Description: "合同签署链接已过期", NextValidStatuses: []enums.CertificationStatus{enums.StatusEnterpriseVerified}, AllowedActors: []enums.ActorType{enums.ActorTypeUser, enums.ActorTypeSystem}, }, } for _, config := range configs { m.stateConfigs[config.Status] = config } } // initializeTransitionRules 初始化状态转换规则 func (m *StateConfigManager) initializeTransitionRules() { rules := []*StateTransitionRule{ // 用户提交企业信息 { FromStatus: enums.StatusPending, ToStatus: enums.StatusInfoSubmitted, TransitionName: "submit_enterprise_info", AllowedActors: []enums.ActorType{enums.ActorTypeUser}, RequiresValidation: true, Description: "用户提交企业信息", BusinessRules: []string{"enterprise_info_complete", "enterprise_info_valid"}, }, // e签宝企业认证成功 { FromStatus: enums.StatusInfoSubmitted, ToStatus: enums.StatusEnterpriseVerified, TransitionName: "enterprise_verification_success", AllowedActors: []enums.ActorType{enums.ActorTypeEsign, enums.ActorTypeSystem}, RequiresValidation: false, Description: "e签宝企业认证成功", BusinessRules: []string{"auth_flow_id_exists"}, }, // e签宝企业认证失败 { FromStatus: enums.StatusInfoSubmitted, ToStatus: enums.StatusInfoRejected, TransitionName: "enterprise_verification_failed", AllowedActors: []enums.ActorType{enums.ActorTypeEsign, enums.ActorTypeSystem}, RequiresValidation: false, Description: "e签宝企业认证失败", BusinessRules: []string{"failure_reason_provided"}, }, // 用户申请合同 { FromStatus: enums.StatusEnterpriseVerified, ToStatus: enums.StatusContractApplied, TransitionName: "apply_contract", AllowedActors: []enums.ActorType{enums.ActorTypeUser}, RequiresValidation: true, Description: "用户申请合同签署", BusinessRules: []string{"enterprise_verified", "auth_flow_id_exists"}, }, // e签宝合同签署成功 { FromStatus: enums.StatusContractApplied, ToStatus: enums.StatusContractSigned, TransitionName: "contract_sign_success", AllowedActors: []enums.ActorType{enums.ActorTypeEsign, enums.ActorTypeSystem}, RequiresValidation: false, Description: "e签宝合同签署成功", BusinessRules: []string{"contract_info_complete"}, }, // 合同签署失败 { FromStatus: enums.StatusContractApplied, ToStatus: enums.StatusContractRejected, TransitionName: "contract_sign_rejected", AllowedActors: []enums.ActorType{enums.ActorTypeEsign, enums.ActorTypeSystem}, RequiresValidation: false, Description: "用户拒绝签署合同", BusinessRules: []string{"failure_reason_provided"}, }, // 合同签署超时 { FromStatus: enums.StatusContractApplied, ToStatus: enums.StatusContractExpired, TransitionName: "contract_sign_expired", AllowedActors: []enums.ActorType{enums.ActorTypeEsign, enums.ActorTypeSystem}, RequiresValidation: false, Description: "合同签署超时", BusinessRules: []string{"failure_reason_provided"}, }, // 重新提交企业信息 { FromStatus: enums.StatusInfoRejected, ToStatus: enums.StatusInfoSubmitted, TransitionName: "resubmit_enterprise_info", AllowedActors: []enums.ActorType{enums.ActorTypeUser}, RequiresValidation: true, Description: "用户重新提交企业信息", BusinessRules: []string{"enterprise_info_complete", "enterprise_info_valid", "retry_limit_check"}, }, // 从合同失败状态恢复 { FromStatus: enums.StatusContractRejected, ToStatus: enums.StatusEnterpriseVerified, TransitionName: "reset_from_contract_rejected", AllowedActors: []enums.ActorType{enums.ActorTypeSystem, enums.ActorTypeUser}, RequiresValidation: false, Description: "从合同拒签状态恢复", BusinessRules: []string{"retry_limit_check"}, }, { FromStatus: enums.StatusContractExpired, ToStatus: enums.StatusEnterpriseVerified, TransitionName: "reset_from_contract_expired", AllowedActors: []enums.ActorType{enums.ActorTypeSystem, enums.ActorTypeUser}, RequiresValidation: false, Description: "从合同超时状态恢复", BusinessRules: []string{"retry_limit_check"}, }, } for _, rule := range rules { key := string(rule.FromStatus) + "->" + string(rule.ToStatus) m.transitionRules[key] = rule } } // initializeActorPermissions 初始化操作者权限 func (m *StateConfigManager) initializeActorPermissions() { m.actorPermissions = map[enums.ActorType][]string{ enums.ActorTypeUser: { "submit_enterprise_info", "apply_contract", "view_certification", "retry_from_failure", }, enums.ActorTypeSystem: { "auto_transition", "system_recovery", "timeout_handling", "data_cleanup", }, enums.ActorTypeEsign: { "verification_callback", "sign_callback", "status_notification", }, enums.ActorTypeAdmin: { "manual_intervention", "force_transition", "view_all_certifications", "system_configuration", }, } } // GetStateConfig 获取状态配置 func (m *StateConfigManager) GetStateConfig(status enums.CertificationStatus) *StateConfig { return m.stateConfigs[status] } // GetTransitionRule 获取状态转换规则 func (m *StateConfigManager) GetTransitionRule(fromStatus, toStatus enums.CertificationStatus) *StateTransitionRule { key := string(fromStatus) + "->" + string(toStatus) return m.transitionRules[key] } // CanTransition 检查是否可以执行状态转换 func (m *StateConfigManager) CanTransition(fromStatus, toStatus enums.CertificationStatus, actor enums.ActorType) (bool, string) { // 获取转换规则 rule := m.GetTransitionRule(fromStatus, toStatus) if rule == nil { return false, "不支持的状态转换" } // 检查操作者权限 allowed := false for _, allowedActor := range rule.AllowedActors { if actor == allowedActor { allowed = true break } } if !allowed { return false, "操作者无权限执行此转换" } return true, "" } // GetAllowedTransitions 获取指定状态下允许的转换 func (m *StateConfigManager) GetAllowedTransitions(fromStatus enums.CertificationStatus, actor enums.ActorType) []*StateTransitionRule { var allowedTransitions []*StateTransitionRule config := m.GetStateConfig(fromStatus) if config == nil { return allowedTransitions } for _, toStatus := range config.NextValidStatuses { if canTransition, _ := m.CanTransition(fromStatus, toStatus, actor); canTransition { if rule := m.GetTransitionRule(fromStatus, toStatus); rule != nil { allowedTransitions = append(allowedTransitions, rule) } } } return allowedTransitions } // GetActorPermissions 获取操作者权限 func (m *StateConfigManager) GetActorPermissions(actor enums.ActorType) []string { if permissions, exists := m.actorPermissions[actor]; exists { return permissions } return []string{} } // HasPermission 检查操作者是否有指定权限 func (m *StateConfigManager) HasPermission(actor enums.ActorType, permission string) bool { permissions := m.GetActorPermissions(actor) for _, p := range permissions { if p == permission { return true } } return false } // ValidateBusinessRules 验证业务规则 func (m *StateConfigManager) ValidateBusinessRules(rule *StateTransitionRule, context map[string]interface{}) error { for _, businessRule := range rule.BusinessRules { if err := m.validateSingleBusinessRule(businessRule, context); err != nil { return err } } return nil } // validateSingleBusinessRule 验证单个业务规则 func (m *StateConfigManager) validateSingleBusinessRule(ruleName string, context map[string]interface{}) error { switch ruleName { case "enterprise_info_complete": if enterpriseInfo, exists := context["enterprise_info"]; !exists || enterpriseInfo == nil { return fmt.Errorf("企业信息不能为空") } case "enterprise_info_valid": // 这里可以添加更复杂的企业信息验证逻辑 return nil case "auth_flow_id_exists": if authFlowID, exists := context["auth_flow_id"]; !exists || authFlowID == "" { return fmt.Errorf("认证流程ID不能为空") } case "failure_reason_provided": if reason, exists := context["failure_reason"]; !exists || reason == "" { return fmt.Errorf("失败原因不能为空") } case "enterprise_verified": if status, exists := context["current_status"]; !exists || status != string(enums.StatusEnterpriseVerified) { return fmt.Errorf("企业必须先完成认证") } case "contract_info_complete": if contractInfo, exists := context["contract_info"]; !exists || contractInfo == nil { return fmt.Errorf("合同信息不能为空") } case "retry_limit_check": if retryCount, exists := context["retry_count"]; exists { if count, ok := retryCount.(int); ok && count >= 3 { return fmt.Errorf("已达到最大重试次数限制") } } } return nil } // GetStateProgress 获取状态进度信息 func (m *StateConfigManager) GetStateProgress(status enums.CertificationStatus) int { if config := m.GetStateConfig(status); config != nil { return config.ProgressPercentage } return 0 } // IsUserActionRequired 检查是否需要用户操作 func (m *StateConfigManager) IsUserActionRequired(status enums.CertificationStatus) bool { if config := m.GetStateConfig(status); config != nil { return config.IsUserActionRequired } return false } // IsSystemAction 检查是否为系统操作状态 func (m *StateConfigManager) IsSystemAction(status enums.CertificationStatus) bool { if config := m.GetStateConfig(status); config != nil { return config.IsSystemAction } return false } // GetTimestampField 获取状态对应的时间戳字段 func (m *StateConfigManager) GetTimestampField(status enums.CertificationStatus) string { if config := m.GetStateConfig(status); config != nil { return config.TimestampField } return "" }