更新金属机箱3.5寸小SKU:按最新标准重新生成,数据盘组合到各SKU;配件清单新增HDD-1T/3T/4T/6T
This commit is contained in:
@@ -8,7 +8,68 @@ description: 设计电商产品的 SKU 配置。当用户需要为产品生成 S
|
||||
## Overview
|
||||
|
||||
- 为每个产品生成 SKU 配置
|
||||
- 将 SKU 配置放到每个产品对应的 `SKU` 目录下
|
||||
- 将 SKU 配置放到每个产品对应的 `sku` 目录下(小写)
|
||||
|
||||
## 产品目录组织原则
|
||||
|
||||
每个产品目录必须遵循以下标准结构:
|
||||
|
||||
```
|
||||
产品名称/
|
||||
├── 商品标题.md # 电商商品标题关键词,一行文本
|
||||
├── sku/ # SKU配置目录(小写),每个SKU一个独立.md文件
|
||||
│ ├── [机箱]-[单/双]-[CPU]-[内存]-[硬盘].md
|
||||
│ └── ...
|
||||
├── image/ # 产品实拍图片(原图)
|
||||
├── 主图/ # 电商主图(html + png)
|
||||
│ ├── 主图1-xxx.html
|
||||
│ ├── 主图1-xxx.png
|
||||
│ └── ...
|
||||
└── 详情/ # 商品详情页(html + png)
|
||||
├── xxx_详情页.html
|
||||
└── xxx_详情页.png
|
||||
```
|
||||
|
||||
### SKU 文件命名规则
|
||||
- 文件名格式:`[机箱简称]-[单/双]-[CPU型号]-[内存容量]-[硬盘容量].md`
|
||||
- "单/双"指该机箱版本对应的SATA口数(单=单SATA口,双=双SATA口)
|
||||
- 示例:`2.5金-单-N2840-4G-32G.md`、`3.5大-双-1037U-4G-32G.md`、`3.5小-单-N2930-4G-32G.md`、`3.5小-双-1037U-4G-32G.md`
|
||||
|
||||
### 机箱与CPU匹配原则
|
||||
- 机箱标注"单"(单SATA口)只能配单SATA口CPU:N2840, N2930, AMD-A4, J1800, J1900, J3160, 3855U
|
||||
- 机箱标注"双"(双SATA口)只能配双SATA口CPU:1037U, 3217U, 5005U
|
||||
- 机箱标注"单/双"(如3.5寸小)支持两种SATA口,需分别生成单/双版本SKU
|
||||
|
||||
### SKU 文件内容格式
|
||||
每个SKU文件包含一个产品信息表格,字段如下:
|
||||
|
||||
```markdown
|
||||
# 产品信息
|
||||
|
||||
| 字段 | 配件名称 | 价格 |
|
||||
|------|---------|------|
|
||||
| **产品编号** | - | - |
|
||||
| **产品名称** | 飞牛NAS [产品线] [机箱] [CPU] | - |
|
||||
| **产品型号** | [机箱]-[盘位]-[CPU]-[内存]-[硬盘] | - |
|
||||
| **用途分类** | NAS | - |
|
||||
| **CPU** | [CPU型号] | ¥[价格] |
|
||||
| **内存** | D3-[容量] | ¥[价格] |
|
||||
| **系统盘** | mSATA-[容量] | ¥[价格] |
|
||||
| **机箱** | [机箱名称] | ¥[价格] |
|
||||
| **电源** | 电源-60W | ¥12 |
|
||||
| **硬盘线** | 硬盘线-单/双 | ¥4/5 |
|
||||
| **双SATA转换器** | 双SATA转换器 | ¥28 | (如需要)
|
||||
| **电池** | 电池 | ¥1 |
|
||||
| **网线** | 网线 | ¥1 |
|
||||
| **运费** | 运费 | ¥10 |
|
||||
| **包装费** | 包装费 | ¥5 |
|
||||
| **装机费** | 装机费 | ¥10 |
|
||||
| **总成本** | - | ¥[总计] |
|
||||
| **建议零售价** | - | ¥[售价] |
|
||||
| **备注** | [描述] | - |
|
||||
```
|
||||
|
||||
> 注意:双SATA转换器仅在单SATA口主板需要扩展盘位时添加
|
||||
|
||||
## SKU 编码规则
|
||||
|
||||
@@ -21,7 +82,10 @@ description: 设计电商产品的 SKU 配置。当用户需要为产品生成 S
|
||||
### 步骤1. 更新对应产品的sku,根据设计原则添加或者删除sku
|
||||
- 根据对应机箱设计原则,选择cpu,内存,硬盘
|
||||
- 按照SKU编码规则生成SKU名称
|
||||
- 将SKU配置保存到对应产品目录下的`SKU`文件夹
|
||||
- 按照产品目录组织原则,确保目录结构完整(商品标题.md、sku/、image/、主图/、详情/)
|
||||
- 每个SKU生成一个独立的.md文件,放到`sku/`目录下
|
||||
- SKU文件命名:`[机箱简称]-[单/双]-[CPU型号]-[内存容量]-[硬盘容量].md`
|
||||
- SKU文件内容按照标准产品信息表格格式填写
|
||||
|
||||
### 步骤2 计算与核对产品价格
|
||||
- 根据配件清单,计算产品价格
|
||||
@@ -32,28 +96,70 @@ description: 设计电商产品的 SKU 配置。当用户需要为产品生成 S
|
||||
- 更新产品信息到产品信息汇总表
|
||||
|
||||
|
||||
## 飞牛 NAS产设计原则
|
||||
### 3.5金属大配置原则
|
||||
- 3.5金属大,用于3盘位和4盘位,通过双sata转化器,主板单sata口就是3盘位,主板双sata口就是4盘位
|
||||
- 3.5金属大可安装cpu:j1900,j3160,i3-3217u,i3-5005u,3855u,1037u
|
||||
- 3.5金属大可安装内存和系统盘: 4G-32G,4G-64G,8G-64G,8G-128G
|
||||
### 3.5金属小配置原则
|
||||
- 3.5金属小可安装cpu:j1900,j3160,i3-3217u,i3-5005u,3855u,1037u
|
||||
- 3.5金属小,可安装一个2.5和一个3.5,配单sata口主板就是单3.5 ,双sata口主板就是 3.5+2.5
|
||||
- 3.5金属小可安装内存和系统盘: 4G-32G,4G-64G,8G-64G,8G-128G
|
||||
## 飞牛 NAS产品设计原则
|
||||
|
||||
### 基础版-金
|
||||
- 机箱与CPU对应:
|
||||
- 2.5金-单(单SATA口):amd-a4, n2840, n2930, j1800
|
||||
- 3.5金属大-双(双SATA口):1037u
|
||||
- 3.5金属小-单(单SATA口):amd-a4, n2840, n2930, j1800
|
||||
- 3.5金属小-双(双SATA口):1037u
|
||||
- 内存-硬盘: 4G-32G
|
||||
- 建议零售价: 成本+30
|
||||
|
||||
### 基础版-亚
|
||||
- 机箱与CPU对应:
|
||||
- 亚克力-双(双SATA口):1037u
|
||||
- 亚克力-单(单SATA口):amd-a4, n2840, n2930, j1800
|
||||
- 内存-硬盘: 4G-32G
|
||||
- 建议零售价: 成本+30
|
||||
|
||||
### 金属机箱3.5寸大
|
||||
- 3盘版(单SATA口CPU):3855U, J1900, J3160
|
||||
- 4盘版(双SATA口CPU):1037U, 3217U, 5005U
|
||||
- 内存硬盘可用:4G-32G, 4G-64G, 8G-64G, 8G-128G
|
||||
- 建议零售价:成本+50
|
||||
|
||||
### 金属机箱3.5寸小
|
||||
- 3.5+2.5盘位(双SATA口):1037U
|
||||
- 内存硬盘可用:4G-32G
|
||||
- 数据盘可选 500G ,1T ,3T ,4T 6T
|
||||
- 建议零售价:成本+50
|
||||
|
||||
### 亚克力机箱-单 配置原则
|
||||
- 可安装单SATA口主板
|
||||
- 可用CPU:N2840,N2930,AMD-A4,J1900,J3160
|
||||
- 可用内存:2G-16G,2G-32G,4G-64G,4G-128G
|
||||
####
|
||||
推荐价格:
|
||||
- 可用CPU:AMD-A4,J1900,J3160
|
||||
- 可用内存:D3-2G,D3-4G
|
||||
- 可用系统盘:mSATA-16G,mSATA-32G,mSATA-64G,mSATA-128G
|
||||
#### 推荐价格:
|
||||
- 配2G内存的成本加20作为推荐售价
|
||||
- 配4G内存的成本加30作为推荐售价
|
||||
|
||||
### 亚克力机箱-双 配置原则
|
||||
- 可安装双SATA口主板
|
||||
- 可用CPU:1037U,i3-3217U,i3-5005U
|
||||
- 可用CPU:1037U,3217U,5005U
|
||||
- 可用内存:2G-16G,2G-32G,4G-64G,4G-128G,8G-128G
|
||||
|
||||
### 高性能版-亚-双-j1900
|
||||
- 使用亚克力-双机箱
|
||||
- CPU J1900(单SATA口,需双SATA转换器)
|
||||
- 内存硬盘可用:4G-32G, 4G-64G, 8G-64G, 8G-128G
|
||||
- 建议零售价:成本+50
|
||||
|
||||
### 高性能版-亚-双-j3160
|
||||
- 使用亚克力-双机箱
|
||||
- CPU J3160(单SATA口,需双SATA转换器)
|
||||
- 内存硬盘可用:4G-32G, 4G-64G, 8G-64G, 8G-128G
|
||||
- 建议零售价:成本+70
|
||||
|
||||
### 高性能-i5-i7
|
||||
- 可使用机箱:亚克力机箱-双、金属机箱3.5寸大
|
||||
- CPU i5可用:i5-2代,i5-3代,i5-4代
|
||||
- CPU i7可用:i7-2代,i7-3代,i7-4代
|
||||
- i5内存硬盘可用:4G-128G,8G-128G
|
||||
- i7内存硬盘统一:8G-128G
|
||||
- 建议零售价:成本+80
|
||||
|
||||
## win 小主机产设计原则
|
||||
- win小主机全部使用2.5存机箱
|
||||
### 龙虾盒子
|
||||
|
||||
158
.trae/skills/sku-designer/scripts/sync-prices-to-summary.js
Normal file
158
.trae/skills/sku-designer/scripts/sync-prices-to-summary.js
Normal file
@@ -0,0 +1,158 @@
|
||||
// 价格同步工具 - 将SKU文件中的价格信息同步到产品价格汇总表
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// 产品目录路径
|
||||
const PRODUCTS_DIR = path.join(__dirname, '../../../../产品');
|
||||
const PRICE_SUMMARY_FILE = path.join(PRODUCTS_DIR, '产品价格汇总表.md');
|
||||
|
||||
// 读取价格汇总表内容
|
||||
function readPriceSummary() {
|
||||
return fs.readFileSync(PRICE_SUMMARY_FILE, 'utf8');
|
||||
}
|
||||
|
||||
// 写入价格汇总表内容
|
||||
function writePriceSummary(content) {
|
||||
fs.writeFileSync(PRICE_SUMMARY_FILE, content, 'utf8');
|
||||
}
|
||||
|
||||
// 递归读取所有SKU文件
|
||||
function findSkuFiles(dir) {
|
||||
const skuFiles = [];
|
||||
|
||||
function traverse(currentDir) {
|
||||
const files = fs.readdirSync(currentDir);
|
||||
|
||||
for (const file of files) {
|
||||
const fullPath = path.join(currentDir, file);
|
||||
const stat = fs.statSync(fullPath);
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
traverse(fullPath);
|
||||
} else if (file.endsWith('.md') && (file.includes('-') || file.includes('openclaw'))) {
|
||||
skuFiles.push(fullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
traverse(dir);
|
||||
return skuFiles;
|
||||
}
|
||||
|
||||
// 解析SKU文件内容
|
||||
function parseSkuFile(filePath) {
|
||||
try {
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
|
||||
const skuData = {
|
||||
model: '',
|
||||
cost: 0,
|
||||
price: 0
|
||||
};
|
||||
|
||||
// 解析产品型号
|
||||
const modelMatch = content.match(/\*\*产品型号\*\*\s*\|\s*([^|]+)\s*\|/);
|
||||
if (modelMatch) {
|
||||
skuData.model = modelMatch[1].trim();
|
||||
} else {
|
||||
console.log(`未找到产品型号: ${filePath}`);
|
||||
}
|
||||
|
||||
// 解析总成本
|
||||
const costMatch = content.match(/\*\*总成本\*\*\s*\|\s*-\s*\|\s*¥(\d+)\s*\|/);
|
||||
if (costMatch) {
|
||||
skuData.cost = parseInt(costMatch[1]);
|
||||
} else {
|
||||
console.log(`未找到总成本: ${filePath}`);
|
||||
}
|
||||
|
||||
// 解析建议零售价
|
||||
const priceMatch = content.match(/\*\*建议零售价\*\*\s*\|\s*-\s*\|\s*¥(\d+)\s*\|/);
|
||||
if (priceMatch) {
|
||||
skuData.price = parseInt(priceMatch[1]);
|
||||
} else {
|
||||
console.log(`未找到建议零售价: ${filePath}`);
|
||||
}
|
||||
|
||||
if (skuData.model && skuData.cost && skuData.price) {
|
||||
console.log(`解析成功: ${skuData.model} - 成本: ¥${skuData.cost}, 售价: ¥${skuData.price}`);
|
||||
}
|
||||
|
||||
return skuData;
|
||||
} catch (error) {
|
||||
console.log(`解析文件失败: ${filePath}, 错误: ${error.message}`);
|
||||
return { model: '', cost: 0, price: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
// 同步价格信息到汇总表
|
||||
function syncPrices() {
|
||||
console.log('开始同步SKU价格到汇总表...');
|
||||
|
||||
// 读取所有SKU文件
|
||||
const skuFiles = findSkuFiles(PRODUCTS_DIR);
|
||||
console.log(`找到 ${skuFiles.length} 个SKU文件`);
|
||||
|
||||
// 解析所有SKU文件
|
||||
const skuDataMap = new Map();
|
||||
let parsedCount = 0;
|
||||
|
||||
for (const file of skuFiles) {
|
||||
const skuData = parseSkuFile(file);
|
||||
if (skuData.model && skuData.cost && skuData.price) {
|
||||
skuDataMap.set(skuData.model, skuData);
|
||||
parsedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`解析完成 ${parsedCount} 个SKU数据`);
|
||||
|
||||
// 读取汇总表内容
|
||||
let summaryContent = readPriceSummary();
|
||||
|
||||
// 更新日期
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
summaryContent = summaryContent.replace(/更新日期:\d{4}-\d{2}-\d{2}/, `更新日期:${today}`);
|
||||
|
||||
// 逐行处理汇总表,避免一次性处理大文件
|
||||
const lines = summaryContent.split('\n');
|
||||
const updatedLines = [];
|
||||
let updatedCount = 0;
|
||||
|
||||
for (const line of lines) {
|
||||
let updatedLine = line;
|
||||
|
||||
// 检查是否是产品行
|
||||
const modelMatch = line.match(/\|\s*\d+\s*\|\s*([^|]+)\s*\|\s*¥\d+\s*\|\s*¥\d+\s*\|\s*¥\d+\s*\|\s*\d+%\s*\|/);
|
||||
if (modelMatch) {
|
||||
const model = modelMatch[1].trim();
|
||||
const skuData = skuDataMap.get(model);
|
||||
|
||||
if (skuData) {
|
||||
const profit = skuData.price - skuData.cost;
|
||||
const profitRate = Math.round((profit / skuData.cost) * 100);
|
||||
|
||||
// 找到行中的序号
|
||||
const indexMatch = line.match(/\|\s*(\d+)\s*\|/);
|
||||
const index = indexMatch ? indexMatch[1] : '1';
|
||||
|
||||
updatedLine = `| ${index} | ${model} | ¥${skuData.cost} | ¥${skuData.price} | ¥${profit} | ${profitRate}% |`;
|
||||
updatedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
updatedLines.push(updatedLine);
|
||||
}
|
||||
|
||||
// 重新组合内容
|
||||
const updatedContent = updatedLines.join('\n');
|
||||
|
||||
// 写入更新后的汇总表
|
||||
writePriceSummary(updatedContent);
|
||||
|
||||
console.log(`同步完成!更新了 ${updatedCount} 个产品的价格信息`);
|
||||
console.log(`价格汇总表已更新,更新日期:${today}`);
|
||||
}
|
||||
|
||||
// 执行同步
|
||||
syncPrices();
|
||||
Reference in New Issue
Block a user