Files
inkreach-official-website/data-cleaning/README.md
T

116 lines
7.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.
# 商品数据清洗(Goods Data Cleaning
本目录存放商品数据清洗相关的全部脚本与规则文件。清洗目标:把右侧 SDS 原产品库
`origin_goods`)按规则批量配置为左侧官网商品(`goods`),替代后台手动逐个点击。
## 转换规则调查(2026-08-27,基于生产环境只读数据)
> 数据来源:`https://official.inkreach.cc/api` 生产接口(JWT 只读拉取):
> `/origin-goods?page=1..3&pageSize=200`(共 552 条)、`/goods?page=1..2&pageSize=200`(共 240 条)、
> `/tags`、`/categories`、`/countries`。未做任何写操作。
> 原始 JSON 快照存于 `runs/survey-2026-08-27/`(已加入 .gitignore,不入库)。
### 1. 右侧原产品(origin_goods)命名结构
右侧只有**一个字符串** `goodName`,整体模式:
```
国家(物流备注)品名-SKU-工艺位置[-仓库名]
↑ ↑ ↑ ↑ ↑
| | | | └─ 可选第4段:美西洛杉矶一仓 / 美中亚特兰大仓 等
| | | └─ 单面印花 / 双面印花 / 直喷双面 / 直喷单面 / 不打印 ...
| | └─ SKU 编码(字母+数字,如 DG001 / C1717 / KRHM003
| └─ 包邮 / 不包邮 / DHL包邮*运费结算订单时支付 / 不包邮光板 等变体
└─ 美国/德国/韩国...(全角括号为主,少量半角混用)
```
统计(552 条):
- **541 条**匹配 `国家(备注)其余` 模式;**11 条异常**
- 4 条自定义商品(`Goods Origin ...`source=CUSTOM
- 2 条缺国家前缀:`(不包邮)230g水洗炒雪花T恤-双面印花` / `(不包邮)180g纯棉T恤成人款-...`
- 1 条用空格代替括号:`法国 180g纯棉T恤-FRTM001-双面印花`
- 2 条半角左括号混用:`美国(不包邮)女士高弹中长款瑜伽运动裤-JSD004-...`
- 2 条同上变体
- 「备注)之后」按 `-` 分段:**387 条 = 3 段**(品名-SKU-工艺)、**154 条 = 4 段**(品名-SKU-工艺-仓库)
- 物流备注出现的变体形态(示例):`包邮``不包邮``DHL包邮``DHL包邮*运费结算订单时支付``包邮*运费订单结算时支付``不包邮光板`
- 国家前缀出现过的值:美国、德国、英国、意大利、西班牙、西班牙直发、韩国、日本、加拿大、墨西哥、巴西、波兰、澳大利亚
### 2. 左侧已配置商品(goods)现状 —— 人工配置的实际结果
240 条 goods 记录,覆盖 **209 个**不同 origin_good_id**343 个 origin 尚未配置**)。
**没有系统级拆分逻辑**:前端 [GoodsView.vue](../apps/admin/src/views/goods/GoodsView.vue) 提交的是完整原名,
后端 [goods.service.ts](../apps/api/src/goods/goods.service.ts) create/batchCreate 也原样入库。
因此左侧名称与右端的差异(113/240 条被改过)全部是**人工在编辑弹窗里改的**,且存在多种风格并存。
改名风格分布(113 条改名的归类):
| 风格 | 数量 | 示例 |
|------|------|------|
| A. 全拆:去前缀去括号,品名+空格+SKU,丢弃工艺段 | 27 | `韩国(包邮)200g纯棉T恤-KRTM001-单面印花``200g纯棉T恤 KRTM001` |
| B. 半改:仅把长备注缩成「X包邮」,其余原样保留 | 86 | `德国(DHL包邮*运费结算订单时支付)230g水洗T恤-DETM002-单面印花``德国(DHL包邮)230g水洗T恤-DETM002-单面印花` |
| R0. 保持原名不动 | 127 | 多为后期配置(2026-06 后期 ~ 07),未加工 |
标签体系(生产库现有 3 组 7 个标签)与左侧使用情况:
| 分组 | 标签(id) | 左侧使用次数 |
|------|----------|--------------|
| 物流渠道 | 包邮(30) / 不包邮(31) | 87 / 153 ← 基本每个商品都挂了物流标签 |
| 印刷位置 | 双面印(35) / 单面印(34) | 14 / 14 ← 只有少数挂了 |
| 印刷工艺 | 烫画(32) / 直喷(33) / 不打印(42) | 11 / 3 / 1 |
其他字段:goodPriority 几乎全部为 5positionId 全部为空;
国家字段与名称里的国家前缀一致率 238/240(仅 `西班牙直发(...)` 两条归入了「西班牙」)。
### 3. 从字符串解析出的隐含规则(草稿,待确认)
一条原产品字符串可以机械解析出以下信息(541/552 可完全机器解析):
| 解析项 | 来源 | 对应目标字段 |
|--------|------|--------------|
| 国家 | 第一个 `` 之前文本(需处理:空格分隔、半角括号、「西班牙直发→西班牙」映射) | `countryId` |
| 物流渠道 | 括号内含「包邮」与否 → 包邮 / 不包邮 | tag: 物流渠道 |
| 工艺/印刷位置 | 最后一段的 关键词:单面印花→单面印、双面印花→双面印、直喷→直喷、烫画→烫画、光板/不打印→不打印 | tags: 印刷位置 + 印刷工艺 |
| 展示名 | 目标形态(用户口径):`品名 SKU`(最后一个 `-` 连接改为空格连接,丢弃工艺/仓库段) | `goodName` |
### 4. 待确认问题(规则定稿前必须回答)
1. 展示名采用哪种?A 全拆(`200g纯棉T恤 KRTM001`,推荐—— majority 且官网展示干净)还是 B 保留国家括号?
2. 同一基础商品的「单面印花」「双面印花」是拆成两个 goods(现状),还是合并为一个 good 并用标签区分?
(注意 A 全拆后两者 goodName 完全相同,如 ITTM001 已出现重名两条)
3. 历史 R0 的 127 条保持原名的记录是否要统一重命名?
4. 未配置的 343 个 origin 是本次要全部自动配置的目标吗?(其中可能有不应上架的商品)
5. 仓库名后缀(第 4 段)只做清洗忽略即可,还是需要保留到某个字段?
6. 国家中文名 → countries 表的映射以 `countryName` 精确匹配为准?缺失国家(如法国 FRTM001 对应的国家若不存在)如何处理?
---
## 执行流水线
```
[生产库]
│ ① 备份(pg_dump 全量,安全网)
② apps/api/scripts/export-data.mjs 导出 JSON(现有脚本)
③ sync-transform.mjs 转换脚本 + sync-rules.config.mjs 规则文件(本目录,待创建)
读取导出 JSON → 按规则加工 → 输出待导入 JSON + 变更摘要报告(人工检查点)
④ apps/api/scripts/import-data.mjs 导入生产库(现有脚本)
⑤ 验证:行数对比 / 抽查商品配置 / 官网公开 API 抽查
```
原则:三步式独立执行,每步可检查、可回滚;规则只改 `sync-rules.config.mjs`,不改代码;
导入前必须有全量备份;转换脚本为纯函数式(JSON in → JSON out),不直接连接数据库。
## 目录内容规划
| 文件 | 状态 | 说明 |
|------|------|------|
| `sync-rules.config.mjs` | 待创建 | 同步规则文件(品类映射 / 国家分配 / 标签分配 / 优先级策略),规则未定,先占位 |
| `sync-transform.mjs` | 待创建 | 数据转换脚本 |
| `runs/` | 待创建 | 每次执行的导出、转换产物与变更摘要报告(按日期归档);已含 `survey-2026-08-27/` 调查快照(gitignore |
详细实施计划见 [plans/feature/goods-data-cleaning-feature.md](../plans/feature/goods-data-cleaning-feature.md)。