This commit is contained in:
2025-07-21 15:13:26 +08:00
parent 8ad1d7288e
commit b03129667a
41 changed files with 8497 additions and 3968 deletions

View File

@@ -0,0 +1,438 @@
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 ""
}