package fsm import ( "context" "fmt" "github.com/looplab/fsm" ) // Task 任务结构体 type Task struct { ID string FSM *fsm.FSM UserID string // 示例:记录操作者 } // NewTask 创建新任务 func NewTask(id string) *Task { task := &Task{ ID: id, } // 创建状态机 task.FSM = fsm.NewFSM( StatePending, // 初始状态 fsm.Events{ // 定义状态转换规则 {Name: EventAssign, Src: []string{StatePending}, Dst: StateAssigned}, {Name: EventAccept, Src: []string{StateAssigned}, Dst: StateAccepted}, {Name: EventSubmit, Src: []string{StateAccepted}, Dst: StateSubmitted}, {Name: EventApprove, Src: []string{StateSubmitted}, Dst: StateApproved}, {Name: EventReject, Src: []string{StateSubmitted}, Dst: StateRejected}, {Name: EventSettle, Src: []string{StateApproved}, Dst: StateSettled}, // Cancel 事件可以从 Pending 或 Assigned 状态触发 {Name: EventCancel, Src: []string{StatePending, StateAssigned}, Dst: StateCanceled}, }, fsm.Callbacks{ // 定义回调函数 // 通用回调:每次触发事件前执行(通过 e.Cancel() 可以组织内存中实际状态变化) "before_event": func(_ context.Context, e *fsm.Event) { if e.Event == EventCancel { e.Cancel(fmt.Errorf("failed to handle event %s", e.Event)) return } fmt.Printf("[Event]Task %s event %s triggered\n", task.ID, e.Event) }, // 通用回调:每次进入新状态时触发 "enter_state": func(_ context.Context, e *fsm.Event) { fmt.Printf("[State] Task %s state changed from %s to %s\n", task.ID, e.Src, e.Dst) // 在这里可以添加通用逻辑,如更新数据库状态 }, // 特定状态回调:进入 Assigned 状态后执行 StateAssigned: func(_ context.Context, e *fsm.Event) { fmt.Printf("[State] Task %s assigned to user %s\n", task.ID, task.UserID) // 在这里可以发送通知给被分配者 }, }, ) return task } // 任务状态流转方法 func (t *Task) Assign(ctx context.Context, userID string) error { t.UserID = userID // 可以在事件触发前设置相关信息 return t.FSM.Event(ctx, EventAssign) // 触发 Assign 事件 } func (t *Task) Accept(ctx context.Context) error { return t.FSM.Event(ctx, EventAccept) } func (t *Task) Submit(ctx context.Context) error { return t.FSM.Event(ctx, EventSubmit) } func (t *Task) Approve(ctx context.Context) error { return t.FSM.Event(ctx, EventApprove) } func (t *Task) Settle(ctx context.Context) error { return t.FSM.Event(ctx, EventSettle) } func (t *Task) Cancel(ctx context.Context) error { return t.FSM.Event(ctx, EventCancel) } // ... 其他事件触发方法 ...