voucher/internal/biz/cmb.go

171 lines
4.1 KiB
Go

package biz
import (
"context"
"fmt"
"github.com/go-kratos/kratos/v2/log"
"time"
err2 "voucher/api/err"
v1 "voucher/api/v1"
"voucher/internal/biz/bo"
"voucher/internal/biz/vo"
"voucher/internal/pkg/lock"
)
func (v *VoucherBiz) CmbOrder(ctx context.Context, req *bo.OrderCreateReqBo) (orderNo string, err error) {
c := vo.CmbOrderLockKey.BuildCache([]string{req.OutBizNo, req.Type.String()})
err = lock.NewMutex(v.rdb.Rdb, c.TTL).Lock(ctx, c.Key, func(ctx context.Context) error {
order, err := v.OrderRepo.GetByOutBizNo(ctx, vo.OrderTypeCmb, req.OutBizNo)
if err != nil && !err2.IsDbNotFound(err) {
return err
}
if order != nil {
if order.Status.IsFail() {
if err = v.orderRetry(ctx, order); err != nil {
return err
}
}
orderNo = order.OrderNo
return nil
}
product, err := v.ProductRepo.GetByPNO(ctx, req.ProductNo)
if err != nil {
return err
}
if !product.Channel.IsWeChat() {
return err2.ErrorCmbProductNotSupported("只支持微信")
}
order, err = v.order(ctx, req, product)
if err != nil {
return err
}
orderNo = order.OrderNo
return nil
})
return
}
func (v *VoucherBiz) CmbQuery(ctx context.Context, orderNo string) (resp *v1.CmbQueryReply, err error) {
c := vo.CmbQueryLockKey.BuildCache([]string{orderNo})
err = lock.NewMutex(v.rdb.Rdb, c.TTL).Lock(ctx, c.Key, func(ctx context.Context) error {
order, err := v.OrderRepo.GetByOrderNo(ctx, orderNo)
if err != nil {
return err
}
if err = v.Query(ctx, order); err != nil {
return err
}
status, err := order.Status.GetCmbStatusText()
if err != nil {
return err
}
resp = &v1.CmbQueryReply{
Ticket: order.OrderNo,
Status: status.GetValue(),
TransDate: time.Now().Format("20060102150405"),
OrgNo: v.bc.Cmb.OrgNo,
Ext: "",
}
return nil
})
return
}
func (v *VoucherBiz) CmbProductQuery(ctx context.Context, productNo string) (reps *v1.CmbQueryProductReply, err error) {
c := vo.CmbProductQueryLockKey.BuildCache([]string{productNo})
err = lock.NewMutex(v.rdb.Rdb, c.TTL).Lock(ctx, c.Key, func(ctx context.Context) error {
product, err := v.ProductRepo.GetByPNO(ctx, productNo)
if err != nil {
return err
}
if !product.Channel.IsWeChat() {
return fmt.Errorf("只支持微信")
}
wechatResp, err := v.WechatCpnRepo.QueryProduct(ctx, product.MchId, product.BatchNo)
if err != nil {
return fmt.Errorf("批次号:%s,微信错误返回:%v", product.BatchNo, err)
}
log.Warnf("微信查询券详情返回:%v", wechatResp)
inputFormat := time.RFC3339
beginTime := ""
if wechatResp.AvailableBeginTime != nil {
// 解析开始时间
availableBeginTime, _ := time.Parse(inputFormat, *wechatResp.AvailableBeginTime)
beginTime = availableBeginTime.Format(time.DateTime)
}
endTime := ""
if wechatResp.AvailableEndTime != nil {
// 解析结束时间
availableEndTime, _ := time.Parse(inputFormat, *wechatResp.AvailableEndTime)
endTime = availableEndTime.Format(time.DateTime)
}
reps = &v1.CmbQueryProductReply{
RespCode: vo.CmbResponseStatusSuccess.GetValue(),
RespMsg: "成功",
ActivityName: product.Name,
ActivityId: product.ProductNo,
Amount: "",
MinAmount: "",
AvailableType: "",
AvailableDays: "", // 动态有效期天数
StartTime: beginTime,
EndTime: endTime,
AvailableStock: "",
Detail: *wechatResp.Description,
}
reps.Amount = fmt.Sprintf("%d", *wechatResp.StockUseRule.FixedNormalCoupon.CouponAmount)
reps.MinAmount = fmt.Sprintf("%d", *wechatResp.StockUseRule.FixedNormalCoupon.TransactionMinimum)
availableStock := *wechatResp.StockUseRule.MaxCoupons - *wechatResp.DistributedCoupons
reps.AvailableStock = fmt.Sprintf("%d", availableStock)
if wechatResp.StartTime != nil {
s, _ := time.Parse(inputFormat, *wechatResp.StartTime)
reps.SaleStartTime = s.Format(time.DateTime)
}
if wechatResp.StopTime != nil {
e, _ := time.Parse(inputFormat, *wechatResp.StopTime)
reps.SaleEndTime = e.Format(time.DateTime)
}
reps.AvailableType = vo.CmbAvailableTypeFixed.GetValue()
return nil
})
return
}