Files
junhong_cmp_fiber/docs/client-api-data-model-fixes/功能总结.md
huang ec86dbf463 feat: 客户端接口数据模型基础准备
- 新增资产状态、订单来源、操作人类型、实名链接类型常量
- 8个模型新增字段(asset_status/generation/source/retail_price等)
- 数据库迁移000082:7张表15+字段,含存量retail_price回填
- BUG-1修复:代理零售价渠道隔离,cost_price分配锁定
- BUG-2修复:一次性佣金仅客户端订单触发
- BUG-4修复:充值回调Store操作纳入事务
- 新增资产手动停用接口(PATCH /iot-cards/:id/deactivate、/devices/:id/deactivate)
- Carrier管理新增实名链接配置
- 后台订单generation写时快照
- BatchUpdatePricing支持retail_price调价目标
- 清理全部H5旧接口和个人客户旧登录方法
2026-03-19 10:56:50 +08:00

128 lines
5.5 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` 接口扩展支持 `pricing_target` 参数(`cost_price`/`retail_price`),默认 `cost_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