Files
junhong_cmp_fiber/docs/client-api-data-model-fixes/功能总结.md
huang b9733c4913
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m12s
fix: 修正零售价架构错误 + 清理旧微信配置 + 归档提案 + 前端接口文档
1. 修正 retail_price 架构:
   - 删除 batch-pricing 接口的 pricing_target 字段和 retail_price 分支
     (上级只能改下级成本价,不能改零售价)
   - 新增 PATCH /api/admin/packages/:id/retail-price 接口
     (代理自己改自己的零售价,校验 retail_price >= cost_price)

2. 清理旧微信 YAML 配置(已全部迁移到数据库 tb_wechat_config):
   - 删除 config.yaml 中 wechat.official_account 配置节
   - 删除 NewOfficialAccountApp() 旧工厂函数
   - 清理 personal_customer service 中的死代码(旧登录/绑定微信方法)
   - 清理 docker-compose.prod.yml 中旧微信环境变量和证书挂载注释

3. 归档四个已完成提案到 openspec/changes/archive/

4. 新增前端接口变更说明文档(docs/前端接口变更说明.md)

5. 修正归档提案和 specs 中关于 pricing_target 的错误描述
2026-03-19 17:39:43 +08:00

129 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 客户端接口数据模型基础准备 - 功能总结
## 概述
本提案作为客户端接口系列的前置基础完成三类工作BUG 修复、基础字段准备、旧接口清理。
## 一、BUG 修复
### BUG-1代理零售价修复
**问题**`ShopPackageAllocation` 缺少 `retail_price` 字段,所有渠道统一使用 `Package.SuggestedRetailPrice`,代理无法设定自己的零售价。
**修复内容**
- `ShopPackageAllocation` 新增 `retail_price` 字段(迁移中存量数据批量回填为 `SuggestedRetailPrice`
- `GetPurchasePrice()` 改为按渠道取价:代理渠道返回 `allocation.RetailPrice`,平台渠道返回 `SuggestedRetailPrice`
- `validatePackages()` 价格累加同步修正,代理渠道额外校验 `RetailPrice >= CostPrice`
- 分配创建(`shop_package_batch_allocation``shop_series_grant`)时自动设置 `RetailPrice = SuggestedRetailPrice`
- 新增 cost_price 分配锁定:存在下级分配记录时禁止修改 `cost_price`
- `BatchUpdatePricing` 接口仅支持成本价批量调整(保留 cost_price 锁定规则)
- 新增独立接口 `PATCH /api/admin/packages/:id/retail-price`,代理可修改自己的套餐零售价
- `PackageResponse` 新增 `retail_price` 字段,利润计算修正为 `RetailPrice - CostPrice`
**涉及文件**
- `internal/model/shop_package_allocation.go`
- `internal/model/dto/shop_package_batch_pricing_dto.go`
- `internal/model/dto/package_dto.go`
- `internal/service/purchase_validation/service.go`
- `internal/service/shop_package_batch_allocation/service.go`
- `internal/service/shop_series_grant/service.go`
- `internal/service/shop_package_batch_pricing/service.go`
- `internal/service/package/service.go`
### BUG-2一次性佣金触发条件修复
**问题**:后台所有订单(包括代理自购)都可能触发一次性佣金。
**修复内容**
- `Order` 新增 `source` 字段(`admin`/`client`),默认 `admin`
- 佣金触发条件从 `!order.IsPurchaseOnBehalf` 改为 `!order.IsPurchaseOnBehalf && order.Source == "client"`
- `CreateAdminOrder()` 设置 `Source: constants.OrderSourceAdmin`
**涉及文件**
- `internal/model/order.go`
- `internal/service/commission_calculation/service.go`(两个方法)
- `internal/service/order/service.go`
### BUG-4充值回调事务一致性修复
**问题**`HandlePaymentCallback``UpdateStatusWithOptimisticLock``UpdatePaymentInfo` 使用 `s.db` 而非事务内 `tx`
**修复内容**
- `AssetRechargeStore` 新增 `UpdateStatusWithOptimisticLockDB``UpdatePaymentInfoWithDB` 方法(支持传入 `tx`
- 原方法保留(委托调用新方法),确保向后兼容
- `HandlePaymentCallback` 改用事务内 `tx` 调用
**涉及文件**
- `internal/store/postgres/asset_recharge_store.go`
- `internal/service/recharge/service.go`
## 二、基础字段准备
### 新增常量文件
| 文件 | 内容 |
|------|------|
| `pkg/constants/asset_status.go` | 资产业务状态(在库/已销售/已换货/已停用) |
| `pkg/constants/order_source.go` | 订单来源admin/client |
| `pkg/constants/operator_type.go` | 操作人类型admin_user/personal_customer |
| `pkg/constants/realname_link.go` | 实名链接类型none/template/gateway |
### 模型字段变更
| 模型 | 新增字段 | 说明 |
|------|---------|------|
| `IotCard` | `asset_status`, `generation` | 业务生命周期状态、资产世代编号 |
| `Device` | `asset_status`, `generation` | 同上 |
| `Order` | `source`, `generation` | 订单来源、资产世代快照 |
| `PackageUsage` | `generation` | 资产世代快照 |
| `AssetRechargeRecord` | `operator_type`, `generation`, `linked_package_ids`, `linked_order_type`, `linked_carrier_type`, `linked_carrier_id` | 操作人类型、世代、强充关联字段 |
| `Carrier` | `realname_link_type`, `realname_link_template` | 实名链接配置 |
| `ShopPackageAllocation` | `retail_price` | 代理零售价 |
| `PersonalCustomer` | `wx_open_id` 索引变更 | 唯一索引改为普通索引 |
### Carrier 管理 DTO 更新
- `CarrierCreateRequest``CarrierUpdateRequest` 新增 `realname_link_type``realname_link_template` 字段
- `CarrierResponse` 新增对应展示字段
- Carrier Service 的 Create/Update 方法同步处理Update 时 `template` 类型强制校验模板非空
### 资产手动停用
- 新增 `PATCH /api/admin/iot-cards/:id/deactivate``PATCH /api/admin/devices/:id/deactivate`
-`asset_status` 为 1在库或 2已销售时允许停用
- 使用条件更新确保幂等
## 三、旧接口清理
### H5 接口删除
- 删除 `internal/handler/h5/` 全部文件5 个)
- 删除 `internal/routes/h5*.go`3 个文件)
- 清理 `routes.go``order.go``recharge.go` 中的 H5 路由注册
- 清理 `bootstrap/` 中 H5 Handler 构造和字段
- 清理 `middlewares.go` 中 H5 认证中间件
- 清理 `pkg/openapi/handlers.go` 中 H5 文档生成引用
- 清理 `cmd/api/main.go` 中 H5 限流挂载
### 个人客户旧登录方法删除
- 删除 `internal/handler/app/personal_customer.go` 中 Login、SendCode、WechatOAuthLogin、BindWechat 方法
- 清理对应路由注册
- 保留 UpdateProfile 和 GetProfile
## 四、数据库迁移
- 迁移编号000082
- 涉及 7 张表、15+ 个字段变更
- 包含存量 `retail_price` 批量回填
- 包含 `wx_open_id` 索引从唯一改为普通
- 所有字段使用 `NOT NULL DEFAULT` 确保存量兼容
## 五、后台订单 generation 快照
- `CreateAdminOrder()` 创建订单时从资产IotCard/Device获取当前 `Generation` 值写入订单
- 不再依赖数据库默认值 1