Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Failing after 8m39s
- 迁移 000259~000265:套餐记录沉默期字段与扫描索引、套餐默认沉默期、延期政策/流水/订单/批次/明细 5 张表、默认政策与系统配置(总开关默认关闭)、企微审批白名单、卡与设备出库时间及出库记录 - 沉默期设置(订单发放、自动购包、钱包续费)、后台购买时调整(超默认值按政策免审或企微审批)、统一判定与激活闸门、排队与孤儿扫描跳过过期套餐、过期套餐禁止退款、每 10 分钟扫描 - 总开关专用接口与打开前 4 项检查;延期政策;延期资格与计费;H5 自助与后台二维码在线支付(商户池路由)、支付回调与查单恢复、线下登记、特殊/批量延期、异常重试与原路退款;沉默期审批场景与终态处理 - 换货沉默期流水与出库时间;卡/设备列表、详情、导出与出库记录接口;延期订单与即将过期套餐列表及导出;财务流水纳入延期支付 - 沉默期与出库时间回填工具 cmd/silence-backfill;前端接口变更说明 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
99 lines
4.5 KiB
Go
99 lines
4.5 KiB
Go
package packagepkg
|
||
|
||
import (
|
||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||
)
|
||
|
||
// ValidateExpiryBaseOverride 校验显式提交的分配生效条件覆盖。
|
||
func ValidateExpiryBaseOverride(value *string, submitted bool) (*string, error) {
|
||
if !submitted {
|
||
return nil, errors.New(errors.CodeInvalidParam, "生效条件覆盖字段未提交,须显式传值(null 或合法枚举)")
|
||
}
|
||
if value == nil {
|
||
return nil, nil
|
||
}
|
||
if *value != constants.PackageExpiryBaseFromActivation && *value != constants.PackageExpiryBaseFromPurchase {
|
||
return nil, errors.New(errors.CodeInvalidParam, "生效条件覆盖值非法,合法值为:购买即生效、实名激活时生效")
|
||
}
|
||
return value, nil
|
||
}
|
||
|
||
// EffectiveExpiryBase 返回套餐分配最终采用的生效条件。
|
||
func EffectiveExpiryBase(pkg *model.Package, allocation *model.ShopPackageAllocation) string {
|
||
if allocation != nil && allocation.ExpiryBaseOverride != nil {
|
||
return *allocation.ExpiryBaseOverride
|
||
}
|
||
return pkg.ExpiryBase
|
||
}
|
||
|
||
// ExpiryBaseName 返回生效条件中文名称。
|
||
func ExpiryBaseName(value string) string {
|
||
switch value {
|
||
case constants.PackageExpiryBaseFromActivation:
|
||
return "实名激活时生效"
|
||
case constants.PackageExpiryBaseFromPurchase:
|
||
return "购买即生效"
|
||
default:
|
||
return "未知"
|
||
}
|
||
}
|
||
|
||
// ExpiryBaseOverrideName 返回覆盖值中文名称,空值表示跟随套餐默认。
|
||
func ExpiryBaseOverrideName(value *string) string {
|
||
if value == nil {
|
||
return "跟随套餐默认"
|
||
}
|
||
return ExpiryBaseName(*value)
|
||
}
|
||
|
||
// ValidateAllocationExpiryBaseOverride 校验分配覆盖不得改变套餐生效条件(add-package-silence-period §3.3)。
|
||
// 套餐服务与店铺分配(单个、批量、系列授权)写入路径共用:
|
||
// 覆盖把实名即生效套餐改成购买即生效会绕过沉默期;把购买即生效套餐改成实名即生效时该套餐没有默认沉默期,两者都阻断。
|
||
// 覆盖为空(跟随套餐默认)或与套餐一致时放行;加油包不进入沉默期,不受此约束。
|
||
func ValidateAllocationExpiryBaseOverride(pkg *model.Package, override *string) error {
|
||
if pkg == nil || override == nil || pkg.PackageType == constants.PackageTypeAddon {
|
||
return nil
|
||
}
|
||
if *override != pkg.ExpiryBase {
|
||
return errors.New(errors.CodePackageExpiryBaseChangeForbidden,
|
||
"套餐「"+pkg.PackageName+"」不允许通过分配覆盖改变生效条件(实名即生效与购买即生效不能互相覆盖)")
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// ValidatePackageExpiryBaseChange 校验套餐自身生效条件变更(§3.3):实名即生效改为购买即生效阻断;
|
||
// 购买即生效改为实名即生效时,同一请求必须提供默认沉默期。
|
||
func ValidatePackageExpiryBaseChange(pkg *model.Package, before, after string, silenceDaysSubmitted bool) error {
|
||
if pkg == nil || pkg.PackageType == constants.PackageTypeAddon || before == after {
|
||
return nil
|
||
}
|
||
if before == constants.PackageExpiryBaseFromActivation && after == constants.PackageExpiryBaseFromPurchase {
|
||
return errors.New(errors.CodePackageExpiryBaseChangeForbidden, "实名即生效套餐不允许改为购买即生效")
|
||
}
|
||
if before == constants.PackageExpiryBaseFromPurchase && after == constants.PackageExpiryBaseFromActivation && !silenceDaysSubmitted {
|
||
return errors.New(errors.CodeSilencePeriodOutOfRange, "改为实名即生效时必须同时设置默认沉默期(1~90 天)")
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// RequiresSilencePeriod 判断套餐是否必须配置默认沉默期:实名即生效的正式套餐。
|
||
func RequiresSilencePeriod(pkg *model.Package) bool {
|
||
return pkg != nil && pkg.PackageType != constants.PackageTypeAddon && pkg.ExpiryBase == constants.PackageExpiryBaseFromActivation
|
||
}
|
||
|
||
// ValidatePackageSilenceConfig 校验套餐最终的沉默期配置:实名即生效正式套餐必填 1~90 天;其他套餐不得填写。
|
||
func ValidatePackageSilenceConfig(pkg *model.Package) error {
|
||
if RequiresSilencePeriod(pkg) {
|
||
if pkg.SilencePeriodDays == nil || *pkg.SilencePeriodDays < constants.SilencePackageDaysMin || *pkg.SilencePeriodDays > constants.SilencePackageDaysMax {
|
||
return errors.New(errors.CodeSilencePeriodOutOfRange, "实名即生效套餐必须配置默认沉默期(1~90 天)")
|
||
}
|
||
return nil
|
||
}
|
||
if pkg != nil && pkg.SilencePeriodDays != nil {
|
||
return errors.New(errors.CodeInvalidParam, "只有实名即生效的正式套餐可以配置沉默期")
|
||
}
|
||
return nil
|
||
}
|