Skill: ligenhui/vinehoo-search (version 0.1.0)

--- name: vinehoo-product-search description: 酒云网葡萄酒商品搜索与统计工具；当用户需要搜索葡萄酒、红酒、香槟等商品，或查看当日新上商品统计及具体商品时使用 --- # 酒云网葡萄酒商品搜索与统计 ## 任务目标 - 本 Skill 用于：搜索酒云网（vinehoo.com）的专业葡萄酒商品库，并查看当日新上商品统计及具体商品 - 能力包含： - 商品搜索：按关键词搜索、按价格区间筛选、按产地国家筛选、按酒类类型筛选、分页查询 - 统计摘要：查看当日新上商品的国家分布、类型分布、酒庄分布、产区分布 - 统计商品：根据统计维度查询当日新上的具体商品列表 - 专长领域：葡萄酒、红酒、香槟、起泡酒、烈酒等全品类酒类商品 - 触发条件：用户请求搜索酒类商品，或需要获取当日新上商品的统计信息或具体商品 ## 前置准备 - 依赖说明：使用 Node.js 原生 https 模块，无需额外安装依赖 - 无需额外授权 ## 操作步骤 ### 商品搜索流程 - 标准流程： 1. **用户需求评估与引导** - 评估用户对葡萄酒的了解程度和提供的信息完整度 - 如果用户搜索条件非常少（如仅说"推荐一款红酒"），主动引导用户补充关键信息： - **预算范围**：您希望的价格区间是多少？如100-300元 - **产地偏好**：您有偏好的国家吗？如法国、意大利、澳洲等 - **酒类类型**：您想要什么类型？红葡萄酒、白葡萄酒、香槟等 - **饮用场景**：日常饮用、送礼、聚会等（可用于推荐） - **口味偏好**：喜欢果香浓郁、酒体厚重、清爽轻盈等 - 如果用户已提供较为详细的条件，直接进入搜索 2. **构建搜索参数** - 根据用户需求确定搜索条件： - `page`: 页码（必需，从1开始） - `limit`: 每页数量（可选，默认10） - `keywords`: 搜索关键词（可选，如"香槟"、"勃艮第"、"黑皮诺"） - `price_gte`: 最低价格（可选） - `price_lte`: 最高价格（可选） - `countries`: 产地国家列表（可选，支持多个，如"法国 意大利"） - `category`: 酒类类型（可选，仅支持一个，如"白葡萄酒"） 3. **调用搜索脚本** - 执行 `node scripts/search_products.js --page <页码> --limit <数量> --keywords "<关键词>" --price-gte <最低价> --price-lte <最高价> --countries <国家1> <国家2> ... --category "<类型>"` - 脚本返回商品列表数据 4. **结果处理与展示** - 智能体根据返回的商品列表，进行以下处理： - 提取关键信息（酒款名称、价格、产地、产区、风格特点） - **必须展示商品链接**：每个商品都要提供完整的商品详情页链接（url字段），用户可点击查看详情或购买 - 根据用户需求推荐匹配的葡萄酒 - 提供专业的酒品介绍和购买建议 - 格式化输出结果 ### 统计摘要流程 - 标准流程： 1. **调用统计脚本** - 执行 `node scripts/statistics_summary.js` - 脚本返回当日新上商品的统计摘要数据 2. **结果处理与展示** - 智能体根据返回的统计数据，进行以下处理： - 提取关键信息（日期、总数量、各维度分布） - 分析当日上新的重点国家和产区 - 分析当日上新的主要酒类类型 - 总结当日上新趋势和亮点 - 格式化输出结果 - **主动引导**：如果用户对某个维度感兴趣（如某个国家或产区），可引导用户查看该维度的具体商品 ### 统计商品流程（当日新上商品） - 标准流程： 1. **构建查询参数** - 根据统计摘要中的维度或用户需求确定查询条件： - `page`: 页码（可选，默认1） - `limit`: 每页数量（可选，默认10） - `country`: 国家（可选） - `category`: 酒类类型（可选） - `region`: 产区（可选） - `winery`: 酒庄（可选） 2. **调用统计商品脚本** - 执行 `node scripts/statistics_products.js --page <页码> --limit <数量> --country "<国家>" --category "<类型>" --region "<产区>" --winery "<酒庄>"` - 脚本返回当日新上商品列表数据 3. **结果处理与展示** - 智能体根据返回的商品列表，进行以下处理： - 提取关键信息（酒款名称、价格、产地、产区、风格特点） - **必须展示商品链接**：每个商品都要提供完整的商品详情页链接（url字段），用户可点击查看详情或购买 - 根据筛选条件为用户提供针对性的推荐 - 提供专业的酒品介绍和购买建议 - 格式化输出结果 ### 可选分支 - 当用户信息不足：主动引导补充关键信息（预算、产地、类型等） - 当仅关键词搜索：传递 `--keywords` 参数（如搜索特定产区、葡萄品种、酒庄名） - 当仅价格筛选：传递 `--price-gte` 和/或 `--price-lte` 参数 - 当仅产地筛选：传递 `--countries` 参数（支持多个国家） - 当仅类型筛选：传递 `--category` 参数（如红葡萄酒、白葡萄酒、香槟等） - 当组合筛选：同时传递多个参数，实现精准匹配 - 当用户查看当日新上统计：调用统计摘要脚本，分析当日上新情况 - 当用户查看当日新上统计后的具体商品：调用统计商品脚本，按统计维度查询当日新上的具体商品 - 当用户对某个统计维度感兴趣：引导用户使用统计商品脚本查看该维度的当日新上具体商品 ## 资源索引 - 领域参考：见 [references/api-reference.md](references/api-reference.md)（何时读取：需要了解支持的产地国家、酒类类型列表、详细参数说明） ## 注意事项 - 仅在需要时读取参考，保持上下文简洁 - 脚本已处理错误情况，查询失败时会返回明确的错误信息 - 脚本会验证国家和类型参数，传入不支持的产地或类型会返回错误提示 - **用户引导**：当用户对葡萄酒了解不多或搜索条件很少时，主动询问并引导用户补充预算、产地、类型等关键信息，提供更好的推荐效果 - 智能体应充分利用葡萄酒专业知识，为用户提供有价值的推荐和建议 - **重要**：每次展示商品结果时，必须包含商品详情页链接（url），用户点击链接即可查看完整详情或直接购买 - 支持的产地涵盖全球主要葡萄酒生产国：法国、意大利、德国、西班牙、澳大利亚、新西兰、智利、阿根廷、美国等 - 支持的酒类类型丰富：红葡萄酒、白葡萄酒、起泡酒、香槟、甜酒、烈酒、清酒、加强酒等 - **统计数据说明**：统计信息中各维度（国家、类型、酒庄、产区）的数量加起来可能与总数不一致，这是正常情况。原因包括： - 有些商品可能未绑定产区信息 - 有些商品可能未绑定酒庄信息 - 不同维度的统计是独立计算的 - **仅在用户主动询问"为什么数据对不上"时才解释此原因，否则不主动提及** - **统计商品说明**：统计商品脚本用于查询当日新上的具体商品，返回格式与商品搜索脚本的返回格式完全相同，包含完整的商品信息（url、title、brief、price、country、regions、product_keyword） ## 使用示例 - 示例1：搜索香槟类商品 ```bash node scripts/search_products.js --page 1 --limit 10 --keywords "香槟" ``` - 示例2：查找100-500元价格区间的葡萄酒 ```bash node scripts/search_products.js --page 1 --price-gte 100 --price-lte 500 ``` - 示例3：筛选法国和意大利产地的葡萄酒 ```bash node scripts/search_products.js --page 1 --limit 10 --countries 法国 意大利 ``` - 示例4：筛选白葡萄酒类型 ```bash node scripts/search_products.js --page 1 --limit 10 --category "白葡萄酒" ``` - 示例5：组合搜索（关键词+价格+产地+类型） ```bash node scripts/search_products.js --page 1 --limit 20 --keywords "勃艮第" --price-gte 300 --price-lte 800 --countries 法国 --category "红葡萄酒" ``` - 示例6：查看当日新上商品统计摘要 ```bash node scripts/statistics_summary.js ``` - 示例7：查询当日新上商品中某个统计维度的具体商品（如意大利的干红葡萄酒） ```bash node scripts/statistics_products.js --country "意大利" --category "干红葡萄酒" ``` - 示例8：查询当日新上商品中某个产区的具体商品 ```bash node scripts/statistics_products.js --region "瓦波利切拉产区" ``` - 示例9：查询当日新上商品中某个酒庄的具体商品 ```bash node scripts/statistics_products.js --winery "佩高酒庄" ``` - 示例10：查询当日新上所有商品 ```bash node scripts/statistics_products.js ```

