refactor: 出库时间更名为首次购买套餐时间,换货新资产不再按换货完成时间记录
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Failing after 38s
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Failing after 38s
- 字段 outbound_at → first_purchase_at,记录表 tb_asset_outbound_record → tb_asset_first_purchase_record,接口 /outbound-records → /first-purchase-records,筛选参数与导出列同步更名 - 换货后的新资产不因换货写入,在当前世代真正支付套餐订单时才记录;记录来源只保留 order / backfill,去掉换货单字段 - 迁移 000266 重命名列、表、索引与约束;同步 Spec、设计、任务与前端接口变更说明 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -18,14 +18,14 @@
|
||||
- 每笔实名即生效套餐有沉默期;过期后不能激活、不能退款;可按四种方式延期。
|
||||
- 总开关默认关闭:上线、配置、回填期间不改变任何现有行为;打开前自动检查。
|
||||
- 延期订单与线上订单同一套支付(商户池、回调、查单、原路退款),交易可追溯。
|
||||
- 卡、设备出库时间与出库记录。
|
||||
- 卡、设备首次购买套餐时间与首次购买套餐记录。
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- 通知提醒(短信、公众号、弹窗)。
|
||||
- 延期费分佣、延期费计入代理业绩。
|
||||
- 运营直接修改截止时间的任何接口。
|
||||
- 老系统无订单资产的出库时间补数(后续另行回填)。
|
||||
- 老系统无订单资产的首次购买套餐时间补数(后续另行回填)。
|
||||
|
||||
## Decisions
|
||||
|
||||
@@ -74,13 +74,13 @@
|
||||
|
||||
截止 = 当日 23:59:59(`Asia/Shanghai`);延期按输入天数 `ceil(days / 30)` 计费,延长天数 = 计费天数;新截止从原截止日加。最少月数 `floor(overdue/30) + 1` 保证新截止晚于今天。特殊延期只受最少月数约束。
|
||||
|
||||
### D9 出库时间写在发放套餐的两个入口
|
||||
### D9 首次购买套餐时间写在发放套餐的入口
|
||||
|
||||
在 `activatePackage` 与 `activatePackages` 的事务里写,条件 `outbound_at IS NULL AND generation = 订单世代`,影响行数为 1 时插入出库记录;当前绑定在设备上的卡跳过。换货在世代 +1 的同一事务里清空并结束旧记录,新资产写换货完成时间。
|
||||
在 `activatePackage` 与 `activatePackages` 的事务里写,条件 `first_purchase_at IS NULL AND generation = 订单世代`,影响行数为 1 时插入首次购买套餐记录;当前绑定在设备上的卡跳过。换货在世代 +1 的同一事务里清空并结束旧记录;换货后的新资产不因换货写入(套餐记录迁移不算购买),在当前世代真正支付套餐订单时才按首次购买写入(10-27 与业务确认,替代技术方案 D28)。
|
||||
|
||||
### D10 历史回填是独立工具,先出清单
|
||||
|
||||
回填(沉默期、出库时间)放在 `cmd/` 下的一次性工具,支持"只出清单"与"执行"两种模式,分批、只处理空值、可重复执行。生产执行前 MUST 由业务确认清单。生产只读拉数遵守项目约束(dbhub 只读)。
|
||||
回填(沉默期、首次购买套餐时间)放在 `cmd/` 下的一次性工具,支持"只出清单"与"执行"两种模式,分批、只处理空值、可重复执行。生产执行前 MUST 由业务确认清单。生产只读拉数遵守项目约束(dbhub 只读)。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
@@ -95,9 +95,9 @@
|
||||
|
||||
## Migration Plan
|
||||
|
||||
迁移①~⑨见技术方案 §13.1:`tb_package_usage` 加 10 个字段与部分索引;`tb_package` 加 2 个字段;新建 5 张表;默认政策;系统配置(总开关默认关闭);扩展 `chk_wecom_approval_scene_business` 加入 `package_silence_approval`;`tb_iot_card`、`tb_device` 加 `outbound_at` 与索引;新建 `tb_asset_outbound_record`。加列使用常量默认值(PostgreSQL 11+ 不重写表),建索引放低峰。
|
||||
迁移①~⑨见技术方案 §13.1:`tb_package_usage` 加 10 个字段与部分索引;`tb_package` 加 2 个字段;新建 5 张表;默认政策;系统配置(总开关默认关闭);扩展 `chk_wecom_approval_scene_business` 加入 `package_silence_approval`;`tb_iot_card`、`tb_device` 加 `first_purchase_at` 与索引;新建 `tb_asset_first_purchase_record`。加列使用常量默认值(PostgreSQL 11+ 不重写表),建索引放低峰。
|
||||
|
||||
上线顺序(技术方案 §13.3):测试环境 `up → down → up` 与全量场景验证 → 生产迁移 → 部署(总开关关闭)→ 配置企微模板与权限 → 业务补齐默认沉默期 → 核查新订单字段 → 回填(沉默期、出库时间)→ 超级管理员打开总开关并观察。
|
||||
上线顺序(技术方案 §13.3):测试环境 `up → down → up` 与全量场景验证 → 生产迁移 → 部署(总开关关闭)→ 配置企微模板与权限 → 业务补齐默认沉默期 → 核查新订单字段 → 回填(沉默期、首次购买套餐时间)→ 超级管理员打开总开关并观察。
|
||||
|
||||
回滚:业务层面用总开关关闭;代码回滚前先关闭总开关;生产不执行 down。
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Why
|
||||
|
||||
实名即生效套餐在资产实名前一直处于待生效,现在没有任何期限:客户买了套餐长期不实名,套餐永远挂着,既不能失效也不能收取延期费用。业务已确认《实名即生效套餐沉默期规则需求确认稿_10.16》及 10-27 的补充决定,需要为这类套餐加上沉默期:期限内实名正常生效,过期失效,失效后可付费或经审批延期。同时卡与设备需要记录出库时间(首次购买套餐时间)用于展示。技术方案见 `docs/沉默期技术方案/实名即生效套餐沉默期技术方案_v3.md`(以下简称"技术方案"),规则以技术方案为准。
|
||||
实名即生效套餐在资产实名前一直处于待生效,现在没有任何期限:客户买了套餐长期不实名,套餐永远挂着,既不能失效也不能收取延期费用。业务已确认《实名即生效套餐沉默期规则需求确认稿_10.16》及 10-27 的补充决定,需要为这类套餐加上沉默期:期限内实名正常生效,过期失效,失效后可付费或经审批延期。同时卡与设备需要记录首次购买套餐时间(首次购买套餐时间)用于展示。技术方案见 `docs/沉默期技术方案/实名即生效套餐沉默期技术方案_v3.md`(以下简称"技术方案"),规则以技术方案为准。
|
||||
|
||||
## What Changes
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
- **企微审批**:新增一个审批场景,用"申请类型"区分购买时调整、特殊延期、线下付费延期。
|
||||
- **换货**:沉默期字段随套餐迁移,不重新起算。
|
||||
- **历史回填**:按购买时间起算,不给上线宽限;截止前已实名的记为已结束;先出影响清单,业务确认后执行。
|
||||
- **出库时间**:卡、设备新增出库时间(当前世代首次购买套餐的支付时间)与出库记录表;设备上绑定的卡不记;换货新资产取换货完成时间;只做记录展示,不受总开关控制。
|
||||
- **首次购买套餐时间**:卡、设备新增首次购买套餐时间(当前世代第一笔套餐订单的支付时间,原技术方案称"出库时间")与首次购买套餐记录表;设备上绑定的卡不记;换货后的新资产在当前世代真正购买套餐后才记录;只做记录展示,不受总开关控制。
|
||||
- 不做通知提醒(确认稿第七节不实现)。
|
||||
|
||||
## Capabilities
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
- `package-silence-period`:实名即生效套餐沉默期的设置、购买时调整、实名与过期判定、激活拦截、扫描、总开关与历史回填。
|
||||
- `package-silence-extension`:延期政策、延期资格与计费、四种延期办理、延期订单与支付、企微审批与免审批、延期执行与异常处理。
|
||||
- `asset-outbound-time`:卡与设备的出库时间与出库记录。
|
||||
- `asset-first-purchase-time`:卡与设备的首次购买套餐时间与首次购买套餐记录。
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
|
||||
## Impact
|
||||
|
||||
- 数据库:迁移 9 项(技术方案 §13.1)——`tb_package_usage` 新增 10 个沉默期字段与扫描索引;`tb_package` 新增 2 个字段;新建延期政策、沉默期流水、延期订单、延期批次、延期明细 5 张表;默认政策与系统配置(含总开关,默认关闭);扩展企微审批场景业务类型白名单;`tb_iot_card`、`tb_device` 新增出库时间与出库记录表。总开关关闭前不改变任何现有行为。
|
||||
- 数据库:迁移 9 项(技术方案 §13.1)——`tb_package_usage` 新增 10 个沉默期字段与扫描索引;`tb_package` 新增 2 个字段;新建延期政策、沉默期流水、延期订单、延期批次、延期明细 5 张表;默认政策与系统配置(含总开关,默认关闭);扩展企微审批场景业务类型白名单;`tb_iot_card`、`tb_device` 新增首次购买套餐时间与首次购买套餐记录表。总开关关闭前不改变任何现有行为。
|
||||
- 代码:套餐服务与分配、订单支付后发放套餐(`internal/service/order/service.go`、`internal/task/auto_purchase.go`)、激活服务(`internal/service/package/activation_service.go`)、排队与孤儿扫描(`internal/polling/package_activation_handler.go`)、退款、换货、支付回调(`internal/handler/callback/payment.go`)、商户池与支付渠道适配、企微审批(`internal/application/approval/`)、新应用层 `internal/application/packagesilence/`、领域规则 `internal/domain/package/`、定时任务、后台与 H5 Handler、导出、财务流水。
|
||||
- 接口:新增延期政策、延期资格、延期下单、线下登记、特殊延期、延期订单查询、总开关、出库记录等接口;套餐、购买、资产套餐、卡与设备列表和详情增加字段。H5 新增延期入口。
|
||||
- 数据:上线后先补齐套餐默认沉默期,再执行历史回填与出库时间回填;打开总开关后,截止已过且期内未实名的历史套餐会失效(不给宽限)。
|
||||
- 接口:新增延期政策、延期资格、延期下单、线下登记、特殊延期、延期订单查询、总开关、首次购买套餐记录等接口;套餐、购买、资产套餐、卡与设备列表和详情增加字段。H5 新增延期入口。
|
||||
- 数据:上线后先补齐套餐默认沉默期,再执行历史回填与首次购买套餐时间回填;打开总开关后,截止已过且期内未实名的历史套餐会失效(不给宽限)。
|
||||
- 运营配置:延期政策、企微审批模板、权限分配、商户池与线下收款方式检查(技术方案 §18.3)。
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 卡与设备首次购买套餐时间
|
||||
|
||||
系统 SHALL 为 IoT 卡与设备记录首次购买套餐时间 `first_purchase_at` = 资产当前世代第一笔套餐订单(主套餐或加油包)的支付成功时间。卡取单卡订单,设备取设备订单;**当前绑定在设备上的卡不记录**(套餐在设备上)。写入后 MUST NOT 被后续订单覆盖,首笔订单退款也不清空。该时间只用于展示、筛选与导出,MUST NOT 参与业务判断,不受沉默期总开关影响。
|
||||
|
||||
写入发生在订单支付后发放套餐的入口(订单 `activatePackage`、自动购包 `activatePackages`、钱包自动续费)的同一事务内:`UPDATE ... SET first_purchase_at = :paid_at WHERE id = :asset_id AND generation = :order_generation AND first_purchase_at IS NULL`,影响行数为 1 时插入首次购买套餐记录。
|
||||
|
||||
#### Scenario: 首次购买写入
|
||||
|
||||
- **WHEN** 新卡当前世代第一次支付套餐订单
|
||||
- **THEN** 卡 `first_purchase_at` 为该订单支付时间,并新增一条首次购买套餐记录(来源 `order`,带订单号)
|
||||
|
||||
#### Scenario: 后续订单不覆盖
|
||||
|
||||
- **WHEN** 同一世代再次购买套餐,或首笔订单被退款
|
||||
- **THEN** `first_purchase_at` 不变
|
||||
|
||||
#### Scenario: 设备上绑定的卡
|
||||
|
||||
- **WHEN** 设备订单支付成功,设备上绑定了两张卡
|
||||
- **THEN** 只写设备的首次购买套餐时间,两张卡不写
|
||||
|
||||
### Requirement: 首次购买套餐记录
|
||||
|
||||
系统 SHALL 用 `tb_asset_first_purchase_record` 保存每个世代的首次购买套餐记录:资产类型与 ID、资产标识快照、世代、首次购买套餐时间、来源(`order` / `backfill`)、订单号、店铺、结束时间与原因。同一资产同一世代只有一条(唯一约束);记录只新增与填写结束信息,不修改时间、不删除。系统 SHALL 提供按资产查询各世代记录的接口。
|
||||
|
||||
#### Scenario: 换货回库后历史可查
|
||||
|
||||
- **WHEN** 资产换货回库后再次销售并购买套餐
|
||||
- **THEN** 能查到两条记录:旧世代带结束时间与原因 `exchange_return`,新世代为新的首次购买套餐时间
|
||||
|
||||
### Requirement: 换货时的首次购买套餐时间
|
||||
|
||||
换货时旧资产世代 +1、回到在库的同一事务内,系统 MUST 清空旧资产 `first_purchase_at` 并为旧世代记录填写结束时间与原因。换货后的新资产 MUST NOT 因换货完成而写入首次购买套餐时间;套餐记录随换货迁移不算购买,新资产在当前世代真正支付套餐订单时才按首次购买写入。
|
||||
|
||||
#### Scenario: 换货新资产未购买套餐
|
||||
|
||||
- **WHEN** 卡 A 换成卡 B 完成,套餐记录迁移到卡 B,卡 B 当前世代没有支付过套餐订单
|
||||
- **THEN** 卡 A 首次购买套餐时间清空;卡 B 首次购买套餐时间为空,直到卡 B 当前世代第一笔套餐订单支付成功
|
||||
|
||||
### Requirement: 首次购买套餐时间历史回填与展示
|
||||
|
||||
系统 SHALL 提供首次购买套餐时间回填工具:按资产当前世代最早一笔已支付或已退款的套餐订单回填(排除当前绑定在设备上的卡),分批执行、只更新为空的、可重复执行,并插入来源 `backfill` 的记录;回填前输出可回填数与无订单数。老系统迁移、新系统无订单的资产保持为空,后续另行回填。卡列表、设备列表返回首次购买套餐时间并支持按时间范围筛选;卡详情、设备详情与资产解析返回该时间;卡、设备导出增加"首次购买套餐时间"列。字段与记录只读。
|
||||
|
||||
#### Scenario: 无订单资产
|
||||
|
||||
- **WHEN** 老系统迁移的卡在新系统没有任何套餐订单
|
||||
- **THEN** 回填后首次购买套餐时间仍为空
|
||||
@@ -1,49 +0,0 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 卡与设备出库时间
|
||||
|
||||
系统 SHALL 为 IoT 卡与设备记录出库时间 `outbound_at` = 资产当前世代第 1 次购买套餐(主套餐或加油包)的订单支付成功时间。卡取单卡订单,设备取设备订单;**当前绑定在设备上的卡不记录出库时间**(套餐在设备上)。出库时间写入后 MUST NOT 被后续订单覆盖,首笔订单退款也不清空。出库时间只用于展示、筛选与导出,MUST NOT 参与业务判断,不受沉默期总开关影响。
|
||||
|
||||
写入发生在订单支付后发放套餐的两个入口(订单 `activatePackage`、自动购包 `activatePackages`)的同一事务内:`UPDATE ... SET outbound_at = :paid_at WHERE id = :asset_id AND generation = :order_generation AND outbound_at IS NULL`,影响行数为 1 时插入出库记录。
|
||||
|
||||
#### Scenario: 首次购买写入
|
||||
|
||||
- **WHEN** 新卡当前世代第一次支付套餐订单
|
||||
- **THEN** 卡 `outbound_at` 为该订单支付时间,并新增一条出库记录(来源 `order`,带订单号)
|
||||
|
||||
#### Scenario: 后续订单不覆盖
|
||||
|
||||
- **WHEN** 同一世代再次购买套餐,或首笔订单被退款
|
||||
- **THEN** `outbound_at` 不变
|
||||
|
||||
#### Scenario: 设备上绑定的卡
|
||||
|
||||
- **WHEN** 设备订单支付成功,设备上绑定了两张卡
|
||||
- **THEN** 只写设备的出库时间,两张卡不写
|
||||
|
||||
### Requirement: 出库记录
|
||||
|
||||
系统 SHALL 用 `tb_asset_outbound_record` 保存每个世代的出库记录:资产类型与 ID、资产标识快照、世代、出库时间、来源(`order` / `exchange` / `backfill`)、订单号或换货单号、店铺、结束时间与原因。同一资产同一世代只有一条(唯一约束);记录只新增与填写结束信息,不修改出库时间、不删除。系统 SHALL 提供按资产查询各世代出库记录的接口。
|
||||
|
||||
#### Scenario: 换货后历史可查
|
||||
|
||||
- **WHEN** 资产换货回库后再次销售并购买套餐
|
||||
- **THEN** 能查到两条记录:旧世代带结束时间与原因 `exchange_return`,新世代为新的出库时间
|
||||
|
||||
### Requirement: 换货时的出库时间
|
||||
|
||||
换货时旧资产世代 +1、回到在库的同一事务内,系统 MUST 清空旧资产 `outbound_at` 并为旧世代记录填写结束时间与原因;换货后的新资产若当前世代出库时间为空,MUST 写入换货完成时间并插入出库记录(来源 `exchange`,带换货单号)。
|
||||
|
||||
#### Scenario: 换货新资产
|
||||
|
||||
- **WHEN** 卡 A 换成卡 B 完成
|
||||
- **THEN** 卡 A 出库时间清空,卡 B 出库时间为换货完成时间
|
||||
|
||||
### Requirement: 出库时间历史回填与展示
|
||||
|
||||
系统 SHALL 提供出库时间回填工具:按资产当前世代最早一笔已支付或已退款的套餐订单回填(排除当前绑定在设备上的卡),分批执行、只更新为空的、可重复执行,并插入来源 `backfill` 的出库记录;回填前输出可回填数与无订单数。老系统迁移、新系统无订单的资产保持为空,后续另行回填。卡列表、设备列表返回出库时间并支持按时间范围筛选;卡详情、设备详情与资产解析返回出库时间;卡、设备导出增加"出库时间"列。字段与记录只读。
|
||||
|
||||
#### Scenario: 无订单资产
|
||||
|
||||
- **WHEN** 老系统迁移的卡在新系统没有任何套餐订单
|
||||
- **THEN** 回填后出库时间仍为空
|
||||
@@ -8,10 +8,10 @@
|
||||
- [x] 1.4 迁移④:新建 `tb_package_silence_extension_policy`、`tb_package_silence_record`、`tb_package_silence_extension_order`、`tb_package_silence_extension_batch`、`tb_package_silence_extension`,含 §7.1 / §7.2 的唯一约束与部分唯一索引(同一套餐最多一笔未结束订单、线下收款方式 + 交易单号唯一、`UNIQUE(batch_id, package_usage_id)`、同一套餐最多一条未结束明细)
|
||||
- [x] 1.5 迁移⑤⑥:插入默认延期政策(全部套餐、长期、500 分/月、免费 1 次、累计 6 个月、单次不限、无免审批场景);插入系统配置 `package.silence.enabled`(false)、`package.silence.default_days`(30)、`package.silence.extension_unit_price`(500)
|
||||
- [x] 1.6 迁移⑦:扩展 `tb_wecom_approval_scene.chk_wecom_approval_scene_business`,在 `000216` 现有白名单基础上加入 `package_silence_approval`;down 恢复原白名单
|
||||
- [x] 1.7 迁移⑧⑨:`tb_iot_card`、`tb_device` 新增 `outbound_at timestamptz NULL` 与索引;新建 `tb_asset_outbound_record`(`UNIQUE(asset_type, asset_id, generation)`)
|
||||
- [x] 1.7 迁移⑧⑨:`tb_iot_card`、`tb_device` 新增 `first_purchase_at timestamptz NULL` 与索引;新建 `tb_asset_first_purchase_record`(`UNIQUE(asset_type, asset_id, generation)`)
|
||||
- [x] 1.8 测试库执行 `up → down → up`,确认约束、索引、默认数据正确
|
||||
- [x] 1.9 模型:`PackageUsage`、`Package`、`IotCard`、`Device` 增加字段;新增 6 个表的模型
|
||||
- [x] 1.10 Store:延期政策、沉默期流水、延期订单、批次、明细、出库记录的 Store(条件更新方法返回影响行数)
|
||||
- [x] 1.10 Store:延期政策、沉默期流水、延期订单、批次、明细、首次购买套餐记录的 Store(条件更新方法返回影响行数)
|
||||
- [x] 1.11 常量与错误码:`silence_status` 取值、延期路径与类型、免审批场景枚举、`order_type = silence_extension`、审批业务类型 `package_silence_approval`、审计动作(§11.2)、权限点(§11.1)、错误码(§12.5)
|
||||
|
||||
## 2. 领域规则(§4.2、§5.2、§8.2、§3.6)
|
||||
@@ -79,12 +79,13 @@
|
||||
- [x] 8.2 回调分发:按审批实例关联的调整申请 / 延期批次 / 延期订单处理通过、驳回、撤回;重复事件只处理一次
|
||||
- [x] 8.3 调整审批通过后重算截止日并调用 `ResolveUsageSilence`;驳回保持默认值并立即判定
|
||||
|
||||
## 9. 换货与出库时间(§9、§17)
|
||||
## 9. 换货与首次购买套餐时间(§9、§17)
|
||||
|
||||
- [x] 9.1 换货迁移写沉默期流水(换货单号、前后资产、截止时间);确认 `expired` 记录随迁移且不重算
|
||||
- [x] 9.2 出库时间写入函数:订单 `activatePackage` 与自动购包入口调用;条件 `outbound_at IS NULL AND generation = 订单世代`;绑定在设备上的卡跳过;影响行数为 1 时插入出库记录
|
||||
- [x] 9.3 换货:旧资产世代 +1 的同一事务清空 `outbound_at` 并结束旧记录;新资产写换货完成时间与 `exchange` 记录
|
||||
- [x] 9.4 卡 / 设备列表返回并可按出库时间筛选;详情与资产解析返回;导出增加"出库时间"列;出库记录查询接口
|
||||
- [x] 9.2 首次购买套餐时间写入函数:订单 `activatePackage` 与自动购包入口调用;条件 `first_purchase_at IS NULL AND generation = 订单世代`;绑定在设备上的卡跳过;影响行数为 1 时插入首次购买套餐记录
|
||||
- [x] 9.3 换货:旧资产世代 +1 的同一事务清空 `first_purchase_at` 并结束旧记录;换货后的新资产不因换货写入,当前世代真正购买套餐时才记录
|
||||
- 备注(2026-10-27):按业务决定取消"新资产写换货完成时间与 `exchange` 记录",并把"出库时间"更名为"首次购买套餐时间"(字段 `first_purchase_at`、表 `tb_asset_first_purchase_record`、接口 `/first-purchase-records`),迁移 000266 在测试库已 up → down → up。
|
||||
- [x] 9.4 卡 / 设备列表返回并可按首次购买套餐时间筛选;详情与资产解析返回;导出增加"首次购买套餐时间"列;首次购买套餐记录查询接口
|
||||
|
||||
## 10. 展示、导出、文档与回填工具(§12、§6、§17.4)
|
||||
|
||||
@@ -92,7 +93,7 @@
|
||||
- [x] 10.2 财务交易流水(`internal/query/audit/finance.go`)纳入延期订单支付类型
|
||||
- [x] 10.3 新增 Handler 同步路由、`cmd/api/docs.go`、`cmd/gendocs/main.go`,重新生成 OpenAPI 文档
|
||||
- [x] 10.4 沉默期回填工具(`cmd/`):`--dry-run` 输出影响清单(§6 第 7 条各项);执行模式分批、只处理空值、可重复执行、按实名时间判定 `ended`、写流水
|
||||
- [x] 10.5 出库时间回填工具:按当前世代最早已支付 / 已退款套餐订单回填,排除绑定在设备上的卡,插入 `backfill` 记录,输出可回填数与无订单数
|
||||
- [x] 10.5 首次购买套餐时间回填工具:按当前世代最早已支付 / 已退款套餐订单回填,排除绑定在设备上的卡,插入 `backfill` 记录,输出可回填数与无订单数
|
||||
- [x] 10.6 前端接口变更说明(新增接口、字段、错误码、总开关对页面的影响)
|
||||
- [x] 10.7 `gofmt`、`go build ./...`、`go vet`、`openspec validate add-package-silence-period`
|
||||
|
||||
@@ -105,17 +106,17 @@
|
||||
- [ ] 11.5 四种延期办理(§14 第 16~21 条):H5 微信或支付宝真实小额支付、后台二维码扫码、线下登记审批、特殊与免费延期、批量部分失败、跨天支付异常退款
|
||||
- [ ] 11.6 延期政策与免审批开关(§14 第 22~23 条)
|
||||
- [ ] 11.7 换货与历史回填(§14 第 24~25 条):回填 dry-run 清单与执行、重复执行结果不变
|
||||
- [ ] 11.8 出库时间(§17.6 全部场景)
|
||||
- [ ] 11.8 首次购买套餐时间(§17.6 全部场景)
|
||||
- [ ] 11.9 应急关闭:打开后关闭,确认规则暂停、数据保留、进行中支付回调照常完成
|
||||
- [ ] 11.10 清理本变更创建的测试数据,记录验证结果到本文件
|
||||
|
||||
## 实施备注(2026-10-27)
|
||||
|
||||
- 迁移编号 000259~000265(测试库 `junhong_cmp_test` 已执行 up → down 7 → up,默认政策、三项系统配置、扫描索引、部分唯一索引、审批白名单核对正确)。
|
||||
- 迁移编号 000259~000266(000266 为首次购买套餐时间更名;测试库 `junhong_cmp_test` 已执行 up → down 7 → up,默认政策、三项系统配置、扫描索引、部分唯一索引、审批白名单核对正确)。
|
||||
- 审批关联:三种申请共用 `package_silence_approval`,审批实例 `business_id` 统一为批次 ID;购买时调整也建批次(`path = adjust`),线下付费的批次与订单一一对应。
|
||||
- H5 自助与后台二维码都复用代理在线充值的渠道适配器 `CreatePaymentURL`,返回 `qr_content`(支付链接 / 二维码内容),未新增 JSAPI 支付方式。
|
||||
- 在线订单执行异常(跨天、金额不一致、订单关闭后到账等)自动按冻结商户原路退款,恢复任务 `package:silence:order_recover` 每 5 分钟重试;线下与特殊延期的异常只能人工重试或关闭。
|
||||
- 支付截止时间不跨天(不晚于当天 23:59:59),降低跨天支付进入异常的概率。
|
||||
- 总开关在通用系统配置接口中只读,只能通过 `PUT /api/admin/package-silence/switch` 切换;进程内缓存 5 秒。
|
||||
- 回填工具:`cmd/silence-backfill`(`-target silence|outbound`,默认只出清单,`-execute` 执行);2026-10-27 在测试库 dry-run:沉默期候选 1 条(套餐未配置默认沉默期、不回填),出库时间可回填卡 9 / 设备 6、无订单卡 7、绑定在设备上的卡 15。
|
||||
- 回填工具:`cmd/silence-backfill`(`-target silence|first_purchase`,默认只出清单,`-execute` 执行);2026-10-27 在测试库 dry-run:沉默期候选 1 条(套餐未配置默认沉默期、不回填),首次购买套餐时间可回填卡 9 / 设备 6、无订单卡 7、绑定在设备上的卡 15。
|
||||
- 前端说明:`docs/2026-10-27-实名即生效套餐沉默期-前端接口变更说明.md`。
|
||||
|
||||
Reference in New Issue
Block a user