price-import
# 价易通 - 价格导入技能
## ⚠️ 触发条件
**必须使用 `/import` 命令触发**,避免误处理群聊中的无关图片。
| 命令 | 说明 |
|------|------|
| `/import` | 导入价格(可附带图片/文本/Excel) |
| `/import help` | 显示使用说明 |
| `/import status` | 查看最近导入记录 |
| `/import rules` | 查看/修改匹配规则 |
| `/import cancel` | 取消当前导入任务 |
| `/fix` | 提交程序功能变动或缺陷修复需求 |
| `/fix status` | 查看修复进度 |
| `/fix list` | 查看待处理需求清单 |
**示例**:
- `/import` + 发送图片
- `/import` 这张价格表:iPhone 17 Pro 256G ¥6500
- `/import help`
---
## 核心流程
```
1. 接收原始数据(图片/文本/Excel)
↓
2. 数据转换(图片/文本 → Excel)
↓
3. 拉取商品库(调用 API 获取所有商品)
↓
4. 智能匹配(根据商品名 + 规格匹配)
↓
5. 输出匹配报告(已识别/未识别)
↓
6. 用户确认(导入/修改规则/再次匹配)
↓
7. 执行导入(调用 API 写入数据)
↓
8. 验证结果(价格/记录/原始数据)
```
---
## 步骤 1:接收原始数据
**触发条件**:必须收到 `/import` 命令才开始处理
**支持的格式**:
- **图片**:价格表截图、照片(模型直接识别)
- **文本**:复制的价格列表、聊天记录
- **Excel**:已整理好的价格表
**处理方式**:
- 图片 → 模型视觉能力识别 → 提取文字 → 转换为标准格式
- 文本 → 直接解析
- Excel → 直接解析
**说明**:使用 qwen3.5-plus 模型的多模态能力,无需第三方 OCR 接口
**⚠️ 注意**:不带 `/import` 命令的图片/文本,本技能不处理
---
## 步骤 2:拉取商品库
**调用接口**:`GET /api/products`
**返回格式**:
```json
[
{
"id": 1,
"name": "iPhone 17 Pro",
"category": "手机",
"brand": "苹果"
},
{
"id": 2,
"name": "iPhone 17 Pro Max",
"category": "手机",
"brand": "苹果"
}
]
```
**同时获取规格列表**:`GET /api/specifications?product_id={id}`
---
## 步骤 3:智能匹配
### 匹配规则
**匹配条件**:商品名 + 规格完全匹配
### 规格标准化规则(必须先执行!)
**型号名称统一**:
- `iPhone 16 MAX` → `iPhone 16 Pro Max`
- `iPhone 17 MAX` → `iPhone 17 Pro Max`
- 以商品库中的名称为基准
**⚠️ 商品名称不带容量**:
- 商品库格式:`iPhone 17 Pro`(名称不含容量)
- 容量在规格中:`256G 银色 渠道版`
- 导入时需从商品名中提取容量,放入规格
**容量单位统一**:
- `TBG` → `TB`(如 1TBG 改为 1TB)
**规格后缀统一**:
- `渠道版` = `全国渠道版` = **默认**(不标注)
- `预激活` = `官网预激活` = **标注"预激活"**
**颜色规则**:
- 保留原始颜色名称
- 黑色/蓝色映射到深蓝色(如用户指定)
### 匹配逻辑
```python
for item in import_data:
# 标准化规格
normalized_spec = normalize_spec(item.spec)
# 匹配商品库
matched = product_library.find(
name=item.name,
spec=normalized_spec
)
if matched:
result.matched.append(item)
else:
result.unmatched.append({
"item": item,
"reason": "商品库中无此商品或规格"
})
```
---
## 步骤 4:输出匹配报告
**报告格式**:
```
📊 匹配结果报告
📌 报价信息
- 渠道:武汉汉堡苹果
- 报价时间:2026-03-25 10:00
- 原始数据:价格表_20260325.xlsx
📌 已识别商品(共 X 条)
├── iPhone 17 Pro(5 条)
│ ├── 256G 银色 - ¥6500
│ ├── 512G 黑色 - ¥7200
│ └── ...
├── iPhone 17 Pro Max(3 条)
│ ├── 256G 白色 - ¥7500
│ └── ...
└── ...
📌 未识别商品(共 Y 条)
├── iPhone 19 Ultra(2 条)
│ ├── 256G 黑色 - ¥9999
│ ├── 原因:商品库中无此商品
│ └── 512G 白色 - ¥10999
│ 原因:商品库中无此商品
└── ...
💡 建议操作:
1. 回复"导入"执行导入
2. 回复"添加新商品"将未识别商品添加到商品库
3. 回复"修改规则:XXX 映射到 YYY"更新匹配规则
4. 回复"重新匹配"使用新规则再次匹配
```
---
## 步骤 5:用户确认
**用户可选择的回复**:
| 回复 | 操作 |
|------|------|
| `导入` | 导入已匹配的商品价格 |
| `全部导入` | 导入所有数据(包括未识别的,会先创建商品) |
| `添加新商品` | 将未识别商品添加到商品库后导入 |
| `修改规则:A 映射到 B` | 更新匹配规则后重新匹配 |
| `重新匹配` | 使用当前规则再次匹配 |
| `取消` | 取消本次导入 |
---
## 步骤 6:执行导入
### 调用接口
**批量导入**:`POST /api/prices/batch-import`
```json
{
"items": [
{
"product_id": 1,
"price": 6500,
"source": "武汉汉堡苹果",
"price_time": "2026-03-25T10:00:00",
"specification": "256G 银色"
}
],
"source": "武汉汉堡苹果",
"price_time": "2026-03-25T10:00:00",
"batch_no": "B20260325001"
}
```
**上传原始数据**:`POST /api/import-logs/{batch_no}/attachment`
### 创建新商品(如需要)
`POST /api/products/batch-create`
```json
{
"products": [
{
"name": "iPhone 19 Ultra",
"category": "手机",
"brand": "苹果"
}
]
}
```
---
## 步骤 7:验证结果
### 验证清单
1. **价格是否更新**
- 调用 `GET /api/prices?source={source}&time={time}`
- 检查返回数量是否与导入数量一致
2. **导入记录是否存在**
- 调用 `GET /api/import-logs/{batch_no}`
- 检查批次记录状态
3. **原始数据是否上传**
- 检查附件链接是否可访问
- 验证文件完整性
### 验证输出
```
✅ 导入验证完成!
✓ 价格记录:103 条(正确)
✓ 导入批次:B20260325001(已创建)
✓ 原始数据:价格表_20260325.xlsx(已上传)
✓ 新商品:3 个(已添加)
查看详情:http://47.96.183.13/price/import-logs.html
```
---
## 匹配规则管理
### 规则存储
规则存储在 `~/.openclaw/workspace/price-import/matching-rules.json`
```json
{
"model_aliases": {
"iPhone 16 MAX": "iPhone 16 Pro Max",
"iPhone 17 MAX": "iPhone 17 Pro Max"
},
"capacity_units": {
"TBG": "TB"
},
"spec_suffixes": {
"渠道版": "",
"全国渠道版": "",
"预激活": "官网预激活"
},
"color_mapping": {
"黑色": "深蓝色",
"蓝色": "深蓝色"
}
}
```
### 更新规则
当用户说 `修改规则:XXX 映射到 YYY` 时:
1. 解析用户的规则描述
2. 更新 matching-rules.json
3. 重新执行匹配
4. 输出新的匹配报告
---
## API 接口清单
| 接口 | 方法 | 说明 |
|------|------|------|
| `/api/products` | GET | 获取所有商品 |
| `/api/specifications` | GET | 获取商品规格 |
| `/api/prices/batch-import` | POST | 批量导入价格 |
| `/api/products/batch-create` | POST | 批量创建商品 |
| `/api/import-logs` | GET | 获取导入记录 |
| `/api/import-logs/{batch_no}` | GET | 获取批次详情 |
| `/api/import-logs/{batch_no}/attachment` | POST | 上传原始数据 |
| `/api/import-logs/{batch_no}/rollback` | POST | 撤销导入 |
---
## 错误处理
### 常见问题
1. **商品库为空**
- 提示用户先添加商品或确认是否批量创建
2. **匹配率过低(<50%)**
- 提示用户检查数据格式或更新匹配规则
3. **API 调用失败**
- 重试 3 次
- 仍失败则提示用户检查服务状态
4. **导入部分失败**
- 记录失败的条目
- 输出失败原因
- 支持单独重试
---
## 示例对话
```
用户:[发送图片:价格表截图]
系统:🔄 正在识别图片内容...
📊 识别完成!共 105 条数据
🔄 正在拉取商品库...
📦 商品库中有 520 个商品
🔄 正在匹配...
📊 匹配结果报告
📌 报价信息
- 渠道:武汉汉堡苹果
- 报价时间:2026-03-25 10:00
📌 已识别商品(共 98 条)
├── iPhone 17 Pro(45 条)
├── iPhone 17 Pro Max(35 条)
└── iPhone 16 系列(18 条)
📌 未识别商品(共 7 条)
├── iPhone 19 Ultra(5 条)
│ 原因:商品库中无此商品
└── 华为 Mate 70(2 条)
原因:商品库中无此商品
💡 建议操作:
1. 回复"导入"执行导入
2. 回复"添加新商品"将未识别商品添加到商品库
3. 回复"修改规则:XXX 映射到 YYY"更新匹配规则
用户:添加新商品
系统:✅ 已添加 2 个新商品到商品库
✅ 导入完成!
批次号:B20260325001
导入价格:105 条
新增商品:2 个
✅ 验证通过!
查看详情:http://47.96.183.13/price/import-logs.html
```
---
## 命令处理逻辑
### `/import` (无参数)
- 回复:请发送价格表(图片/文本/Excel)
- 等待用户发送数据后进入步骤 2
### `/import help`
- 回复:显示完整使用说明(本文件内容摘要)
### `/import status`
- 调用:`GET /api/import-logs?limit=10`
- 回复:最近 10 条导入记录
### `/import rules`
- 读取:`~/.openclaw/workspace/price-import/matching-rules.json`
- 回复:当前匹配规则
- 支持:`/import rules set XXX=YYY` 添加新规则
### `/import cancel`
- 清空当前待导入数据
- 回复:已取消本次导入任务
### `/fix` [需求描述]
- 接收用户需求,进行分析并生成需求文档
- 示例:`/fix 导入的渠道名称老是错,希望能统一`
### `/fix status` [需求编号]
- 查看指定需求的处理进度
- 示例:`/fix status REQ-PPS-20260326-001`
### `/fix list`
- 查看所有待处理需求清单
- 显示:编号、标题、优先级、状态、提交时间
---
## 🔧 程序功能变动/缺陷修复指令 (`/fix`)
### 指令说明
**用途**:当用户发现程序 bug、提出新功能需求、或需要优化现有功能时使用
**处理流程**:
```
1. 接收用户需求
↓
2. 需求分析与整理
- 问题描述/功能描述
- 影响范围
- 优先级评估
↓
3. 任务拆分
- 程序虾负责的任务(后端/API/数据库)
- 本技能负责的任务(导入逻辑/匹配规则)
↓
4. 发送用户确认
- 详细需求文档
- 任务清单
- 预计影响
↓
5. 等待用户确认
↓
6. 生成程序虾任务清单
- 详细技术任务
- 验收标准
↓
7. 等待程序虾完成
↓
8. 核实与验收
- 功能测试
- 结果反馈
```
---
### 需求分析模板
当收到用户需求时,按以下格式整理:
```markdown
## 📋 需求文档
### 问题描述
[用户反馈的原始问题或功能需求]
### 影响范围
- 受影响的功能模块
- 受影响的数据范围
- 受影响的用户群体
### 优先级
- 🔴 高:影响核心功能/数据准确性
- 🟡 中:影响使用体验
- 🟢 低:优化建议
### 任务拆分
#### 程序虾负责(后端/服务)
- [ ] 任务 1:...
- [ ] 任务 2:...
#### 本技能负责(导入/匹配)
- [ ] 任务 1:...
- [ ] 任务 2:...
### 验收标准
1. [具体的验收条件 1]
2. [具体的验收条件 2]
3. ...
```
---
### 程序虾任务清单格式(MD 文件)
当需要程序虾处理时,生成标准 MD 文件:
**文件命名**:`REQ-{系统缩写}-{YYYYMMDD}-{序号}.md`
**文件路径**:`~/.openclaw/workspace/requirements/`
```markdown
# 需求文档 - {需求标题}
## 📋 基本信息
| 字段 | 值 |
|------|-----|
| **需求编号** | REQ-PPS-20260326-001 |
| **所属系统** | 价易通 - 商品报价管理系统 |
| **提交时间** | 2026-03-26 06:44 |
| **提交人** | 价易通导入技能 |
| **优先级** | 🔴 高 / 🟡 中 / 🟢 低 |
| **状态** | 待确认 / 开发中 / 已完成 / 已验收 |
---
## 🎯 需求概述
### 问题描述
[用户反馈的原始问题或功能需求描述]
### 业务背景
[为什么需要这个功能/修复,解决什么业务问题]
### 影响范围
- **功能模块**:[受影响的功能模块]
- **数据范围**:[影响的数据表/数据范围]
- **用户影响**:[影响哪些用户/使用场景]
---
## 📝 详细需求
### 当前状态(As-Is)
[描述当前系统的行为或问题]
### 期望状态(To-Be)
[描述期望的行为或功能]
### 功能变动说明
#### 模块 1:[模块名称]
- **变动类型**:新增 / 修改 / 删除
- **变动位置**:[具体文件/API/表名]
- **变动说明**:[详细的技术描述]
- **接口变更**:
- 新增接口:`POST /api/xxx`
- 修改接口:`PUT /api/yyy` - 新增参数 `xxx`
- **数据库变更**:
- 新增表:`xxx_table`
- 修改表:`yyy_table` - 新增字段 `zzz`
#### 模块 2:[模块名称]
...
---
## ✅ 验收标准
### 功能测试
- [ ] 测试用例 1:[具体测试步骤和期望结果]
- [ ] 测试用例 2:[具体测试步骤和期望结果]
- [ ] 测试用例 3:[具体测试步骤和期望结果]
### 数据验证
- [ ] 验证点 1:[具体的数据验证标准]
- [ ] 验证点 2:[具体的数据验证标准]
### 边界条件
- [ ] 边界测试 1:[边界情况描述]
- [ ] 边界测试 2:[边界情况描述]
### 回归测试
- [ ] 确保不影响功能 A
- [ ] 确保不影响功能 B
---
## 📎 附件
### 参考数据
```json
{
"示例数据": "如有需要,提供示例 JSON"
}
```
### 相关文档
- [相关 API 文档链接]
- [相关设计文档链接]
---
## 📝 变更记录
| 日期 | 版本 | 变更内容 | 变更人 |
|------|------|---------|--------|
| 2026-03-26 | v1.0 | 初始版本 | 价易通导入技能 |
---
## 🔧 开发备注
[程序虾填写]
- **开发开始时间**:
- **开发完成时间**:
- **实际工作量**:
- **技术难点**:
- **注意事项**:
---
## ✅ 验收记录
[价易通导入技能填写]
- **验收时间**:
- **验收结果**:通过 / 不通过
- **测试报告**:
- **验收人**:
```
---
### 文件生成流程
1. **创建目录**(如不存在):
```bash
mkdir -p ~/.openclaw/workspace/requirements
```
2. **生成需求文档**:
- 文件名:`REQ-{系统缩写}-{YYYYMMDD}-{序号}.md`
- 系统缩写:
- `PPS` = Product Price System(价易通商品报价系统)
- `其他系统` = 按实际系统命名
3. **发送用户确认** ⚠️:
- 发送完整需求文档给用户
- 说明问题、影响范围、任务拆分、验收标准
- **等待用户确认后再发送给程序虾**
- 技能相关修改也必须经用户确认
4. **用户确认后**:
- 标记状态为"待开发"
- 更新 registry.json
- 发送给程序虾处理
5. **程序虾开发完成**:
- 程序虾生成**执行反馈文档**(MD 格式)
- 标注对应的需求编号
- 用户验收测试
6. **验收通过后**:
- 更新状态为"已验收"
- 填写验收记录
- 归档需求和反馈文档
---
### 需求文件管理规范
#### 目录结构
```
~/.openclaw/workspace/requirements/
├── README.md # 需求管理说明
├── registry.json # 需求注册表(所有需求的索引)
│
├── PPS/ # 价易通 - 商品报价管理系统
│ ├── REQ-PPS-20260326-001.md # 具体需求文档
│ ├── REQ-PPS-20260326-002.md
│ └── archive/ # 已归档需求
│ ├── 2026-03/
│ └── 2026-04/
│
├── {SYSTEM}/ # 其他系统目录
│ ├── REQ-{SYS}-YYYYMMDD-001.md
│ └── archive/
│
└── templates/ # 需求文档模板
├── standard.md # 标准功能需求模板
├── bugfix.md # Bug 修复需求模板
└── optimization.md # 优化需求模板
```
#### 系统目录命名
| 目录名 | 系统名称 | 说明 |
|--------|---------|------|
| `PPS` | Product Price System | 价易通 - 商品报价管理系统 |
| `{系统缩写}` | 按实际系统命名 | 新增系统时创建对应目录 |
#### 需求编号规则
- **格式**:`REQ-{系统缩写}-{日期}-{序号}`
- **示例**:`REQ-PPS-20260326-001`
- **序号规则**:每个系统每日独立计数,从 001 开始
#### 需求注册表(registry.json)
```json
{
"systems": {
"PPS": "价易通 - 商品报价管理系统"
},
"requirements": [
{
"id": "REQ-PPS-20260326-001",
"system": "PPS",
"title": "渠道名称统一与别名映射",
"priority": "🟡 中",
"status": "待确认",
"created_at": "2026-03-26T06:44:00",
"file_path": "PPS/REQ-PPS-20260326-001.md"
}
]
}
```
#### 状态流转
```
待确认 → 待开发 → 开发中 → 已完成 → 已验收
↓ ↓ ↓
取消 暂停 不通过
```
#### 文件版本控制
- 需求文档变更时更新版本号(v1.0 → v1.1 → v2.0)
- 重大变更升主版本,小变更升次版本
- 变更记录表中记录每次变更
#### 归档规则
- **活跃需求**:存放在系统根目录(如 `PPS/`)
- **已验收需求**:按月移入归档目录(如 `PPS/archive/2026-03/`)
- **保存期限**:永久(作为系统演进历史)
#### 新增系统流程
当需要支持新系统时:
1. **创建系统目录**:
```bash
mkdir -p ~/.openclaw/workspace/requirements/{SYS}/archive
```
2. **更新注册表**:
```json
{
"systems": {
"PPS": "价易通 - 商品报价管理系统",
"{SYS}": "新系统名称"
}
}
```
3. **通知用户**:
```
✅ 已注册新系统:{SYS} - {系统名称}
📁 目录:requirements/{SYS}/
📝 需求编号:REQ-{SYS}-YYYYMMDD-001
```
---
### 执行反馈文档格式
程序虾完成任务后,必须生成执行反馈文档:
**文件命名**:`FEEDBACK-{需求编号}.md`
**文件路径**:`~/.openclaw/workspace/requirements/{系统}/feedback/`
```markdown
# 执行反馈 - {需求标题}
## 📋 基本信息
| 字段 | 值 |
|------|-----|
| **反馈编号** | FEEDBACK-REQ-PPS-20260326-001 |
| **关联需求** | REQ-PPS-20260326-001 |
| **所属系统** | 价易通 - 商品报价管理系统 |
| **提交时间** | 2026-03-26 10:00 |
| **提交人** | 程序虾 |
| **状态** | 已完成 / 部分完成 / 未完成 |
---
## ✅ 任务执行清单
### 已完成任务
- [x] 任务 1:[任务名称]
- **执行时间**:2026-03-26 09:00-09:30
- **执行说明**:[具体执行内容]
- **执行结果**:成功/失败
- [x] 任务 2:[任务名称]
- **执行时间**:2026-03-26 09:30-10:00
- **执行说明**:[具体执行内容]
- **执行结果**:成功/失败
### 未完成/部分完成任务
- [ ] 任务 3:[任务名称]
- **未完成原因**:[说明原因]
- **预计完成时间**:2026-03-27
- **备注**:[其他说明]
---
## 📝 技术实现说明
### 数据库变更
```sql
-- 示例:执行的 SQL 语句
ALTER TABLE products MODIFY specification VARCHAR(200);
UPDATE products SET specification = CONCAT(specification, ' 黑色 预激活') WHERE ...;
```
### API 变更
- **新增接口**:`POST /api/xxx`
- **修改接口**:`PUT /api/yyy` - 新增参数 `xxx`
### 代码变更
- **修改文件**:`/opt/product-price-system/app/api/products.py`
- **修改行数**:+50 -20
- **Git 提交**:`abc1234 fix: 恢复商品规格完整字段`
---
## 📊 数据修复结果
### 修复统计
| 商品类别 | 修复数量 | 修复前示例 | 修复后示例 |
|---------|---------|-----------|-----------|
| iPhone | 52 | 256G | 256G 黑色 预激活 |
| iPad | 48 | 128G | 128G 黑色 WiFi |
| 其他 | 0 | - | - |
| **合计** | **100** | - | - |
### 验证查询
```sql
-- 验证修复结果的 SQL
SELECT name, specification FROM products WHERE name LIKE '%iPhone%' LIMIT 10;
```
### 验证结果
```
iPhone 17 Pro | 256G 黑色 预激活
iPhone 17 Pro | 256G 白色 渠道版
iPhone 17 Pro Max | 512G 蓝色 已激活
...
```
---
## ⚠️ 注意事项
1. [需要用户注意的事项 1]
2. [需要用户注意的事项 2]
3. [后续建议]
---
## 📎 附件
- [相关 Git 提交链接]
- [数据库备份文件位置]
- [其他相关文档]
---
## ✅ 验收申请
已完成以上任务,申请验收。
**自检结果**:
- [x] 所有任务已完成
- [x] 数据已验证
- [x] 功能测试通过
- [x] 回归测试通过
请价易通导入技能进行验收测试。
---
**程序虾签名**:程序虾
**提交时间**:2026-03-26 10:00
```
---
### 反馈文档流程
1. **程序虾生成反馈**:
- 完成任务后生成反馈文档
- 标注对应的需求编号
- 详细说明执行结果
2. **发送用户通知**:
```
✅ 程序虾已完成需求:REQ-PPS-20260326-001
📄 反馈文档:requirements/PPS/feedback/FEEDBACK-REQ-PPS-20260326-001.md
🔍 请进行验收测试
```
3. **价易通验收**:
- 根据反馈文档进行验证
- 填写需求文档中的"验收记录"
- 更新状态为"已验收"或"不通过"
4. **归档**:
- 需求文档 + 反馈文档一起归档
- 作为系统演进历史记录
---
### 核实与验收流程
程序虾完成任务后,本技能负责:
1. **功能测试**
- 调用相关 API 验证功能
- 检查数据是否正确
- 验证边界情况
2. **回归测试**
- 确保修复不影响现有功能
- 检查相关模块是否正常
3. **结果反馈**
```
✅ 验收通过
- 功能:XXX
- 测试结果:正常
- 验证时间:2026-03-26 10:00
❌ 验收未通过
- 功能:XXX
- 问题描述:...
- 需要重新处理
```
---
### 示例对话
```
用户:/fix 导入的渠道名称老是错,希望能统一
系统:📋 收到需求!正在分析...
---
## 📋 需求分析
### 问题描述
导入价格时渠道名称不统一,如"武汉菠萝苹果"和"武汉菠萝"实际是同一渠道
### 影响范围
- 功能模块:价格导入
- 数据范围:所有历史导入记录
- 用户影响:数据统计不准确
### 优先级
🟡 中
### 任务拆分
#### 程序虾负责(后端/服务)
- [ ] 1. 添加渠道别名映射表
- [ ] 2. 修改导入 API 支持别名自动转换
- [ ] 3. 提供渠道合并 API
#### 本技能负责(导入/匹配)
- [ ] 1. 更新渠道名称映射规则
- [ ] 2. 导入前进行渠道名称校验
### 验收标准
1. 导入"武汉菠萝苹果"自动转为"武汉菠萝"
2. 历史数据可以合并
3. 渠道列表不出现重复
---
请确认以上需求分析是否正确?回复"确认"后我将生成正式需求文档。
用户:确认
系统:✅ 需求已确认,正在生成需求文档...
📄 已创建文件:`requirements/REQ-PPS-20260326-001.md`
---
# 需求文档 - 渠道名称统一与别名映射
## 📋 基本信息
| 字段 | 值 |
|------|-----|
| **需求编号** | REQ-PPS-20260326-001 |
| **所属系统** | 价易通 - 商品报价管理系统 |
| **提交时间** | 2026-03-26 06:44 |
| **提交人** | 价易通导入技能 |
| **优先级** | 🟡 中 |
| **状态** | 待确认 |
---
## 🎯 需求概述
### 问题描述
导入价格时渠道名称不统一,"武汉菠萝苹果"和"武汉菠萝"实际是同一渠道,导致数据统计分散
### 业务背景
- 不同导入人员使用不同渠道名称
- 同一渠道数据分散在多条记录中
- 影响渠道统计和数据分析准确性
### 影响范围
- **功能模块**:价格导入 API、渠道管理
- **数据范围**:`prices` 表的 `source` 字段、`channels` 表
- **用户影响**:所有使用渠道统计功能的用户
---
## 📝 详细需求
### 当前状态(As-Is)
- 导入 API 直接使用用户输入的渠道名称
- 无渠道别名映射机制
- 渠道列表中存在重复渠道
### 期望状态(To-Be)
- 支持渠道别名配置
- 导入时自动转换为标准渠道名称
- 提供渠道合并功能
### 功能变动说明
#### 模块 1:数据库
- **变动类型**:新增
- **变动位置**:新增 `channel_aliases` 表
- **变动说明**:
```sql
CREATE TABLE channel_aliases (
id INT PRIMARY KEY AUTO_INCREMENT,
standard_name VARCHAR(100) NOT NULL, -- 标准名称
alias_name VARCHAR(100) NOT NULL, -- 别名
created_at DATETIME DEFAULT NOW()
);
```
#### 模块 2:导入 API
- **变动类型**:修改
- **变动位置**:`/api/prices/batch-import`
- **变动说明**:导入时检查渠道别名,自动转换为标准名称
- **伪代码**:
```python
def normalize_channel(source):
alias = db.query("SELECT standard_name FROM channel_aliases WHERE alias_name = ?", source)
return alias if alias else source
```
#### 模块 3:渠道管理 API
- **变动类型**:新增
- **变动位置**:新增 `/api/channels/merge` 接口
- **变动说明**:合并两个渠道名称的所有数据
---
## ✅ 验收标准
### 功能测试
- [ ] 使用"武汉菠萝苹果"导入,数据库中存储为"武汉菠萝"
- [ ] 使用"武汉菠萝"导入,数据库中存储为"武汉菠萝"
- [ ] 查询渠道列表,只显示"武汉菠萝",不显示"武汉菠萝苹果"
### 数据验证
- [ ] 历史数据中"武汉菠萝苹果"的记录可以通过合并功能合并到"武汉菠萝"
- [ ] 合并后统计数量正确
### 边界条件
- [ ] 别名可以配置多个(如 A→标准,B→标准)
- [ ] 标准名称本身不能作为其他标准的别名
### 回归测试
- [ ] 确保不影响现有导入功能
- [ ] 确保不影响渠道查询功能
---
## 📎 附件
### 示例数据
```json
{
"alias_mappings": [
{"standard": "武汉菠萝", "alias": "武汉菠萝苹果"},
{"standard": "武汉汉堡", "alias": "武汉汉堡苹果"}
]
}
```
---
## 📝 变更记录
| 日期 | 版本 | 变更内容 | 变更人 |
|------|------|---------|--------|
| 2026-03-26 | v1.0 | 初始版本 | 价易通导入技能 |
---
## 🔧 开发备注
[程序虾填写]
- **开发开始时间**:
- **开发完成时间**:
- **实际工作量**:
- **技术难点**:
- **注意事项**:
---
## ✅ 验收记录
[价易通导入技能填写]
- **验收时间**:
- **验收结果**:通过 / 不通过
- **测试报告**:
- **验收人**:
---
@程序虾 请查收需求文档,确认后开始开发。
文件路径:`~/.openclaw/workspace/requirements/REQ-PPS-20260326-001.md`
```
---
## 职责边界
⚠️ **本技能遵守以下职责限制**:
1. **操作数据库必须确认** - 导入前必须用户确认
2. **禁止改动运行服务的代码** - 只调用 API,不修改服务端代码
3. **发现 bug 或需求不满足时反馈** - 不自行修改后端逻辑
4. **必须通过 `/import` 命令触发** - 避免误处理无关内容
---
## 🤖 与程序虾的职责划分
### 本技能(价易通导入技能)职责 ✅
**负责**:
1. 接收用户发送的价格表(图片/文本/Excel)
2. 识别和解析原始数据
3. 拉取商品库并进行智能匹配
4. 输出匹配报告供用户确认
5. 调用 API 执行批量导入
6. 验证导入结果
**不负责**:
- ❌ 商品库管理(添加/编辑/删除商品)
- ❌ 渠道管理(添加/修改渠道名称)
- ❌ 数据库直接操作(只通过 API)
- ❌ 服务端代码修改
- ❌ 重复数据清理
- ❌ 历史数据修复
---
### 程序虾(发布服务器)职责 ✅
**负责**:
1. **商品库管理**
- 添加新商品
- 编辑商品信息(名称、规格、分类、品牌)
- 删除/停用商品
- 维护商品库数据质量
2. **渠道管理**
- 添加新渠道
- 统一渠道名称(如"武汉菠萝苹果"→"武汉菠萝")
- 维护渠道列表
3. **数据维护**
- 重复数据清理
- 历史数据修复
- 数据库备份与恢复
- 数据一致性检查
4. **系统运维**
- 服务部署与更新
- API 接口开发
- 数据库结构变更
- 日志管理与监控
---
### 协作流程
```
用户 → 本技能:发送价格表导入
↓
发现未识别商品
↓
本技能 → 用户:提示"有 X 个商品未识别,需要联系程序虾添加"
↓
用户 → 程序虾:添加新商品/统一渠道名称
↓
程序虾 → 用户:商品已添加,可以重新导入
↓
用户 → 本技能:重新导入
```
---
### 典型场景处理
| 场景 | 本技能处理 | 程序虾处理 |
|------|-----------|-----------|
| 新商品不在库中 | 标记为未识别,提示用户 | 添加商品到库 |
| 渠道名称不统一 | **记录用户指定的正确名称**,反馈问题 | 统一渠道名称 |
| 重复数据 | 不处理,只负责导入 | 清理重复数据 |
| 商品名称变更 | 不处理,匹配失败 | 更新商品库 |
| API 接口 bug | 反馈给用户 | 修复代码 |
| 数据结构变更 | 不处理 | 修改数据库结构 |
---
### 📝 历史教训(2026-03-26)
**问题**:
1. 渠道名称错误使用了"武汉菠萝苹果",应为"武汉菠萝"
2. 导入了重复数据,需要后续清理
**改进**:
1. ✅ 渠道名称以用户指定为准,不确定时先确认
2. ✅ 导入前检查是否存在重复(相同 source + product_id + price_time)
3. ✅ 明确职责:数据清理是程序虾的职责,本技能只负责导入
4. ✅ 发现数据问题先反馈,不要越权处理
**渠道名称规则**:
- "武汉菠萝苹果" = "武汉菠萝" → 统一使用 **武汉菠萝**
- 类似情况先确认,不要自行决定
---
### 越界行为禁止 🚫
**本技能禁止**:
- 直接 SSH 到服务器修改数据库
- 修改服务端 Python/Go 代码
- 执行数据库清理脚本(除非用户明确要求且确认)
- 添加/修改渠道列表
- 修改商品库结构
**正确做法**:
- 发现数据问题 → 反馈给用户 → 由程序虾处理
- 发现 API bug → 记录问题 → 反馈给开发者
- 需要新接口 → 提出需求 → 等待程序虾实现
标签
skill
ai