114 lines
7.1 KiB
Markdown
114 lines
7.1 KiB
Markdown
# 产品中心
|
||
|
||
官网产品中心位于 `apps/website/app/pages/product-center.vue`,访问路径为 `/product-center`。
|
||
|
||
## 默认展示
|
||
|
||
页面首次加载时展示全部商品和全部国家,不默认选择分类、物流或工艺标签。每页默认请求 20 条商品,用户操作筛选项后再按真实业务 ID 查询。
|
||
|
||
## 筛选与分页
|
||
|
||
- 左侧分类树:选择父分类或子分类。
|
||
- 国家:点击国家胶囊筛选,点击“全部”取消国家筛选。
|
||
- 物流与工艺:按标签组展示下拉选项,每个分组内暂为单选,不同分组可各选择一项。
|
||
- 筛选菜单在选择选项或点击组件外部后自动关闭;已选 Tag 使用独立标签行。仅选择工艺时标签从最左侧开始;物流与工艺同时选择时按物流、工艺顺序与上方筛选项对应排列。
|
||
- 搜索:输入关键词后按回车或点击“搜索”。
|
||
- 商品卡:整卡链接到 `https://inkpod.vip/portal/detail/{商品ID}`,在新窗口打开。
|
||
- 公共商品接口的 `id` 来自 `originGood.sdsGoodId`,即 InkPOD 商品 ID;`goods.good_id` 仅作为本站数据库内部主键使用。
|
||
- URL 国家筛选:支持 `/product-center?countryId={后台国家ID}`,仅接受后台已配置的国家 ID。
|
||
- 无结果:展示设计稿空状态,可通过“查看全部商品”或“清空筛选”恢复完整列表。
|
||
- 加载中:展示两行共八个商品骨架卡,筛选栏保持可操作。
|
||
- 分页:支持页码、前后翻页、每页数量和页码跳转。
|
||
|
||
所有查询通过 `useProductCenter.ts` 调用 `/api/backend/*` 代理路由,不在页面中硬编码业务 ID。
|
||
|
||
## 后台配置联动
|
||
|
||
- 品类树、国家、Tag 与 Tag Group 均来自 NestJS `/public/*` 接口。
|
||
- 国家旗帜读取 `countryIcon`,品类图标读取 `categoryIcon`;前端不提供外部旗帜 CDN 或固定名称兜底。
|
||
- `/uploads/*` 与 `/assets/*` 等后台相对资源地址由 `useProductCenter.ts` 根据 `runtimeConfig.public.backendUrl` 转为完整 URL。
|
||
- 物流和工艺筛选分别由后台名称包含“物流”和“工艺”的 Tag Group 生成;“印刷位置”等其他分组仍可用于商品卡片标签,但不会自动成为顶部筛选项。
|
||
- Figma 基准图标位于 `apps/api/public/product-center/`,通过后端 `/assets/product-center/*` 提供。
|
||
- 更新现有数据库图标配置:`pnpm --filter @inkreach/api configure:product-center-icons`。脚本按中文名称幂等更新,不创建缺失的国家或品类。
|
||
|
||
## 响应式
|
||
|
||
桌面采用 240px 分类栏,页面左右保留 `24–56px` 自适应留白,分类栏可滚动但隐藏可见 scrollbar。商品网格以 240px 为最小卡片宽度自动增加或减少列数:1440px 基准宽度保持四列,1920px 可显示六列。国家筛选区按内容自然增高,不保留固定空白。
|
||
|
||
左侧品类栏不显示最左侧边线,一级品类之间保留 10px 间距;国家筛选区及物流、工艺、搜索工具区的底部分隔线从内容区向右延伸至页面边缘。
|
||
|
||
宽度低于 1000px 后分类栏变为抽屉;移动端商品网格降为两列或单列,国家筛选仅在自身区域横向滚动,不会撑宽页面。
|
||
|
||
## 多源合并商品
|
||
|
||
后台支持把名称相同但工厂/仓库不同的多个 SDS 原产品合并为一个官网商品:
|
||
|
||
- 数据层:主源存 `goods.origin_good_id`,副源存中间表 `good_origin_goods`。
|
||
- 详情可达性:官网上通过**任一**关联原产品的 `sdsGoodId` 都能访问到该商品详情,即副源的旧链接不会 404。
|
||
- 变体合并:详情中的 SKU 是「主源变体 ∪ 全部副源变体」,按颜色归组展示媒体图;价格与详情页内容以主源为准。
|
||
- 后台维护入口:
|
||
- 配置弹窗(右栏拖拽/配置按钮):自动勾选同分类下同名兄弟原产品作为副源提交(`mergedOriginGoodIds`);
|
||
- 编辑弹窗「关联原产品」区:可搜索添加副源、移除副源、切换主源(切换后旧主源自动转为副源)。
|
||
|
||
> 该 Good 级合并能力保留可用;新一级的「产品族(SPU)合并」见下节,公开读路径接入族数据属于三期范围。
|
||
|
||
## 产品族(SPU 层,一期后端已上线)
|
||
|
||
设计文档:`docs/superpowers/specs/2026-08-28-product-family-merge-design.md`。
|
||
|
||
**模型**:SDS 叶子分类即产品模型(如分类 `DG001 180G纯棉T恤(JSA002)` 下 16 条链接),
|
||
族 = 同分类链接的合并体;链接名解析列(`国家(物流)品名-SKU-工艺[-仓库]`)提供
|
||
物流/工艺归因。例:DG001 族 = 16 链接 × 3 工艺 × 3 物流 × 9 尺码(S~XXXXXL 并集)× 20 颜色 ≈ 470 格价格矩阵,起价取光板(不打印)最低价。
|
||
|
||
**价格**:`价格 = f(尺码, 颜色, 物流, 工艺[含印花数量])`,全部从成员链接变体推导透传
|
||
(同格子多仓库取最低价,来源全保留);`family_price_overrides` 表支持按格人工改价,
|
||
删覆盖即恢复推导价。
|
||
|
||
**关键端点用法示例**(JWT):
|
||
|
||
```bash
|
||
# 1. 自动成族:先预览
|
||
curl -X POST /product-families/auto-group -H "Authorization: Bearer $T" \
|
||
-d '{"apply": false}'
|
||
# → { applied: 0, groups: [{ groupKey: "cat:8240", familyName: "DG001 180G纯棉T恤(JSA002)", memberCount: 16, ... }] }
|
||
|
||
# 2. 应用(幂等,可重复执行)
|
||
curl -X POST /product-families/auto-group -H "Authorization: Bearer $T" -d '{"apply": true}'
|
||
|
||
# 3. 族详情:成员 + 并集尺码表/包装 + 五维价格矩阵
|
||
curl /product-families/12 -H "Authorization: Bearer $T"
|
||
|
||
# 4. 人工改价(维度必须存在于族矩阵选项,否则 400 并列出非法键)
|
||
curl -X PUT /product-families/12/price-overrides -H "Authorization: Bearer $T" \
|
||
-d '{"items": [{"sizeId":"size_S","colorId":"color_blk","craft":"单面印花","logistics":"包邮","price": 23, "note": "促销"}]}'
|
||
|
||
# 5. 删覆盖恢复推导价
|
||
curl -X DELETE /product-families/12/price-overrides -H "Authorization: Bearer $T" \
|
||
-d '{"cells": [{"sizeId":"size_S","colorId":"color_blk","craft":"单面印花","logistics":"包邮"}]}'
|
||
|
||
# 6. 族内创建自定义商品(人工补链接,物流/工艺归因必填)
|
||
curl -X POST /product-families/12/members/custom -H "Authorization: Bearer $T" \
|
||
-d '{"goodName":"美国(海运)180g纯棉T恤-DG001-烫画","logisticsLabel":"海运","craftLabel":"烫画",
|
||
"variants":[{"sku":"C-M","sizeId":"size_M","sizeName":"M","colorId":"color_red","colorName":"红色","price": 33}]}'
|
||
```
|
||
|
||
**同步联动**:商品同步落库时刷新解析列;新链接与已有族**同分类唯一命中**时自动挂族
|
||
(多族/零族留给管理员;锁定族只置 `stale`);详情同步提交后异步重算受影响族
|
||
(进程内去重、幂等)。回填/修复脚本:
|
||
|
||
```bash
|
||
pnpm --filter @inkreach/api backfill:product-families
|
||
# → [1/2] 解析全部链接名 [2/2] 自动建族 [3/3] 全量族重算(幂等,可随时重跑)
|
||
```
|
||
|
||
|
||
## 验证
|
||
|
||
```bash
|
||
pnpm --filter @inkreach/website test --run
|
||
pnpm --filter @inkreach/website build
|
||
pnpm --filter @inkreach/website dev
|
||
pnpm --filter @inkreach/api test -- --runInBand
|
||
pnpm --filter @inkreach/api build
|
||
```
|