package biz import ( "crypto/rand" "encoding/hex" "errors" "io" "strconv" "sync" "time" "xy_sh/internal/entities" ) type OrderStore struct { mu sync.RWMutex orders map[string]*OrderInfo } type OrderInfo struct { OrderNo string ActOrderNum string GoodsCode string ActCode string Account string Status int CouponNo string CouponCode string ExpireTime string CouponId string AppId string OpenId string CreateTime time.Time UpdateTime time.Time } var store *OrderStore func init() { store = &OrderStore{ orders: make(map[string]*OrderInfo), } } func CreateOrder(req *entities.OrderRequest) (*entities.OrderResponseData, error) { store.mu.Lock() defer store.mu.Unlock() orderNo := generateOrderNo() orderInfo := &OrderInfo{ OrderNo: orderNo, ActOrderNum: req.ActOrderNum, GoodsCode: req.GoodsCode, ActCode: req.ActCode, Account: req.Account, Status: entities.StatusSuccess, CreateTime: time.Now(), UpdateTime: time.Now(), } orderInfo.CouponNo = generateCouponNo() orderInfo.CouponCode = orderInfo.CouponNo orderInfo.ExpireTime = time.Now().AddDate(1, 0, 0).Format("2006-01-02 15:04:05") store.orders[orderNo] = orderInfo return &entities.OrderResponseData{ OrderNo: orderNo, CouponNo: orderInfo.CouponNo, CouponCode: orderInfo.CouponCode, Status: orderInfo.Status, ExpireTime: orderInfo.ExpireTime, }, nil } func QueryOrder(req *entities.QueryOrderRequest) (*entities.QueryOrderResponseData, error) { store.mu.RLock() defer store.mu.RUnlock() orderInfo, exists := store.orders[req.OrderNo] if !exists { return nil, errors.New("订单不存在") } resp := &entities.QueryOrderResponseData{ OrderNo: orderInfo.OrderNo, Status: orderInfo.Status, Account: orderInfo.Account, CouponId: orderInfo.CouponId, } if orderInfo.CouponNo != "" { resp.CardInfo = &entities.CardInfo{ CouponNo: orderInfo.CouponNo, CouponCode: orderInfo.CouponCode, ExpireTime: orderInfo.ExpireTime, } } return resp, nil } func WxRecharge(req *entities.WxRechargeRequest) (*entities.WxRechargeResponseData, error) { store.mu.Lock() defer store.mu.Unlock() if orderInfo, exists := store.orders[req.OrderNo]; exists { return &entities.WxRechargeResponseData{ OrderNo: orderInfo.OrderNo, Status: orderInfo.Status, CouponId: orderInfo.CouponId, }, nil } orderNo := req.OrderNo orderInfo := &OrderInfo{ OrderNo: orderNo, ActOrderNum: req.ActOrderNum, GoodsCode: req.GoodsCode, ActCode: req.ActCode, AppId: req.AppId, OpenId: req.OpenId, Status: entities.StatusSuccess, CouponId: generateCouponId(), CreateTime: time.Now(), UpdateTime: time.Now(), } store.orders[orderNo] = orderInfo return &entities.WxRechargeResponseData{ OrderNo: orderNo, Status: orderInfo.Status, CouponId: orderInfo.CouponId, }, nil } func HandleCallback(req *entities.CallbackRequest) error { store.mu.Lock() defer store.mu.Unlock() orderInfo, exists := store.orders[req.OrderNo] if !exists { orderInfo = &OrderInfo{ OrderNo: req.OrderNo, ActOrderNum: req.ActOrderNum, CreateTime: time.Now(), } store.orders[req.OrderNo] = orderInfo } orderInfo.Status = req.Status orderInfo.Account = req.Account orderInfo.CouponId = req.CouponId orderInfo.UpdateTime = time.Now() if req.CardInfo != nil { orderInfo.CouponNo = req.CardInfo.CouponNo orderInfo.CouponCode = req.CardInfo.CouponCode orderInfo.ExpireTime = req.CardInfo.ExpireTime } return nil } func generateOrderNo() string { return "HM" + strconv.FormatInt(time.Now().UnixMilli(), 10) + randomString(16) } func generateCouponNo() string { return randomString(16) } func generateCouponId() string { return randomString(8) } func randomString(n int) string { b := make([]byte, (n+1)/2) if _, err := io.ReadFull(rand.Reader, b); err != nil { panic(err) } return hex.EncodeToString(b)[:n] }