店铺列表与商品数据下载(R1) #8

Open
opened 2026-09-02 16:09:09 +08:00 by ila · 1 comment
Owner

基本信息

  • 类型:需求 | 所属 Epic:#2 | 所属 MVP:#3 | 阶段:待实施

依赖与并行

  • 前置工单:#7(货憨憨登录)
  • 允许并行:否;原因:本工单的所有请求都要先有可用认证。

要解决什么

实现界面上的「店铺下拉」和「下载数据」两个功能,让商品真正出现在列表里。
这是 MVP1 的最后一块。

接口都有真实抓包可对照,见负责人提供的 payloads/huohanhan_product.har
(已 gitignore,不要提交):

接口 用途 HAR 中出现次数
erp/shop/all,form type=1 取当前账号全部店铺 3
product/shop/getPage 商品分页 12
product/shop/getCount 各状态数量 10

getPage 最小请求体:

{"size":20,"current":1,"itemStatus":"NORMAL","platform":"0",
 "platformShopId":"","sortField":"updateTime","sortType":"desc"}

界面四个筛选条件到接口参数的映射(已确认,不要另造):
店铺 → platformShopId;蝦皮ID → itemIds;创建时间 → createTimeStart/createTimeEnd;
状态 → itemStatus。

响应 records[] 关键字段:id(货憨憨记录 ID,是后续写操作的关联键,
不是 itemId)、itemId(Shopee 商品 ID)、itemName、mainImage、
shopName、platformShopId、currency、minSkuPrice、itemStatus、createTime。

做什么 / 不做什么

  • 做:ListShops 真实实现;DownloadProductData 分页拉全量并 upsert 进 SQLite;
    进度通过 logx 输出;界面店铺下拉改为真实数据。
  • 不做:不实现 getCount(暂时用不到);不做增量同步,每次全量 upsert。

预计修改文件

  • internal/huohanhan/shop.go、shop_test.go
  • internal/huohanhan/product.go、product_test.go
  • app.go(ListShops、DownloadProductData 换成真实实现)
  • frontend/src/views/ProductListView.vue(去掉店铺加载失败时的静默处理)

验收标准

  • 店铺下拉显示真实店铺,含店铺名与地区
  • 点「下载数据」后商品出现在列表,分页拉完全部
  • 重复点击不会把已有的下载/上传状态清零(UpsertProducts 已保证,要有测试)
  • 四个筛选条件都能正确过滤
  • 拉取过程有进度日志,失败有明确原因
  • 单元测试用 httptest 模拟,不需要真实账号

验证方式

go vet ./...
go test ./internal/huohanhan/...

真实店铺验证由负责人在界面操作确认。

交给 Codex 实施的约定

本工单由本机 Codex CLI(模型 gpt-5.6-sol)实施,由 Claude 审核。

Codex 必须遵守:

  • 先读仓库根目录 AGENTS.md,第 10 节「项目专用规则」是不可违反的红线。
  • 只改本工单「预计修改文件」列出的范围;发现别的问题记录下来,不要顺手改。
  • Wails 专有 API 只能出现在 main.go 和 app.go;internal/ 不许 import wails。
  • 不把账号、密码、token、Cookie 写入代码、日志、注释或测试固定值。
  • 面向初级维护者写代码:直白实现,注释解释「为什么」和边界,不逐行翻译代码。
  • 新增逻辑要有 go test 覆盖;不能联网的部分用假数据测,不要写需要真实账号才能跑的测试。
  • 完成后必须真实执行并贴出输出:go vet ./...、go build ./...、go test ./...。
  • 不要自行提交 Git,也不要改 docs/ 下的任何文件(那是 Wiki 镜像)。
