package logic import ( "context" "joybuywork/internal/app" "joybuywork/internal/plugins/jsonm" "joybuywork/internal/repository/dao" "joybuywork/internal/service/provider/fissionaction" "joybuywork/internal/service/provider/operatelog" "joybuywork/internal/utils/merr" "joybuywork/proto/go_proto/workerr" "fmt" "time" grds "github.com/go-redis/redis/v8" "gits.branchcn.com/backend/microcode/plugins/derivative/lock" "go-micro.dev/v4/errors" ) type afterRunFunc func() (err error) type afterRuns struct { runs []afterRunFunc errRuns []afterRunFunc mustRuns []afterRunFunc } type errNotify struct { eqCode []int32 neqCode map[int32]struct{} } type once struct { key string lock *lock.RedisLock } type Logic struct { Context cache *grds.Client stop bool afterRuns afterRuns afterErr []error once *once // 锁 errNotify errNotify // 错误通知 markPoint *fissionaction.MarkPoint // 埋点 ol *operatelog.OperateLog // 操作日志 errData jsonm.JsonM } // Dao 获取初始化的dao func (l *Logic) Dao() *dao.Query { return l.dao } // GetCache 获取cache func (l *Logic) GetCache() *grds.Client { return l.cache } // Init 初始化一个逻辑类 func (l *Logic) Init(ctx context.Context, opts ...Option) { l.Context.Init(ctx, dao.Q, merr.NewBE(ctx)) l.cache = app.Redis.Cache for _, opt := range opts { opt(l) } } // AddAfterRun 追加运行完之后要执行的方法 func (l *Logic) AddAfterRun(fn afterRunFunc) { l.afterRuns.runs = append(l.afterRuns.runs, fn) } // AddErrRun 追加错误运行之后要执行的方法 func (l *Logic) AddErrRun(fn afterRunFunc) { l.afterRuns.errRuns = append(l.afterRuns.errRuns, fn) } // AddMustRun 追加运行之后必须要执行的方法 func (l *Logic) AddMustRun(fn afterRunFunc) { l.afterRuns.mustRuns = append(l.afterRuns.mustRuns, fn) } // After 执行逻辑后要处理的东西 func (l *Logic) After(err error) { l.release() // 必须执行 for _, fn := range l.afterRuns.mustRuns { frr := fn() if frr == nil { continue } if l.stop { return } l.afterErr = append(l.afterErr, frr) } // 出错了要执行的 if err != nil { for _, fn := range l.afterRuns.errRuns { frr := fn() if frr == nil { continue } if l.stop { return } l.afterErr = append(l.afterErr, frr) } return } // 没有错误要执行的 for _, fn := range l.afterRuns.runs { frr := fn() if frr == nil { continue } if l.stop { return } l.afterErr = append(l.afterErr, frr) } if l.markPoint != nil { l.markPoint.Push() } if l.ol != nil { l.ol.InDB() } if l.fnTimer != nil { l.fnTimer.Push() } return } // CacheSet 缓存设置 func (l *Logic) CacheSet(key string, value any, exp time.Duration) error { return l.cacheDone(func() error { return l.cache.Set(l.Ctx, key, value, exp).Err() }) } // CacheDel 删除缓存 func (l *Logic) CacheDel(keys ...string) error { return l.cacheDone(func() error { return l.cache.Del(l.Ctx, keys...).Err() }) } // 缓存操作 func (l *Logic) cacheDone(fn func() error) error { if !l.withTran { return fn() } l.AddAfterRun(func() error { if err := fn(); err != nil { return workerr.InternalServerError(err.Error()) } return nil }) return nil } // 锁操作 func (l *Logic) lock() (err error) { //不需要锁,或者锁成功了 if l.once == nil || l.once.lock.SoftLock() { return } return workerr.OnceLockError } // 解锁 func (l *Logic) release() { if l.once != nil { l.once.lock.Release() } return } // Before 执行之前 func (l *Logic) Before() (err error) { //先锁任务 err = l.lock() if err != nil { return } return } // GetAfterErr 获取执行错误 func (l *Logic) GetAfterErr() []error { return l.afterErr } func (l *Logic) Data() (data jsonm.JsonM) { return l.errData } // PushErr 推送错误 func (l *Logic) PushErr(data jsonm.JsonM, err error) { wrr, ok := errors.As(err) if !ok { app.Logger.Error(l.Ctx, fmt.Sprintf("逻辑处理未定义错误: %v, 数据: %s", err, data.ToString())) return } if len(l.errNotify.eqCode) > 0 { for _, v := range l.errNotify.eqCode { if wrr.GetCode() == v { app.Logger.Error(l.Ctx, fmt.Sprintf("逻辑处理错误: %v, 数据: %s", err, data.ToString())) return } } } if len(l.errNotify.neqCode) > 0 { if _, ok1 := l.errNotify.neqCode[wrr.GetCode()]; !ok1 { app.Logger.Error(l.Ctx, fmt.Sprintf("逻辑处理错误: %v, 数据: %s", err, data.ToString())) return } } } // MP 埋点 func (l *Logic) MP() *fissionaction.MarkPoint { return l.markPoint } // OL 操作记录 func (l *Logic) OL() *operatelog.OperateLog { return l.ol }