七月迭代短暂完结,还有很多后端的关键东西没有弄,这是一版赶时间做的东西
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m26s

This commit is contained in:
2026-07-25 17:06:58 +08:00
parent ad9f613dd6
commit 73f5125d3d
249 changed files with 17137 additions and 877 deletions

View File

@@ -20,7 +20,7 @@
|需求07实名筛选|卡和设备列表增加实名状态筛选|卡按自身状态,设备按有效绑定卡维护/查询实名状态|12小时|23小时|设备多当前卡、绑定历史异常会增加 23 小时|
|需求08设备批量分配|拆分“分配代理”和“分配套餐系列”两个入口,展示任务结果|复用 Excel/Asynq新增两个独立批量命令和失败明细|23小时|34小时|前端无现成上传任务组件或生产文件格式不统一会增加 24 小时|
|需求09C 端支付限制|支付页按接口返回方式展示,后台增加配置控件|实现受控系统配置、缓存和订单支付二次校验|1.52.5小时|23小时|多端支付入口未复用同一接口会增加逐端排查时间|
|需求10Gateway 限速|卡/设备详情增加设置和取消入口|统一 `speed_kbps` 接口,设备解析当前卡后调用 Gateway|12小时|23小时|Gateway 取消参数不明确或联调不稳定会增加 24 小时|
|需求10Gateway 限速|仅 IoT 卡详情增加固定档位设置和恢复不限速入口|卡专用 `speed-tier` 接口按 ICCID 调用 Gateway,设备无入口|12小时|23小时|Gateway 档位或联调不稳定会增加 24 小时|
|需求11当前套餐到期高亮|并入需求06/22不单独建设第二个资产汇总字段|并入预计最终到期 Query|0小时|0小时|无独立工时|
|需求12换货显示与搜索|拆分新旧资产搜索并修正字段展示|修正新建换货快照,增加新旧资产关键词过滤|12小时|12小时|历史数据不回填导致验收口径混淆会增加沟通时间|
|需求13列表字段新增|退款、充值、换货列表增加提交人和企微审批摘要|补提交人快照,批量查询企微状态和审批人摘要|12小时|23小时|旧记录缺提交人或企微实例会增加兼容展示时间|

View File

@@ -782,13 +782,8 @@ sequenceDiagram
```mermaid
flowchart TD
Trigger[后台手动设置或取消] --> Asset{资产类型}
Asset -->|卡| ICCID[读取卡 ICCID]
Asset -->|设备| Binding[查询 is_current=true 的当前卡]
Binding --> Exists{当前卡有效?}
Exists -->|否| Reject[拒绝操作并记录原因]
Exists -->|是| ICCID
ICCID --> Gateway[SetSpeedLimit cardNo, speedLevel]
Trigger[卡详情手动选择固定档位] --> ICCID[校验 IoT 卡 ICCID 与数据权限]
ICCID --> Gateway[SetCardSpeedTier cardNo, code]
Gateway --> Audit[记录操作审计和 Gateway 结果]
```
@@ -796,15 +791,15 @@ flowchart TD
数据和契约:
- 应用层只接收语义化 `speed_level`,前端只能从固定档位中选择,禁止输入任意速率,也不得接触 Gateway 渠道 `code`
- 统一接口:`POST /api/admin/assets/{identifier}/speed-limit`。资产为设备时解析当前绑定卡,不存在当前卡则拒绝,绝不把设备 IMEI 传给 Gateway
- Gateway 端口只有 `SetSpeedLimit(cardNo, speedLevel)`Infrastructure Adapter 根据 Gateway 账户和运营商把业务等级映射为上游字符串 `code`,映射不得进入 Handler、前端或领域模型
- 后台接口只接收固定整数档位 `code=-1..8`,前端只能从固定档位中选择,禁止输入任意速率
- 卡专用接口:`PUT /api/admin/iot-cards/{iccid}/speed-tier`。设备没有限速入口,也不得通过设备当前绑定卡间接限速
- Gateway 端口只有 `SetCardSpeedTier(cardNo, code)``cardNo` 必须是经过本地权限校验的卡 ICCID不得传设备 ID 或 IMEI
- “恢复不限速”和“限到 0kbps”是两个不同业务等级必须分别映射为上游 `code=-1``code=0`,禁止继续用数值 `0` 表示取消限速。
- 上游说明只有广电和电信直接支持限速接口,联通通过通信计划调整,移动不支持限速。调用前必须按卡的运营商能力校验;不支持或缺少账户档位映射时返回明确业务错误,不得猜测 `code` 或盲目调用
- 上游是否支持具体运营商与账户由 Gateway 返回结果确认;本系统只校验固定档位并原样发送,不自行推算运营商策略
- 不新增 `tb_package.speed_limit_kbps``SpeedLimitApplyRequested` Outbox 或自动补偿 Worker。本期也不宣称能展示 Gateway 当前实际限速,除非上游另提供查询接口。
- 卡详情和设备详情都提供固定档位选择及恢复不限速入口;设备入口明确显示“当前使用卡 ICCID”。每次操作记录资产、最终 `cardNo`、业务 `speed_level`、实际发送的渠道 `code`Gateway 返回的 `appliedSpeed/channelRawValue`、操作人、请求结果和错误摘要。
- 卡详情提供固定档位选择及恢复不限速入口。每次操作记录卡 ICCID、实际发送的 `code`操作人、Integration Log、请求结果和错误摘要。
CMP 固定业务等级如下。枚举名称属于本系统稳定契约;展示文案和上游默认 `code` 仅用于表达当前已知映射,实际调用仍须按 Gateway 账户和运营商查找映射
CMP 固定档位如下,接口直接提交表中的整数 `code`
| `speed_level` | 展示文案 | 当前上游默认 `code` |
|---------------|----------|----------------------|

View File

@@ -103,7 +103,7 @@ FE/BE 研发需求开发完成
| #53 实名状态筛选 | **标题:**卡和设备实名状态筛选。<br>**页面:**两个资产列表增加全部/已实名/未实名筛选和状态列。 | **标题:**卡和设备实名状态查询。<br>**接口:**`GET /api/admin/iot-cards?real_name_status=0\|1``GET /api/admin/devices?real_name_status=0\|1`。<br>**返回:**`real_name_status/real_name_status_name`。 |
| #49 设备批量分配 | **标题:**设备批量分配代理和套餐系列双入口。<br>**页面:**两个独立上传弹框,展示总数、成功数、失败数和失败原因。 | **标题:**设备两类批量分配任务。<br>**接口:**`POST /api/admin/devices/batch-assign-shop``POST /api/admin/devices/batch-assign-series``GET /api/admin/devices/batch-allocation/{task_id}`。<br>**入参:**文件和目标ID。<br>**返回:**任务状态及失败明细。 |
| #48 支付方式限制 | **标题:**C端按资产展示支付方式。<br>**页面:**支付页只展示接口返回的支付方式;无可用方式时禁止提交。 | **标题:**资产支付方式配置与订单校验。<br>**接口:**`GET /api/c/v1/asset/info` 返回 `allowed_payment_methods``POST /api/c/v1/orders/create``POST /api/c/v1/orders/{id}/pay` 再次校验。<br>**后台:**`PUT /api/admin/system/config/{config_key}`。 |
| #47 Gateway限速 | **标题:**卡和设备手动限速。<br>**页面:**详情提供设置、取消入口设备显示最终使用的当前卡ICCID。 | **标题:**Gateway按cardNo统一限速。<br>**接口:**`POST /api/admin/assets/{identifier}/speed-limit`。<br>**入参:**`speed_kbps`0表示取消。<br>**返回:**资产标识、最终 `card_no`、目标值和执行结果。 |
| #47 Gateway限速 | **标题:**IoT 卡手动固定档位限速。<br>**页面:**仅卡详情提供设置、恢复不限速入口;设备不提供限速操作。 | **标题:**Gateway 卡 ICCID 固定档位限速。<br>**接口:**`PUT /api/admin/iot-cards/{iccid}/speed-tier`。<br>**入参:**`code=-1..8``-1` 表示恢复不限速。<br>**返回:**卡ID、ICCID、档位名称和 Integration Log ID。 |
| #46 预计最终到期 | **标题:**预计套餐到期时间和临期高亮。<br>**页面:**资产详情只显示一个最终到期字段;不可预计时显示“待激活后起算”。 | **标题:**当前及排队套餐最终到期Query。<br>**接口:**`GET /api/admin/assets/resolve/{identifier}`。<br>**返回:**`estimated_final_expires_at/days_until_final_expiry/expiry_estimate_status/is_expiring`。 |
| #45 换货管理 | **标题:**换货新旧资产展示和独立搜索。<br>**页面:**列表分别搜索旧资产、新资产展示统一卡ICCID或设备号。 | **标题:**换货标识快照和查询。<br>**接口:**`GET /api/admin/exchanges?old_asset_keyword=&new_asset_keyword=`。<br>**返回:**新旧资产类型、ID、标识及换货状态。新建换货统一保存规范化标识。 |
| #44 列表字段新增 | **标题:**退款、充值、换货列表提交人与审批摘要。<br>**页面:**增加提交人、企微状态、当前审批人摘要和业务处理状态。 | **标题:**提交人快照与企微摘要查询。<br>**接口:**复用 `GET /api/admin/refunds`、`GET /api/admin/agent-recharges`、`GET /api/admin/exchanges`。<br>**返回:**`submitter_name/approval_status_name/current_approver_summary/processing_status_name`。 |
@@ -200,7 +200,7 @@ FE/BE 研发需求开发完成
| INT-04 | CSV批量任务与导出联调 | #49#36#42 | FE 11.5h / BE 11.5h,已含 | 上传、任务详情、Worker和导出场景完成 | 模板校验、部分成功、失败明细、任务恢复、字段权限和文件下载 |
| INT-05 | 支付、代理钱包、信用和余额预警联调 | #48#38#34#36#96#97 | FE 11.5h / BE 11.5h,已含 | 支付配置、钱包领域和业务员接口完成 | 支付方式限制、扫码充值、信用扣款、角色默认额度、店铺调额、100元预警 |
| INT-06 | 企业微信审批、退款和线下充值联调 | #37#35#34#44 | FE 1.52h / BE 1.52h已含 | 企微模板、绑定、回调、轮询和业务详情完成 | 扫码绑定、发起审批、意见附件、通过/驳回/撤销、退款/充值终态和列表摘要 |
| INT-07 | Gateway卡限速联调 | #47 | FE 0.51h / BE 0.51h已含 | Gateway联调配置和卡/设备入口完成 | 单卡限速、设备解析当前卡、取消限速、无当前卡、失败审计 |
| INT-07 | Gateway卡限速联调 | #47 | FE 0.51h / BE 0.51h已含 | Gateway联调配置和卡专用入口完成 | 单卡各固定档位、恢复不限速、越权卡、Gateway 失败/结果未知与审计 |
| INT-08 | 七月迭代全链路与停机发布验收 | 全部激活需求及三项公共技术需求 | FE 34h / BE 45h额外 | INT-0107、公共基础12、全局审计19、公共通知08及各业务发布门禁完成 | 权限、通知、全系统审计覆盖、正式Adapter、事件消费者、历史数据、旧入口关闭、Worker恢复、生产阈值和发布检查 |
## 七、联调任务责任方式

View File

