89 lines
2.6 KiB
Go
89 lines
2.6 KiB
Go
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)
|
|
}
|
|
|
|
// ... 其他事件触发方法 ...
|
|
|