package domainservice import ( "Cold_Logistic/internal/pkg/common/global" "context" "gogs.baozhida.cn/Cold_Logistic_libs/pkg/contrib/database/myredis" "gogs.baozhida.cn/Cold_Logistic_libs/pkg/contrib/errors" "gogs.baozhida.cn/Cold_Logistic_libs/pkg/contrib/log" "gogs.baozhida.cn/Cold_Logistic_libs/pkg/contrib/util/idutil" "time" ) const OrderRedisKey = "bzd_clod_logistic_order_no" func GetOrderNo(ctx context.Context) (string, error) { client := global.CommonConnectRepoInst.Redis if client == nil { return "", errors.WithStackOnce(errors.New("未初始化Redis,无法使用")) } orderNo, err := client.BRPop(ctx, 3*time.Second, OrderRedisKey).Result() if err != nil { return "", errors.WithStackOnce(err) } if len(orderNo) < 2 { return "", errors.WithStackOnce(errors.New("订单号获取失败")) } // 异步增加订单号 go func() { if err = GenOrderNo(ctx); err != nil { log.FromContext(ctx).Errorf("%#+v", err) } }() return orderNo[1], nil } func GenOrderNo(ctx context.Context) (err error) { client := global.CommonConnectRepoInst.Redis if client == nil { return errors.WithStackOnce(errors.New("未初始化Redis,无法使用")) } count, err := client.LLen(ctx, OrderRedisKey).Result() if err != nil { return errors.WithStackOnce(err) } if count > 1000 { return nil } mutex := myredis.NewRedisMutexLock(OrderRedisKey, client) if err = mutex.LockContext(ctx); err != nil { return errors.WithStackOnce(errors.New("获取分布式锁失败")) } defer func() { // 如果释放失败了,就重试一次 var ok bool if ok, err = mutex.UnlockContext(ctx); !ok || err != nil { _, err = mutex.UnlockContext(ctx) } }() // 每次生成订单号:n*i for n := 0; n < 10; n++ { orderNoList := make([]string, 0, 500) for i := 0; i < 500; i++ { orderNoList = append(orderNoList, idutil.GetSonyFlakeStringID()) time.Sleep(500 * time.Millisecond) } err = client.LPush(ctx, OrderRedisKey, orderNoList).Err() if err != nil { return errors.WithStackOnce(err) } } return nil } // GetOrderSubNo 订单揽件码 func GetOrderSubNo(ctx context.Context, orderNo string) (string, error) { client := global.CommonConnectRepoInst.Redis code, err := client.Get(ctx, orderNo).Result() if err != nil { return "", errors.WithStackOnce(err) } if code == "" { code = orderNo[len(orderNo)-6:] err = client.Set(ctx, code, orderNo, 7*24*time.Hour).Err() if err != nil { return "", errors.WithStackOnce(err) } } return code, nil } // DelOrderSubNo 删除订单揽件码 func DelOrderSubNo(ctx context.Context, keys ...string) error { client := global.CommonConnectRepoInst.Redis _, err := client.Del(ctx, keys...).Result() if err != nil { return errors.WithStackOnce(err) } return nil }