@@ -784,29 +784,28 @@
**标题**
```text
[FE][UR#47] 卡设备手动设置与取消限速
[FE][UR#47] IoT 卡手动设置固定限速档位
```
**描述**
```markdown
目标:在卡和设备详情提供统一的手动限速入口,不展示自动限速规则。
目标:仅在 IoT 卡详情提供手动固定档位限速入口,不展示自动限速规则。
预计工时前端12小时。
页面入口:卡详情设备详情。
页面入口:IoT 卡详情设备详情不提供限速入口
页面结构:
1. “手动限速”弹框只展示后端返回的固定语义档位,不允许输入任意速率或上游code
2. “恢复不限速”提交speed_level=unlimited“限到0kbps”提交speed_level=zero_kbps,两者严格区分。
3. 设备详情必须显示本次实际作用的当前卡ICCID无当前卡时禁用操作并展示原因
4. 不展示“Gateway当前实际限速”除非接口未来明确返回查询结果。
1. “手动限速”弹框只展示 `code=-1..8` 固定档位,不允许输入任意速率。
2. “恢复不限速”提交 `code=-1`“限到0kbps”提交 `code=0`,两者严格区分。
3. 不展示“Gateway当前实际限速”除非接口未来明确返回查询结果
接口约定:POST /api/admin/assets/{identifier}/speed-limitbody={speed_level:string}返回asset_type、asset_identifier、card_no、speed_level、channel_code、applied_speed、channel_raw_value、result、message
接口约定:`PUT /api/admin/iot-cards/{iccid}/speed-tier``body={code:int}`;返回 `iot_card_id/iccid/code/speed_tier_name/integration_id`
交互规则:提交中禁用按钮;失败保留所选档位;中国电信/广电按后端能力展示,联通/移动或映射缺失时禁用并展示原因;结果未知不能显示成功。
交互规则:提交中禁用按钮;失败保留所选档位;结果未知不能显示成功,并提示按 ICCID 核对 Gateway 实际档位
完成标准:卡限速、设备解析当前卡、取消限速和无当前卡四类场景完整
完成标准:卡固定档位、恢复不限速、越权卡、明确失败和结果未知场景完整;设备无入口
```
### 后端研发需求
@@ -814,23 +813,23 @@
**标题**
```text
[BE][UR#47] Gateway按cardNo统一限速接口
[BE][UR#47] Gateway按卡ICCID设置固定限速档位
```
**描述**
```markdown
目标:只开放一个手动限速接口,最终始终按卡ICCID调用Gateway。
目标:只开放 IoT 卡手动限速接口,按卡 ICCID 调用 Gateway。
预计工时后端23小时。
接口:POST /api/admin/assets/{identifier}/speed-limit入参为固定语义枚举speed_level恢复不限速与限到0kbps是不同值前端和业务层不得接触渠道code
接口:`PUT /api/admin/iot-cards/{iccid}/speed-tier`,入参为固定整数档位 `code=-1..8`恢复不限速与限到0kbps分别使用 `-1``0`
规则:资产为卡时读取ICCID资产为设备时解析is_current=true的唯一有效当前卡不存在或多条当前卡都拒绝绝不把设备号传给Gateway。仅中国电信和中国广电直连POST /flow-card/speedLimitAdapter按Gateway账号+运营商+speed_level映射code缺失映射不猜测。外部副作用关闭自动重试超时等结果不明记录unknown。
规则:按 ICCID 查询 IoT 卡并沿用现有数据权限;只向 `POST /flow-card/speedLimit` 发送 `cardNo + code`。设备没有限速入口,也不得解析设备当前绑定卡间接调用。外部副作用关闭盲目自动重试,超时等结果不明记录 `unknown`
非目标不建立套餐固定限速不因激活、到期、停机或切卡自动限速不增加自动补偿Worker。
完成标准:返回最终card_no、语义档位和规范化调用结果电信、广电、联通、移动、映射缺失、明确失败和结果未知均有正确行为每次请求记录操作审计及Integration Log。
完成标准:返回卡 ID、ICCID、固定档位和 Integration Log ID明确失败和结果未知均有正确行为;每次请求记录操作审计及 Integration Log。
```
## UR#46 资产信息详情字段新增
@@ -1914,7 +1913,7 @@
进入条件统一限速接口、卡和设备详情入口、Gateway联调配置完成。
联调范围:单卡固定speed_level、设备解析当前卡、恢复不限速与限到0kbps区分、设备无当前卡、电信/广电档位映射、联通/移动不支持、Gateway失败/结果未知及审计记录。
联调范围:单卡固定 `code`、恢复不限速与限到0kbps区分、越权卡、Gateway 明确失败/结果未知及审计记录;确认设备端没有限速入口
完成标准Gateway收到的cardNo始终为卡ICCID设备号不会被发送上游结果在页面和审计中可追踪。
```

View File

@@ -0,0 +1,152 @@
# 七月迭代实现与接口对接说明
> 面向:产品、前端、测试和联调人员
> 范围:`deliver-july-iteration-confirmed-scope` 及本期确认“后端已完成,只需前端联调”的需求
> 接口细节:以 [`docs/admin-openapi.yaml`](../admin-openapi.yaml) 为准,本文只说明关键调用和字段变化。
## 一、先看这几个关键结论
1. **设备没有限速接口**:限速只允许对 IoT 卡 ICCID 操作,固定档位 `-18`,不通过设备绑定卡间接限速。
2. **企微模板在企微后台创建**:系统只配置应用、默认发起人、账号 userid 绑定、`template_id` 和控件映射,不在本系统设计审批节点。
3. **代理发起审批走默认发起人**:企微单据使用配置的默认成员发起,但退款、充值等本地业务单仍记录真实代理提交人。
4. **下架套餐续费不新增专用接口**:历史订单和资产信息返回稳定套餐 ID前端仍调用现有 C 端创建订单接口生成一张新订单。
5. **实名流程由后端返回值决定**:前端使用 `effective_realname_policy`,不能按卡或设备自行推断;设备有任意一张有效绑定卡已实名即视为已实名。
6. **支付按钮由后端返回值决定**:前端使用 `allowed_payment_methods`,不要自行写死卡/设备的微信、支付宝或钱包规则。
7. **设备批量分配只复用导入任务外壳**:复用任务表、队列、进度和结果页;不会进入原 Excel 创建设备逻辑。
8. **系列套餐批量授权后端原本就支持多选**:前端把多选套餐组装为 `packages[]` 调现有接口即可,不需要新后端接口。
## 二、本期需求怎么实现
### 2.1 本期新增或修改后端的需求
| 需求 | 实现方式 | 关键口径检查 |
| --- | --- | --- |
| #189 换货后退款套餐未失效 | 退款处理不再只按旧资产查套餐,而是按原订单和换货迁移关系定位新资产上的对应套餐权益 | 只失效该退款订单产生的权益,不影响其他订单套餐;无前端改动 |
| #188 换货 C 端提醒 | 创建物流换货单时写可靠通知事件,继续走现有 C 端站内通知和未读弹窗 | 不做营销投放、ERP、自动创建其他单据 |
| #182/#44 提交人和审批展示 | 退款、代理充值、换货列表/详情批量解析提交人 ID 和名称;企微详情已具备将审批节点 userid 批量映射系统账号的内部能力 | 当前退款/充值业务 DTO 只稳定返回提交人和审批状态,尚未直接返回审批节点人员列表;如页面必须展示具体审批人,仍需把已有投影接入业务查询 |
| #181 订单渠道和资产标识 | C 端新订单保存正确 `purchase_role`;卡返回 ICCID设备优先 VirtualNo、为空时返回 IMEI | 不用 SN 冒充订单设备标识;历史空数据不伪造 |
| #41 店铺 C 端登录限制 | 店铺增加 `client_login_disabled`C 端验证资产后、签发短期令牌前检查所属店铺 | 只阻止新登录,不吊销已有 Token平台库存保持原行为 |
| #53 卡/设备实名筛选 | 卡按自身实名状态过滤;设备通过有效绑定卡 `EXISTS` 实时判断 | 设备任意一张有效绑定卡已实名即为已实名;未建投影或 Worker |
| #57 退款中禁止换货 | 在现有换货创建入口前检查资产未终结退款 | 拒绝文案为“该资产存在退款申请”;不依赖企微实时接口 |
| #62 三种实名顺序 | 保留 `none/before_order/after_order`,补齐卡和设备最多 500 条批量修改C 端返回生效策略 | 批量全成全败;设备和下卡冲突时以设备策略为准 |
| #97 主钱包低余额预警 | 消费主钱包扣款事实,余额首次从不少于 100 元跌破 100 元时通知店铺业务员 | 阈值以下不重复;恢复后再次跌破可再次提醒;无业务员不猜接收人 |
| #33 套餐临期提醒 | 每日计算 15/7/3 天节点,提供后台/代理临期列表及数量,并向个人客户发送站内通知 | 高亮为 815、47、03 天03 天优先;不发企微业务员提醒 |
| #34 员工线下代充值 | 原充值创建入口在 `offline` 场景创建通用审批实例和企微提交事件;通过后幂等入主钱包 | 在线扫码充值后置;真实提交人、金额和凭证明文业务快照保留 |
| #35 退款企微审批 | 原退款申请关联唯一通用审批实例,企微标准终态驱动现有退款处理 | 不做原路退款;重复回调/轮询不会重复退款或失效套餐 |
| #37 企业微信审批 | 完成应用连接、通讯录同步、账号绑定、默认发起人、模板映射、提交、回调、详情查询和轮询恢复 | 模板/审批人规则由企微维护;超时结果未知不盲目重提 |
| #36 批量订购套餐 | 单列 CSV整批选择一个套餐和支付方式走独立异步任务逐行复用现有订单和钱包规则 | 不选择代理,不在 CSV 中逐行指定套餐;部分失败不影响其他行 |
| #40 下架套餐老客户续费 | 普通可购列表排除下架套餐;当前使用者可用历史订单或当前资产返回的套餐 ID 调现有下单接口创建新订单 | 无专用续费接口;新客户和代理代购仍拒绝;历史订单不修改 |
| #42 六类导出 | 在现有导出任务框架新增 IoT 卡、套餐、钱包流水、代理充值、退款、换货 datasource | 按现有数据权限和字段来源导出,不建设新字段权限平台 |
| #47 卡固定档位限速 | 后台选择固定档位,按 ICCID 调用 Gateway并记录操作审计和 Integration Log | 仅 IoT 卡;设备无接口;超时返回结果未知并人工核对 |
| #48 按资产类型配置支付方式 | `system_config` 分别保存卡、设备允许的 `wallet/wechat/alipay` 集合C 端返回业务场景交集,订单端再次校验 | 至少保留一种;强充和普通充值剔除钱包;前端不可绕过 |
| #49 设备批量分配 | 扩展现有设备导入任务的 `operation_type`,新增分配代理和设置套餐系列两个 CSV 分支 | CSV 单列 VirtualNo/IMEI/SN复用现有权限、分配、系列绑定和幂等规则 |
### 2.2 后端此前已经完成,主要由前端正确调用或展示
| 需求 | 后端现状 | 前端要做什么 |
| --- | --- | --- |
| #45 换货新旧资产展示/搜索 | 换货列表已分别返回新旧资产,并支持两个独立搜索参数 | 分别提供“旧资产”和“新资产”搜索框,不要继续共用一个字段 |
| #46 预计套餐到期 | 资产详情、C 端资产信息和相关列表已返回预计最终到期字段 | 展示 `estimated_final_expires_at`;按 `is_expiring` 或剩余天数高亮,不要只显示当前套餐到期时间 |
| #55 套餐分配生效条件 | 套餐和分配接口已支持默认值、覆盖值和最终生效值 | 创建/编辑套餐传 `expiry_base`;分配时传 `expiry_base_override`,展示 `effective_expiry_base` |
| #60 店铺联系电话搜索 | 店铺列表已支持 11 位联系电话精确查询 | 将输入值作为 `contact_phone` 查询参数传给店铺列表接口 |
| #86 资产换货标识和跳转 | 资产解析接口已返回 `exchange_trace.previous_asset/next_asset``can_view` | 仅 `can_view=true` 且存在资产 ID 时允许跳转;该需求前端已对接可保持现状 |
| #38 代理信用额度 | 角色默认额度、店铺实际额度、资金概况和负可用余额均已有接口 | 使用分单位字段;更新时携带钱包 `version`;余额为负数时正常展示 |
| #94 状态同步和运营商回调 | 后端回调、定时触发和原轮询链路已装配 | 通常无前端新调用;状态页面继续读取现有资产状态字段 |
| #96 店铺业务员 | 店铺创建/更新、候选人、列表/详情和筛选都已支持业务员 | 创建/编辑店铺选择 `business_owner_account_id`;列表可按该 ID 筛选并展示名称 |
| #98 换货新资产继承旧店铺 | 换货完成时后端自动继承旧资产店铺归属 | 前端继续调用原换货完成接口,不新增分配步骤 |
| #43 系列套餐批量授权 | 创建授权和管理套餐接口均支持 `packages[]`,单次 1100 项 | 页面实现套餐多选,一次提交整个数组;删除项使用 `remove=true` |
> 注意:#44 的“提交人”已经可以直接对接;“审批人”目前不是退款、充值列表的稳定返回字段。后端已经能从企微详情快照解析并映射 userid但当前前端不能把 `processor_id` 当作完整企微审批人列表。
### 2.3 本期明确不由后端处理
- #84 H5 首页隐藏设备下 ICCID纯前端显示调整但本期范围确认标记为“不做”。
- #63 授权列表滚动条和字段顺序:纯前端页面调整,需求已关闭。
- #73 行业卡未实名复机:后端保持原有行业卡放行逻辑,不改接口、不改前端。
- #99 原路退款、#52 聚水潭、#51 跨品类换货、#39 分销码/佣金提现:本期不做。
- #168#90#75#64:已关闭,本期不重新修改。
## 三、需求与接口对接表
### 3.1 资产、店铺、订单和换货
| 需求 | 接口 | 参数或返回变化 / 前端调用说明 |
| --- | --- | --- |
| #41 登录限制 | `PUT /api/admin/shops/:id``GET /api/admin/shops``GET /api/admin/shops/:id` | 更新请求增加可选 `client_login_disabled`;列表/详情返回同名布尔值。C 端仍调 `POST /api/c/v1/auth/verify-asset`,受限时直接展示后端错误,不会返回资产令牌 |
| #53 实名筛选 | `GET /api/admin/iot-cards/standalone``GET /api/admin/devices` | 查询参数增加 `real_name_status=0|1`;响应已有 `real_name_status``real_name_status_name` |
| #62 实名顺序 | `PATCH /api/admin/assets/:identifier/realname-mode``POST /api/admin/iot-cards/batch-update-realname-policy``POST /api/admin/devices/batch-update-realname-policy` | 单条传 `realname_policy`;批量传 `asset_ids[] + realname_policy`,最多 500 条 |
| #62/#48 C 端初始化 | `GET /api/c/v1/asset/info?identifier=...` | 使用 `effective_realname_policy``realname_required``real_name_status``allowed_payment_methods`;前端不要自行覆盖 |
| #45 换货搜索 | `GET /api/admin/exchanges` | 使用 `old_asset_keyword``new_asset_keyword` 两个独立参数,可同时传并按 AND 组合 |
| #57/#98 换货 | `POST /api/admin/exchanges``POST /api/admin/exchanges/:id/complete` | 请求结构不变;存在退款时创建接口返回业务错误;完成后店铺归属由后端继承 |
| #188 换货提醒 | `GET /api/c/v1/notifications/unread-count``GET /api/c/v1/notifications``PUT /api/c/v1/notifications/:id/read` | 无新增通知接口;前端继续使用现有未读数、列表和已读接口弹窗展示 |
| #181 订单字段 | `GET /api/admin/orders``GET /api/admin/orders/:id``GET /api/c/v1/orders``GET /api/c/v1/orders/:id` | 返回正确 `purchase_role``asset_identifier`;设备标识为 VirtualNo 优先、IMEI 兜底 |
| #40 下架套餐续费 | `GET /api/c/v1/asset/info``GET /api/c/v1/orders``GET /api/c/v1/orders/:id``POST /api/c/v1/orders/create` | 资产信息返回 `current_package_id`,历史订单返回 `package_ids`;前端把选中的套餐 ID、资产 `identifier` 和当前允许的 `payment_method` 传给原创建订单接口 |
| #46/#86 资产展示 | `GET /api/admin/assets/resolve/:identifier``GET /api/c/v1/asset/info` | 返回预计最终到期字段;后台解析额外返回 `exchange_trace`,跳转前检查 `can_view` |
### 3.2 店铺业务员、信用和套餐授权
| 需求 | 接口 | 参数或返回变化 / 前端调用说明 |
| --- | --- | --- |
| #60 联系电话搜索 | `GET /api/admin/shops?contact_phone=11位号码` | 精确查询;可与店铺名称、编号等条件组合 |
| #96 店铺业务员 | `GET /api/admin/shops/business-owner-candidates``POST /api/admin/shops``PUT /api/admin/shops/:id``GET /api/admin/shops` | 创建/更新传 `business_owner_account_id`;列表可用同名参数筛选,响应展示账号 ID、名称和可用状态 |
| #38 信用额度 | `PUT /api/admin/roles/:id/default-credit``PUT /api/admin/shops/:id/credit-limit``GET /api/admin/shops/fund-summary` | 角色接口配置新建代理默认值;店铺接口传 `credit_enabled + credit_limit + version`;金额单位均为分 |
| #55 套餐默认生效条件 | `POST /api/admin/packages``PUT /api/admin/packages/:id``GET /api/admin/packages/:id` | 请求使用 `expiry_base=from_activation|from_purchase`;响应展示默认生效条件名称 |
| #55 分配覆盖 | `POST /api/admin/shop-package-batch-allocations``PATCH /api/admin/shop-package-allocations/:id/expiry-base` | 分配时使用 `expiry_base_override``null` 表示跟随套餐默认值 |
| #43 系列套餐多选 | `POST /api/admin/shop-series-grants``PUT /api/admin/shop-series-grants/:id/packages` | `packages` 是 1100 项数组,每项包含 `package_id``cost_price`,删除时传 `remove=true` |
### 3.3 审批、退款和员工线下代充值
| 需求 | 接口 | 参数或返回变化 / 前端调用说明 |
| --- | --- | --- |
| #182/#44 退款 | `GET /api/admin/refunds``GET /api/admin/refunds/:id` | 新增/补齐 `submitter_id``submitter_name``approval_provider``approval_status``approval_status_name` |
| #182/#44 充值 | `GET /api/admin/agent-recharges``GET /api/admin/agent-recharges/:id` | 同上;线下代充值的审批状态只读展示 |
| #44 换货 | `GET /api/admin/exchanges``GET /api/admin/exchanges/:id` | 新增/补齐 `submitter_id``submitter_name` |
| #34 员工线下代充 | `POST /api/admin/agent-recharges` | 仍用原入口;`payment_method=offline` 时传目标 `shop_id`、金额、15 个 `payment_voucher_key` 和备注,创建后等待企微审批 |
| #35 退款申请 | `POST /api/admin/refunds` | 仍用原入口;请求结构保持订单、实收金额、申请金额、凭证、原因等业务字段,创建后等待企微审批 |
| #34/#35 旧按钮 | `POST /api/admin/agent-recharges/:id/offline-pay``POST /api/admin/refunds/:id/approve|reject` | 仅兼容存量旧审批记录;企微记录前端不得显示这些操作按钮,最终按发布配置停用 |
| #37 企微应用 | `POST/GET /api/admin/wecom/applications``POST /api/admin/wecom/applications/:id/test` | 配置 corp_id、agent_id、Secret、回调 Token、EncodingAESKey管理端按明文填写 |
| #37 默认发起人和成员 | `POST /api/admin/wecom/applications/:id/members/sync``GET /api/admin/wecom/applications/:id/members``PUT /api/admin/wecom/applications/:id/default-creator` | 先同步成员,再从可见成员中选择默认 `userid` |
| #37 账号绑定 | `PUT /api/admin/accounts/:id/wecom-binding` | 管理员选择应用可见成员,绑定 `(corp_id,userid)`;不做扫码绑定 |
| #37 场景模板 | `PUT /api/admin/wecom/scenes/:business_type``GET /api/admin/wecom/scenes` | `business_type``refund_approval``offline_recharge_approval`;传 `application_id``template_id``control_mapping[]` |
| #37 回调 | `GET/POST /api/callback/wecom/approval/:application_id` | 由企微服务器调用,前端无需调用 |
### 3.4 通知、批量任务、导出和 Gateway
| 需求 | 接口 | 参数或返回变化 / 前端调用说明 |
| --- | --- | --- |
| #97 后台低余额通知 | `GET /api/admin/notifications/unread-count``GET /api/admin/notifications``PUT /api/admin/notifications/:id/read` | 复用现有后台通知接口;业务员账号正常展示低余额通知 |
| #33 临期列表 | `GET /api/admin/expiring-assets` | 支持资产类型、关键词、店铺、套餐、剩余天数和日期范围;响应含 `summary``expiry_level``is_priority` |
| #33 C 端提醒 | `GET /api/c/v1/notifications/unread-count``GET /api/c/v1/notifications` | 复用现有站内通知,前端在 15/7/3 天节点按未读通知弹窗 |
| #36 批量订购上传 | `POST /api/admin/storage/upload-url` | `purpose=batch_purchase`,上传 UTF-8 单列 CSV 后取得 `file_key` |
| #36 批量订购任务 | `POST /api/admin/asset-package-batch-orders``GET /api/admin/asset-package-batch-orders``GET /api/admin/asset-package-batch-orders/:id` | 创建传 `file_key + package_id + payment_method`,线下支付另传 `voucher_keys[]`;详情返回逐行结果 |
| #42 业务导出 | `POST /api/admin/export-tasks``GET /api/admin/export-tasks``GET /api/admin/export-tasks/:id` | `scene` 使用 `iot_card/package/agent_wallet_transaction/agent_recharge/refund/exchange`,筛选条件放 `query` |
| #47 卡限速 | `PUT /api/admin/iot-cards/:iccid/speed-tier` | 请求只传 `code=-1..8`;设备页面不要展示限速入口 |
| #48 后台支付配置 | `GET /api/admin/system-configs``PUT /api/admin/system-configs/:key` | Key 为 `c2b.payment.card_allowed_methods``c2b.payment.device_allowed_methods`;更新请求的 `value` 是 JSON 数组字符串 |
| #48 C 端支付 | `GET /api/c/v1/asset/info``GET /api/c/v1/wallet/recharge-check``POST /api/c/v1/orders/create``POST /api/c/v1/wallet/recharge` | 展示和提交都使用后端返回的 `allowed_payment_methods`;创建订单时 `payment_method` 必传,微信场景按接口要求传 `app_type` |
| #49 分配 CSV 上传 | `POST /api/admin/storage/upload-url` | `purpose=device_batch_allocation`,上传单列 CSV 后取得 `file_key` |
| #49 创建设备分配任务 | `POST /api/admin/devices/import/allocations` | 传 `file_key + operation_type + target_id``operation_type=assign_shop|assign_series` |
| #49 查询任务 | `GET /api/admin/devices/import/tasks``GET /api/admin/devices/import/tasks/:id` | 复用原设备导入任务页面,新增展示 `operation_type``operation_name``target_id``status_name` |
## 四、前端本期最容易漏掉的工作
- 换货列表拆成新、旧资产两个搜索参数。
- 资产预计到期展示使用“预计最终到期”,并按临期字段高亮。
- 套餐分配页面传递默认/覆盖生效条件。
- 店铺页面接入联系电话查询、业务员选择和 C 端登录限制开关。
- 系列套餐授权页面真正使用现有 `packages[]` 做多选提交。
- C 端实名流程只读取 `effective_realname_policy`
- C 端支付按钮只读取 `allowed_payment_methods`
- 历史订单续费继续调用原创建订单接口,不等待新续费接口。
- 企微退款和线下代充值只读展示审批状态,隐藏本地人工审批按钮。
- 卡页面提供固定档位限速;设备页面不得出现限速入口。
- 设备批量分配继续复用原设备导入任务列表/详情页面,但根据 `operation_type` 改标题和结果说明。
## 五、联调和验收边界
- 当前有两个需要在联调时明确的接口边界:
- #44:退款/充值列表已经返回提交人和审批状态,但没有直接返回企微审批节点人员列表;现有 userid 映射能力尚未接入这两个业务 DTO。
- #49:设备批量分配创建服务允许平台和代理账号,但复用的设备导入任务列表/详情 Handler 目前仍沿用“仅平台用户可查看”的旧限制。若本期只允许平台操作则前端应隐藏代理入口;若要求代理自行查看任务,需要再统一后端权限。
- OpenAPI 已生成,新增路径和 DTO 已检查;设备限速旧契约不存在。
- 本次没有执行数据库迁移、完整构建、自动化测试、LSP 或真实企微/Gateway 闭环。
- 企微、Gateway、Redis/Asynq、对象存储配置和回滚步骤见 [`七月迭代联调交付说明.md`](七月迭代联调交付说明.md)。
- 涉及金额的字段默认单位为分;前端展示时统一转换,提交时不要传浮点元金额。

View File

@@ -0,0 +1,126 @@
# 七月迭代联调交付说明
## 交付状态
本说明覆盖 `deliver-july-iteration-confirmed-scope` 的企业微信、Gateway、Redis/Asynq、对象存储和前端联调输入。生产代码、增量迁移和 OpenAPI 已生成至可联调状态;测试库已执行至 `000194` 并完成结构核对尚未执行自动化测试、完整构建、LSP 或真实外部环境闭环。
接口统一使用 `{code,msg,data,timestamp}` 响应。完整请求和响应结构以 `docs/admin-openapi.yaml` 为准。
## 企业微信联调
### 环境和管理配置
| 配置 | 来源 | 说明 |
| --- | --- | --- |
| `JUNHONG_WECOM_BASE_URL` | 环境变量 | 默认 `https://qyapi.weixin.qq.com` |
| `JUNHONG_WECOM_TIMEOUT` | 环境变量 | 默认 `10s` |
| `JUNHONG_WECOM_CREDENTIAL_ENCRYPTION_KEY` | 环境变量 | 32 字节随机密钥的 Base64 文本;更换前必须先完成历史凭据重加密 |
| `corp_id``agent_id`、Secret | `POST /api/admin/wecom/applications` | 管理端按明文提交,服务端加密保存;超级管理员读取时返回明文,业务日志不记录 |
| 回调 Token、EncodingAESKey | 同上 | Token 按明文提交EncodingAESKey 固定 43 位 |
| 默认发起人 | `PUT /api/admin/wecom/applications/:id/default-creator` | 必须先同步可见成员,再从当前可见成员中选择 |
| `template_id` 和控件映射 | `PUT /api/admin/wecom/scenes/:business_type` | 模板必须先在企微后台创建,本系统只校验和绑定 |
部署侧还必须在企微管理后台配置:自建应用审批权限、应用可见通讯录范围、调用接口的可信 IP以及公开可访问的回调地址
```text
GET/POST {API_PUBLIC_BASE_URL}/api/callback/wecom/approval/{application_id}
```
### 配置和联调顺序
1. 配置加密 Key部署 API 和 Worker。
2. 创建应用配置并调用 `POST /api/admin/wecom/applications/:id/test` 验证取 token。
3. 调用 `POST /api/admin/wecom/applications/:id/members/sync`,再分页查询成员。
4. 为内部系统账号调用 `PUT /api/admin/accounts/:id/wecom-binding` 绑定 `(corp_id,userid)`
5. 选择一个当前可见成员作为默认发起人。代理退款、代理相关业务以及未绑定内部员工均使用该成员发起,但本地业务单仍保存真实提交人。
6. 分别配置 `refund_approval``offline_recharge_approval``template_id` 和控件映射。选择控件必须填写企微模板真实 option key。
7. 在企微后台配置回调 URL、Token、EncodingAESKey完成 GET 校验。
8. 分别提交一笔退款和员工线下代充值,验证 `applyevent``sp_no`、回调、详情同步、标准终态和业务终态。
Integration Log 不记录 Secret、access_token、media_id、附件正文或完整企微响应普通业务字段和业务快照按明文保存便于业务处理。
### 结果未知和旧入口
- `applyevent` 超时或断连后标记为结果未知不自动创建第二张审批单Worker 通过时间窗单号和详情查询恢复。
- `wecom:approval:recovery` 每 2 分钟触发,详情同步使用 `wecom:approval:sync`
- 在真实退款和线下代充值闭环、存量 provider 清单均验证前,保持 `JUNHONG_APPROVAL_LEGACY_REFUND_MANUAL_ENABLED=true``JUNHONG_APPROVAL_LEGACY_OFFLINE_RECHARGE_PAY_ENABLED=true`
- 切换后前端只读展示 `approval_provider``approval_status``approval_status_name`,不得再提供企微记录的本地人工通过、驳回或线下确认按钮。
## Gateway 卡限速联调
| 环境变量 | 说明 |
| --- | --- |
| `JUNHONG_GATEWAY_BASE_URL` | Gateway API 基础地址 |
| `JUNHONG_GATEWAY_APP_ID` | Gateway 应用 ID |
| `JUNHONG_GATEWAY_APP_SECRET` | Gateway 应用密钥 |
| `JUNHONG_GATEWAY_TIMEOUT` | 超时秒数,允许 5300默认配置为 60 |
接口固定为:
```text
PUT /api/admin/iot-cards/:iccid/speed-tier
```
请求只允许 `code=-1..8`Gateway 业务参数只有卡 ICCID 对应的 `cardNo` 和档位 `code`。设备没有限速接口,也不得通过设备绑定关系间接限速。
联调需覆盖全部档位、越权卡、明确失败和超时。超时返回结果未知时,按 Integration Log 中的 ICCID 到 Gateway 运维侧核对当前档位,再决定是否人工重试;系统不会盲目自动重发。
## Redis、Asynq 和 Worker
API 与 Worker 必须连接同一 Redis/Asynq。新增或复用的任务如下
| 任务类型 | 队列 | 用途 |
| --- | --- | --- |
| `wecom:approval:sync` | `wecom:approval` | 拉取企微详情并同步标准决策 |
| `wecom:approval:recovery` | `wecom:approval` | 结果未知恢复和未终态轮询 |
| `asset:package:batch_order` | 同名独立队列 | 单列 CSV 批量订购 |
| `device:import` | 同名独立队列 | 原设备导入和设备 CSV 批量分配共用任务外壳,通过 `operation_type` 分支 |
| `package:expiry:reminder` | `data:cleanup` | 每日 15/7/3 天套餐临期提醒 |
| `export:dispatch/shard/finalize` | 各自既有队列 | 六类新增 datasource 继续复用导出流水线 |
联调时确认 Worker 启动日志已注册上述 Handler`JUNHONG_WORKER_ROLE` 的部署拓扑为单实例 `all`,或严格一个 `leader` 加多个 `consumer`
## 对象存储和 CSV
先调用 `POST /api/admin/storage/upload-url` 获取预签名地址,再把文件直传对象存储,业务接口只接收返回的 `file_key`
| purpose | 业务 | 文件要求 |
| --- | --- | --- |
| `batch_purchase` | 资产套餐批量订购 | UTF-8 单列 CSV最多 1000 行、10MB |
| `device_batch_allocation` | 设备分配代理或设置套餐系列 | UTF-8 单列 CSV支持 VirtualNo、IMEI、SN最多 1000 行、10MB |
对象存储需配置 `JUNHONG_STORAGE_PROVIDER`、S3 endpoint/region/bucket/access key/secret key、SSL/path style 和预签名有效期。Worker 必须具备下载相同私有对象的权限。
## 前端接口和字段
| 场景 | 前端接入要点 |
| --- | --- |
| 店铺登录限制 | `PUT /api/admin/shops/:id``client_login_disabled`;列表和详情同字段回显,只阻止新登录,不踢出已有 Token |
| 实名策略 | 卡、设备分别调用 `POST /api/admin/iot-cards/batch-update-realname-policy``POST /api/admin/devices/batch-update-realname-policy`;最多 500 条、全成全败 |
| C 端资产初始化 | 使用 `effective_realname_policy``realname_required``realname_status``allowed_payment_methods`,不要在前端重新推断策略 |
| 支付方式配置 | `GET/PUT /api/admin/system-configs` 管理 `c2b.payment.card_allowed_methods``c2b.payment.device_allowed_methods`;至少保留一种 |
| 临期资产 | `GET /api/admin/expiring-assets`,使用数量、高亮和优先标识 |
| 企微配置 | 使用应用、成员同步/选择、默认发起人、账号绑定和场景接口;模板节点和审批人规则仍在企微后台维护 |
| 退款/充值/换货 | 展示 `submitter_id/submitter_name`;退款和充值只读展示企微审批渠道及状态 |
| 订单/退款资产 | 卡展示 ICCID设备优先 VirtualNo、缺失时展示 IMEI订单同时展示 `purchase_role` |
| 批量订购 | 上传 `purpose=batch_purchase`,再调用 `POST /api/admin/asset-package-batch-orders`;任务列表和详情使用统一状态名称 |
| 设备批量分配 | 上传 `purpose=device_batch_allocation`,再调用 `POST /api/admin/devices/import/allocations`;任务查询复用设备导入任务接口并展示 `operation_type/operation_name/target_id/status_name` |
| 业务导出 | `POST /api/admin/export-tasks`;新增场景为 `iot_card``package``agent_wallet_transaction``agent_recharge``refund``exchange` |
| 卡固定限速 | 只在卡页面展示固定档位选择;设备页面不得出现限速入口 |
## 已知限制
- 本系统不创建企微模板、不配置审批节点或审批人规则,也不提供扫码绑定。
- 企微应用只能看到其可见范围内的成员;可见范围或可信 IP 错误会导致连接、绑定或提交失败。
- 卡限速不保存本地当前档位,结果未知必须人工向 Gateway 核对。
- CSV 任务逐行部分成功,不保证整批业务原子性;任务详情是失败和跳过原因的权威展示。
- 店铺登录限制不主动吊销既有 C 端 Token。
- 测试库已完成 `000182``000194` 结构落库和注释核对;其他环境尚未执行迁移,外部系统闭环和前端浏览器验收也未完成。
## 发布和回滚
1. 测试库已执行至 `000194`;其他环境发布时仍须按迁移顺序执行并核对最终版本和表结构。
2. 先部署数据库兼容代码、API 和 Worker保持旧审批入口开启再配置企微应用、模板、回调和默认发起人。
3. 真实审批闭环通过后,先隐藏前端旧按钮,再关闭旧入口配置并重启 API。
4. 回滚时先停止新批量任务和新审批提交,等待已领取任务结束,再回退应用版本。新增表和列暂不删除。
5. 已产生的审批、退款、钱包流水、订单、通知、Outbox、Integration Log、设备分配和限速审计均为业务事实不得清表回滚使用前向修复。

View File

