bindbox-game/.trae/documents/活动复制接口与前端功能.md
邹方成 642b3cf7dd
Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 50s
build: 更新前端构建产物和资源文件
更新了前端构建产物包括JavaScript、CSS和HTML文件,主要涉及以下变更:

1. 新增了多个组件和工具函数,包括异常页面组件、iframe组件等
2. 更新了活动管理、产品管理、优惠券管理等业务模块
3. 优化了构建配置和依赖管理
4. 修复了一些样式和功能问题
5. 更新了测试相关文件

同时更新了部分后端服务接口和测试用例。这些变更主要是为了支持新功能和改进现有功能的用户体验。
2025-11-21 01:24:13 +08:00

230 lines
6.1 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.

## 项目架构对齐
* 后端框架:`gin``internal/pkg/core`),统一中间件与响应封装
* 路由分组:`internal/router/router.go` 下 APP 公开/鉴权分组可扩展 `products` 资源
* 鉴权APP 端采用 `core.WrapAuthHandler(intc.AppTokenAuthVerify)``Authorization: Bearer <token>`
* ORM/DB`gorm` + `gorm/gen``internal/repository/mysql/dao/Query`),读写分离 `GetDbR/GetDbW`
* Swagger通过注释生成`swaggo/swag`),挂载 `GET /swagger/*any`
* 商品相关模型:`product`SPU`sku``category``spec``spec_option``product_spec``sku_spec_value`、推荐位 `recommendation_slot/item`
## 接口设计
### 1) 商品列表
* 路径:`GET /api/app/products`
* 鉴权需要App Token
* 请求参数:
* `page`默认1`pageSize`默认20最大50
* `categoryId`(可选)
* `priceMin``priceMax`(可选,闭区间)
* `salesMin`(可选)
* `inStock`布尔可选默认true仅展示可售
* `sortBy``sales|price|createdAt``order``asc|desc`,默认 `desc`
* 业务规则:只返回 `status=上架` 的 SPU`inStock=true` 时需至少一个 SKU `stock-stock_locked>0`
* 响应结构:
```json
{
"total": 1234,
"currentPage": 1,
"pageSize": 20,
"list": [
{
"id": 1001,
"name": "羽绒服",
"mainImage": "https://.../xx.jpg",
"price": 299.00,
"sales": 5230,
"inStock": true,
"categoryId": 12
}
]
}
```
* 过滤/排序实现:
* 基于 `product``status/category_id/sales_count/created_at/price_min/price_max` 组合条件
* `inStock` 通过子查询/EXISTS 关联 `sku` 计算有效库存
### 2) 商品详情
* 路径:`GET /api/app/products/:id`
* 鉴权需要App Token
* 业务规则SPU `status=上架` 且可售;下架/缺货返回业务态错误码
* 响应结构:
```json
{
"id": 1001,
"name": "羽绒服",
"album": ["https://.../1.jpg", "https://.../2.jpg"],
"priceRange": {"min": 199.00, "max": 399.00},
"sales": 5230,
"stock": {"total": 235, "available": 220},
"specs": [
{"name": "颜色", "options": ["黑色", "白色"]},
{"name": "尺码", "options": ["M", "L", "XL"]}
],
"description": "高蓬松保暖...",
"service": ["7天无理由", "运费险"],
"recommendations": [
{"id": 1002, "name": "羽绒马甲", "mainImage": "...", "price": 199.00}
]
}
```
* 规格/相册/描述来源:
* 相册:`product.images_json` 或关联表(若存在),解析为数组
* 规格:`product_spec` + `spec` + `spec_option` 聚合;
* 描述/服务保障:从 `product` 富文本字段(或扩展表)读取
* 推荐逻辑:
* 优先使用 `recommendation_slot.scene='detail_related'` 的绑定数据
* 兜底:同类目类目内 `sales_count` Top N去重当前商品
## 路由与代码结构
* 路由注册:`internal/router/router.go`
* `appAuthGroup := router.Group("/api/app", core.WrapAuthHandler(intc.AppTokenAuthVerify))`
* `appAuthGroup.GET("/products", product.New(repo, logger).List)`
* `appAuthGroup.GET("/products/:id", product.New(repo, logger).Detail)`
* Handler`internal/api/product/list_app.go``internal/api/product/detail_app.go`
* 统一入参校验、容错与错误码
* Service`internal/service/product/service.go`
* 封装查询、库存计算、推荐聚合、缓存命中
* DAO查询使用 `dao.Query``GetDbR`
* DTO`internal/api/product/dto.go`(列表项与详情结构体)
## 鉴权与权限
* 使用现有 APP Token 验证中间件Swagger `@Security LoginVerifyToken`
* 接口动作无需RBAC面向APP用户但保留限流与风控扩展点
## 性能与优化500ms SLA
* 索引:
* `product(status, category_id, sales_count, created_at)` 复合索引
* `sku(product_id, status)``sku(stock, stock_locked)` 参与计算库存
* 查询:
* 列表:单次查询 + `EXISTS` 子查询校验库存;分页使用 `LIMIT/OFFSET`页码≤100
* 详情:读取 SPU + 聚合 `SUM(stock-stock_locked)` + 规格与相册多表查询
* 缓存:
* 本地 TTL 缓存:
* 列表:键 `list:{filters}:{page}:{pageSize}`TTL 30s命中后直接返回
* 详情:键 `detail:{id}`TTL 60s库存变更事件可主动失效后续扩展
* 并发合并:使用 `singleflight` 避免热点详情击穿
* 传输仅必要字段GZIP 已由中间件统一处理
* 限流:`/products` 每用户每秒 ≤10后续中间件实现可选
## 错误码与校验
* 下架:`PRODUCT_OFFSHELF`HTTP 200业务码提示“商品已下架”
* 缺货:`PRODUCT_OUT_OF_STOCK`
* 参数错误:`INVALID_PARAM`(页码、价格区间校验)
* 统一响应封装沿用 `internal/pkg/core/context.go`
## Swagger文档
* 在两个 Handler 顶部添加注释:
* `@Summary``@Description``@Tags products`
* `@Param`(列出查询参数与类型)
* `@Success 200 {object} ListResp` / `DetailResp`
* `@Router /api/app/products [get]``/api/app/products/{id} [get]`
* `@Security LoginVerifyToken`
* 生成后可在 `http://127.0.0.1:9991/swagger/index.html` 查看
## 单元测试
* Handler`httptest.NewServer` + 构造 `Authorization` 头,校验分页与过滤、错误码
* Service使用内存/模拟 DAO或事务性测试库覆盖库存计算、规格聚合、推荐兜底
* 覆盖率目标:核心逻辑 ≥70%
## 压力测试
* 工具:`hey``wrk`
* 示例:
* 列表:`hey -n 5000 -c 100 'http://localhost:9991/api/app/products?page=1&pageSize=20'`
* 详情:`wrk -t4 -c200 -d30s 'http://localhost:9991/api/app/products/1001'`
* 目标P95 ≤ 500ms错误率 < 0.1%
## 联调与交付
* 与前端约定字段与筛选参数提供响应示例与错误码表
* 提供 Swagger 文档与可复用的 Postman/HTTP 文件
* 完成线上/测试环境联调回归
## 验收标准
* 两个接口完成并通过单元与压力测试
* Swagger 文档完整含请求/响应示例
* P95 响应时间 500ms测试环境数据量下
* 鉴权与状态校验生效缓存命中率提升热点访问性能