## 基本信息 - 类型:需求 | 所属 Epic:#2 | 所属 MVP:#3 | 阶段:待实施 ## 依赖与并行 - 前置工单:#7(货憨憨登录) - 允许并行:否;原因:本工单的所有请求都要先有可用认证。 ## 要解决什么 实现界面上的「店铺下拉」和「下载数据」两个功能,让商品真正出现在列表里。 这是 MVP1 的最后一块。 接口都有真实抓包可对照,见负责人提供的 `payloads/huohanhan_product.har` (已 gitignore,不要提交): | 接口 | 用途 | HAR 中出现次数 | |---|---|---| | `erp/shop/all`,form `type=1` | 取当前账号全部店铺 | 3 | | `product/shop/getPage` | 商品分页 | 12 | | `product/shop/getCount` | 各状态数量 | 10 | `getPage` 最小请求体: ```json {"size":20,"current":1,"itemStatus":"NORMAL","platform":"0", "platformShopId":"","sortField":"updateTime","sortType":"desc"} ``` 界面四个筛选条件到接口参数的映射(已确认,不要另造): 店铺 → `platformShopId`;蝦皮ID → `itemIds`;创建时间 → `createTimeStart`/`createTimeEnd`; 状态 → `itemStatus`。 响应 `records[]` 关键字段:`id`(货憨憨记录 ID,是后续写操作的关联键, **不是** `itemId`)、`itemId`(Shopee 商品 ID)、`itemName`、`mainImage`、 `shopName`、`platformShopId`、`currency`、`minSkuPrice`、`itemStatus`、`createTime`。 ## 做什么 / 不做什么 - 做:`ListShops` 真实实现;`DownloadProductData` 分页拉全量并 upsert 进 SQLite; 进度通过 logx 输出;界面店铺下拉改为真实数据。 - 不做:不实现 `getCount`(暂时用不到);不做增量同步,每次全量 upsert。 ## 预计修改文件 - `internal/huohanhan/shop.go`、`shop_test.go` - `internal/huohanhan/product.go`、`product_test.go` - `app.go`(ListShops、DownloadProductData 换成真实实现) - `frontend/src/views/ProductListView.vue`(去掉店铺加载失败时的静默处理) ## 验收标准 - [ ] 店铺下拉显示真实店铺,含店铺名与地区 - [ ] 点「下载数据」后商品出现在列表,分页拉完全部 - [ ] 重复点击不会把已有的下载/上传状态清零(`UpsertProducts` 已保证,要有测试) - [ ] 四个筛选条件都能正确过滤 - [ ] 拉取过程有进度日志,失败有明确原因 - [ ] 单元测试用 httptest 模拟,不需要真实账号 ## 验证方式 ```powershell go vet ./... go test ./internal/huohanhan/... ``` 真实店铺验证由负责人在界面操作确认。 ## 交给 Codex 实施的约定 本工单由本机 Codex CLI(模型 `gpt-5.6-sol`)实施,由 Claude 审核。 Codex 必须遵守: - 先读仓库根目录 `AGENTS.md`,第 10 节「项目专用规则」是不可违反的红线。 - 只改本工单「预计修改文件」列出的范围;发现别的问题记录下来,不要顺手改。 - Wails 专有 API 只能出现在 `main.go` 和 `app.go`;`internal/` 不许 import wails。 - 不把账号、密码、token、Cookie 写入代码、日志、注释或测试固定值。 - 面向初级维护者写代码:直白实现,注释解释「为什么」和边界,不逐行翻译代码。 - 新增逻辑要有 `go test` 覆盖;不能联网的部分用假数据测,不要写需要真实账号才能跑的测试。 - 完成后必须真实执行并贴出输出:`go vet ./...`、`go build ./...`、`go test ./...`。 - 不要自行提交 Git,也不要改 `docs/` 下的任何文件(那是 Wiki 镜像)。
Author
Owner

状态:进行中(Codex gpt-5.6-sol,--yolo,Claude 审核)

实施前从真实 HAR 核对出的三处矛盾

我逐条读了负责人提供的 payloads/huohanhan_product.har,发现真实请求与
D:\chengma\hhh_api 的 Python 实现及其接口文档有三处不一致
。已在提示词中
明确要求以抓包为准,不要照抄 Python。

矛盾一:erp/shop/all 的请求参数

来源 请求体
Python shop_service.py 与接口文档 type=1
真实抓包 userId=(值为空)

矛盾二:getPage 的编码方式

来源 Content-Type
Python product_query_service.py json=body(JSON)
真实抓包 application/x-www-form-urlencoded;charset=UTF-8

矛盾三:响应没有 {type, bean} 包裹

接口文档说「所有接口统一返回 {type, message, code, bean, extension}」,
但这两个接口实测都不是:

  • erp/shop/all 直接返回裸 JSON 数组(该账号 19 个店铺)
  • getPage 直接返回 {records, total, size, current, orders, searchCount, pages}