@@ -0,0 +1,654 @@
# 七月迭代需求范围确认表
> 用途:由需求负责人逐条确认本期是否实施、按什么口径实施,以及哪些内容明确后置或取消。
>
> 来源:`docs/7月迭代/物联网卡管系统-需求.csv` 当前 41 条记录。其中 36 条挂在七月迭代计划5 条已关闭。
>
> 填写完成后,请通知后端重新审查。本表确认前,不据此修改 `complete-july-iteration-test-release` 或实施业务代码。
## 填写说明
每条需求只勾选一个“本期决定”,然后在“说明”中补充你的处理意见即可。
本期决定:
- [ ] 本期做:本次迭代必须上线。
- [ ] 已完成,只联调/验收:不再重复开发后端。
- [ ] 后置:需求保留,但不阻塞本次上线。
- [ ] 不做:取消或移出当前产品范围。
- [ ] 待确认:产品口径仍不清楚,暂不实施。
填写示例:
```markdown
本期决定(单选):
- [x] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:只在现有店铺列表增加联系电话精确筛选。
```
---
## 一、新增、漏项或未被当前提案准确追踪的需求
### #189 换货迁移套餐退款后未正常失效
- 原始需求:换货后的新卡继承旧卡套餐后,对原订单退款,退款通过但套餐没有正常失效。
- 当前判断:提案漏项;属于退款与换货交叉缺陷。
本期决定(单选):
- [x] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:跟前端没关系;这个问题是后端查找路径有问题,按 Bug 修复即可。
### #188 广电管控卡弹窗提醒
- 原始需求:广电风险停机卡在 H5 弹窗提醒换卡并采集收货地址;描述中还包含后台主动投放、自定义营销内容、自动换货单和 ERP 对接设想。
- 当前判断:提案漏项;“风险卡提醒”与“通用营销投放/ERP”应分别确认。
本期决定(单选):
- [x] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:他描述的有远,我们只在已经完成的站内通知的基础上,保证创建物流换货单的时候会在C端弹窗通知用户
### #182 退款和代理充值列表增加提交人
- 原始需求:退款管理和订单/代理充值后台列表增加提交人字段。
- 当前判断:与 #44 部分重复;可先作为简单字段独立交付,不应等待完整企微审批体系。
本期决定(单选):
- [x] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明现在数据库里面存了提交人的ID,在列表跟详情中返回id跟名称就好了
### #181 订单和退款列表缺少资产标识、订单渠道
- 原始需求:设备类订单、退款记录未正确展示资产标识符和订单渠道。
- 当前判断:提案漏项;属于 DTO/查询/展示字段修复。
本期决定(单选):
- [x] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明这算是一个bug,我记得只有C端购买订单的时候会缺少订单渠道,然后退款列表跟退款详情是设备的标识没有正确放入
### #99 退款支持原路退回
- 原始需求:支持原路退款和客户收款凭证退款;原路退款前校验原收款商户退款能力,失败后允许改为凭证退款。
- 当前判断:提案漏项,并与现提案“部分支付方式系统外退款”口径冲突;属于资金业务,需明确真实范围。
本期决定(单选):
- [ ] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [X] 不做
- [ ] 待确认
- 说明:
### #84 H5 首页隐藏设备下 ICCID
- 原始需求:新卡管 H5 首页不再显示设备号下方的 ICCID。
- 当前判断:提案漏项;基本属于纯前端调整。
本期决定(单选):
- [ ] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [X] 不做
- [ ] 待确认
- 说明:跟我们后端没关系
### #52 聚水潭对接
- 原始需求:打通聚水潭订单、发货等数据。
- 当前判断:提案漏项;当前没有接口清单、数据方向和验收标准,不能直接实施。
本期决定(单选):
- [ ] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [X] 不做
- [ ] 待确认
- 说明:现在不做
### #51 不同品类资产换货及补差价
- 原始需求:卡与设备跨品类换货、补差价、旧套餐失效、新资产使用正确品类套餐。
- 当前判断:当前为草稿,旧规划排除;属于独立复杂业务,不适合顺带实现。
本期决定(单选):
- [ ] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [X] 不做
- [ ] 待确认
- 说明:
### #41 代理 API 查询限制
- 原始需求名称存在误导,最终业务口径不是“代理跨级 API 查询限制”。
- 最终口径:为每个店铺提供一个 C 端登录限制开关;开关开启后,该店铺名下的卡和设备不能再发起新的系统 C 端登录。
- 建议最小范围店铺增加配置字段并提供管理员配置入口C 端资产校验成功后、签发短期资产令牌前按资产所属店铺校验。平台库存或未归属店铺的资产保持原行为。
- 明确不做:不重构代理权限体系,不做全局 Token 吊销,不强制已登录用户立即下线,不迁移现有认证模块。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:提供接口针对某个店铺开关;打开后,属于该店铺的资产不能登录系统 C 端。
### #39 代理分销码与佣金提现
- 原始需求:分销归属、分销码、佣金提现及合同/证照/发票材料。
- 当前判断:现提案明确移出本期;其中“员工作为发展人”已由 #96 单独承接。
本期决定(单选):
- [ ] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [X] 不做
- [ ] 待确认
- 说明:
---
## 二、已有后端成果,优先确认前端联调和验收
### #45 换货列表新旧资产展示和独立搜索
- 原始需求:修正新旧资产标识混乱;新旧资产分别支持 ICCID、接入号、虚拟号搜索。
- 当前判断:后端已完成且有测试,主要剩前端和人工验收。
本期决定(单选):
- [ ] 本期做
- [X] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:现在跟我们后端没关系了
### #46 资产预计套餐到期时间
- 原始需求:显示当前生效套餐过期时间,剩余 15 天时高亮。
- 当前实现:后端已实现“当前套餐加排队套餐后的预计最终到期时间”,且有测试。
- 需要确认:接受当前“预计最终到期”口径,还是改回只显示当前生效套餐到期时间。
本期决定(单选):
- [ ] 本期做
- [X] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:现在这个口径是对的,已经跟我们后端没有关系了,接口已经提供给前端
### #55 套餐分配生效条件
- 原始需求:套餐支持购买即生效或实名即生效,分配时可覆盖条件。
- 当前判断:后端已完成且有测试。
本期决定(单选):
- [ ] 本期做
- [X] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:已经提供给前端对接了,跟我们没关系了
### #60 店铺联系电话搜索
- 原始需求:店铺列表增加联系电话检索。
- 当前判断:后端已沿用旧 Store 完成精确查询并有测试,符合简单需求处理方式。
本期决定(单选):
- [ ] 本期做
- [X] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:已经提供给前端接口,跟后端没有关系了
### #73 行业卡允许未实名复机
- 原始需求:行业卡允许未实名复机。
- 当前实现:旧代码已经按 `card_category=industry` 放行未实名复机。
- 提案偏差:现提案准备改成按运营商 `realname_link_type` 判断,可能反向改变原需求。
本期决定(单选):
- [ ] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [X] 不做
- [ ] 待确认
- 说明:先不管这个,只要行业卡能正确的不管有没有实名都能复机即可
### #86 资产详情换货标识与跳转
- 原始需求:详情显示新资产/旧资产换货标识,旧资产可链接新资产。
- 当前判断:后端已完成且有测试,主要剩前端和历史数据人工抽样。
本期决定(单选):
- [ ] 本期做
- [X] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:前端已经对接,现在与后端无关
### #38 代理信用额度
- 原始需求:代理可授权额度、不同额度下限、金额业务使用额度、允许显示负余额。
- 当前判断:后端代码基本完成,但资金链自动化和真实验证延期。
本期决定(单选):
- [ ] 本期做
- [X] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:接口已经提供给前端,具体测试是测试环节的事情,现在与后端无关吧,最好确认一下代码是否完成
### #94 状态同步优化和运营商回调
- 原始需求:因资产迁移优化状态同步和回调,原描述没有具体验收标准。
- 当前判断:后端已完成大范围公共观测和四类运营商回调,但真实运营商/Gateway 验证延期。
本期决定(单选):
- [ ] 本期做
- [x] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明: 现在就算优化完了,有运营商回调,有时间触发,轮询还是保持老样子
### #96 店铺业务员/发展人
- 原始需求:新建店铺可选业务员,列表/详情展示,可按业务员筛选。
- 当前判断:后端代码完成,主要剩前端和验证。
本期决定(单选):
- [ ] 本期做
- [X] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:接口已经提供给前端了,与后端无关
### #98 换货新资产继承旧店铺
- 原始需求:换货时新资产默认继承旧资产归属。
- 当前判断:旧换货 Service 已实现主要归属继承逻辑;提案任务状态滞后,不应再建新的 Domain/分配记录。
本期决定(单选):
- [ ] 本期做
- [X] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:这算做完了,就不要动了,到时候我会统一说创建一个新的提案,把原来的提案废掉
### #43 代理系列套餐批量授权
- 原始需求:支持一次多选,展示建议售价和公司成本价,区分已分配/未分配套餐。
- 当前判断:核心批量授权、价格和移除兼容能力基本已有;应轻量收口,不从头重构。
本期决定(单选):
- [ ] 本期做
- [X] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:这他妈就是错误的描述,之前我们的接口本身就支持批量多选,但是前端没做,这个需求跟后端没关系
---
## 三、适合沿用现有代码做局部修改的需求
### #53 卡和设备实名状态筛选
- 原始需求:卡管理、设备管理增加已实名/未实名筛选。
- 提案问题:增加设备实名投影、历史初始化、事件消费者和 Worker明显超出简单筛选需求。
- 建议最小范围:优先在现有列表 DTO、Store 查询和返回字段上补筛选;只有现有数据无法准确查询时再讨论快照。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:设备有一个情况是,只要有任意一张卡实名了,就算实名
### #57 存在退款申请时禁止换货
- 原始需求:资产存在未完成退款申请时禁止换货,并提示“该资产存在退款申请”。
- 提案问题:被绑定到尚未完成的全新退款模型和企微审批链。
- 建议最小范围:在现有换货创建入口查询现有退款状态并拦截。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:没有什么特别注意的,越简单达成需求越好
### #62 H5 先充值/先实名流程配置
- 原始需求:进入 H5 先绑定手机号,并可按资产批次选择先充值后实名或先实名后充值。
- 当前判断:已有 `realname_policy`、单资产修改接口和 C 端购买/充值门禁,不应按从零 DDD 建设。
本期决定(单选):
- [x] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明: 这个有点奇怪,之前我跟前端的约定是这样的"目标:支持无需实名、先实名后购买、先购买后实名三种流程,并提供后台批量配置。
预计工时前端23小时。
页面入口C端资产初始化流程后台卡列表和设备列表。
页面结构:
1. C端按 effective_realname_policy 决定直接购买、先实名或购买后提示实名。
2. 后台卡和设备列表分别增加“批量修改实名顺序”入口。
3. 弹框提供无需实名、先实名后购买、先购买后实名三选一,并展示已选数量。
4. 修改设备下卡策略时提示“实际H5流程由设备策略决定”。
接口约定:
- PATCH /api/admin/assets/{identifier}/realname-mode入参 realname_policy:none|before_order|after_order。
- POST /api/admin/iot-cards/batch-update-realname-policy、POST /api/admin/devices/batch-update-realname-policy入参 asset_ids:int64[]、realname_policy:string。
- C端初始化返回 effective_realname_policy:string、realname_required:bool、realname_status:int。
交互规则单次最多500条批量接口全成全败前端不根据资产类型自行覆盖策略。
完成标准三种C端流程和卡/设备批量配置均可运行,冲突数据能展示明确错误。"
### #44 退款、充值、换货列表字段
- 原始需求:退款列表增加提交人/审批人;代理充值列表增加提交人/审批人;换货列表增加提交人。
- 提案问题:将简单字段绑定到通用审批、企微节点、历史回填和新状态模型。
- 建议最小范围:先交付已有数据能够提供的提交人/审批人字段;企微详情和历史快照另行确认。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:这个很关键,提交人我们现在就按照现在的有,只是存了id没有存名称,相关接口也没有返回,至于审批人,我们没办法拿到,这是企微模版中已经做好的,所以不用加审批人,或者说如果我们能通过模版拿到审批人企微的id,同时又跟我们系统的账号绑定了的话,就能正常展示审批人,这个看怎么搞,反正不能搞复杂了,我觉得就是一个很简单的,现有的逻辑都有了,只是把审批通过从我们系统中变成到企微中
### #97 代理钱包余额预警
- 原始需求:不同代理可配置不同预警额度,达到阈值时提醒代理及其发展人。
- 提案偏差:被改成固定 100 元且不提供阈值配置。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:这个主要是发站内通知,站内通知的功能好像已经做完了,这个就是低于100元的时候提醒发展人(业务员,创建店铺的时候选择的)
---
## 四、确有复杂业务,但需要重新确认原始口径
### #33 套餐临期提醒
- 原始需求每日计算15/7/3 天节点;企业客户企微推送业务员;代理端数量/高亮/置顶C 端续费提醒。
- 提案偏差:企业微信提醒被排除,只保留站内通知。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:这个得做,我们只做站内提醒,还有代理端数量/高亮/置顶(我记得现在好像是单独开一个临期列表吧,后台管理跟代理端都要),然后C端那边的话就是这几个时间点站内通知弹窗提醒
### #34 代理在线充值与员工线下代充值
- 原始需求:代理提交充值后扫码支付;员工线下代充值走部门领导、财务审批并通知结果。
- 当前判断:业务未完成;在线支付、资金入账和线下审批应分别确认。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:在线充值可以后置,员工线下代充这个其实就是走企微审批,现在我记得是做了我们系统的审批,不知道怎么做的,好像是做成灵活的,未来可以接任何第三方的,现在不要考虑那么多了,先赶紧按照企微的审批做完再说别的
### #35 退款审核
- 原始需求:员工申请,部门领导和财务顺序审批,逐环节企微提醒,通过/驳回通知申请人。
- 当前判断:业务未完成;与 #37 共用审批能力,不应建立第二套审批系统。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:这个其实也是企微审批,退款本身我们已经做了,我记得退款好像本身也有审批吧,只是说我们让前端做成权限的了,谁能看见谁就能通过来着,现在就是把企微审批接进来
### #36 批量订购套餐
- 原始需求:内部员工上传 Excel文件含资产类型、资产标识、套餐系列、套餐、代理、支付账户校验后扣款订购并展示失败明细。
- 提案偏差:改成单列 CSV不选择代理整批只选一个套餐和支付方式。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:这个"改成单列 CSV不选择代理整批只选一个套餐和支付方式。"是对的
### #37 企业微信审核流转
- 原始需求:充值和退款多级审批、待办提醒、逐环节通知、结果通知,并接入企业微信。
- 当前判断:只完成渠道无关审批核心,企业微信 Adapter、绑定、模板、回调和轮询均未完成。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:是的剩下的东西都要完成。企微审批模板由管理员在企微后台创建,系统只配置“业务场景与企微模板”的绑定并按模板发起审批,不在本系统新建审批模板或设计审批节点。账号身份不采用用户扫码自助绑定;通过企微通讯录接口获取成员,在系统账号列表中由管理员维护系统账号对应的企微 userid。退款、员工线下代充等业务发起审批后通过企微回调接收结果并保留查询审批详情/轮询作为回调丢失时的补偿。是否能取得审批人 userid 并映射为系统账号名称,以企微官方接口实际返回能力为准,不能为列表展示另建复杂审批人模型。
### #40 下架套餐老客户续费
- 原始需求:正在使用下架套餐的客户仍可自行续费;新客户不可购买;代理不可代购。
- 当前判断:未完成;有购买资格校验,但不需要迁移整个套餐模块。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:这个要做,主要是提供一个续费接口,只有通过这个接口才能去购买下架后的套餐(我记得是这样设计的),然后确保C端的可购套餐列表中没有下架的套餐,其次就是可以在历史订单里面续费,应该也是用同一个接口
### #42 导出功能
- 原始需求:分别支持 lot 卡、钱包流水、套餐、退款、换货、代理充值六类导出及指定字段。
- 提案问题:将六个独立导出需求扩大成统一字段权限平台,并依赖多个未完成业务。
- 建议:按业务场景逐个交付,优先使用现有导出框架,不阻塞在“统一平台全部完成”。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:这个没啥好说的,确保按照我们有的字段,以及业务要求的字段去导出即可,可能需要探索一下,如果有字段我们没有,需要决定一下是否要加
### #47 限速规则
- 原始需求:根据不同运营商规则,基于套餐流量设置卡/设备限速规则。
- 提案偏差:改成后台手动选择固定档位并调用 Gateway明确排除自动限速。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明:改成后台在 IoT 卡详情手动选择固定档位并调用 GatewayGateway 只支持按卡 ICCID 限速,设备没有限速接口,也不通过设备绑定卡间接限速
### #48 按资产类型限制支付方式
- 原始需求:卡只允许支付宝/钱包,拒绝微信;设备只允许微信/钱包,拒绝支付宝。
- 当前判断:未完成;前端展示和后端订单/支付强校验都需要实施。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明这个其实就是在system_config里面做一个参数修改而已,通过这个参数可以决定卡/设备的支付方式限制,这个我们的迭代方案中好像说明是对的,其他的就是在C端不知道有没有东西能让前端判断展示哪些支付方式了
### #49 设备批量分配代理和套餐系列
- 原始需求:上传 Excel以设备号批量分配代理或套餐系列。
- 提案偏差:改成 CSV、异步五态任务、对象存储和失败明细平台。
本期决定(单选):
- [X] 本期做
- [ ] 已完成,只联调/验收
- [ ] 后置
- [ ] 不做
- [ ] 待确认
- 说明是改成csv了,其他跟现在导入没有什么区别,就是业务不一样
---
## 五、已关闭需求回归确认
以下 5 条在 CSV 中未挂七月计划且已关闭。默认不重新开发;如本次需要回归,请勾选。
### #168 停机阈值显示
- 原始需求:虚流量停机阈值显示为真流量总量。
本期决定(单选):
- [ ] 仅回归
- [ ] 重新修改
- [X] 不处理
- 说明:已经做过了
### #90 资产详情敏感字段展示调整
- 原始需求:代理/企业只显示运营商名称,不显示运营商账户;代理不显示设备实名策略和制造商。
本期决定(单选):
- [ ] 仅回归
- [ ] 重新修改
- [X] 不处理
- 说明:
### #75 支付配置命名调整
- 原始需求:“微信配置”改名为“支付配置”,同步权限编码和路由命名。
本期决定(单选):
- [ ] 仅回归
- [ ] 重新修改
- [X] 不处理
- 说明:
### #64 H5 设备支持支付宝
- 原始需求H5 设备支付增加支付宝。
本期决定(单选):
- [ ] 仅回归
- [ ] 重新修改
- [x] 不处理
- 说明:
### #63 授权列表滚动条和字段顺序
- 原始需求:代理系列授权套餐列表增加滚动条,调整后台资产字段展示顺序。
本期决定(单选):
- [ ] 仅回归
- [ ] 重新修改
- [x] 不处理
- 说明:
---
## 六、填写完成后
填写完成后通知后端复核即可。后端将根据选择结果重新整理 OpenSpec 提案和实施顺序。

View File

