package logic import ( "micro-bundle/internal/dao" "micro-bundle/internal/model" "micro-bundle/pb/bundle" "time" ) // CheckOrderEligibility 下单前置校验(先用后付)。 // 规则: // 4. 套餐订单 + 先用后付 + 到期未付:禁止所有套餐下单 // 5. 套餐到期未付不影响增值下单(无限续杯) // 3. 套餐有效期内只允许存在一笔 func CheckOrderEligibility(req *bundle.CheckOrderEligibilityRequest) (*bundle.CheckOrderEligibilityResponse, error) { res := &bundle.CheckOrderEligibilityResponse{Allow: true} if req == nil || req.CustomerID == "" { res.Allow = false res.Reason = "INVALID_PARAM" res.Msg = "customerID 必填" return res, nil } // 套餐下单校验(增值订单不受这些限制:无限续杯) if req.OrderKind == model.OrderKindBundle { // 1. 先用后付套餐逾期未付 → 不可再下单任何套餐(普通/先用后付)。 overdue, err := dao.ExistsOverduePayLaterBundle(req.CustomerID) if err != nil { return res, err } if overdue { res.Allow = false res.Reason = model.OrderGateReasonPayLaterBundleOverdue res.Msg = "您有过期的先用后付订单,无法再次体验" return res, nil } // 2. 已存在先用后付且未支付(待付款)的套餐订单 → 提示去支付。 pending, err := dao.ExistsPendingPayLaterBundle(req.CustomerID) if err != nil { return res, err } if pending { res.Allow = false res.Reason = model.OrderGateReasonPayLaterBundlePending res.Msg = "当前已存在未支付订单,请去我的页面支付" return res, nil } // 3. 有效期内已存在套餐订单 → 保证套餐有效期内只存在一笔。 exists, err := dao.ExistsActiveBundle(req.CustomerID) if err != nil { return res, err } if exists { res.Allow = false res.Reason = model.OrderGateReasonBundleActiveExists res.Msg = "有效期内已存在套餐订单" return res, nil } } return res, nil } // MarkOverdueOrders 扫描到期订单(套餐 → 冻结;增值 → 余量作废) func MarkOverdueOrders(req *bundle.MarkOverdueOrdersRequest) (*bundle.MarkOverdueOrdersResponse, error) { res := &bundle.MarkOverdueOrdersResponse{} now := time.Now() if req != nil && req.Now != "" { if t, err := time.ParseInLocation("2006-01-02 15:04:05", req.Now, time.Local); err == nil { now = t } } if n, err := dao.MarkBundleOverdue(now); err != nil { res.Msg = err.Error() return res, err } else { res.BundleOverdueCount = int32(n) } if n, err := dao.MarkValueAddExpiredByDue(now); err != nil { res.Msg = err.Error() return res, err } else { res.ValueAddExpiredCount = int32(n) } res.Msg = "ok" return res, nil }