七月迭代短暂完结,还有很多后端的关键东西没有弄,这是一版赶时间做的东西
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m26s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m26s
This commit is contained in:
152
docs/7月迭代/七月迭代实现与接口对接说明.md
Normal file
152
docs/7月迭代/七月迭代实现与接口对接说明.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# 七月迭代实现与接口对接说明
|
||||
|
||||
> 面向:产品、前端、测试和联调人员
|
||||
> 范围:`deliver-july-iteration-confirmed-scope` 及本期确认“后端已完成,只需前端联调”的需求
|
||||
> 接口细节:以 [`docs/admin-openapi.yaml`](../admin-openapi.yaml) 为准,本文只说明关键调用和字段变化。
|
||||
|
||||
## 一、先看这几个关键结论
|
||||
|
||||
1. **设备没有限速接口**:限速只允许对 IoT 卡 ICCID 操作,固定档位 `-1~8`,不通过设备绑定卡间接限速。
|
||||
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 天节点,提供后台/代理临期列表及数量,并向个人客户发送站内通知 | 高亮为 8~15、4~7、0~3 天;0~3 天优先;不发企微业务员提醒 |
|
||||
| #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[]`,单次 1~100 项 | 页面实现套餐多选,一次提交整个数组;删除项使用 `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` 是 1~100 项数组,每项包含 `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`、金额、1~5 个 `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)。
|
||||
- 涉及金额的字段默认单位为分;前端展示时统一转换,提交时不要传浮点元金额。
|
||||
Reference in New Issue
Block a user