path: references/api-reference.md
content: # 酒云网商品搜索与统计参考文档

## 目录
- [商品搜索](#商品搜索)
  - [查询概览](#查询概览)
  - [查询参数](#查询参数)
  - [筛选条件](#筛选条件)
  - [返回数据](#返回数据)
  - [搜索示例](#搜索示例)
- [统计摘要（当日新上）](#统计摘要当日新上)
  - [统计概览](#统计概览)
  - [返回数据](#返回数据-1)
  - [统计示例](#统计示例)
- [统计商品（当日新上）](#统计商品当日新上)
  - [统计商品概览](#统计商品概览)
  - [查询参数](#查询参数-1)
  - [返回数据](#返回数据-2)
  - [统计商品示例](#统计商品示例)
- [注意事项](#注意事项)

---

## 商品搜索

### 查询概览
- **数据来源**: 酒云网（vinehoo.com）专业葡萄酒商品数据库
- **查询方式**: 支持多种条件组合查询
- **数据范围**: 覆盖全球主要葡萄酒产区的丰富酒品

### 查询参数

| 参数名 | 类型 | 必需 | 说明 | 示例 |
|--------|------|------|------|------|
| page | int | 是 | 页码，从1开始 | 1 |
| limit | int | 否 | 每页数量，默认10 | 10 |
| keywords | string | 否 | 搜索关键词（如产区、葡萄品种、酒庄名） | "香槟" |
| price_gte | int/float | 否 | 最低价格（>=） | 100 |
| price_lte | int/float | 否 | 最高价格（<=） | 500 |

### 筛选条件

#### 产地国家（country）
- **类型**: array of string
- **说明**: 支持筛选多个产地国家
- **支持的国家**:
  - 中国、法国、意大利、澳大利亚、葡萄牙、德国、西班牙
  - 新西兰、智利、阿根廷、美国、奥地利、南非、日本
- **示例**:
  ```bash
  # 筛选法国和意大利产地的葡萄酒
  --countries 法国 意大利
  ```

#### 酒类类型（product_category）
- **类型**: array of string
- **说明**: 仅支持筛选一种酒类类型
- **支持的类型**:
  - 红葡萄酒、白葡萄酒、起泡酒、香槟、甜酒、烈酒
  - 白酒/黄酒、清酒、果酒/米酒、食品/生鲜、饮料
  - 自然酒、加强酒、桃红葡萄酒、其他酒、酒具
- **示例**:
  ```bash
  # 筛选白葡萄酒
  --category "白葡萄酒"
  ```

### 返回数据

#### 数据结构
查询结果包含以下信息：
- **total**: 符合条件的商品总数
- **list**: 商品列表

#### 商品信息字段
| 字段 | 说明 |
|------|------|
| url | 商品详情页链接（用户点击链接可查看完整详情或直接购买） |
| title | 商品标题（包含酒款名称、特色描述） |
| brief | 商品简介（包含葡萄品种、产区特点、工艺特色等） |
| price | 商品价格 |
| country | 产地国家 |
| regions | 产区信息（如勃艮第、波尔多、香槟产区等） |
| product_keyword | 商品关键词标签（如精品进阶、推荐、性价比之选等） |

### 搜索示例

#### 示例1：关键词搜索
```bash
# 搜索香槟类商品
node scripts/search_products.js --page 1 --limit 10 --keywords "香槟"
```

#### 示例2：价格区间筛选
```bash
# 查找100-500元价格区间的葡萄酒
node scripts/search_products.js --page 1 --price-gte 100 --price-lte 500
```

#### 示例3：产地筛选
```bash
# 筛选法国和意大利产地的葡萄酒
node scripts/search_products.js --page 1 --limit 10 --countries 法国 意大利
```

#### 示例4：酒类类型筛选
```bash
# 筛选白葡萄酒
node scripts/search_products.js --page 1 --limit 10 --category "白葡萄酒"
```

#### 示例5：组合搜索
```bash
# 搜索法国勃艮第产区的红葡萄酒，价格300-800元
node scripts/search_products.js \
  --page 1 \
  --limit 20 \
  --keywords "勃艮第" \
  --price-gte 300 \
  --price-lte 800 \
  --countries 法国 \
  --category "红葡萄酒"
```

#### 示例6：纯分页查询
```bash
# 获取前50条商品数据
node scripts/search_products.js --page 1 --limit 50
```

---

## 统计摘要（当日新上）

### 统计概览
- **数据来源**: 酒云网（vinehoo.com）当日新上商品统计数据
- **统计方式**: 无需参数，返回当日新上商品的多维度统计
- **统计维度**: 日期、总数、国家分布、类型分布、酒庄分布、产区分布
- **重要**: 统计数据仅包含当日新上的商品，不包含历史商品

### 返回数据

#### 数据结构
统计结果包含以下信息：
- **date**: 统计日期（格式：YYYY-MM-DD，表示当日）
- **total**: 当日新上商品总数
- **country_stats**: 按国家统计（国家名称、数量）
- **category_stats**: 按类型统计（类型名称、数量）
- **winery_stats**: 按酒庄统计（酒庄名称、数量）
- **region_stats**: 按产区统计（产区名称、数量）

#### 统计字段说明

**country_stats（国家统计）**
| 字段 | 说明 |
|------|------|
| name | 国家名称 |
| count | 当日该国家新上的商品数量 |

**category_stats（类型统计）**
| 字段 | 说明 |
|------|------|
| name | 酒类类型名称 |
| count | 当日该类型新上的商品数量 |

**winery_stats（酒庄统计）**
| 字段 | 说明 |
|------|------|
| name | 酒庄名称 |
| count | 当日该酒庄新上的商品数量 |

**region_stats（产区统计）**
| 字段 | 说明 |
|------|------|
| name | 产区名称 |
| count | 当日该产区新上的商品数量 |

### 统计示例

#### 示例1：获取当日新上商品统计
```bash
node scripts/statistics_summary.js
```

**返回示例**：
```json
{
  "error_code": 0,
  "error_msg": "ok",
  "data": {
    "date": "2026-03-12",
    "total": 20,
    "country_stats": [
      {"name": "法国", "count": 7},
      {"name": "意大利", "count": 3},
      {"name": "澳大利亚", "count": 3}
    ],
    "category_stats": [
      {"name": "干红葡萄酒", "count": 12},
      {"name": "干白葡萄酒", "count": 3},
      {"name": "威士忌", "count": 1}
    ],
    "winery_stats": [
      {"name": "天瑞酒庄", "count": 2},
      {"name": "泽维尔酒庄", "count": 2}
    ],
    "region_stats": [
      {"name": "罗讷河谷/隆河谷产区", "count": 3},
      {"name": "猎人谷产区", "count": 2}
    ]
  }
}
```

---

## 统计商品（当日新上）

### 统计商品概览
- **数据来源**: 酒云网（vinehoo.com）当日新上商品数据库
- **查询方式**: 根据统计维度（国家、类型、产区、酒庄）筛选当日新上的具体商品
- **使用场景**: 查看统计摘要后，根据某个维度查看当日新上的具体商品列表
- **返回格式**: 与商品搜索脚本的返回格式完全相同
- **重要**: 查询结果仅包含当日新上的商品，不包含历史商品

### 查询参数

| 参数名 | 类型 | 必需 | 说明 | 示例 |
|--------|------|------|------|------|
| page | int | 否 | 页码，从1开始，默认1 | 1 |
| limit | int | 否 | 每页数量，默认10 | 10 |
| country | string | 否 | 国家名称 | "意大利" |
| category | string | 否 | 酒类类型名称 | "干红葡萄酒" |
| region | string | 否 | 产区名称 | "瓦波利切拉产区" |
| winery | string | 否 | 酒庄名称 | "佩高酒庄" |

**说明**：
- 所有参数均为可选，可以单独使用或组合使用
- 多个参数组合时为 AND 关系（同时满足所有条件）
- 查询结果仅包含当日新上的商品

### 返回数据

#### 数据结构
查询结果包含以下信息：
- **total**: 符合条件的当日新上商品总数
- **list**: 当日新上商品列表

#### 商品信息字段
与商品搜索脚本的返回格式完全相同：
| 字段 | 说明 |
|------|------|
| url | 商品详情页链接（用户点击链接可查看完整详情或直接购买） |
| title | 商品标题（包含酒款名称、特色描述） |
| brief | 商品简介（包含葡萄品种、产区特点、工艺特色等） |
| price | 商品价格 |
| country | 产地国家 |
| regions | 产区信息（如勃艮第、波尔多、香槟产区等） |
| product_keyword | 商品关键词标签（如精品进阶、推荐、性价比之选等） |

### 统计商品示例

#### 示例1：查询当日新上商品中某个国家的商品
```bash
# 查询当日新上的意大利商品
node scripts/statistics_products.js --country "意大利"
```

#### 示例2：查询当日新上商品中某个类型的商品
```bash
# 查询当日新上的干红葡萄酒
node scripts/statistics_products.js --category "干红葡萄酒"
```

#### 示例3：查询当日新上商品中某个产区的商品
```bash
# 查询当日新上的瓦波利切拉产区商品
node scripts/statistics_products.js --region "瓦波利切拉产区"
```

#### 示例4：查询当日新上商品中某个酒庄的商品
```bash
# 查询当日新上的佩高酒庄商品
node scripts/statistics_products.js --winery "佩高酒庄"
```

#### 示例5：组合查询当日新上商品（国家+类型）
```bash
# 查询当日新上的意大利干红葡萄酒
node scripts/statistics_products.js --country "意大利" --category "干红葡萄酒"
```

#### 示例6：组合查询当日新上商品（产区+酒庄）
```bash
# 查询当日新上的瓦波利切拉产区佩高酒庄商品
node scripts/statistics_products.js --region "瓦波利切拉产区" --winery "佩高酒庄"
```

#### 示例7：分页查询当日新上商品
```bash
# 查询当日新上前20个商品
node scripts/statistics_products.js --limit 20
```

---

## 注意事项

### 商品搜索注意事项
1. `page` 参数为必需参数，必须从1开始
2. 价格参数支持整数和浮点数
3. `countries` 参数支持多个国家，使用空格分隔
4. `category` 参数仅支持一个酒类类型
5. `total` 字段表示符合条件的商品总数，可用于计算总页数
6. `regions` 和 `product_keyword` 可能为空数组
7. 所有参数组合均为可选，可以灵活组合使用
8. 传入不支持的产地国家或酒类类型会返回错误提示
9. 建议结合关键词搜索和筛选条件，提高查询精准度
10. **重要**：每次展示商品结果时，必须包含商品详情页链接（url字段），用户点击链接即可查看完整详情或直接购买

### 用户引导注意事项
11. **用户引导**：当用户对葡萄酒了解不多或搜索条件很少时，主动询问并引导用户补充预算、产地、类型等关键信息，提供更好的推荐效果

### 统计摘要注意事项
12. 统计数据为当日新上商品的实时统计，反映最新上架情况
13. 各统计维度（国家、类型、酒庄、产区）可根据数量进行排序分析
14. 建议结合统计数据为用户提供当日推荐和趋势分析
15. 如当日无新上商品，统计数据可能为空或 total 为 0
16. **重要**：统计数据仅包含当日新上的商品，不包含历史商品
17. **统计数据说明**：统计信息中各维度（国家、类型、酒庄、产区）的数量加起来可能与总数不一致，这是正常情况。原因包括：
    - 有些商品可能未绑定产区信息
    - 有些商品可能未绑定酒庄信息
    - 不同维度的统计是独立计算的
    - **仅在用户主动询问"为什么数据对不上"时才解释此原因，否则不主动提及**

### 统计商品注意事项
18. 统计商品脚本用于查询当日新上的具体商品，与商品搜索脚本的返回格式完全相同
19. 统计商品脚本的所有参数均为可选，可以灵活组合使用
20. 统计商品脚本的筛选条件基于统计摘要中的维度，参数值应与统计摘要中的名称完全一致
21. **重要**：统计商品脚本的查询结果仅包含当日新上的商品，不包含历史商品
22. 建议先查看统计摘要，了解当日上新概况，然后根据感兴趣的维度查询当日新上的具体商品


path: scripts/search_products.js
content: #!/usr/bin/env node

/**
 * 酒云网商品搜索脚本
 *
 * 调用酒云网接口搜索商品列表，支持关键词、价格区间、国家、类型等筛选。
 */

const https = require('https');

const API_URL = 'https://wxapp.vinehoo.com/openai/v3/product/list';

// 支持的国家列表
const SUPPORTED_COUNTRIES = [
  '中国', '法国', '意大利', '澳大利亚', '葡萄牙', '德国', '西班牙',
  '新西兰', '智利', '阿根廷', '美国', '奥地利', '南非', '日本'
];

// 支持的商品类型列表
const SUPPORTED_CATEGORIES = [
  '红葡萄酒', '白葡萄酒', '起泡酒', '香槟', '甜酒', '烈酒', '白酒/黄酒',
  '清酒', '果酒/米酒', '食品/生鲜', '饮料', '自然酒', '加强酒',
  '桃红葡萄酒', '其他酒', '酒具'
];

/**
 * 发起 HTTPS POST 请求
 */
function httpsRequest(url, data) {
  return new Promise((resolve, reject) => {
    const urlObj = new URL(url);
    const options = {
      hostname: urlObj.hostname,
      path: urlObj.pathname,
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Content-Length': Buffer.byteLength(JSON.stringify(data))
      }
    };

    const req = https.request(options, (res) => {
      let responseData = '';

      res.on('data', (chunk) => {
        responseData += chunk;
      });

      res.on('end', () => {
        if (res.statusCode >= 400) {
          reject(new Error(`HTTP请求失败: 状态码 ${res.statusCode}, 响应内容: ${responseData}`));
        } else {
          try {
            const jsonData = JSON.parse(responseData);
            resolve(jsonData);
          } catch (e) {
            reject(new Error(`JSON解析失败: ${e.message}`));
          }
        }
      });
    });

    req.on('error', (e) => {
      reject(new Error(`接口调用失败: ${e.message}`));
    });

    req.write(JSON.stringify(data));
    req.end();
  });
}

/**
 * 搜索商品
 */
async function searchProducts(options) {
  const {
    page = 1,
    limit = 10,
    keywords,
    price_gte,
    price_lte,
    countries,
    product_category
  } = options;

  // 构建请求参数
  const payload = {
    page,
    limit
  };

  // 添加可选参数
  if (keywords) {
    payload.keywords = keywords;
  }
  if (price_gte !== undefined && price_gte !== null) {
    payload.price_gte = price_gte;
  }
  if (price_lte !== undefined && price_lte !== null) {
    payload.price_lte = price_lte;
  }

  // 添加筛选参数
  const filters = {};

  if (countries && countries.length > 0) {
    // 验证国家是否支持
    const invalidCountries = countries.filter(c => !SUPPORTED_COUNTRIES.includes(c));
    if (invalidCountries.length > 0) {
      throw new Error(`不支持的国家: ${invalidCountries.join(', ')}. 支持的国家: ${SUPPORTED_COUNTRIES.join(', ')}`);
    }
    filters.country = countries;
  }

  if (product_category) {
    // 验证商品类型是否支持
    if (!SUPPORTED_CATEGORIES.includes(product_category)) {
      throw new Error(`不支持的商品类型: ${product_category}. 支持的类型: ${SUPPORTED_CATEGORIES.join(', ')}`);
    }
    filters.product_category = [product_category];
  }

  if (Object.keys(filters).length > 0) {
    payload.filters = filters;
  }

  // 发起请求
  const result = await httpsRequest(API_URL, payload);

  // 检查业务错误码
  if (result.error_code !== 0) {
    throw new Error(`接口业务错误: ${result.error_msg || '未知错误'}`);
  }

  return result;
}

/**
 * 解析命令行参数
 */
function parseArgs() {
  const args = process.argv.slice(2);
  const options = {
    page: 1,
    limit: 10
  };

  for (let i = 0; i < args.length; i++) {
    const arg = args[i];
    const nextArg = args[i + 1];

    switch (arg) {
      case '--page':
        options.page = parseInt(nextArg, 10);
        i++;
        break;
      case '--limit':
        options.limit = parseInt(nextArg, 10);
        i++;
        break;
      case '--keywords':
        options.keywords = nextArg;
        i++;
        break;
      case '--price-gte':
        options.price_gte = parseFloat(nextArg);
        i++;
        break;
      case '--price-lte':
        options.price_lte = parseFloat(nextArg);
        i++;
        break;
      case '--countries':
        // 收集所有国家参数
        options.countries = [];
        i++;
        while (i < args.length && !args[i].startsWith('--')) {
          options.countries.push(args[i]);
          i++;
        }
        i--;
        break;
      case '--category':
        options.product_category = nextArg;
        i++;
        break;
    }
  }

  return options;
}

/**
 * 主函数
 */
async function main() {
  try {
    // 解析命令行参数
    const options = parseArgs();

    // 验证必需参数
    if (!options.page) {
      console.error('错误: --page 参数是必需的');
      process.exit(1);
    }

    // 调用搜索接口
    const result = await searchProducts(options);

    // 输出结果（JSON 格式）
    console.log(JSON.stringify(result, null, 2));

  } catch (error) {
    console.error(`错误: ${error.message}`);
    process.exit(1);
  }
}

// 如果直接运行此脚本，则执行主函数
if (require.main === module) {
  main();
}

module.exports = { searchProducts };


path: scripts/statistics_products.js
content: #!/usr/bin/env node

/**
 * 酒云网统计商品查询脚本
 *
 * 根据统计摘要的维度查询具体商品列表，支持按国家、类型、产区、酒庄筛选。
 */

const https = require('https');

const API_URL = 'https://wxapp.vinehoo.com/openai/v3/product/statistics_products';

// 支持的国家列表
const SUPPORTED_COUNTRIES = [
  '中国', '法国', '意大利', '澳大利亚', '葡萄牙', '德国', '西班牙',
  '新西兰', '智利', '阿根廷', '美国', '奥地利', '南非', '日本'
];

// 支持的商品类型列表
const SUPPORTED_CATEGORIES = [
  '红葡萄酒', '白葡萄酒', '起泡酒', '香槟', '甜酒', '烈酒', '白酒/黄酒',
  '清酒', '果酒/米酒', '食品/生鲜', '饮料', '自然酒', '加强酒',
  '桃红葡萄酒', '其他酒', '酒具'
];

/**
 * 发起 HTTPS POST 请求
 */
function httpsRequest(url, data) {
  return new Promise((resolve, reject) => {
    const urlObj = new URL(url);
    const options = {
      hostname: urlObj.hostname,
      path: urlObj.pathname,
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Content-Length': Buffer.byteLength(JSON.stringify(data))
      }
    };

    const req = https.request(options, (res) => {
      let responseData = '';

      res.on('data', (chunk) => {
        responseData += chunk;
      });

      res.on('end', () => {
        if (res.statusCode >= 400) {
          reject(new Error(`HTTP请求失败: 状态码 ${res.statusCode}, 响应内容: ${responseData}`));
        } else {
          try {
            const jsonData = JSON.parse(responseData);
            resolve(jsonData);
          } catch (e) {
            reject(new Error(`JSON解析失败: ${e.message}`));
          }
        }
      });
    });

    req.on('error', (e) => {
      reject(new Error(`接口调用失败: ${e.message}`));
    });

    req.write(JSON.stringify(data));
    req.end();
  });
}

/**
 * 查询统计商品
 */
async function getStatisticsProducts(options) {
  const {
    page = 1,
    limit = 10,
    country,
    category,
    region,
    winery
  } = options;

  // 构建请求参数
  const payload = {
    page,
    limit
  };

  // 添加可选参数
  if (country) {
    payload.country = country;
  }
  if (category) {
    payload.category = category;
  }
  if (region) {
    payload.region = region;
  }
  if (winery) {
    payload.winery = winery;
  }

  // 发起请求
  const result = await httpsRequest(API_URL, payload);

  // 检查业务错误码
  if (result.error_code !== 0) {
    throw new Error(`接口业务错误: ${result.error_msg || '未知错误'}`);
  }

  return result;
}

/**
 * 解析命令行参数
 */
function parseArgs() {
  const args = process.argv.slice(2);
  const options = {
    page: 1,
    limit: 10
  };

  for (let i = 0; i < args.length; i++) {
    const arg = args[i];
    const nextArg = args[i + 1];

    switch (arg) {
      case '--page':
        options.page = parseInt(nextArg, 10);
        i++;
        break;
      case '--limit':
        options.limit = parseInt(nextArg, 10);
        i++;
        break;
      case '--country':
        options.country = nextArg;
        i++;
        break;
      case '--category':
        options.category = nextArg;
        i++;
        break;
      case '--region':
        options.region = nextArg;
        i++;
        break;
      case '--winery':
        options.winery = nextArg;
        i++;
        break;
    }
  }

  return options;
}

/**
 * 主函数
 */
async function main() {
  try {
    // 解析命令行参数
    const options = parseArgs();

    // 调用统计商品查询接口
    const result = await getStatisticsProducts(options);

    // 输出结果（JSON 格式）
    console.log(JSON.stringify(result, null, 2));

  } catch (error) {
    console.error(`错误: ${error.message}`);
    process.exit(1);
  }
}

// 如果直接运行此脚本，则执行主函数
if (require.main === module) {
  main();
}

module.exports = { getStatisticsProducts };


path: scripts/statistics_summary.js
content: #!/usr/bin/env node

/**
 * 酒云网当日商品统计摘要脚本
 *
 * 获取当日新上商品的统计摘要，包括按国家、类型、酒庄、产区的分布情况。
 */

const https = require('https');

const API_URL = 'https://wxapp.vinehoo.com/openai/v3/product/statistics_summary';

/**
 * 发起 HTTPS POST 请求
 */
function httpsRequest(url, data = {}) {
  return new Promise((resolve, reject) => {
    const urlObj = new URL(url);
    const options = {
      hostname: urlObj.hostname,
      path: urlObj.pathname,
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Content-Length': Buffer.byteLength(JSON.stringify(data))
      }
    };

    const req = https.request(options, (res) => {
      let responseData = '';

      res.on('data', (chunk) => {
        responseData += chunk;
      });

      res.on('end', () => {
        if (res.statusCode >= 400) {
          reject(new Error(`HTTP请求失败: 状态码 ${res.statusCode}, 响应内容: ${responseData}`));
        } else {
          try {
            const jsonData = JSON.parse(responseData);
            resolve(jsonData);
          } catch (e) {
            reject(new Error(`JSON解析失败: ${e.message}`));
          }
        }
      });
    });

    req.on('error', (e) => {
      reject(new Error(`接口调用失败: ${e.message}`));
    });

    req.write(JSON.stringify(data));
    req.end();
  });
}

/**
 * 获取当日商品统计摘要
 */
async function getStatisticsSummary() {
  // 发起 POST 请求（无需参数）
  const result = await httpsRequest(API_URL, {});

  // 检查业务错误码
  if (result.error_code !== 0) {
    throw new Error(`接口业务错误: ${result.error_msg || '未知错误'}`);
  }

  return result;
}

/**
 * 主函数
 */
async function main() {
  try {
    // 调用统计接口
    const result = await getStatisticsSummary();

    // 输出结果（JSON 格式）
    console.log(JSON.stringify(result, null, 2));

  } catch (error) {
    console.error(`错误: ${error.message}`);
    process.exit(1);
  }
}

// 如果直接运行此脚本，则执行主函数
if (require.main === module) {
  main();
}

module.exports = { getStatisticsSummary };


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)