@@ -0,0 +1,202 @@
# 企业微信审批官方接口调研
> 调研范围:企业微信开发者中心官方文档
> 访问日期2026-07-24
> 结论口径:文中“官方明确”均来自企业微信官方页面;“建议”是基于官方约束形成的系统接入方案,不代表企业微信额外承诺。
## 一、结论摘要
1. 管理员手工绑定系统账号与企业微信成员是可行的。系统应保存企业标识与 `userid` 的绑定关系,并用姓名、部门辅助管理员辨认。`userid` 是企业内唯一、对应管理端账号的成员标识;手机号和邮箱属于敏感字段,不能假定一定能取得,也不应作为唯一绑定依据。[读取成员][1]
2. 审批模板通常可以在企业微信管理后台维护,模板 ID 可从模板编辑页 URL、审批回调或审批详情取得系统再调用“获取审批模板详情”读取控件 ID、类型、必填属性和选项 key。自建应用和代开发应用也可以通过接口创建模板因此“模板只能由管理员在后台创建”的设想不成立但第三方应用不支持创建模板接口。[获取审批模板详情][6] [创建审批模板][7]
3. 系统发起审批时,必须使用已绑定且位于应用可见范围内的申请人 `userid`,提交模板 ID、审批流程选择、控件值和摘要。附件须先上传为临时素材再将返回的 `media_id` 作为附件控件的 `file_id` 提交。[提交审批申请][8] [上传临时素材][9]
4. 审批结果同步不能只依赖回调。官方明确说明回调不能保证 100% 成功,应采用“回调实时处理 + 批量获取审批单号 + 获取审批详情”的主动补偿机制。[回调配置][12] [批量获取审批单号][11] [获取审批申请详情][10]
5. 上线前必须具备正确应用 Secret、按应用缓存的 `access_token`、审批接口权限、应用可见范围、可信 IP以及可完成签名校验和 AES 解密的回调服务。[开发前必读][15] [获取 access_token][14] [审批状态变化回调][13]
## 二、通讯录能力与手工绑定方案
### 2.1 官方接口能取得什么
| 信息 | 官方能力 | 主要限制 |
| --- | --- | --- |
| `userid` | “读取成员”返回成员标识;“获取部门成员/详情”可按部门返回成员;“获取成员 ID 列表”可分页返回 `userid` 与部门 ID 关系 | 只能读取应用可见范围;“获取成员 ID 列表”只支持“通讯录同步 secret”调用。[读取成员][1] [获取部门成员][2] [获取成员 ID 列表][4] |
| 姓名 | 自建应用可在权限范围内通过成员接口取得;代开发自建应用需要管理员授权 | 第三方应用通常不能直接取得真实姓名,接口可能以 `userid` 代替,需要使用通讯录展示组件。[读取成员][1] |
| 部门 | 成员接口返回部门 ID部门成员接口也返回成员所属部门列表 | 只返回应用有查看权限的部门;要取得部门名称还需结合部门列表接口。成员授权模式下,部门信息还可能固定为根部门。[读取成员][1] [获取部门列表][5] |
| 手机号、邮箱 | 接口字段存在;自建应用与代开发应用可在满足授权条件后获取 | 2022-06-20 之后新建的自建应用和代开发应用,敏感字段需管理员在应用详情选择,并由成员通过 OAuth2 授权;第三方应用不可通过“获取访问用户敏感信息”取得手机、邮箱。[读取成员][1] [获取访问用户敏感信息][3] |
`userid` 对应企业微信管理端账号,在企业内必须唯一、不区分大小写,长度为 164 字节。对于企业内部自建应用,建议将 `(corp_id, userid)` 作为企业微信身份键;不要仅保存姓名,也不要用手机号或邮箱充当稳定主键。[读取成员][1]
### 2.2 推荐的管理员手工绑定流程
1. 为企业微信自建应用配置足够但最小化的通讯录可见范围。
2. 系统按部门拉取可见成员,向管理员展示 `userid`、姓名和部门。若使用通讯录同步能力,可用“获取成员 ID 列表”分页取得完整 `userid`/部门关系;该接口不能用普通应用 Secret 替代通讯录同步 Secret。[获取部门成员详情][2] [获取成员 ID 列表][4]
3. 管理员在系统账号页面选择一个企业微信成员,系统保存系统账号 ID、企业 ID、`userid`,并保存姓名/部门快照用于展示和审计。
4. 发起审批前再次确认绑定仍有效,且该成员仍在审批调用应用的可见范围内;否则“提交审批申请”会因无权限或提单者不可见失败。[提交审批申请][8]
5. 手机号、邮箱只能作为获得成员明确授权后的辅助核对信息。没有敏感字段时,绑定流程仍应可完成。[获取访问用户敏感信息][3]
此方案是“管理员明确选择并绑定”,不是依据姓名、手机号自动猜测成员。重名、敏感字段缺失和通讯录权限变化都使自动匹配存在误绑风险。
## 三、审批模板与控件配置
### 3.1 模板从哪里来
企业微信提供两条路径:
- 管理后台创建和维护:模板 ID 可从模板编辑页面的浏览器 URL 取得,也会出现在审批状态回调和审批详情中。[获取审批模板详情][6]
- 接口创建:自建应用需被配置到“审批 - 可调用接口的应用”,代开发应用需具有“审批”权限;第三方应用暂不支持。创建成功后,管理后台和审批应用内会生成对应模板,并生效默认流程和规则配置。[创建审批模板][7]
因此,本项目若由客户企业管理员掌控流程,优先采用“后台建模板 + 系统配置模板 ID”若模板由平台标准化交付且应用权限满足要求可以评估调用创建模板接口。系统不应假定存在“列出企业全部模板”的接口官方“获取审批模板详情”要求调用方已知 `template_id`。[获取审批模板详情][6]
### 3.2 系统应如何配置控件
配置模板 ID 后,系统调用:
```text
POST https://qyapi.weixin.qq.com/cgi-bin/oa/gettemplatedetail?access_token=ACCESS_TOKEN
{"template_id":"TEMPLATE_ID"}
```
返回的 `template_content.controls` 包含:
- `property.control`:控件类型,如 `Text``Money``Date``Selector``Contact``File``Table` 等;
- `property.id`:提交审批时必须使用的控件唯一 ID
- `property.title``placeholder`:控件名称和填写说明;
- `property.require`:是否必填;
- `config`:日期精度、单/多选、成员/部门模式、明细子控件等配置;
- 选择控件的 `options[].key`:提交选择值时使用的稳定选项键。[获取审批模板详情][6]
建议系统保存“业务字段 → 控件 ID/类型/选项 key”的显式映射并在保存配置及发起审批前校验模板结构。不能仅按控件中文标题赋值因为提交接口以控件 ID 和选项 key 为准,管理员修改模板后原映射可能失效。
## 四、发起审批申请
### 4.1 请求与关键字段
接口为:
```text
POST https://qyapi.weixin.qq.com/cgi-bin/oa/applyevent?access_token=ACCESS_TOKEN
```
核心字段如下:[提交审批申请][8]
| 字段 | 含义与约束 |
| --- | --- |
| `creator_userid` | 申请人 `userid`;审批将以该员工身份提交,且申请人必须在应用可见范围内 |
| `template_id` | 审批模板 ID |
| `use_template_approver` | `0` 表示接口通过 `process` 指定审批人/抄送人;`1` 表示使用后台模板流程 |
| `choose_department` | 提单部门 ID不填时默认主部门 |
| `process.node_list` | 接口指定流程时必填;节点类型可为审批人、抄送人、办理人,并配置人员及多人处理方式 |
| `apply_data.contents` | 控件赋值数组,每项必须携带 `control``id``value`;模板必填控件必须有值 |
| `summary_list` | 审批通知卡片和审批列表摘要,最多 3 行,每行文字不超过 20 个字符 |
`use_template_approver=1`,后台审批流程中不能存在“申请人自选”节点。若为 `0``process` 必填。接口当前不支持提交“打卡补卡”“调班”模板审批单。[提交审批申请][8]
不同控件的 `value` 结构不同,例如文本使用 `text`,金额使用 `new_money`,日期使用 `date`,选择控件使用 `selector.options[].key`,成员控件使用 `members[].userid`,部门控件使用 `departments[].openapi_id`。具体结构必须同时服从模板详情和提交接口附录,不能用一个通用字符串值替代。[获取审批模板详情][6] [提交审批申请][8]
提交成功返回审批单号 `sp_no`,系统应立即将其与本地业务单据关联,作为后续回调去重、详情查询和补偿对账的关键标识。[提交审批申请][8]
### 4.2 附件
附件需先调用临时素材上传接口:
```text
POST https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=file
Content-Type: multipart/form-data
```
上传结果中的 `media_id` 仅 3 天有效;提交附件控件时将其写入 `value.files[].file_id`。审批提单后,企业微信会将其转换为长期文件。单个审批申请全局最多支持 6 个附件;普通文件上传上限为 20 MB且所有文件必须大于 5 字节。[上传临时素材][9] [提交审批申请][8]
## 五、审批结果回传与主动补偿
### 5.1 状态变化回调
审批回调事件名为 `sys_approval_change`。回调包含 `SpNoStr``SpStatus``TemplateId`、申请人、流程节点、备注及 `StatuChangeEvent` 等信息。官方推荐使用字符串字段 `SpNoStr` 代替原有数值字段 `SpNo`。[审批状态变化回调][13]
申请单状态包括审批中、已通过、已驳回、已撤销、通过后撤销、已删除、已支付;状态变化类型还覆盖提单、同意、驳回、转审、催办、撤销、添加备注、退回、加签、办理和转交等。[审批状态变化回调][13]
回调处理建议:
1. 校验签名并解密消息;验证解密后的 `receiveid` 与企业 `corpid` 一致。[加解密方案][16]
2. 持久化必要的接收记录并快速应答,把详情拉取和业务状态更新交给异步任务。
3.`SpNoStr` 查询“获取审批申请详情”,以详情中的最终状态、流程和表单值更新本地数据,而不是仅依赖一次回调载荷。[获取审批申请详情][10]
4. 业务处理必须幂等。企业微信在网络失败或超时时会重试,且状态变化可能多次发生;本地应允许同一审批单重复对齐到最新详情。
企业微信服务器在 5 秒内未收到响应会断开连接并重新发起请求,总共重试 3 次,但仅针对网络连接失败或超时。官方同时明确说明无法保证 100% 回调成功,并建议不要强依赖回调、增加额外机制对齐业务数据。[回调配置][12]
### 5.2 主动查询与轮询补偿
补偿链路使用两个接口:
1. “批量获取审批单号”按审批单提交时间范围拉取 `sp_no_list`,可按模板 ID、申请人、部门、审批状态筛选单次最多 100 条,通过 `new_cursor`/`new_next_cursor` 分页。时间跨度不能超过 31 天,频率上限 600 次/分钟。[批量获取审批单号][11]
2. 对每个审批单号调用“获取审批申请详情”,取得 `sp_status`、模板、申请人、流程、表单控件值、备注和附件等完整信息;频率上限同样为 600 次/分钟。[获取审批申请详情][10]
建议定时任务按模板 ID 拉取最近时间窗,并保留重叠回看区间,以覆盖任务延迟、分页中断和回调丢失;本地以 `sp_no` 幂等更新。时间窗应以“提交时间”理解,因为批量接口的 `starttime`/`endtime` 定义为审批单提交时间,而不是最后状态更新时间。因此,对仍处于审批中的历史单据,还应单独维护待终态集合并周期性查询详情,不能只扫描最近新提交的单据。[批量获取审批单号][11]
## 六、接入前置条件
### 6.1 凭证与权限
- `access_token` 必须由后端使用企业 ID 和正确应用 Secret 获取,禁止返回给前端。每个应用的 Secret 和 Token 相互独立,必须按应用分别缓存。[获取 access_token][14]
- Token 正常有效期为 7200 秒,但可能提前失效;系统需按 `expires_in` 缓存,并在失效时重新获取,不能高频调用获取接口。[获取 access_token][14]
- 自建应用必须配置到“审批 - 可调用接口的应用”;代开发应用和第三方应用必须具有“审批”权限。提交人还必须在应用可见范围内。[获取审批模板详情][6] [提交审批申请][8]
- 自 2023-12-01 起,审批接口不再支持通过系统应用 Secret 调用,存量企业暂不受影响;新接入不能依赖系统应用 Secret。[获取审批模板详情][6]
- 2022-06-20 之后新开启的通讯录同步助手及新创建的自建应用,必须在管理端配置可信 IP只有配置的 IP 才能调用接口。[开发前必读][15]
### 6.2 回调服务
自建应用需在应用详情的“设置 API 接收”中配置 `URL``Token``EncodingAESKey`,并打开审批状态通知事件;其中 Token 用于签名43 位 `EncodingAESKey` 用于消息体加密。[审批状态变化回调][13] [回调配置][12]
回调端点必须同时支持:
- `GET`:校验 `msg_signature`,解密 `echostr`,在 1 秒内原样返回明文且不能带引号、BOM 或换行;
- `POST`:校验签名,解密 XML 中的 `Encrypt`,处理明文事件并正确响应;
- AES-256-CBC、PKCS#7 填充、签名计算及 `receiveid` 校验。官方提供 Go 等语言的加解密库,宜优先使用官方库。[回调配置][12] [加解密方案][16]
如防火墙按来源 IP 放行,可调用官方回调 IP 接口获取网段。官方提示 IP 段可能变化,建议每天定时拉取并更新防火墙。[回调配置][12]
## 七、不成立或存在明确限制的设想
| 设想 | 官方结论 |
| --- | --- |
| 只要能调审批接口,就一定能读取全企业通讯录 | 不成立。通讯录接口受应用可见范围、通讯录权限和 Secret 类型限制;审批权限不等于全通讯录权限。[读取成员][1] [获取成员 ID 列表][4] |
| 总能取得员工手机号或邮箱,用它自动匹配系统账号 | 不成立。新自建/代开发应用需管理员选择敏感字段并获得成员 OAuth2 授权;第三方应用还存在更严格限制。[获取访问用户敏感信息][3] |
| `userid` 可以跨企业直接当全局用户 ID | 不成立。官方定义的是企业内唯一;本地应与企业 ID 组合存储。第三方应用的成员接口还可能返回 `open_userid`。[读取成员][1] |
| 审批模板只能在企业微信后台人工创建 | 不成立。自建和代开发应用可调用创建模板接口;但第三方应用暂不支持。[创建审批模板][7] |
| 系统可以不保存模板 ID启动时自动枚举全部模板 | 官方“获取模板详情”接口要求已知 `template_id`,官方给出的来源是编辑页 URL、回调、审批详情或创建接口返回值不能据此假定存在全量模板枚举能力。[获取审批模板详情][6] [创建审批模板][7] |
| 修改模板控件标题不会影响系统提交 | 有限制。提交依赖控件 `id`、类型及选择项 `key`,不是只按标题匹配;模板变化后应重新校验映射。[获取审批模板详情][6] [提交审批申请][8] |
| 使用后台模板流程时,任何流程配置都能直接发起 | 不成立。`use_template_approver=1` 时,后台流程不能含“申请人自选”节点。[提交审批申请][8] |
| 所有审批模板都能通过接口发起 | 不成立。官方明确暂不支持“打卡补卡”“调班”模板。[提交审批申请][8] |
| 回调成功配置后可保证每次审批变化都送达一次 | 不成立。官方明确无法保证 100% 回调成功,超时重试也仅有限次数;必须主动补偿并实现幂等。[回调配置][12] |
| 回调就是完整审批详情,不需要再查询 | 有限制。状态回调提供状态和流程信息;完整表单控件值以“获取审批申请详情”为准。[审批状态变化回调][13] [获取审批申请详情][10] |
| 上传得到的附件 ID 可长期暂存,审批单附件数量不限 | 不成立。临时素材 `media_id` 仅 3 天有效,单个审批申请全局最多 6 个附件。[上传临时素材][9] [提交审批申请][8] |
| 可继续使用系统应用 Secret 接入新企业 | 不成立。审批接口自 2023-12-01 起不再支持系统应用 Secret只有存量企业暂不受影响。[获取审批模板详情][6] |
## 八、建议的最小接入闭环
1. 企业管理员创建并启用自建应用,配置应用可见范围、审批可调用应用、可信 IP、回调 URL/Token/EncodingAESKey。
2. 系统按应用维度安全保存 Secret并在后端缓存 `access_token`
3. 管理员通过可见成员列表,把本地账号绑定到 `(corp_id, userid)`
4. 管理员填写模板 ID系统拉取模板详情保存并校验业务字段与控件 ID/选项 key 的映射。
5. 发起审批时使用已绑定 `userid`;附件即时上传后随审批提交;保存返回的 `sp_no`
6. 回调服务验签解密、快速应答并异步按 `sp_no` 拉取详情,幂等更新本地业务状态。
7. 定时通过“批量获取审批单号 + 获取审批申请详情”补偿回调遗漏,同时周期性刷新未终态审批单。
## 九、官方资料
以下页面均为企业微信开发者中心官方文档,访问日期均为 **2026-07-24**
[1]: https://developer.work.weixin.qq.com/document/path/90196 "读取成员"
[2]: https://developer.work.weixin.qq.com/document/path/90201 "获取部门成员详情"
[3]: https://developer.work.weixin.qq.com/document/path/95833 "获取访问用户敏感信息"
[4]: https://developer.work.weixin.qq.com/document/path/96067 "获取成员ID列表"
[5]: https://developer.work.weixin.qq.com/document/path/90208 "获取部门列表"
[6]: https://developer.work.weixin.qq.com/document/path/91982 "获取审批模板详情"
[7]: https://developer.work.weixin.qq.com/document/path/97437 "创建审批模板"
[8]: https://developer.work.weixin.qq.com/document/path/91853 "提交审批申请"
[9]: https://developer.work.weixin.qq.com/document/path/90253 "上传临时素材"
[10]: https://developer.work.weixin.qq.com/document/path/91983 "获取审批申请详情"
[11]: https://developer.work.weixin.qq.com/document/path/91816 "批量获取审批单号"
[12]: https://developer.work.weixin.qq.com/document/path/90930 "回调配置"
[13]: https://developer.work.weixin.qq.com/document/path/91815 "审批申请状态变化回调通知"
[14]: https://developer.work.weixin.qq.com/document/path/91039 "获取access_token"
[15]: https://developer.work.weixin.qq.com/document/path/90664 "开发前必读"
[16]: https://developer.work.weixin.qq.com/document/path/90968 "加解密方案说明"

View File

