You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
259 lines
4.6 KiB
Go
259 lines
4.6 KiB
Go
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
|
|
}
|