另外 total/size/current/pages 在实测响应里可能是字符串也可能是数字,
解析必须兼容两种。

安全问题:店铺响应含真实凭据

erp/shop/all 返回的每个店铺对象里带有:

  • accessToken —— Shopee OAuth 令牌
  • refreshToken —— Shopee OAuth 刷新令牌
  • createUser —— 手机号,属于真实个人数据

已在提示词中列为红线:Go 结构体只允许包含界面需要的 8 个字段
(id、shopName、shopAlias、region、regionName、platform、platformShopId、status),
不得解析、记录、存储或返回 token 与手机号,并要求写测试断言结构体不含 token 字段。

实测数据规模

  • 该账号有 19 个店铺(原型里假设 3 个,属于示意数据)
  • 单店铺 platformShopId=1664202094 有 1256 个商品,63 页

因此要求 DownloadProductData 必须接收店铺 ID 参数,未选店铺时报
「请先选择店铺」,不默认拉全部——19 个店铺全拉会非常慢。
同时要求分页上限保护(最多 200 页),防止 pages 异常导致死循环。

已确认可直接使用的字段

records[] 共 52 个字段,本工单只取以下 10 个(均已在抓包中确认存在):
id、itemId、itemName、mainImage、shopName、platformShopId、
currency、minSkuPrice、itemStatus、createTime。

id 是货憨憨内部记录 ID,itemId 是 Shopee 商品 ID,两者不可混用,
落库主键必须用 id。

状态:**进行中**(Codex `gpt-5.6-sol`,`--yolo`,Claude 审核) ## 实施前从真实 HAR 核对出的三处矛盾 我逐条读了负责人提供的 `payloads/huohanhan_product.har`,发现**真实请求与 `D:\chengma\hhh_api` 的 Python 实现及其接口文档有三处不一致**。已在提示词中 明确要求以抓包为准,不要照抄 Python。 ### 矛盾一:`erp/shop/all` 的请求参数 | 来源 | 请求体 | |---|---| | Python `shop_service.py` 与接口文档 | `type=1` | | **真实抓包** | **`userId=`(值为空)** | ### 矛盾二:`getPage` 的编码方式 | 来源 | Content-Type | |---|---| | Python `product_query_service.py` | `json=body`(JSON) | | **真实抓包** | **`application/x-www-form-urlencoded;charset=UTF-8`** | ### 矛盾三:响应没有 `{type, bean}` 包裹 接口文档说「所有接口统一返回 `{type, message, code, bean, extension}`」, 但这两个接口实测都不是: - `erp/shop/all` 直接返回**裸 JSON 数组**(该账号 19 个店铺) - `getPage` 直接返回 `{records, total, size, current, orders, searchCount, pages}` 另外 `total`/`size`/`current`/`pages` 在实测响应里可能是字符串也可能是数字, 解析必须兼容两种。 ## 安全问题:店铺响应含真实凭据 `erp/shop/all` 返回的每个店铺对象里带有: - `accessToken` —— Shopee OAuth 令牌 - `refreshToken` —— Shopee OAuth 刷新令牌 - `createUser` —— 手机号,属于真实个人数据 已在提示词中列为红线:Go 结构体只允许包含界面需要的 8 个字段 (id、shopName、shopAlias、region、regionName、platform、platformShopId、status), **不得解析、记录、存储或返回 token 与手机号**,并要求写测试断言结构体不含 token 字段。 ## 实测数据规模 - 该账号有 **19 个店铺**(原型里假设 3 个,属于示意数据) - 单店铺 `platformShopId=1664202094` 有 **1256 个商品,63 页** 因此要求 `DownloadProductData` 必须接收店铺 ID 参数,未选店铺时报 「请先选择店铺」,不默认拉全部——19 个店铺全拉会非常慢。 同时要求分页上限保护(最多 200 页),防止 `pages` 异常导致死循环。 ## 已确认可直接使用的字段 `records[]` 共 52 个字段,本工单只取以下 10 个(均已在抓包中确认存在): `id`、`itemId`、`itemName`、`mainImage`、`shopName`、`platformShopId`、 `currency`、`minSkuPrice`、`itemStatus`、`createTime`。 **`id` 是货憨憨内部记录 ID,`itemId` 是 Shopee 商品 ID,两者不可混用**, 落库主键必须用 `id`。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: chengma/cmsp#8