@@ -1,72 +1,135 @@
"编号","所属产品","所属模块","所属计划","来源","来源备注","用户需求名称","描述","验收标准","需求层级","父需求","关键词","优先级","预计工时","当前状态","所处阶段","类别","T","B","C","由谁创建","创建日期","指派给","指派日期","抄送给","已评审人","评审时间","由谁关闭","关闭日期","关闭原因","最后修改","最后修改日期","反馈者","重复需求","附件"
"189 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","换过货的卡迁移的旧套餐退款不会正常失效","目前换过货的新卡接受了旧卡的套餐,对这笔订单申请退款,退款通过后,这个套餐订单在卡上不会正常失效。
<img src=&quot;{157.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=157&quot; />
<img src=&quot;{158.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=158&quot; />
<img src=&quot;{159.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=159&quot; />
","","1 ","0 ","","3(#3)","","评审中(#reviewing)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-24 11:05:51","","","","","","","","","邹进","2026-07-24 20:18:13","","","",""
"188 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","广电管控卡弹窗提醒","广电风险停机的卡可以在H5进行弹窗提醒。
方式一系统自动弹窗提示客户需要换卡引导客户填写收货地址并同步至后台最好可以直接生成物流换货的换货单同时对接ERP系统
方式二:支持我们主动发出弹窗。提供发出弹窗功能,可以自定义弹窗内容,可以选择适用客户或适用设备类型或卡类型等。我们同时可以使用弹窗功能进行新的套餐政策推广,新品到货通知,从而引导客户消费等。(方式二是否需要新建一个需求,具体分析?)
","","1 ","0 ","","3(#3)","","评审中(#reviewing)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-23 17:18:34","","","","","","","","","邹进","2026-07-24 20:18:13","","","",""
"182 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","退款和订单充值提交人记录","退款管理和订单充值在后台的列表中都需要添加一个提交人字段
","","1 ","0 ","","3(#3)","","评审中(#reviewing)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-23 10:47:43","","","","","","","","","邹进","2026-07-24 20:18:13","","","",""
"181 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","订单列表和退款管理资产标识符、订单渠道缺失","目前订单列表和退款管理页面存在资产标识符、订单渠道缺失的情况,主要为设备:
退款单号RF20260723085931918896
<img src=&quot;{155.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=155&quot; />
订单号ORD20260721121735544971
<img src=&quot;{156.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=156&quot; />
","","1 ","0 ","","3(#3)","","评审中(#reviewing)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-23 09:50:32","","","","","","","","","邹进","2026-07-24 20:18:13","","","",""
"168 ","物联网卡管系统(#2)","/(#0)","","","","停机阈值显示","虚流量的停机阈值应为真流量的总流量
","","1 ","0 ","","3(#3)","0.50 ","激活(#active)","已关闭(#closed)","功能(#feature)","","","","李昕娉","2026-07-21 14:09:25","罗洋平","2026-07-21 14:09:25","","
黄燚麒(#huang)","2026-07-21 14:11:00","","","","罗洋平","2026-07-22 14:19:48","","","",""
"99 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","退款管理支持原路退回","系统需支持两种退款方式:
1. 原路退款
2. 客户提供收款凭证退款
同时,若选择原路退款,系统需先校验该订单对应的原收款商户当前是否具备退款能力,避免进入不可执行的退款流程。
2. 需求目标
1. 退款申请时支持选择退款方式。
2. 原路退款前自动校验原收款商户当前是否支持退款。
3. 当原收款商户不支持退款时,改为“客户提供收款凭证退款”。
4. 保留退款方式、校验结果、退款凭证、处理记录,便于财务复核与追溯。
3. 流程说明
1. 员工发起退款申请。
2. 选择退款方式。
3. 若选择原路退款,系统先执行原收款商户退款能力校验。
4. 校验通过,进入退款审核及执行流程。
5. 校验失败,提示原因,并允许改为客户提供收款凭证退款。
6. 若选择客户提供收款凭证退款,上传收款凭证后进入审核及财务处理流程。
7. 财务完成退款后,系统记录退款结果并通知申请人。
","","1 ","0 ","","2(#2)","6.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-16 11:50:41","黄燚麒","2026-07-16 12:06:36","","
黄燚麒(#huang)","2026-07-16 12:06:00","","","","邹进","2026-07-24 20:18:13","","","",""
"98 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","换过管理新资产归属","默认换货把旧资产的所属权一起划过去
","","1 ","0 ","","3(#3)","0.50 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-15 14:08:57","黄燚麒","2026-07-16 11:51:00","","
黄燚麒(#huang)","2026-07-16 11:50:00","","","","黄燚麒","2026-07-16 11:51:00","","","",""
","","1 ","0 ","","3(#3)","2.00 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-15 14:08:57","黄燚麒","2026-07-16 11:51:00","","
黄燚麒(#huang)","2026-07-16 11:50:00","","","","黄燚麒","2026-07-17 15:42:34","","","",""
"97 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","代理钱包阈值提醒","代理资金概况板块新增余额预警。不同代理可设置不同的预警额度。达到阈值时可提醒代理和其发展人。
","","1 ","0 ","","3(#3)","0.50 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-15 11:23:35","黄燚麒","2026-07-16 15:40:38","","
黄燚麒(#huang)","2026-07-16 15:40:00","","","","黄燚麒","2026-07-16 15:40:38","","","",""
","","1 ","0 ","","3(#3)","2.10 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-15 11:23:35","黄燚麒","2026-07-16 15:40:38","","
黄燚麒(#huang)","2026-07-16 15:40:00","","","","黄燚麒","2026-07-17 15:52:54","","","",""
"96 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","员工作为发展人进行标识","新建店铺添加业务员字段,可以进行指定相应业务员。非必填。同时店铺列表以及详情中新增发展人字段。发展人也可作为检索条件,检索发展人名下的相关店铺。
","","1 ","0 ","","2(#2)","1.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-15 11:22:00","黄燚麒","2026-07-15 11:23:15","","
黄燚麒(#huang)","2026-07-15 11:23:00","","","","李昕娉","2026-07-15 11:23:42","","","",""
","","1 ","0 ","","2(#2)","2.50 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-15 11:22:00","黄燚麒","2026-07-15 11:23:15","","
黄燚麒(#huang)","2026-07-15 11:23:00","","","","黄燚麒","2026-07-17 15:57:47","","","",""
"94 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","系统状态同步优化以及回调处理","因资产迁移需要涉及回调和状态同步,故进行相关优化
","","1 ","0 ","","1(#1)","40.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-14 10:53:29","黄燚麒","2026-07-14 11:00:14","","
黄燚麒(#huang)","2026-07-14 10:59:00","","","","李昕娉","2026-07-14 11:01:12","","","",""
","","1 ","0 ","","1(#1)","12.00 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-14 10:53:29","黄燚麒","2026-07-14 11:00:14","","
黄燚麒(#huang)","2026-07-14 10:59:00","","","","黄燚麒","2026-07-17 15:59:07","","","",""
"90 ","物联网卡管系统(#2)","/(#0)","","","","资产详情列表的字段修改","因运营商账户字段不想直接展示给代理、企业客户等查看。现需要将运营商账户字段在代理、企业客户处直接显示为:中国移动、中国电信、中国联通、中国广电。
<img src=&quot;{134.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=134&quot; />
且设备的实名认证策略和制造商均不展示给代理显示。
<img src=&quot;{135.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=135&quot; />
","","1 ","0 ","","3(#3)","1.40 ","激活(#active)","已关闭(#closed)","功能(#feature)","","","","李昕娉","2026-07-13 15:11:48","罗洋平","2026-07-13 15:11:48","","
黄燚麒(#huang)","2026-07-13 15:13:00","","","","罗洋平","2026-07-13 16:22:48","","","",""
"86 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","资产详情中换货标识","在资产详情页卡信息或设备信息列表中需要显示是否发生过换货或是换货标识,标注新资产或旧资产。旧资产需要可以链接至新资产。<img src=&quot;{128.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=128&quot; /><img src=&quot;{129.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=129&quot; />
","","1 ","0 ","","1(#1)","2.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-13 11:50:17","黄燚麒","2026-07-13 11:54:36","","
黄燚麒(#huang)","2026-07-13 11:54:00","","","","黄燚麒","2026-07-13 11:54:36","","","",""
","","1 ","0 ","","1(#1)","1.00 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-13 11:50:17","黄燚麒","2026-07-13 11:54:36","","
黄燚麒(#huang)","2026-07-13 11:54:00","","","","黄燚麒","2026-07-17 16:03:36","","","",""
"84 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","新卡管H5首页设备号下的ICCID去掉显示","新卡管H5首页设备号下的ICCID去掉显示
<img src=&quot;{133.jpg}&quot; alt=&quot;index.php?m=file&f=read&t=jpg&fileID=133&quot; />
","","1 ","0 ","","3(#3)","0.20 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-11 17:17:47","罗洋平","2026-07-13 15:12:41","","
黄燚麒(#huang)","2026-07-13 15:12:00","","","","邹进","2026-07-24 20:18:13","","","",""
"75 ","物联网卡管系统(#2)","/(#0)","","","","支付配置","将微信配置修改为支付配置,并修改权限编码以及路由和其他参数的变量名
","","1 ","0 ","","3(#3)","0.50 ","激活(#active)","已关闭(#closed)","功能(#feature)","","","","李昕娉","2026-07-11 14:21:59","罗洋平","2026-07-11 14:21:59","","
黄燚麒(#huang)","2026-07-11 14:25:00","","","","罗洋平","2026-07-11 14:44:28","","","",""
"73 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","行业卡操作停复机","行业卡允许未实名复机
","","1 ","0 ","","3(#3)","1.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-11 10:02:33","黄燚麒","2026-07-11 14:22:26","","
黄燚麒(#huang)","2026-07-11 14:22:00","","","","黄燚麒","2026-07-11 14:22:26","","","",""
","","1 ","0 ","","3(#3)","1.20 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-11 10:02:33","黄燚麒","2026-07-11 14:22:26","","
黄燚麒(#huang)","2026-07-11 14:22:00","","","","黄燚麒","2026-07-17 16:05:54","","","",""
"64 ","物联网卡管系统(#2)","/(#0)","","","","新卡管支付方式变更","新卡管H5设备新增支付宝支付
","","1 ","0 ","","3(#3)","0.20 ","激活(#active)","已关闭(#closed)","功能(#feature)","","","","李昕娉","2026-07-10 09:37:24","罗洋平","2026-07-10 09:37:24","","
黄燚麒(#huang)","2026-07-10 09:41:00","","","","罗洋平","2026-07-10 10:01:22","","","",""
"63 ","物联网卡管系统(#2)","/(#0)","","","","代理系列授权套餐列表增加滚动条","代理系列授权套餐列表添加滚动条和卡管后台资产信息字段显示顺序。
","","1 ","0 ","","3(#3)","0.20 ","激活(#active)","已关闭(#closed)","功能(#feature)","","","","李昕娉","2026-07-10 09:36:52","罗洋平","2026-07-10 09:36:52","","
黄燚麒(#huang)","2026-07-10 09:41:00","","","","罗洋平","2026-07-10 09:58:35","","","",""
"62 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","新卡管H5需要设置先充值后实名","用户进入H5后需要先绑定手机号后强制先充值后强制实名。这个功能能否进行后台设置例如这一批设备需要强制先充值后实名这一批资产可以先实名后充值
","","1 ","0 ","","3(#3)","2.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-09 17:04:27","李昕娉","2026-07-09 18:13:07","","
黄燚麒(#huang)","2026-07-11 14:23:00","","","","黄燚麒","2026-07-11 14:23:36","","","",""
","","1 ","0 ","","3(#3)","3.00 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-09 17:04:27","李昕娉","2026-07-09 18:13:07","","
黄燚麒(#huang)","2026-07-11 14:23:00","","","","黄燚麒","2026-07-17 16:07:55","","","",""
"60 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","店铺管理新增检索条件","店铺列表搜索栏新增一项:联系电话,便于搜索
","","1 ","0 ","","3(#3)","0.10 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-09 16:00:56","黄燚麒","2026-07-09 17:37:57","","
黄燚麒(#huang)","2026-07-09 17:37:00","","","","黄燚麒","2026-07-09 17:37:57","","","",""
","","1 ","0 ","","3(#3)","1.00 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-09 16:00:56","黄燚麒","2026-07-09 17:37:57","","
黄燚麒(#huang)","2026-07-09 17:37:00","","","","黄燚麒","2026-07-17 16:08:34","","","",""
"57 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","操作拦截","若当前资产存在退款申请时(但为通过审批时),该资产不允许操作换货。且出现提示:该资产存在退款申请
","","1 ","0 ","","3(#3)","1.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-09 15:07:17","黄燚麒","2026-07-09 17:32:56","","
黄燚麒(#huang)","2026-07-09 17:32:00","","","","李昕娉","2026-07-09 17:33:21","","","",""
","","1 ","0 ","","3(#3)","1.50 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-09 15:07:17","黄燚麒","2026-07-09 17:32:56","","
黄燚麒(#huang)","2026-07-09 17:32:00","","","","黄燚麒","2026-07-17 16:09:19","","","",""
"55 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","套餐生效条件","套餐延续创建时选择购买即生效或实名即生效的条件,同时在套餐分配时提供修改条件的功能,并以变更后的条件为最终版本
","","1 ","0 ","","1(#1)","4.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-09 11:57:51","黄燚麒","2026-07-09 16:54:53","","
黄燚麒(#huang)","2026-07-09 16:54:00","","","","黄燚麒","2026-07-09 16:54:53","","","",""
"54 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","资产详情页面新增套餐到期时间显示","增加所有待生效套餐加上生效套餐加起来的最后到期时间
","","1 ","0 ","","2(#2)","","已关闭(#closed)","已关闭(#closed)","功能(#feature)","","","","李昕娉","2026-07-09 11:56:50","closed","2026-07-09 17:26:38","","
黄燚麒(#huang)","2026-07-09 17:26:00","黄燚麒","2026-07-09 17:26:38","重复(#duplicate)","黄燚麒","2026-07-09 17:26:38","","#46 资产信息详情字段新增","",""
","","1 ","0 ","","1(#1)","5.00 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-09 11:57:51","黄燚麒","2026-07-09 16:54:53","","
黄燚麒(#huang)","2026-07-09 16:54:00","","","","黄燚麒","2026-07-17 16:11:34","","","",""
"53 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","资产管理查询字段新增","lot卡管理和设备管理新增已实名/未实名的筛选查询条件
","","1 ","0 ","","1(#1)","1.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-09 09:39:53","黄燚麒","2026-07-09 16:53:29","","
黄燚麒(#huang)","2026-07-09 16:53:00","","","","黄燚麒","2026-07-09 16:53:29","","","",""
","","1 ","0 ","","1(#1)","2.50 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-09 09:39:53","黄燚麒","2026-07-09 16:53:29","","
黄燚麒(#huang)","2026-07-09 16:53:00","","","","黄燚麒","2026-07-17 16:12:35","","","",""
"52 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","对接聚水潭","因很多流程需要聚水潭的配合,故想将聚水潭打通。例如订单接口、发货数据等
","","1 ","0 ","","3(#3)","200.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-09 08:46:31","黄燚麒","2026-07-09 08:46:31","","
黄燚麒(#huang)","2026-07-09 17:38:00","","","","邹进","2026-07-24 20:18:13","","","",""
"51 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","不同品类资产的换货","因换货存在不同资产间的换货,且存在补差价进行卡换设备的操作。但卡的套餐和设备套餐不同会存在补差价等操作。且原卡套餐需失效,新资产设备需要使用设备套餐。直接操作换货,套餐会同步卡套餐,对公司来说成本增加。
","","1 ","0 ","","1(#1)","","草稿(#draft)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 17:54:32","李昕娉","2026-07-09 16:53:05","","","2026-07-09 16:52:00","","","","黄燚麒","2026-07-09 16:53:05","","","",""
"49 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","设备批量分配代理和套餐系列","因设备号不是连号故需要提供导入excel表的方式进行批量分配代理和套餐系列。excle表头为设备号
","","1 ","0 ","","1(#1)","2.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 17:43:58","黄燚麒","2026-07-08 17:43:58","","
黄燚麒(#huang)","2026-07-09 16:45:00","","","","黄燚麒","2026-07-09 16:46:08","","","",""
"48 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","根据不同的资产使用不同的支付方式","C端支付时,卡资产只允许支付宝支付以及钱包支付,如果用微信支付就拒绝,设备只允许微信支付以及钱包支付,如果用支付宝支付就拒绝","","1 ","0 ","","1(#1)","1.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:56:52","黄燚麒","2026-07-09 16:45:21","","
黄燚麒(#huang)","2026-07-09 16:45:00","","","","黄燚麒","2026-07-09 16:45:21","","","",""
"47 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","限速规则","根据不同运营商限速规则,基于套餐流量设置不同的卡/设备的限速规则","","1 ","0 ","","3(#3)","4.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:54:39","黄燚麒","2026-07-09 17:30:42","","
黄燚麒(#huang)","2026-07-09 17:27:00","","","","黄燚麒","2026-07-09 17:30:42","","","",""
"46 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","资产信息详情字段新增","资产信息页面卡信息/设备信息板块将当前生效套餐的过期时间作为一个字段显示且套餐还剩15天到期时该字段高亮显示。","","1 ","0 ","","2(#2)","1.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:52:36","黄燚麒","2026-07-09 17:25:53","","
黄燚麒(#huang)","2026-07-09 17:25:00","","","","黄燚麒","2026-07-09 17:25:53","","","",""
","","1 ","0 ","","1(#1)","5.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 17:43:58","黄燚麒","2026-07-08 17:43:58","","
黄燚麒(#huang)","2026-07-09 16:45:00","","","","黄燚麒","2026-07-17 16:13:53","","","",""
"48 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","根据不同的资产使用不同的支付方式","C端支付时,卡资产只允许支付宝支付以及钱包支付,如果用微信支付就拒绝,设备只允许微信支付以及钱包支付,如果用支付宝支付就拒绝","","1 ","0 ","","1(#1)","4.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:56:52","黄燚麒","2026-07-09 16:45:21","","
黄燚麒(#huang)","2026-07-09 16:45:00","","","","黄燚麒","2026-07-17 16:15:40","","","",""
"47 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","限速规则","根据不同运营商限速规则,基于套餐流量设置不同的卡/设备的限速规则","","1 ","0 ","","3(#3)","3.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:54:39","黄燚麒","2026-07-09 17:30:42","","
黄燚麒(#huang)","2026-07-09 17:27:00","","","","黄燚麒","2026-07-17 16:16:36","","","",""
"46 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","资产信息详情字段新增","资产信息页面卡信息/设备信息板块将当前生效套餐的过期时间作为一个字段显示且套餐还剩15天到期时该字段高亮显示。","","1 ","0 ","","2(#2)","4.00 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-08 15:52:36","黄燚麒","2026-07-09 17:25:53","","
黄燚麒(#huang)","2026-07-09 17:25:00","","","","黄燚麒","2026-07-17 16:17:29","","","",""
"45 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","换货管理","| 编号 | 需求 |
| ------- | ---------------------------------------------------- |
| EXC-001 | 修正换货列表旧资产标识和新资产标识显示混乱问题。 |
| EXC-002 | 换货列表中旧资产标识符和新资产标识符均显示为 ICCID。 |
| EXC-003 | 旧资产查询支持 ICCID、接入号、虚拟号。 |
| EXC-004 | 新资产查询支持 ICCID、接入号、虚拟号。 |","","1 ","0 ","","1(#1)","3.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:51:13","黄燚麒","2026-07-09 16:44:46","","
黄燚麒(#huang)","2026-07-09 16:44:00","","","","黄燚麒","2026-07-09 16:44:46","","","",""
| EXC-004 | 新资产查询支持 ICCID、接入号、虚拟号。 |","","1 ","0 ","","1(#1)","2.50 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-08 15:51:13","黄燚麒","2026-07-09 16:44:46","","
黄燚麒(#huang)","2026-07-09 16:44:00","","","","黄燚麒","2026-07-17 16:18:30","","","",""
"44 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","列表字段新增","| 编号 | 模块 | 新增字段 |
| ------- | ------------ | -------------- |
| COL-001 | 退款管理列表 | 提交人、审批人 |
| COL-002 | 代理充值列表 | 提交人、审批人 |
| COL-003 | 换号管理列表 | 提交人 |","","1 ","0 ","","1(#1)","1.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:51:13","黄燚麒","2026-07-09 16:44:20","","
黄燚麒(#huang)","2026-07-09 16:44:00","","","","黄燚麒","2026-07-09 16:44:20","","","",""
| COL-003 | 换号管理列表 | 提交人 |","","1 ","0 ","","1(#1)","3.00 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-08 15:51:13","黄燚麒","2026-07-09 16:44:20","","
黄燚麒(#huang)","2026-07-09 16:44:00","","","","黄燚麒","2026-07-17 16:19:27","","","",""
"43 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","代理系列授权","| 编号 | 需求 |
| ------- | ------------------------------------------------------------ |
| AUT-001 | 代理系列授权-套餐列表中,添加授权套餐支持一次性多选分套餐。 |
| AUT-002 | 授权套餐时展示建议售价。 |
| AUT-003 | 授权套餐时展示公司成本价。 |
| AUT-004 | 已分配套餐和未分配套餐需要明显区分。 |
| AUT-005 | 新增代理系列授权时,选择套餐需明确显示当前代理已经被分配过的套餐。 |","","1 ","0 ","","2(#2)","5.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:51:13","黄燚麒","2026-07-09 17:25:42","","
黄燚麒(#huang)","2026-07-09 17:12:00","","","","黄燚麒","2026-07-09 17:25:42","","","",""
| AUT-005 | 新增代理系列授权时,选择套餐需明确显示当前代理已经被分配过的套餐。 |","","1 ","0 ","","2(#2)","1.50 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:51:13","黄燚麒","2026-07-09 17:25:42","","
黄燚麒(#huang)","2026-07-09 17:12:00","","","","黄燚麒","2026-07-17 16:20:11","","","",""
"42 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","导出功能","#### 6.8.1 lot 卡导出
##### 支持套餐临期30天内所有资产的导出。字段按照卡/设备的导出表进行导出。
@@ -208,8 +271,8 @@
| 部门领导审批人 |
| 财务审批人 |
| 支付凭证 |
| 备注 |","","1 ","0 ","","1(#1)","16.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 16:42:07","","
黄燚麒(#huang)","2026-07-09 16:40:00","","","","黄燚麒","2026-07-09 16:42:07","","","",""
| 备注 |","","1 ","0 ","","1(#1)","8.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 16:42:07","","
黄燚麒(#huang)","2026-07-09 16:40:00","","","","黄燚麒","2026-07-17 16:20:58","","","",""
"41 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","代理查询限制(类似酷蛙这种客户)","下级只能看到上级给的信息。api对接客户无法通过他的上级代理查到我们公司的信息。
| 编号 | 需求 | | ------- | -------------------------------------------------------- | | API-001 | 支持配置代理 API 对接查询限制。下级客户/代理无法跨级查询 |
","","1 ","0 ","","1(#1)","","草稿(#draft)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","李昕娉","2026-07-09 16:42:55","","","2026-07-11 14:24:00","","","","黄燚麒","2026-07-11 14:25:30","","","",""
@@ -218,15 +281,27 @@
| PKG-001 | 套餐需标准化管理。 |
| PKG-002 | 套餐下架后,正在使用该套餐的客户仍可续费。 |
| PKG-003 | 下架套餐续费仅支持客户自己购买。 |
| PKG-004 | 下架套餐不可被新购买。 |","","1 ","0 ","","2(#2)","3.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 17:11:34","","
黄燚麒(#huang)","2026-07-09 17:10:00","","","","黄燚麒","2026-07-09 17:11:34","","","",""
| PKG-004 | 下架套餐不可被新购买。 |","","1 ","0 ","","2(#2)","4.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 17:11:34","","
黄燚麒(#huang)","2026-07-09 17:10:00","","","","黄燚麒","2026-07-17 16:21:43","","","",""
"39 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","代理分销码与佣金提现","##### 员工可作为代理发展人进行标识。(在系统中如何体现?)
| 编号 | 需求 |
| ------- | ---------------------------------------------------- |
| DST-001 | 新建代理时自动建立分销归属关系。 |
| DST-002 | 员工可作为代理发展人进行标识。(在系统中如何体现?) |
| DST-003 | 佣金提现前,代理必须签署合同。(必填) |
| DST-004 | 佣金提现需上传营业执照。(可选) |
| DST-005 | 佣金提现需上传法人身份证。(必填) |
| DST-006 | 佣金提现可选上传门头照。(可选) |
| DST-007 | 佣金提现需上传发票,且公司主体需与合同一致。(可选) |","","1 ","0 ","","3(#3)","40.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 17:43:17","","
黄燚麒(#huang)","2026-07-09 17:43:00","","","","邹进","2026-07-24 20:18:13","","","",""
"38 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","不同渠道额度处理","| 编号 | 需求 |
| ------- | ------------------------------------------------------------ |
| BPO-009 | 新建代理时新增“是否可授权额度”开关。平台用户账号默认拥有授权额度。 |
| BPO-010 | 不同代理可设置不同额度下限。平台用户可根据不同的角色设置不同的额度下限。 |
| BPO-011 | 授权额度用于订购套餐、代理余额充值等需要涉及金额的所有模块。 |
| BPO-012 | 授权额度代理可显示负数余额。平台用户也可显示负数余额。 |","","1 ","0 ","","2(#2)","16.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 16:58:16","","
黄燚麒(#huang)","2026-07-09 16:57:00","","","","黄燚麒","2026-07-09 16:58:16","","","",""
| BPO-012 | 授权额度代理可显示负数余额。平台用户也可显示负数余额。 |","","1 ","0 ","","2(#2)","7.00 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 16:58:16","","
黄燚麒(#huang)","2026-07-09 16:57:00","","","","黄燚麒","2026-07-17 16:22:35","","","",""
"37 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","审核流转","| 编号 | 需求 |
| ------- | ------------------------------------------------------------ |
| APR-001 | 代理可在系统提交充值申请。 |
@@ -237,8 +312,8 @@
| APR-006 | 审核提醒按流程环节触发,上一审批人完成审批后才提示下一审批人。 |
| APR-007 | 审核通过后通知申请人。 |
| APR-008 | 审核驳回后通知申请人,并附带驳回原因。 |
| APR-009 | 审核流程需对接企业微信审批流程。 |","","1 ","0 ","","2(#2)","24.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 16:57:35","","
黄燚麒(#huang)","2026-07-09 16:57:00","","","","黄燚麒","2026-07-09 16:57:35","","","",""
| APR-009 | 审核流程需对接企业微信审批流程。 |","","1 ","0 ","","2(#2)","16.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 16:57:35","","
黄燚麒(#huang)","2026-07-09 16:57:00","","","","黄燚麒","2026-07-17 16:23:22","","","",""
"36 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","批量订购套餐","1. 内部员工进入批量订购页面。
2. 选择代理、ICCID号段/设备号、订购套餐。或上传 Excel 文件,资产标识支持 ICCID/设备号
3. Excel表头跳转至6.3会显示。
@@ -266,15 +341,15 @@ excel
| 套餐系列名称 |
| 套餐名称 |
| 代理名称 |
| 支付方式:代理商账户/员工账户 |","","1 ","0 ","","1(#1)","4.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 16:31:53","","
黄燚麒(#huang)","2026-07-09 16:31:00","","","","黄燚麒","2026-07-09 16:31:53","","","",""
| 支付方式:代理商账户/员工账户 |","","1 ","0 ","","1(#1)","8.00 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 16:31:53","","
黄燚麒(#huang)","2026-07-09 16:31:00","","","","黄燚麒","2026-07-17 16:24:11","","","",""
"35 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","退款审核","(审批均可通过企微进行提醒和显示并将最新状态同步至卡管)
1. 员工提交退款申请。
2. 退款单进入多级审核流程。
3. 按部门领导、财务顺序审批。
4. 当前环节审批完成后,下一环节审批人收到消息提示。
5. 审批通过或驳回后通知申请人。","","1 ","0 ","","2(#2)","24.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 16:56:31","","
黄燚麒(#huang)","2026-07-09 16:55:00","","","","黄燚麒","2026-07-09 16:56:31","","","",""
5. 审批通过或驳回后通知申请人。","","1 ","0 ","","2(#2)","7.00 ","激活(#active)","研发中(#developing)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 16:56:31","","
黄燚麒(#huang)","2026-07-09 16:55:00","","","","黄燚麒","2026-07-17 16:25:07","","","",""
"34 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","充值审核流程","代理自己充值:
1. 代理在系统提交充值申请。
2. 系统展示收款二维码。
@@ -285,8 +360,8 @@ excel
2. 提交人部门领导先审批。
3. 财务在上一审批人通过后收到待办提醒并审批。
4. 审批通过后通知申请人。
5. 审批驳回后通知申请人,并展示驳回原因。","","1 ","0 ","","2(#2)","32.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 16:55:42","","
黄燚麒(#huang)","2026-07-09 16:55:00","","","","黄燚麒","2026-07-09 16:55:42","","","",""
5. 审批驳回后通知申请人,并展示驳回原因。","","1 ","0 ","","2(#2)","16.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 16:55:42","","
黄燚麒(#huang)","2026-07-09 16:55:00","","","","黄燚麒","2026-07-17 16:26:05","","","",""
"33 ","物联网卡管系统(#2)","/(#0)","7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1)","","","套餐临期提醒","1. 系统每日计算卡/设备套餐剩余有效期。
2. 命中临期规则后生成临期数据。临期提醒规则:按 15 天、7 天、3 天节点分别进行不同方式的提醒。
3. 企业客户场景:按 15 天、7 天、3 天节点生成临期列表,并通过企业微信推送给对应业务员。
@@ -325,5 +400,5 @@ excel
卡号/设备号xxx
剩余有效期xx 天
为避免到期后影响正常使用,请您提前完成续费。","","1 ","0 ","","1(#1)","","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 16:30:06","","
黄燚麒(#huang)","2026-07-09 16:29:00","","","","黄燚麒","2026-07-09 16:30:06","","","",""
为避免到期后影响正常使用,请您提前完成续费。","","1 ","0 ","","1(#1)","8.00 ","激活(#active)","已计划(#planned)","功能(#feature)","","","","李昕娉","2026-07-08 15:49:25","黄燚麒","2026-07-09 16:30:06","","
黄燚麒(#huang)","2026-07-09 16:29:00","","","","黄燚麒","2026-07-17 16:26:41","","","",""
1 编号 所属产品 所属模块 所属计划 来源 来源备注 用户需求名称 描述 验收标准 需求层级 父需求 关键词 优先级 预计工时 当前状态 所处阶段 类别 T B C 由谁创建 创建日期 指派给 指派日期 抄送给 已评审人 评审时间 由谁关闭 关闭日期 关闭原因 最后修改 最后修改日期 反馈者 重复需求 附件
2 189 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 换过货的卡迁移的旧套餐退款不会正常失效 目前换过货的新卡接受了旧卡的套餐,对这笔订单申请退款,退款通过后,这个套餐订单在卡上不会正常失效。 <img src=&quot;{157.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=157&quot; /> <img src=&quot;{158.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=158&quot; /> <img src=&quot;{159.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=159&quot; /> 1 0 3(#3) 评审中(#reviewing) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-24 11:05:51 邹进 2026-07-24 20:18:13
3 188 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 广电管控卡弹窗提醒 广电风险停机的卡可以在H5进行弹窗提醒。 方式一:系统自动弹窗,提示客户需要换卡,引导客户填写收货地址并同步至后台;(最好可以直接生成物流换货的换货单,同时对接ERP系统) 方式二:支持我们主动发出弹窗。提供发出弹窗功能,可以自定义弹窗内容,可以选择适用客户或适用设备类型或卡类型等。我们同时可以使用弹窗功能进行新的套餐政策推广,新品到货通知,从而引导客户消费等。(方式二是否需要新建一个需求,具体分析?) 1 0 3(#3) 评审中(#reviewing) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-23 17:18:34 邹进 2026-07-24 20:18:13
4 182 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 退款和订单充值提交人记录 退款管理和订单充值在后台的列表中都需要添加一个提交人字段 1 0 3(#3) 评审中(#reviewing) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-23 10:47:43 邹进 2026-07-24 20:18:13
5 181 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 订单列表和退款管理资产标识符、订单渠道缺失 目前订单列表和退款管理页面存在资产标识符、订单渠道缺失的情况,主要为设备: 退款单号:RF20260723085931918896 <img src=&quot;{155.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=155&quot; /> 订单号:ORD20260721121735544971 <img src=&quot;{156.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=156&quot; /> 1 0 3(#3) 评审中(#reviewing) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-23 09:50:32 邹进 2026-07-24 20:18:13
6 168 物联网卡管系统(#2) /(#0) 停机阈值显示 虚流量的停机阈值应为真流量的总流量 1 0 3(#3) 0.50 激活(#active) 已关闭(#closed) 功能(#feature) 李昕娉 2026-07-21 14:09:25 罗洋平 2026-07-21 14:09:25 黄燚麒(#huang) 2026-07-21 14:11:00 罗洋平 2026-07-22 14:19:48
7 99 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 退款管理支持原路退回 系统需支持两种退款方式: 1. 原路退款 2. 客户提供收款凭证退款 同时,若选择原路退款,系统需先校验该订单对应的原收款商户当前是否具备退款能力,避免进入不可执行的退款流程。 2. 需求目标 1. 退款申请时支持选择退款方式。 2. 原路退款前自动校验原收款商户当前是否支持退款。 3. 当原收款商户不支持退款时,改为“客户提供收款凭证退款”。 4. 保留退款方式、校验结果、退款凭证、处理记录,便于财务复核与追溯。 3. 流程说明 1. 员工发起退款申请。 2. 选择退款方式。 3. 若选择原路退款,系统先执行原收款商户退款能力校验。 4. 校验通过,进入退款审核及执行流程。 5. 校验失败,提示原因,并允许改为客户提供收款凭证退款。 6. 若选择客户提供收款凭证退款,上传收款凭证后进入审核及财务处理流程。 7. 财务完成退款后,系统记录退款结果并通知申请人。 1 0 2(#2) 6.00 激活(#active) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-16 11:50:41 黄燚麒 2026-07-16 12:06:36 黄燚麒(#huang) 2026-07-16 12:06:00 邹进 2026-07-24 20:18:13
8 98 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 换过管理新资产归属 默认换货把旧资产的所属权一起划过去 1 0 3(#3) 2.00 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-15 14:08:57 黄燚麒 2026-07-16 11:51:00 黄燚麒(#huang) 2026-07-16 11:50:00 黄燚麒 2026-07-17 15:42:34
9 97 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 代理钱包阈值提醒 代理资金概况板块新增余额预警。不同代理可设置不同的预警额度。达到阈值时可提醒代理和其发展人。 1 0 3(#3) 2.10 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-15 11:23:35 黄燚麒 2026-07-16 15:40:38 黄燚麒(#huang) 2026-07-16 15:40:00 黄燚麒 2026-07-17 15:52:54
10 96 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 员工作为发展人进行标识 新建店铺添加业务员字段,可以进行指定相应业务员。非必填。同时店铺列表以及详情中新增发展人字段。发展人也可作为检索条件,检索发展人名下的相关店铺。 1 0 2(#2) 2.50 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-15 11:22:00 黄燚麒 2026-07-15 11:23:15 黄燚麒(#huang) 2026-07-15 11:23:00 黄燚麒 2026-07-17 15:57:47
11 94 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 系统状态同步优化以及回调处理 因资产迁移需要涉及回调和状态同步,故进行相关优化 1 0 1(#1) 12.00 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-14 10:53:29 黄燚麒 2026-07-14 11:00:14 黄燚麒(#huang) 2026-07-14 10:59:00 黄燚麒 2026-07-17 15:59:07
12 90 物联网卡管系统(#2) /(#0) 资产详情列表的字段修改 因运营商账户字段不想直接展示给代理、企业客户等查看。现需要将运营商账户字段在代理、企业客户处直接显示为:中国移动、中国电信、中国联通、中国广电。 <img src=&quot;{134.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=134&quot; /> 且设备的实名认证策略和制造商均不展示给代理显示。 <img src=&quot;{135.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=135&quot; /> 1 0 3(#3) 1.40 激活(#active) 已关闭(#closed) 功能(#feature) 李昕娉 2026-07-13 15:11:48 罗洋平 2026-07-13 15:11:48 黄燚麒(#huang) 2026-07-13 15:13:00 罗洋平 2026-07-13 16:22:48
13 86 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 资产详情中换货标识 在资产详情页卡信息或设备信息列表中需要显示是否发生过换货或是换货标识,标注新资产或旧资产。旧资产需要可以链接至新资产。<img src=&quot;{128.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=128&quot; /><img src=&quot;{129.png}&quot; alt=&quot;index.php?m=file&f=read&t=png&fileID=129&quot; /> 1 0 1(#1) 1.00 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-13 11:50:17 黄燚麒 2026-07-13 11:54:36 黄燚麒(#huang) 2026-07-13 11:54:00 黄燚麒 2026-07-17 16:03:36
14 84 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 新卡管H5首页设备号下的ICCID去掉显示 新卡管H5首页设备号下的ICCID去掉显示 <img src=&quot;{133.jpg}&quot; alt=&quot;index.php?m=file&f=read&t=jpg&fileID=133&quot; /> 1 0 3(#3) 0.20 激活(#active) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-11 17:17:47 罗洋平 2026-07-13 15:12:41 黄燚麒(#huang) 2026-07-13 15:12:00 邹进 2026-07-24 20:18:13
15 75 物联网卡管系统(#2) /(#0) 支付配置 将微信配置修改为支付配置,并修改权限编码以及路由和其他参数的变量名 1 0 3(#3) 0.50 激活(#active) 已关闭(#closed) 功能(#feature) 李昕娉 2026-07-11 14:21:59 罗洋平 2026-07-11 14:21:59 黄燚麒(#huang) 2026-07-11 14:25:00 罗洋平 2026-07-11 14:44:28
16 73 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 行业卡操作停复机 行业卡允许未实名复机 1 0 3(#3) 1.20 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-11 10:02:33 黄燚麒 2026-07-11 14:22:26 黄燚麒(#huang) 2026-07-11 14:22:00 黄燚麒 2026-07-17 16:05:54
17 64 物联网卡管系统(#2) /(#0) 新卡管支付方式变更 新卡管H5设备新增支付宝支付 1 0 3(#3) 0.20 激活(#active) 已关闭(#closed) 功能(#feature) 李昕娉 2026-07-10 09:37:24 罗洋平 2026-07-10 09:37:24 黄燚麒(#huang) 2026-07-10 09:41:00 罗洋平 2026-07-10 10:01:22
18 63 物联网卡管系统(#2) /(#0) 代理系列授权套餐列表增加滚动条 代理系列授权套餐列表添加滚动条和卡管后台资产信息字段显示顺序。 1 0 3(#3) 0.20 激活(#active) 已关闭(#closed) 功能(#feature) 李昕娉 2026-07-10 09:36:52 罗洋平 2026-07-10 09:36:52 黄燚麒(#huang) 2026-07-10 09:41:00 罗洋平 2026-07-10 09:58:35
19 62 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 新卡管H5需要设置先充值后实名 用户进入H5后需要先绑定手机号后强制先充值后强制实名。这个功能能否进行后台设置,例如这一批设备需要强制先充值后实名,这一批资产可以先实名后充值? 1 0 3(#3) 3.00 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-09 17:04:27 李昕娉 2026-07-09 18:13:07 黄燚麒(#huang) 2026-07-11 14:23:00 黄燚麒 2026-07-17 16:07:55
20 60 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 店铺管理新增检索条件 店铺列表搜索栏新增一项:联系电话,便于搜索 1 0 3(#3) 1.00 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-09 16:00:56 黄燚麒 2026-07-09 17:37:57 黄燚麒(#huang) 2026-07-09 17:37:00 黄燚麒 2026-07-17 16:08:34
21 57 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 操作拦截 若当前资产存在退款申请时(但为通过审批时),该资产不允许操作换货。且出现提示:该资产存在退款申请 1 0 3(#3) 1.50 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-09 15:07:17 黄燚麒 2026-07-09 17:32:56 黄燚麒(#huang) 2026-07-09 17:32:00 黄燚麒 2026-07-17 16:09:19
22 55 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 套餐生效条件 套餐延续创建时选择购买即生效或实名即生效的条件,同时在套餐分配时提供修改条件的功能,并以变更后的条件为最终版本 1 0 1(#1) 5.00 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-09 11:57:51 黄燚麒 2026-07-09 16:54:53 黄燚麒(#huang) 2026-07-09 16:54:00 黄燚麒 2026-07-17 16:11:34
23 53 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 资产管理查询字段新增 lot卡管理和设备管理新增已实名/未实名的筛选查询条件 1 0 1(#1) 2.50 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-09 09:39:53 黄燚麒 2026-07-09 16:53:29 黄燚麒(#huang) 2026-07-09 16:53:00 黄燚麒 2026-07-17 16:12:35
24 52 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 对接聚水潭 因很多流程需要聚水潭的配合,故想将聚水潭打通。例如订单接口、发货数据等 1 0 3(#3) 200.00 激活(#active) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-09 08:46:31 黄燚麒 2026-07-09 08:46:31 黄燚麒(#huang) 2026-07-09 17:38:00 邹进 2026-07-24 20:18:13
25 51 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 不同品类资产的换货 因换货存在不同资产间的换货,且存在补差价进行卡换设备的操作。但卡的套餐和设备套餐不同会存在补差价等操作。且原卡套餐需失效,新资产设备需要使用设备套餐。直接操作换货,套餐会同步卡套餐,对公司来说成本增加。 1 0 1(#1) 草稿(#draft) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-08 17:54:32 李昕娉 2026-07-09 16:53:05 2026-07-09 16:52:00 黄燚麒 2026-07-09 16:53:05
26 49 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 设备批量分配代理和套餐系列 因设备号不是连号,故需要提供导入excel表的方式进行批量分配代理和套餐系列。excle表头为:设备号 1 0 1(#1) 5.00 激活(#active) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-08 17:43:58 黄燚麒 2026-07-08 17:43:58 黄燚麒(#huang) 2026-07-09 16:45:00 黄燚麒 2026-07-17 16:13:53
27 48 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 根据不同的资产使用不同的支付方式 C端支付时,卡资产只允许支付宝支付以及钱包支付,如果用微信支付就拒绝,设备只允许微信支付以及钱包支付,如果用支付宝支付就拒绝 1 0 1(#1) 4.00 激活(#active) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-08 15:56:52 黄燚麒 2026-07-09 16:45:21 黄燚麒(#huang) 2026-07-09 16:45:00 黄燚麒 2026-07-17 16:15:40
28 47 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 限速规则 根据不同运营商限速规则,基于套餐流量设置不同的卡/设备的限速规则 1 0 3(#3) 3.00 激活(#active) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-08 15:54:39 黄燚麒 2026-07-09 17:30:42 黄燚麒(#huang) 2026-07-09 17:27:00 黄燚麒 2026-07-17 16:16:36
29 46 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 资产信息详情字段新增 资产信息页面卡信息/设备信息板块,将当前生效套餐的过期时间作为一个字段显示且套餐还剩15天到期时该字段高亮显示。 1 0 2(#2) 4.00 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-08 15:52:36 黄燚麒 2026-07-09 17:25:53 黄燚麒(#huang) 2026-07-09 17:25:00 黄燚麒 2026-07-17 16:17:29
30 45 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 换货管理 | 编号 | 需求 | | ------- | ---------------------------------------------------- | | EXC-001 | 修正换货列表旧资产标识和新资产标识显示混乱问题。 | | EXC-002 | 换货列表中旧资产标识符和新资产标识符均显示为 ICCID。 | | EXC-003 | 旧资产查询支持 ICCID、接入号、虚拟号。 | | EXC-004 | 新资产查询支持 ICCID、接入号、虚拟号。 | 1 0 1(#1) 2.50 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-08 15:51:13 黄燚麒 2026-07-09 16:44:46 黄燚麒(#huang) 2026-07-09 16:44:00 黄燚麒 2026-07-17 16:18:30
31 44 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 列表字段新增 | 编号 | 模块 | 新增字段 | | ------- | ------------ | -------------- | | COL-001 | 退款管理列表 | 提交人、审批人 | | COL-002 | 代理充值列表 | 提交人、审批人 | | COL-003 | 换号管理列表 | 提交人 | 1 0 1(#1) 3.00 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-08 15:51:13 黄燚麒 2026-07-09 16:44:20 黄燚麒(#huang) 2026-07-09 16:44:00 黄燚麒 2026-07-17 16:19:27
32 43 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 代理系列授权 | 编号 | 需求 | | ------- | ------------------------------------------------------------ | | AUT-001 | 代理系列授权-套餐列表中,添加授权套餐支持一次性多选分套餐。 | | AUT-002 | 授权套餐时展示建议售价。 | | AUT-003 | 授权套餐时展示公司成本价。 | | AUT-004 | 已分配套餐和未分配套餐需要明显区分。 | | AUT-005 | 新增代理系列授权时,选择套餐需明确显示当前代理已经被分配过的套餐。 | 1 0 2(#2) 1.50 激活(#active) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-08 15:51:13 黄燚麒 2026-07-09 17:25:42 黄燚麒(#huang) 2026-07-09 17:12:00 黄燚麒 2026-07-17 16:20:11
33 42 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 导出功能 #### 6.8.1 lot 卡导出 ##### 支持套餐临期30天内所有资产的导出。字段按照卡/设备的导出表进行导出。 | 编号 | 需求 | | -------- | ---------------------------- | | EXPD-001 | lot 卡导出字段新增套餐名称。 | | EXPD-002 | lot 卡导出字段新增使用流量。 | | EXPD-003 | lot 卡导出字段新增剩余流量。 | #### 6.8.2 代理资金概况-预充值钱包流水导出 导出字段: | 字段 | 说明 | | ------------------- | ------------------------------------------------------------ | | 店铺名称 | 代理店铺名称 | | 交易类型 | 充值、扣款、退款等 | | 交易金额 | 以元为单位 | | 状态 | 交易状态 | | 资产类型 | 卡/设备等 | | 资产标识 | ICCID/设备号等 | | 交易时间 | 流水生成时间 | | 交易前金额 | 交易前余额 | | 交易后金额 | 交易后余额 | | 购买套餐名称 | 资产此条扣款记录对应的套餐名称 | | 操作人 | 明确交易执行主体:代理账号 / 平台账号(明确账号名称) | | 交易 ID | 每一笔流水的全局唯一主键,彻底避免重复流水、对账串号、精准定位单条交易 | | 关联业务订单号 | 充值、扣款、退款等交易对应的原始业务订单编号 | | 交易渠道 / 支付方式 | 明确交易来源:余额支付等 | #### 6.8.3 套餐列表导出 导出字段: | 字段 | | -------------- | | 套餐编码 | | 套餐名称 | | 套餐系列名称 | | 套餐类型 | | 套餐时长(月) | | 套餐时长说明 | | 套餐周期类型 | | 套餐天数 | | 真流量额度(MB) | | 虚流量额度(MB) | | 是否启用虚流量 | | 虚流量比例 | | 流量重置周期 | | 到期时间基准 | | 成本价(元) | | 建议售价(元) | | 价格配置状态 | | 状态 | | 上架状态 | | 是否赠送套餐 | | 创建人ID | | 更新人ID | | 创建时间 | | 更新时间 | | 删除时间 | #### 6.8.4 退款管理退款列表导出 导出字段: | 字段 | | ---------------- | | 退款单号 | | 代理店铺名称 | | 关联的支付订单号 | | 资产类型 | | 资产标识 | | 套餐名称 | | 原订单金额 | | 实收金额 | | 可退金额 | | 申请退款金额 | | 实际退款金额 | | 退款到账方式 | | 状态 | | 退款原因 | | 备注 | | 审批备注 | | 退款申请时间 | | 退款完成时间 | | 提交人 | | 部门领导审批人 | | 财务审批人 | | 退款凭证 | #### 6.8.5 换货管理导出 ##### C端客户有自己的唯一标识码。换货管理可以针对该C端客户记录该客户换过几次设备或卡。同时资产本身也做换货标识。 导出字段: | 字段 | | ------------ | | 换货单号 | | 换货类型 | | 换货原因 | | 问题描述 | | 旧资产类型 | | 旧资产标识符 | | 新资产标识符 | | 收货人姓名 | | 收货人电话 | | 收货地址 | | 快递公司 | | 快递单号 | | 状态 | | 创建人 | | 创建时间 | #### 6.8.6 代理充值导出 导出字段: | 字段 | | -------------- | | 充值单号 | | 店铺名称 | | 充值类型 | | 充值金额 | | 实付金额 | | 充值前余额 | | 充值后余额 | | 状态 | | 支付方式 | | 支付通道 | | 运营备注 | | 驳回原因 | | 创建时间 | | 支付时间 | | 完成时间 | | 提交人 | | 部门领导审批人 | | 财务审批人 | | 支付凭证 | | 备注 | 1 0 1(#1) 8.00 激活(#active) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-08 15:49:25 黄燚麒 2026-07-09 16:42:07 黄燚麒(#huang) 2026-07-09 16:40:00 黄燚麒 2026-07-17 16:20:58
34 41 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 代理查询限制(类似酷蛙这种客户) 下级只能看到上级给的信息。api对接客户无法通过他的上级代理查到我们公司的信息。 | 编号 | 需求 | | ------- | -------------------------------------------------------- | | API-001 | 支持配置代理 API 对接查询限制。下级客户/代理无法跨级查询 | 1 0 1(#1) 草稿(#draft) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-08 15:49:25 李昕娉 2026-07-09 16:42:55 2026-07-11 14:24:00 黄燚麒 2026-07-11 14:25:30
35 40 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 套餐设计 | 编号 | 需求 | | ------- | ------------------------------------------ | | PKG-001 | 套餐需标准化管理。 | | PKG-002 | 套餐下架后,正在使用该套餐的客户仍可续费。 | | PKG-003 | 下架套餐续费仅支持客户自己购买。 | | PKG-004 | 下架套餐不可被新购买。 | 1 0 2(#2) 4.00 激活(#active) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-08 15:49:25 黄燚麒 2026-07-09 17:11:34 黄燚麒(#huang) 2026-07-09 17:10:00 黄燚麒 2026-07-17 16:21:43
36 39 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 代理分销码与佣金提现 ##### 员工可作为代理发展人进行标识。(在系统中如何体现?) | 编号 | 需求 | | ------- | ---------------------------------------------------- | | DST-001 | 新建代理时自动建立分销归属关系。 | | DST-002 | 员工可作为代理发展人进行标识。(在系统中如何体现?) | | DST-003 | 佣金提现前,代理必须签署合同。(必填) | | DST-004 | 佣金提现需上传营业执照。(可选) | | DST-005 | 佣金提现需上传法人身份证。(必填) | | DST-006 | 佣金提现可选上传门头照。(可选) | | DST-007 | 佣金提现需上传发票,且公司主体需与合同一致。(可选) | 1 0 3(#3) 40.00 激活(#active) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-08 15:49:25 黄燚麒 2026-07-09 17:43:17 黄燚麒(#huang) 2026-07-09 17:43:00 邹进 2026-07-24 20:18:13
37 38 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 不同渠道额度处理 | 编号 | 需求 | | ------- | ------------------------------------------------------------ | | BPO-009 | 新建代理时新增“是否可授权额度”开关。平台用户账号默认拥有授权额度。 | | BPO-010 | 不同代理可设置不同额度下限。平台用户可根据不同的角色设置不同的额度下限。 | | BPO-011 | 授权额度用于订购套餐、代理余额充值等需要涉及金额的所有模块。 | | BPO-012 | 授权额度代理可显示负数余额。平台用户也可显示负数余额。 | 1 0 2(#2) 7.00 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-08 15:49:25 黄燚麒 2026-07-09 16:58:16 黄燚麒(#huang) 2026-07-09 16:57:00 黄燚麒 2026-07-17 16:22:35
38 37 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 审核流转 | 编号 | 需求 | | ------- | ------------------------------------------------------------ | | APR-001 | 代理可在系统提交充值申请。 | | APR-002 | 提交充值申请后系统展示收款二维码,代理扫码支付。 | | APR-003 | 充值和退款均支持多级审核。 | | APR-004 | 审核环节包括提交人部门领导审核和财务审核。 | | APR-005 | 待审核订单需有消息提示。 | | APR-006 | 审核提醒按流程环节触发,上一审批人完成审批后才提示下一审批人。 | | APR-007 | 审核通过后通知申请人。 | | APR-008 | 审核驳回后通知申请人,并附带驳回原因。 | | APR-009 | 审核流程需对接企业微信审批流程。 | 1 0 2(#2) 16.00 激活(#active) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-08 15:49:25 黄燚麒 2026-07-09 16:57:35 黄燚麒(#huang) 2026-07-09 16:57:00 黄燚麒 2026-07-17 16:23:22
39 36 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 批量订购套餐 1. 内部员工进入批量订购页面。 2. 选择代理、ICCID号段/设备号、订购套餐。或上传 Excel 文件,资产标识支持 ICCID/设备号 3. Excel表头:跳转至6.3会显示。 4. 系统校验导入文件和资产状态。 5. 校验通过的资产从代理余额扣款并完成订购。 6. 校验失败的明细在页面展示失败原因。 7. 系统记录操作员、导入明细、导入数量和导入时间。 | 编号 | 需求 | | ------- | ---------------------------------------------------- | | BPO-001 | 批量订购由内部员工操作。 | | BPO-002 | 支持代理自行充值钱包后,由员工批量订购并从余额扣款。 | | BPO-003 | 支持员工代充值至代理余额后,再批量订购并从余额扣款。 | | BPO-004 | 批量订购无需审核。 | | BPO-005 | 资产标识支持 ICCID/设备号。 | | BPO-006 | 支持 Excel 模板导入。 | | BPO-007 | 需记录操作员、导入明细、导入数量和导入时间。 | | BPO-008 | 导入失败明细需展示在页面,并显示失败原因。 | excel表导入字段: | 字段 | | ----------------------------- | | 资产类型 | | 资产标识 | | 套餐系列名称 | | 套餐名称 | | 代理名称 | | 支付方式:代理商账户/员工账户 | 1 0 1(#1) 8.00 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-08 15:49:25 黄燚麒 2026-07-09 16:31:53 黄燚麒(#huang) 2026-07-09 16:31:00 黄燚麒 2026-07-17 16:24:11
40 35 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 退款审核 (审批均可通过企微进行提醒和显示并将最新状态同步至卡管) 1. 员工提交退款申请。 2. 退款单进入多级审核流程。 3. 按部门领导、财务顺序审批。 4. 当前环节审批完成后,下一环节审批人收到消息提示。 5. 审批通过或驳回后通知申请人。 1 0 2(#2) 7.00 激活(#active) 研发中(#developing) 功能(#feature) 李昕娉 2026-07-08 15:49:25 黄燚麒 2026-07-09 16:56:31 黄燚麒(#huang) 2026-07-09 16:55:00 黄燚麒 2026-07-17 16:25:07
41 34 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 充值审核流程 代理自己充值: 1. 代理在系统提交充值申请。 2. 系统展示收款二维码。 3. 代理扫码支付。 员工代充值:(审批均可通过企微进行提醒和显示并将最新状态同步至卡管) 1. 充值单进入多级审核流程。 2. 提交人部门领导先审批。 3. 财务在上一审批人通过后收到待办提醒并审批。 4. 审批通过后通知申请人。 5. 审批驳回后通知申请人,并展示驳回原因。 1 0 2(#2) 16.00 激活(#active) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-08 15:49:25 黄燚麒 2026-07-09 16:55:42 黄燚麒(#huang) 2026-07-09 16:55:00 黄燚麒 2026-07-17 16:26:05
42 33 物联网卡管系统(#2) /(#0) 7月份迭代计划 [2026-07-10 ~ 2026-07-31](#1) 套餐临期提醒 1. 系统每日计算卡/设备套餐剩余有效期。 2. 命中临期规则后生成临期数据。临期提醒规则:按 15 天、7 天、3 天节点分别进行不同方式的提醒。 3. 企业客户场景:按 15 天、7 天、3 天节点生成临期列表,并通过企业微信推送给对应业务员。 4. 代理端场景(展示):首页展示卡、设备临期数量;资产列表按临期天数高亮。 5. C 端场景(展示):公众号首页在套餐剩余有效期小于或等于 15天时展示续费提醒,并显示立即续费按钮。 6. 当资产续费成功或不再满足临期条件时,临期提醒自动取消。 #### 6.1.1 企业客户临期提醒 | 编号 | 需求 | | ------- | ------------------------------------------------------------ | | EXP-001 | 后台每日生成企业客户临期列表。 | | EXP-002 | 临期节点包括 15 天、7 天、3 天。 | | EXP-003 | 系统需对接企业微信,将临期列表推送给对应业务员。 | | EXP-004 | 同一资产在不同临期节点可重复触发对应节点提醒,但同一节点每日不可重复推送给同一业务员。 | #### 6.1.2 代理端临期提醒 | 编号 | 需求 | | ------- | ------------------------------------------------------------ | | EXP-005 | 代理端首页分别展示临期卡数量和临期设备数量。 | | EXP-006 | 代理端资产列表对临期资产进行颜色标记。 | | EXP-007 | 剩余 15 天标记为粉色,剩余 7 天标记为紫色,剩余 3 天标记为红色。 | | EXP-008 | 剩余 3 天资产在列表中置顶优先展示。 | #### 6.1.3 C 端公众号首页提醒 | 编号 | 需求 | | ------- | ------------------------------------------------------------ | | EXP-009 | 当客户套餐剩余有效期小于或等于 15 天时,公众号首页展示套餐到期提醒。 | | EXP-010 | 提醒展示卡号/设备号、剩余有效期和续费引导文案。 | | EXP-011 | 按钮文案为“立即续费”。 | | EXP-012 | 剩余天数需要按日期每天自动更新。 | | EXP-013 | 当套餐已续费或不再满足临期条件时,提醒不再展示。 | 推荐展示文案: 您的套餐即将到期 卡号/设备号:xxx 剩余有效期:xx 天 为避免到期后影响正常使用,请您提前完成续费。 1 0 1(#1) 8.00 激活(#active) 已计划(#planned) 功能(#feature) 李昕娉 2026-07-08 15:49:25 黄燚麒 2026-07-09 16:30:06 黄燚麒(#huang) 2026-07-09 16:29:00 黄燚麒 2026-07-17 16:26:41
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
271
272
273
274
275
276
277
278
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
312
313
314
315
316
317
318
319
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
360
361
362
363
364
365
366
367
400
401
402
403
404

View File

@@ -4,15 +4,17 @@
## 1. success 示例
### 1.1 设备限速(`device_speed_limit`
### 1.1 IoT 卡固定档位限速(`card_speed_tier`
```bash
curl -X POST "http://127.0.0.1:8080/api/admin/devices/<identifier>/speed-limit" \
curl -X PUT "http://127.0.0.1:8080/api/admin/iot-cards/<iccid>/speed-tier" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"speed_limit":1024}'
-d '{"code":3}'
```
该入口只接受 IoT 卡 ICCID设备没有限速接口也不通过设备当前绑定卡间接限速。
### 1.2 资产轮询开关(`asset_polling_status`
```bash

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,44 @@
# 资产套餐批量订购功能总结
## 交付范围
本功能复用现有对象存储、Asynq、统一异步任务五态和后台单笔订单 Service为一批卡或设备统一购买一个套餐
- `POST /api/admin/storage/upload-url` 使用 `purpose=batch_purchase` 获取只允许 `.csv` 的上传地址和稳定 `file_key`
- `POST /api/admin/asset-package-batch-orders` 接收 CSV `file_key`、一个 `package_id`、整批统一的 `wallet|offline` 支付方式及可选线下凭证;请求不选择代理。
- `GET /api/admin/asset-package-batch-orders` 分页查询任务,默认 20、最大 100可按统一五态筛选。
- `GET /api/admin/asset-package-batch-orders/:id` 返回任务汇总和逐行成功/失败明细。
- 平台可查看全部任务;代理只能查看自己及下级店铺创建的任务,权限上下文缺失时失败关闭。
## CSV 契约
- 文件必须为 UTF-8 编码的 `.csv`,允许 UTF-8 BOM最大 10MB、最多 1000 个业务行。
- 文件只能有一列,每行填写一个资产标识。首行可使用 `资产标识``identifier``iccid``iccid/虚拟号` 表头,也可直接从第一行填写数据。
- 空资产标识作为行级失败;多列、非法 CSV、非 UTF-8、空文件和超限作为任务级失败在任何订单写入前终止。
- 同一输入标识重复时仅第一行进入订单规则;不同标识解析为同一资产时复用订单幂等结果,后续行记录重复原因,不重复下单或扣款。
## 支付和订单规则
- 整批只选择一个套餐和一种支付方式,不选择代理。每行由现有订单 Service 根据资产当前归属解析结算关系、套餐授权、价格和钱包。
- `wallet` 不允许凭证,支持超级管理员、平台和代理账号;逐行复用现有代理主钱包扣款、信用边界、成功流水、套餐激活、佣金任务和订单幂等规则。
- `offline` 仅允许超级管理员或平台账号,必须提交 15 个凭证 Key每个成功订单保存同一批凭证快照并按现有线下订单规则立即激活不扣钱包。
- 每行独立处理,业务失败不回滚其他成功行。全部行业务失败仍表示任务完成,通过 `success_count=0``fail_count=total_count` 表达。
## 任务与幂等
- 任务状态固定为 `1:待处理, 2:处理中, 3:已完成, 4:已失败, 5:已取消`;当前版本没有取消入口,仅保留统一状态契约。
- Asynq 载荷只包含结构化 `task_id`,不传 CSV 字节、临时路径或预序列化 `[]byte`
- Worker 通过任务状态和超时时间条件领取任务;重复消息发现任务正在有效执行或已终结时直接跳过。
- 超过任务最长执行时间仍停留在“处理中”的记录可被重新领取,用于 Worker 崩溃后恢复;未超时的处理中任务不会并发重入。
- Worker 使用任务快照恢复创建人权限;代理创建的任务仅能处理自己及下级店铺资产,权限范围查询失败时收紧为仅自己店铺,不会按平台无限制权限执行。
- 单行继续复用订单 Service 的资产级锁、Redis 业务键和钱包订单数据库幂等指纹,重复消费不得重复创建订单或扣款。
## 数据与发布
- 迁移 `000192_create_asset_package_batch_order_task` 新增 `tb_asset_package_batch_order_task`,保存套餐/操作者/支付/文件快照、五态、汇总及最多 1000 行 JSONB 结果;不建立外键。
- Worker 必须配置 Redis/Asynq 和对象存储,并监听 `asset:package:batch_order` 独立队列。
- 回滚时先隐藏创建入口并停止新任务,等待已领取任务完成。已经创建的订单、钱包流水、套餐使用和任务结果均为业务事实,不做反向删除。
## 当前验证边界
本次未运行测试、完整构建、LSP 或迁移;按用户后续明确要求已运行 OpenAPI 生成器,并执行 `gofmt`、只读一致性检查和 `git diff --check`。真实对象存储上传、Worker 消费、钱包扣款和线下订单需在后续联调流程验证。

View File

@@ -0,0 +1,59 @@
# 业务数据导出功能总结
## 公共交付方式
业务导出复用现有 `POST /api/admin/export-tasks` 异步任务入口、DataSource 注册、Asynq 分片、对象存储和 CSV/XLSX 汇总流程。前端只提交 `scene``format` 和当前列表的 `query.filters`,不另外选择导出列。
Worker 使用任务创建时固化的用户类型、店铺和下级店铺范围,不从运行时上下文猜测权限。`Count``Fetch` 使用同一套筛选和权限条件,分片按稳定 ID 顺序读取。
## IoT 卡导出
- 场景编码:`iot_card`
- 继续沿用现有卡列表筛选和店铺层级权限。
- 在原有 ICCID、MSISDN、设备、运营商、店铺、实名和网络状态列后追加“套餐名称”、“使用流量(MB)”和“剩余流量(MB)”。
- 套餐字段取当前生效主套餐,名称优先使用购买时快照;剩余流量由套餐真流量总量减已用量得出,超额使用时收敛为 `0`
## 套餐列表导出
- 场景编码:`package`
- 支持现有套餐列表的 `package_name``series_id``status``shelf_status``package_type` 筛选。
- 平台和超级管理员导出套餐本体数据;代理只导出已分配给自己店铺且分配状态启用的非赠送套餐,成本价和上下架状态取自当前店铺分配记录。
- 固定输出已确认的 25 列:编码、名称、系列、类型、时长、周期、真/虚流量、虚流量配置、重置周期、到期基准、价格、状态、赠送标识、创建/更新人及时间。当前列表不返回软删除套餐,因此“删除时间”按契约保留为空列。
- 金额从数据库的“分”转为两位小数的“元”;未配置建议售价时输出空值,不用 `0.00` 冒充已配置价格。
## 代理主钱包流水导出
- 场景编码:`agent_wallet_transaction`
- 仅导出主钱包流水,代理按任务创建时固化的自己及下级店铺范围读取;平台和超级管理员可读取全部有权数据。
- 支持现有流水列表的 `shop_id``transaction_type``start_date``end_date``asset_identifier` 筛选,纯日期截止时间包含当天。
- 固定输出 14 列:店铺、交易类型、交易金额、状态、资产类型与标识、交易时间、交易前后金额、购买套餐名称、操作人、交易 ID、关联业务订单号、支付方式。
- 金额沿用钱包流水中的分值事实并格式化为两位小数的元;套餐名称优先读取订单项快照,历史缺失时回退流水元数据。历史操作账号即使已软删除仍保留名称展示,但不参与权限判断。
## 代理充值导出
- 场景编码:`agent_recharge`
- 支持现有充值列表的 `shop_id``status``start_date``end_date` 筛选,代理权限使用任务创建时固化的店铺范围。
- 固定输出 18 列:充值单号、店铺、充值类型、充值/实付金额、充值前后余额、状态、支付方式、运营备注、驳回原因、三个业务时间、提交人、审批来源、审批状态和支付凭证。
- 充值金额取充值单事实;成功入账后的实付金额和余额前后值取首条匹配的成功主钱包充值流水,缺失时留空,不用零值冒充。
- 审批字段只读取本地通用审批实例,不逐行实时调用企业微信。支付凭证按业务需要输出明文对象存储 Key并按原顺序以逗号连接Integration Log 仍不得记录 Secret、access_token、media_id 或附件正文。
## 退款导出
- 场景编码:`refund`
- 支持退款列表的 `status``order_id``shop_id``asset_identifier` 筛选,代理按任务创建时固化的自己及下级店铺范围导出。
- 固定输出 21 列:退款单号、店铺、支付订单号、资产、套餐、五项金额、退款状态与原因、审批备注、审批来源与状态、退款处理状态、申请/审批时间、提交人和退款凭证。
- 订单号和资产标识使用退款申请快照;套餐名称优先使用指定套餐使用记录快照,否则聚合同一订单的订单项快照。原订单金额、可退金额、申请金额和实际退款金额均读取既有订单或退款事实,来源缺失时留空,不用零值冒充。
- 退款处理状态仅从退款状态、佣金回扣和资产处理完成标记稳定推导。当前模型没有可靠的当前审批节点和逐节点审批记录结构,因此不输出无意义空列;审批来源与状态只读取本地通用审批实例,不实时调用企业微信。
- 退款凭证按业务需要输出明文对象存储 Key。历史软删除账号仍可用于提交人名称展示但不参与权限判断。
## 换货导出
- 场景编码:`exchange`
- 支持换货列表的 `status``flow_type``old_asset_keyword``new_asset_keyword``created_at_start``created_at_end` 筛选;新旧资产关键词继续按 AND 组合,并按卡/设备当前权威标识命中资产 ID。
- 固定输出 15 列:换货单号、流程类型、原因、问题描述/备注、新旧资产标识、收货信息、物流信息、状态、创建人和创建时间。
- 新旧资产列直接使用换货单已固化的权威快照,卡为完整 ICCID设备按虚拟号、IMEI、SN 的既定优先级保存;不会在导出时重新拼接或覆盖历史快照。
- 收货人电话、地址等业务字段按用户确认保持明文输出。代理权限使用任务创建时固化的店铺层级范围,历史软删除创建人只用于名称展示。
## 当前验证边界
本次不运行测试、完整构建、LSP 或迁移;按用户后续明确要求已运行 OpenAPI 生成器。静态收口使用 `gofmt`、只读一致性检查和 `git diff --check`真实数据行数、筛选、分片、CSV/XLSX 文件和下载链接由后续联调验证。

View File

@@ -0,0 +1,51 @@
# 设备 CSV 批量分配功能总结
## 功能边界
本功能复用现有设备导入任务的对象存储、任务状态、Asynq 队列、进度统计和失败明细能力。复用的是异步任务外壳,原多列 Excel 创建设备与绑卡逻辑保持不变。
新增任务创建接口:
```text
POST /api/admin/devices/import/allocations
```
请求参数:
```json
{
"file_key": "device-batch-allocations/2026/07/25/example.csv",
"operation_type": "assign_shop",
"target_id": 1001
}
```
- `assign_shop``target_id` 为目标代理店铺 ID。
- `assign_series``target_id` 为目标套餐系列 ID。
- 每个任务只能选择一种操作和一个目标,不能逐行指定不同目标。
## CSV 格式
CSV 只能有一列,每行填写一个设备标识,支持 VirtualNo、IMEI 或 SN。首行可选使用 `device_identifier``设备标识` 表头。文件必须使用上传用途 `device_batch_allocation` 获取对象存储 Key最多 1000 个设备且不超过 10MB。
## 规则复用与幂等
Worker 批量解析设备后调用现有业务方法:
- 分配代理调用 `DeviceService.AllocateDevices`,沿用直属下级、平台库存、绑定卡归属同步、分配记录和资产审计规则。
- 设置套餐系列调用 `DeviceService.BatchSetSeriesBinding`,沿用套餐系列有效性、代理授权、设备归属和资产审计规则。
任务创建时冻结操作者 ID、类型和店铺 IDWorker 重建权限上下文不能因异步执行丢失数据范围。重复消费时已经属于目标店铺或已经绑定目标系列的设备直接按成功处理任务完成或失败后不重复执行。CSV 内重复设备记录为跳过,不产生重复副作用。
## 任务查询与回滚
继续使用现有接口查询任务:
```text
GET /api/admin/devices/import/tasks
GET /api/admin/devices/import/tasks/:id
```
响应新增 `operation_type``operation_name``target_id`,逐行失败原因继续通过原详情结构返回。
回滚应用版本前应先停止新任务入口并等待处理中的任务结束。迁移新增列保持兼容,不删除既有任务;已经完成的设备归属、套餐系列关系、分配记录和资产审计不得通过清表回滚,应使用现有回收或系列绑定接口前向修正。

View File

@@ -165,6 +165,36 @@ JUNHONG_WORKER_ROLE=consumer
JUNHONG_WORKER_INSTANCE_NAME=worker-consumer-1
```
### Gateway 服务
| 环境变量 | 默认值 | 说明 |
|---------|--------|------|
| `JUNHONG_GATEWAY_BASE_URL` | 默认配置文件值 | Gateway API 基础地址,配置后必须为 HTTP/HTTPS URL |
| `JUNHONG_GATEWAY_APP_ID` | 默认配置文件值 | Gateway 应用 ID |
| `JUNHONG_GATEWAY_APP_SECRET` | 默认配置文件值 | Gateway 应用密钥 |
| `JUNHONG_GATEWAY_TIMEOUT` | `60` | Gateway 请求超时秒数,允许 5300 |
生产环境必须通过环境变量覆盖应用身份和密钥。IoT 卡固定档位限速只向 Gateway 发送卡 ICCID 和档位编码,不支持设备限速。
### 企业微信 Adapter
| 环境变量 | 默认值 | 说明 |
|---------|--------|------|
| `JUNHONG_WECOM_BASE_URL` | `https://qyapi.weixin.qq.com` | 企业微信 API 基础地址 |
| `JUNHONG_WECOM_TIMEOUT` | `10s` | 企业微信外部请求超时时间 |
| `JUNHONG_WECOM_CREDENTIAL_ENCRYPTION_KEY` | `""` | 启用企业微信功能前必填32 字节随机密钥的 Base64 文本 |
可使用 `openssl rand -base64 32` 生成加密密钥。密钥缺失或格式错误不会阻止不使用企微的环境启动,但企业微信配置保存、查询和连接测试会按失败关闭处理。更换密钥前必须先制定已有凭据的重新加密方案,否则历史密文将无法读取。
### 审批旧入口切换
| 环境变量 | 默认值 | 说明 |
|---------|--------|------|
| `JUNHONG_APPROVAL_LEGACY_REFUND_MANUAL_ENABLED` | `true` | 是否保留退款人工通过/拒绝入口;仅在企微真实闭环和存量清单完成后改为 `false` |
| `JUNHONG_APPROVAL_LEGACY_OFFLINE_RECHARGE_PAY_ENABLED` | `true` | 是否保留线下充值人工确认入口;仅在企微真实闭环和存量清单完成后改为 `false` |
两个开关默认开启,避免部署新版本时中断存量旧 provider。关闭后接口仍保留路由但返回“入口已停用”前端只展示本地批量投影的审批渠道和状态。配置变更需要重启 API 实例Worker 不依赖这两个旧入口开关。
### 限流中间件
| 环境变量 | 默认值 | 说明 |

View File

@@ -5,8 +5,8 @@
本文档提供 Gateway 客户端所有 API 接口的完整参考,包括请求参数、响应格式和使用示例。
**API 分类**
- 流量卡管理(7 个接口)
- 设备管理(7 个接口)
- 流量卡管理(8 个接口)
- 设备管理(6 个接口)
**基础信息**
- 协议HTTPS
@@ -270,7 +270,43 @@ fmt.Printf("实名链接: %s\n", resp.Link)
---
### 7. 批量查询(预留)
### 7. 设置流量卡固定限速档位
按 ICCID 设置或恢复流量卡固定限速档位。Gateway 不提供设备限速能力,禁止传入设备 ID、IMEI 或通过设备绑定关系间接调用。
**方法**: `SetCardSpeedTier`
**请求参数**:
```go
type CardSpeedTierReq struct {
CardNo string `json:"cardNo" validate:"required"`
Code string `json:"code" validate:"required"`
}
```
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| CardNo | string | ✅ | 流量卡 ICCID |
| Code | string | ✅ | 固定档位编码:`-1` 恢复不限速,`0` 0kbps`1` 128Kbps`2` 512Kbps`3` 1Mbps`4` 2Mbps`5` 10Mbps`6` 20Mbps`7` 50Mbps`8` 100Mbps |
**响应参数**: 无(成功返回 nil失败返回 error
**使用示例**:
```go
err := client.SetCardSpeedTier(ctx, &gateway.CardSpeedTierReq{
CardNo: "898608070422D0010269",
Code: "3",
})
if err != nil {
return err
}
fmt.Println("流量卡固定限速档位设置成功")
```
---
### 8. 批量查询(预留)
批量查询流量卡信息(暂未实现)。
@@ -427,48 +463,7 @@ for _, slot := range resp.Slots {
---
### 3. 设置设备限速
设置设备的上行和下行速率限制。
**方法**: `SetSpeedLimit`
**请求参数**:
```go
type SpeedLimitReq struct {
DeviceID string `json:"deviceId" validate:"required"`
UploadSpeed int `json:"uploadSpeed" validate:"required,min=1"`
DownloadSpeed int `json:"downloadSpeed" validate:"required,min=1"`
Extend string `json:"extend,omitempty"`
}
```
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| DeviceID | string | ✅ | 设备 ID/IMEI |
| UploadSpeed | int | ✅ | 上行速率KB/s最小1 |
| DownloadSpeed | int | ✅ | 下行速率KB/s最小1 |
| Extend | string | ❌ | 扩展字段 |
**响应参数**: 无(成功返回 nil失败返回 error
**使用示例**:
```go
err := client.SetSpeedLimit(ctx, &gateway.SpeedLimitReq{
DeviceID: "123456789012345",
UploadSpeed: 100,
DownloadSpeed: 500,
})
if err != nil {
return err
}
fmt.Println("限速设置成功")
```
---
### 4. 设置设备 WiFi
### 3. 设置设备 WiFi
设置设备的 WiFi 信息。
@@ -516,7 +511,7 @@ fmt.Println("WiFi设置成功")
---
### 5. 设备切换卡
### 4. 设备切换卡
切换设备当前使用的卡到指定的目标卡。
@@ -554,7 +549,7 @@ fmt.Println("切换卡成功")
---
### 6. 设备恢复出厂设置
### 5. 设备恢复出厂设置
将设备恢复到出厂设置状态。
@@ -589,7 +584,7 @@ fmt.Println("恢复出厂设置成功")
---
### 7. 设备重启
### 6. 设备重启
远程重启设备。

View File

@@ -212,28 +212,28 @@ func (s *Service) GetDeviceSlots(ctx context.Context, imei string) ([]gateway.Sl
}
```
#### 设置设备限速
#### 设置流量卡固定限速档位
```go
func (s *Service) SetDeviceSpeed(ctx context.Context, imei string, uploadKBps, downloadKBps int) error {
err := s.gatewayClient.SetSpeedLimit(ctx, &gateway.SpeedLimitReq{
DeviceID: imei,
UploadSpeed: uploadKBps,
DownloadSpeed: downloadKBps,
func (s *Service) SetCardSpeedTier(ctx context.Context, iccid string, code int) error {
err := s.gatewayClient.SetCardSpeedTier(ctx, &gateway.CardSpeedTierReq{
CardNo: iccid,
Code: strconv.Itoa(code),
})
if err != nil {
return errors.Wrap(errors.CodeGatewayError, err, "设置限速失败")
return errors.Wrap(errors.CodeGatewayError, err, "设置流量卡固定限速档位失败")
}
s.logger.Info("设置限速成功",
zap.String("imei", imei),
zap.Int("upload", uploadKBps),
zap.Int("download", downloadKBps),
s.logger.Info("设置流量卡固定限速档位成功",
zap.String("iccid", iccid),
zap.Int("code", code),
)
return nil
}
```
Gateway 限速对象只有流量卡 ICCID。设备没有限速接口业务代码不得传入设备 ID、IMEI也不得先解析设备当前绑定卡再间接限速。
#### 设置设备 WiFi
```go

View File

@@ -0,0 +1,55 @@
# IoT 卡固定档位限速功能总结
## 功能边界
本功能只允许后台账号为有权限的 IoT 卡设置 Gateway 固定限速档位。限速对象始终是请求路径中的卡 ICCID设备没有限速接口系统也不会查询设备当前绑定卡后间接限速。
接口:
```text
PUT /api/admin/iot-cards/:iccid/speed-tier
```
请求体:
```json
{
"code": 3
}
```
## 固定档位
| code | 含义 |
| ---: | --- |
| -1 | 恢复不限速 |
| 0 | 0kbps |
| 1 | 128Kbps |
| 2 | 512Kbps |
| 3 | 1Mbps |
| 4 | 2Mbps |
| 5 | 10Mbps |
| 6 | 20Mbps |
| 7 | 50Mbps |
| 8 | 100Mbps |
前端只能提交上述固定档位,不允许输入任意速率。`-1``0` 是不同操作,不能混用。
## 权限与调用链
- 仅超级管理员、平台账号和代理后台账号可调用。
- 通过现有 `IotCardStore.GetByICCID` 查询卡并应用当前数据权限;不存在和无权限统一返回“无权限操作该资源或资源不存在”。
- 外呼 Gateway 使用 `/flow-card/speedLimit`,请求业务参数只有 `cardNo``code`,其中 `cardNo` 必须是已校验的卡 ICCID。
- 不根据套餐流量、运营商或设备绑定关系自动计算或转换档位。
## 审计与结果未知
每次实际外呼前先创建 `pending` Integration Log记录卡、档位、操作者和请求关联标识外呼完成后终结为 `success``failed``unknown`。资产操作审计使用 `card_speed_tier` 动作编码记录操作者、卡、档位及结果。
Gateway 请求超时时外部是否已生效无法确定。接口返回可识别的结果未知错误Integration Log 保存人工恢复策略:通过 Gateway 运维侧按 ICCID 核对当前档位后,再决定是否重试。系统不会盲目声称成功,也不会自动重复提交。
## 联调与回滚
联调需覆盖全部固定档位、越权卡、Gateway 明确失败和请求超时,并确认设备详情和设备 API 中不存在限速入口。
回滚时可隐藏前端入口并回退应用版本;已经产生的资产操作审计和 Integration Log 不得删除或清空。由于本功能不保存本地“当前限速档位”,不涉及数据库状态回滚。

View File

@@ -0,0 +1,29 @@
# UR#33 套餐临期提醒功能总结
## 交付范围
- 新增 `GET /api/admin/expiring-assets`,平台与代理共用当前后台认证和店铺层级权限。
- 仅返回预计最终到期状态为 `exact`、剩余 0 至 15 个上海自然日的卡和设备。
- 返回卡、设备及合计数量,提供 `pink/purple/red` 高亮等级和 0 至 3 天优先标识。
- 每日上海时间 03:00 扫描 15、7、3 天节点,向资产关联个人客户写入站内通知 Outbox。
- C 端继续复用既有通知列表、未读数和弹窗机制,不新增营销、短信或企业微信提醒。
## 数据与幂等
- 临期时间复用 `internal/query/packageexpiry` 的最终到期算法,不建立临期状态快照。
- 列表候选使用当前主套餐到期时间预筛,再批量计算当前与排队主套餐的最终到期时间。
- 通知事件 ID 固化资产类型、资产 ID、到期日、节点和个人客户 ID定时任务、Outbox Relay 和通知消费者重复执行均不会重复通知。
- `000183_add_package_expiry_scan_indexes` 仅增加卡、设备主套餐到期扫描索引,不新增外键。
## 权限和异常边界
- 平台与超级管理员读取全局范围;代理只读取当前认证上下文的下级店铺范围。
- 代理权限范围为空时查询固定返回空集,不能因空切片退化为全局读取。
- `shop_id` 只缩小既有权限范围;企业账号禁止调用。
- 无关联个人客户的资产正常跳过通知,不影响临期列表事实。
## 联调与回滚
- 前端按 `expiry_level` 渲染颜色,按 `is_priority` 置顶,不自行重算阈值。
- 回滚应用版本后可删除迁移新增的两个扫描索引;已产生的通知和 Outbox 事实不得清表。
- 本 Change 未运行测试、完整构建、LSP 和迁移;按用户后续明确要求已运行 OpenAPI 生成器,另执行 `gofmt`、只读一致性检查和 `git diff --check`

View File

@@ -0,0 +1,125 @@
# 企业微信应用连接 Adapter 功能总结
## 交付范围
本切片提供企业微信自建应用的最小连接能力,不迁移或改造通用审批核心:
- `POST /api/admin/wecom/applications`:按 `corp_id + agent_id` 创建或更新应用配置。
- `GET /api/admin/wecom/applications`:分页查询应用配置,默认每页 20、最大 100向超级管理员返回可直接编辑的明文 Secret、回调 Token 和 EncodingAESKey。
- `POST /api/admin/wecom/applications/:id/test`:失效旧缓存并测试能否取得 access_token仅返回测试是否成功不返回 access_token。
- `PUT /api/admin/wecom/applications/:id/default-creator`:从应用当前可见成员中选择代理等非企微账号使用的默认审批发起人。
- `POST /api/admin/wecom/applications/:id/members/sync`:拉取应用可见范围内的成员并原子刷新本地选择快照。
- `GET /api/admin/wecom/applications/:id/members`:按姓名或 userid 搜索并分页选择最近同步的可见成员。
- `PUT /api/admin/accounts/:id/wecom-binding`:把系统账号绑定到管理员明确选择的 `(corp_id, userid)`,同时保存姓名快照。
- `PUT /api/admin/wecom/scenes/:business_type`:配置已知 `template_id` 和业务字段控件映射,保存前实时读取模板详情校验。
- `GET /api/admin/wecom/scenes`:分页查询退款、员工线下代充值两个稳定业务场景的当前模板映射。
- 应用凭据保存、查询和连接测试仅允许超级管理员;通讯录同步、选择和账号绑定允许超级管理员或平台账号。
## 凭据与配置
管理端按业务需要使用明文填写和读取连接参数,服务端在写入 PostgreSQL 前使用 AES-256-GCM 加密。数据库不保存明文,日志、配置审计和 Integration Log 也不记录明文、密文或 access_token。
启用前必须设置 `JUNHONG_WECOM_CREDENTIAL_ENCRYPTION_KEY`,值为 32 字节随机密钥的 Base64 文本。未配置或格式错误时服务仍可启动,但企业微信相关业务接口失败关闭。
## Token 缓存与并发控制
- access_token 使用应用配置 ID 隔离缓存TTL 按企微返回有效期减去 5 分钟刷新窗口计算。
- 缓存未命中时通过 Redis 单应用短锁限制并发回源;未取得锁的请求最多等待 2 秒读取回填结果。
- Redis 读取或加锁故障时记录中文告警并受控直连企微,确保缓存故障不直接中断连接测试。
- 配置更新后立即失效该应用 token 缓存。
## 通讯录与账号绑定
- 同步只读取 `userid`、姓名和部门 ID不读取手机号或邮箱也不做手机号、姓名自动匹配。
- `tb_wecom_member` 仅保存应用可见成员的选择快照;同步时把不再可见的成员标记为不可见,不建立本地部门或组织模型。
- 成员 userid 入库前统一转为小写,身份键按 `(corp_id, userid)` 管理;同一企微成员不能同时绑定多个未删除系统账号。
- 账号列表和详情返回 `wecom_corp_id``wecom_userid``wecom_name``wecom_bound`
- 应用禁用或成员不再可见后,不能创建新的账号绑定;历史绑定快照保留,供审批提交前再次校验。
## 默认审批发起人
- 内部超级管理员或平台员工已绑定企微成员且仍在应用可见范围内时,审批优先以本人 userid 发起。
- 代理和企业账号不要求绑定企微,始终使用应用配置的默认审批发起人;内部员工未绑定时也可回退到默认发起人。
- 默认发起人只能从最近同步的应用可见成员中选择。未配置、应用禁用或成员不再可见时,新审批在业务事实写入前失败关闭。
- 默认企微发起人只承担 `applyevent.creator_userid` 身份;本地业务单和通用审批实例继续保存真实代理或员工提交人,企微表单应通过业务字段映射展示真实申请人信息。
## Integration Log
每次真实调用 `/cgi-bin/gettoken`、可见成员接口、`/cgi-bin/oa/gettemplatedetail`、临时素材上传或 `/cgi-bin/oa/applyevent` 前先创建公共 Integration Log完成后记录 HTTP 状态、企微错误码、耗时和安全摘要。请求摘要只包含应用配置 ID、corp_id、agent_id、template_id、控件数量和附件大小等非密钥标识响应摘要不保存 access_token、media_id、附件正文或外部响应正文。
## 审批场景与模板映射
- 稳定业务类型固定为 `refund_approval``offline_recharge_approval`,业务代码不直接写死企微模板 ID。
- 模板必须先在企业微信后台创建;本系统不创建模板,也不保存审批节点或审批人规则。
- 保存映射时调用模板详情,逐项校验控件 ID、控件类型和选择项 key并要求模板所有必填控件都有映射模板结构已变化时拒绝覆盖当前有效配置。
- 员工线下代充值只允许映射 `recharge_no``shop_id``shop_name``amount``amount_cent``payment_voucher_key``remark``submitter_id``submitter_name`
- 退款只允许映射 `refund_no``order_id``order_no``asset_identifier``asset_type``actual_received_amount``requested_refund_amount``refund_voucher_key``refund_reason``package_usage_id``submitter_id``submitter_name`
- `template_snapshot` 只保存控件 ID、类型、标题、必填标识和选择项 key 的最小快照。
## 数据库变更
- 迁移 `000184_create_wecom_application` 新增 `tb_wecom_application`,以 `(corp_id, agent_id)` 作为未删除记录的唯一身份。
- 迁移 `000185_add_wecom_member_binding` 新增 `tb_wecom_member`,并为 `tb_account` 增加企微绑定字段和唯一索引。
- 迁移 `000186_create_wecom_approval_scene` 新增当前业务场景、模板和控件映射配置表。
- 迁移 `000187_add_wecom_approval_submission` 增加应用默认发起人,并新增 `tb_wecom_approval_context` 保存不含凭据的模板、发起人和提交状态快照。
- 迁移 `000188_add_wecom_approval_detail_snapshot` 增加最近企微状态、权威详情快照和同步时间。
- 迁移 `000189_add_wecom_approval_recovery_timestamps` 增加实际提交尝试时间和最近恢复时间,周期恢复不会覆盖原始查询时间窗。
- 迁移 `000190_add_agent_recharge_approval_instance` 为员工线下代充值记录增加唯一通用审批实例引用,不建立外键。
- 迁移 `000191_add_refund_approval_instance` 为退款申请增加唯一通用审批实例引用,不建立外键。
- 所有迁移都不建立数据库外键。
## Approval Port 与异步提交
- 企微 Adapter 在业务事务前重新校验场景、应用、发起人可见性和模板指纹,通过后返回不含 Secret/access_token 的短期准备结果。
- 业务事务复用通用 Approval Port原子保存业务申请、`tb_approval_instance`、企微渠道上下文和 `approval.submission.requested` Outbox。
- Worker 领取事件后先条件更新为“请求处理中”,再按业务字段映射组装控件;文件控件从对象存储下载并上传企微临时素材,单单最多 6 个、单文件不超过 20MB。
- `applyevent` 明确成功时同时保存 `sp_no` 并把通用实例置为审批中;企微明确拒绝时记提交失败;请求已发出但超时、断连或响应不可确认时记结果未知,禁止 Outbox 自动创建第二张审批单。
- 结果未知记录明确恢复策略,主动恢复优先读取成功提交 Integration Log 中已安全保存的 `sp_no`;没有成功日志时,按应用、模板、发起人和实际提交时刻前后 5 分钟调用批量单号接口。
- 批量查询单页最多 100 条并使用 `new_cursor/new_next_cursor` 分页;排除已关联本地实例的单号后,只有唯一候选才允许恢复关联,多候选或无候选继续保持结果未知,绝不自动重提 `applyevent`
## 加密回调与标准决策
- 回调地址为 `GET/POST /api/callback/wecom/approval/:application_id`,企业微信后台为每个应用填写对应应用配置 ID。
- GET 校验 `msg_signature`,使用当前应用的 Token 和 EncodingAESKey 执行 AES-256-CBC/PKCS#7 解密,并原样返回 `echostr` 明文。
- POST 从 XML 读取 `Encrypt`,校验签名和 `receiveid=corp_id`,只接受 `sys_approval_change`;入站 Integration Log 只保存密文载荷哈希和稳定幂等键。
- 回调在成功写入幂等记录并提交结构化 Asynq 任务后立即返回纯文本 `success`,不在 HTTP 请求内更新退款或充值状态。
- Worker 使用 `SpNoStr` 调用 `oa/getapprovaldetail` 取得权威详情,保存最近状态和详情快照,再把 2/3/4/6/7 翻译为 approved/rejected/cancelled/revoked_after_approved/deleted 并调用现有 `SyncDecisionService`
- 标准终态继续由通用审批核心在单事务内写状态、决策投递事实和终态 Outbox企微 Adapter 不直接执行退款或钱包入账。
## 主动恢复、轮询与读取投影
- Asynq Scheduler 每 2 分钟提交 `wecom:approval:recovery`;提交中状态占用超过 5 分钟时保守转为结果未知,不恢复为待提交。
- 已关联 `sp_no` 且通用审批仍为审批中的记录,按最近成功同步时间批量扫描并提交结构化 `wecom:approval:sync` 任务,继续复用同一详情同步和标准决策链路。
- 结果未知记录单轮最多处理 10 条,避免最坏外部超时阻塞整个周期;每次 `getapprovalinfo``getapprovaldetail` 真实外呼均写 Integration Log。
- 未知企微回调会从权威详情取得模板、申请人和提交时间,仅在本地结果未知记录唯一匹配时恢复;真正无关的审批回调记为 ignored不反复重试。
- `ApprovalProjectionResolver` 只从 `latest_detail_snapshot.sp_record` 读取审批节点 userid按应用企业 ID 分组后用一次账号批量查询映射系统账号;映射不到时账号 ID/名称为空,不影响审批状态,也不实时调用企微。
## 员工线下代充值审批
- `POST /api/admin/agent-recharges` 继续作为创建入口;当 `payment_method=offline` 时,仅平台员工或超级管理员可提交,并要求 15 个对象存储凭证 Key。
- 创建前校验提交人账号、目标店铺、正常主钱包、企微应用、场景、模板和实际发起人;任一前置不完整时,不写业务单、审批实例或 Outbox。
- 充值单保存真实系统提交人;内部员工有效绑定优先本人发起企微审批,否则使用应用默认发起人。默认发起人只作为企微 creator不覆盖本地真实提交人。
- 充值单、提交人/金额/凭证明文快照、通用审批实例、企微渠道上下文和 `approval.submission.requested` 在同一 GORM 事务内保存。
- 标准 `approved` 终态通过统一钱包 `PostingService` 入账,稳定幂等键为 `topup + recharge_record_id``rejected/cancelled/deleted` 只终结申请,不修改钱包;`revoked_after_approved` 不自动冲正。
- 列表和详情按一批审批实例查询 `provider/status/status_name`,不逐条访问企微。带审批实例的新申请禁止通过旧人工确认或驳回入口绕过企微;旧入口暂时仅服务存量记录,是否整体停用由后续切换任务控制。
## 退款企微审批
- `POST /api/admin/refunds` 在既有订单、金额、资产和权限校验后,先检查企微应用、退款场景、模板和实际发起人,再原子保存退款申请、真实提交人/订单/金额/凭证明文快照、通用审批实例、企微上下文和提交 Outbox。
- 代理账号始终使用应用默认企微发起人,平台员工有效绑定优先本人、否则回退默认发起人;本地退款申请和通用审批实例始终保存真实系统提交人。
- 标准 `approved` 终态条件更新退款单和订单,复用统一代理主钱包退款及资产钱包退款逻辑;代理主钱包按退款 ID、资产钱包按退款单号复核成功流水重复终态不会重复回款。
- `rejected/cancelled/deleted` 将本地申请终结为未退款状态,并在 `reject_reason` 保留对应企微终态;`revoked_after_approved` 不自动反向改账,需后续人工前向处理。
- 佣金回扣按佣金记录锁定、唯一业务引用和状态失效实现可重入;套餐失效沿订单/换货迁移关系复用既有幂等路径。只有佣金与资产后处理都完成后,标准决策投递才标记成功,失败会释放租约等待重试。
- 退款列表和详情批量读取审批渠道、审批状态和中文状态名,不实时调用企微。带审批实例的新退款禁止旧人工通过、拒绝或退回入口绕过企微;存量旧 provider 的入口切换由后续发布任务控制。
## 旧审批入口切换
- `JUNHONG_APPROVAL_LEGACY_REFUND_MANUAL_ENABLED``JUNHONG_APPROVAL_LEGACY_OFFLINE_RECHARGE_PAY_ENABLED` 默认均为 `true`,避免新版本部署时中断 `approval_instance_id IS NULL` 的存量旧 provider。
- 真实企微闭环验收和存量处理完成后,发布配置可分别关闭退款 `approve/reject` 与线下充值 `offline-pay`;关闭需要重启 APIWorker 标准终态消费者不依赖这些开关。
- 前端切换后隐藏旧操作按钮,只读展示 `approval_instance_id``approval_provider``approval_status``approval_status_name`
- 存量核对 SQL、关闭门禁和回滚步骤见 [存量审批切换清单](存量审批切换清单.md)。存量记录不得伪造企微实例,回滚不得删除任何审批、资金或集成事实。
## 已知边界
- 当前已包含审批准备、提交、加密回调、详情终态同步、批量单号时间窗补偿、未终态轮询、结果未知主动恢复和审批人批量读取投影。
- 本次未运行迁移、测试、完整构建或 LSP按用户后续明确要求已运行 OpenAPI 生成器并检查企微管理及回调契约,静态收口另执行格式化和一致性检查。

View File

@@ -0,0 +1,62 @@
# 企业微信审批存量切换清单
## 目标与边界
本清单用于把退款人工 `approve/reject` 和线下充值人工 `offline-pay` 从存量兼容模式切换为企业微信只读审批状态模式。切换只关闭旧 HTTP 入口不删除路由、历史退款、充值、审批实例、钱包流水、Outbox 或 Integration Log也不为存量记录伪造企业微信审批实例。
## 发布开关
两个开关默认均为 `true`,部署新版本后继续允许 `approval_instance_id IS NULL` 的存量旧 provider 完成处理:
| 环境变量 | 默认值 | 关闭后的入口 |
|---|---|---|
| `JUNHONG_APPROVAL_LEGACY_REFUND_MANUAL_ENABLED` | `true` | 退款 `approve/reject` 返回“入口已停用” |
| `JUNHONG_APPROVAL_LEGACY_OFFLINE_RECHARGE_PAY_ENABLED` | `true` | 线下充值 `offline-pay` 返回“入口已停用” |
配置变更后必须重启 API 实例。Worker 的企业微信标准终态消费者不读取这两个开关,不受切换影响。
## 切换前只读核对
以下 SQL 仅用于发布人员核对,不在本 Change 中执行。待审批状态值按当前模型均为 `1`
```sql
-- 仍需通过旧人工入口完成的存量待审批退款
SELECT id, refund_no, order_id, shop_id, creator, status, created_at
FROM tb_refund_request
WHERE deleted_at IS NULL
AND status = 1
AND approval_instance_id IS NULL
ORDER BY id;
-- 仍需通过旧人工入口完成的存量待确认线下充值
SELECT id, recharge_no, shop_id, user_id, amount, status, created_at
FROM tb_agent_recharge_record
WHERE deleted_at IS NULL
AND payment_method = 'offline'
AND status = 1
AND approval_instance_id IS NULL
ORDER BY id;
```
核对和处理规则:
- `approval_instance_id IS NULL` 表示存量旧 provider必须在关闭开关前通过原入口处理完成不得补写或伪造企微实例。
- `approval_instance_id IS NOT NULL` 表示新企微审批记录,只能由企微回调或轮询产生的标准终态处理;旧人工入口已在代码中逐单阻断。
- 存量清单应保存退款/充值业务 ID、业务单号、当前状态、责任人和处理结果不复制 Secret、access_token、media_id 或附件正文。
## 关闭门禁
只有同时满足以下条件才关闭旧入口:
1. 退款和员工线下代充值已在真实企微环境完成发起、审批、回调或轮询补偿、标准终态以及资金副作用联调。
2. 上述两份存量清单已清零,或剩余记录已有明确的前向处理方案和责任人。
3. 前端已隐藏退款 `approve/reject` 与线下充值 `offline-pay` 操作,只读展示 `approval_instance_id``approval_provider``approval_status``approval_status_name`
4. API 发布配置把对应开关设为 `false`,并完成全部 API 实例滚动重启。
关闭后应抽查新企微记录的列表和详情审批字段一致旧入口返回明确停用错误Worker 仍能消费 `approved/rejected/cancelled/deleted` 标准终态。
## 回滚
如关闭后发现前端或存量处理遗漏,将对应开关重新设为 `true` 并重启 API 实例。回滚只恢复旧入口可用性,不改变企微审批记录的逐单防绕过规则。
不得删除、清空或回退已经产生的审批实例、退款、充值、钱包流水、Outbox、Integration Log 或企微外部审批;不得把新企微记录改为旧 provider。问题应通过前向修复处理。

View File

@@ -0,0 +1,24 @@
ICCID(必填)联通必须是20位,MSISDN(必填),虚拟号(非必填)
89860624660030801094,861400566073546,
89860624590015958355,861400498975835,
89860624660030813982,861400566074835,
89860624590015955237,861400498975523,
89860624660030811838,861400566074620,
89860624660030811747,861400566074611,
89860624590015958967,861400498975896,
89860624660030816431,861400566075080,
89860624590015955880,861400498975588,
89860624660030816456,861400566075082,
89860624660030816431,861400566075080,
89860624660030807117,861400566074148,
89860624660030801904,861400566073627,
89860624590015958058,861400498975805,
89860624660030801615,861400566073598,
89860624590015958108,861400498975810,
89860624660030813669,861400566074803,
89860624660030812513,861400566074688,
89860624660030813503,861400566074787,
89860624660030807521,861400566074189,
89860624660030813107,861400566074747,
89860624660030807919,861400566074228,
89860624660030812687,861400566074705,
1 ICCID(必填)联通必须是20位 MSISDN(必填) 虚拟号(非必填)
2 89860624660030801094 861400566073546
3 89860624590015958355 861400498975835
4 89860624660030813982 861400566074835
5 89860624590015955237 861400498975523
6 89860624660030811838 861400566074620
7 89860624660030811747 861400566074611
8 89860624590015958967 861400498975896
9 89860624660030816431 861400566075080
10 89860624590015955880 861400498975588
11 89860624660030816456 861400566075082
12 89860624660030816431 861400566075080
13 89860624660030807117 861400566074148
14 89860624660030801904 861400566073627
15 89860624590015958058 861400498975805
16 89860624660030801615 861400566073598
17 89860624590015958108 861400498975810
18 89860624660030813669 861400566074803
19 89860624660030812513 861400566074688
20 89860624660030813503 861400566074787
21 89860624660030807521 861400566074189
22 89860624660030813107 861400566074747
23 89860624660030807919 861400566074228
24 89860624660030812687 861400566074705

View File

@@ -0,0 +1,24 @@
虚拟号(必填),SN非必填,设备名称(非必填),设备型号(非必填),设备类型(非必填),IMEI(非必填),制造商(非必填),最大SIM槽数 (非必填),卡1 ICCID (非必填),卡2 ICCID (非必填),卡3 ICCID (非必填),卡4 ICCID (非必填)
60003080109,,Dongle005,,Dongle005,869555083143381,,1,89860624660030801094,,,
90001595835,,Dongle005,,Dongle005,869555083142417,,1,89860624590015958355,,,
60003081398,,Dongle005,,Dongle005,869555083105034,,1,89860624660030813982,,,
90001595523,,Dongle005,,Dongle005,869555083142359,,1,89860624590015955237,,,
60003081183,,Dongle005,,Dongle005,869555083109259,,1,89860624660030811838,,,
60003081174,,Dongle005,,Dongle005,869555083106321,,1,89860624660030811747,,,
90001595896,,Dongle005,,Dongle005,869555083120306,,1,89860624590015958967,,,
60003081643,,Dongle005,,Dongle005,869555083104151,,1,89860624660030816431,,,
90001595588,,Dongle005,,Dongle005,869555083145048,,1,89860624590015955880,,,
60003081645,,Dongle005,,Dongle005,869555083089592,,1,89860624660030816456,,,
60003081643,,Dongle005,,Dongle005,869555083089568,,1,89860624660030816431,,,
60003080711,,Dongle005,,Dongle005,869555083144835,,1,89860624660030807117,,,
60003080190,,Dongle005,,Dongle005,869555083100118,,1,89860624660030801904,,,
90001595805,,Dongle005,,Dongle005,869555083127673,,1,89860624590015958058,,,
60003080161,,Dongle005,,Dongle005,869555083101702,,1,89860624660030801615,,,
90001595810,,Dongle005,,Dongle005,869555083127665,,1,89860624590015958108,,,
60003081366,,Dongle005,,Dongle005,869555083108509,,1,89860624660030813669,,,
60003081251,,Dongle005,,Dongle005,869555083100134,,1,89860624660030812513,,,
60003081350,,Dongle005,,Dongle005,869555083099575,,1,89860624660030813503,,,
60003080752,,Dongle005,,Dongle005,869555083145261,,1,89860624660030807521,,,
60003081310,,Dongle005,,Dongle005,869555083100308,,1,89860624660030813107,,,
60003080791,,Dongle005,,Dongle005,869555083144884,,1,89860624660030807919,,,
60003081268,,Dongle005,,Dongle005,869555083088545,,1,89860624660030812687,,,
1 虚拟号(必填) SN(非必填) 设备名称(非必填) 设备型号(非必填) 设备类型(非必填) IMEI(非必填) 制造商(非必填) 最大SIM槽数 (非必填) 卡1 ICCID (非必填) 卡2 ICCID (非必填) 卡3 ICCID (非必填) 卡4 ICCID (非必填)
2 60003080109 Dongle005 Dongle005 869555083143381 1 89860624660030801094
3 90001595835 Dongle005 Dongle005 869555083142417 1 89860624590015958355
4 60003081398 Dongle005 Dongle005 869555083105034 1 89860624660030813982
5 90001595523 Dongle005 Dongle005 869555083142359 1 89860624590015955237
6 60003081183 Dongle005 Dongle005 869555083109259 1 89860624660030811838
7 60003081174 Dongle005 Dongle005 869555083106321 1 89860624660030811747
8 90001595896 Dongle005 Dongle005 869555083120306 1 89860624590015958967
9 60003081643 Dongle005 Dongle005 869555083104151 1 89860624660030816431
10 90001595588 Dongle005 Dongle005 869555083145048 1 89860624590015955880
11 60003081645 Dongle005 Dongle005 869555083089592 1 89860624660030816456
12 60003081643 Dongle005 Dongle005 869555083089568 1 89860624660030816431
13 60003080711 Dongle005 Dongle005 869555083144835 1 89860624660030807117
14 60003080190 Dongle005 Dongle005 869555083100118 1 89860624660030801904
15 90001595805 Dongle005 Dongle005 869555083127673 1 89860624590015958058
16 60003080161 Dongle005 Dongle005 869555083101702 1 89860624660030801615
17 90001595810 Dongle005 Dongle005 869555083127665 1 89860624590015958108
18 60003081366 Dongle005 Dongle005 869555083108509 1 89860624660030813669
19 60003081251 Dongle005 Dongle005 869555083100134 1 89860624660030812513
20 60003081350 Dongle005 Dongle005 869555083099575 1 89860624660030813503
21 60003080752 Dongle005 Dongle005 869555083145261 1 89860624660030807521
22 60003081310 Dongle005 Dongle005 869555083100308 1 89860624660030813107
23 60003080791 Dongle005 Dongle005 869555083144884 1 89860624660030807919
24 60003081268 Dongle005 Dongle005 869555083088545 1 89860624660030812687