feat: 智能添加根据类别参数字段配置解析 - 支持子类别额外字段
This commit is contained in:
134
app.py
134
app.py
@@ -101,64 +101,70 @@ def save_data(file_path, data):
|
|||||||
|
|
||||||
# ============ 大模型智能解析 ============
|
# ============ 大模型智能解析 ============
|
||||||
|
|
||||||
def parse_with_llm(text, category_type, images=None):
|
def parse_with_llm(text, category_type, images=None, category_id=None, subcategory_id=None):
|
||||||
"""
|
"""
|
||||||
使用大模型解析文本/图片,提取结构化数据
|
使用大模型解析文本/图片,提取结构化数据
|
||||||
支持多张图片输入,可能解析出多个产品
|
支持多张图片输入,可能解析出多个产品
|
||||||
|
根据类别配置的参数字段进行解析
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# 根据类型定义字段模板
|
# 从类别配置中获取字段定义
|
||||||
field_templates = {
|
categories = load_data(CATEGORIES_FILE)
|
||||||
'model': {
|
|
||||||
'name': '模型名称',
|
# 确定类别ID
|
||||||
'organization': '厂商/组织',
|
if category_id:
|
||||||
'parameters': '参数量(数字,单位B)',
|
cat = next((c for c in categories if c['id'] == category_id), None)
|
||||||
'context_length': '上下文长度(数字)',
|
else:
|
||||||
'architecture': '架构类型',
|
# 根据类型映射到内置类别ID
|
||||||
'is_open_source': '是否开源(true/false)',
|
type_to_cat_id = {'model': 'ai-models', 'gpu': 'gpus', 'cpu': 'cpus'}
|
||||||
'mmlu': 'MMLU分数(数字)',
|
cat_id = type_to_cat_id.get(category_type)
|
||||||
'input_price': '输入价格(数字)',
|
cat = next((c for c in categories if c['id'] == cat_id), None)
|
||||||
'output_price': '输出价格(数字)',
|
|
||||||
'license': '许可证',
|
# 构建字段模板
|
||||||
'description': '简介描述',
|
fields = {}
|
||||||
},
|
|
||||||
'gpu': {
|
if cat and 'fields' in cat:
|
||||||
'name': 'GPU名称',
|
# 使用类别配置的字段
|
||||||
'manufacturer': '厂商',
|
for field in cat['fields']:
|
||||||
'architecture': '架构',
|
field_desc = field['label']
|
||||||
'memory_gb': '显存大小(数字,单位GB)',
|
if field['type'] == 'number':
|
||||||
'cuda_cores': 'CUDA核心数(数字)',
|
field_desc += '(数字)'
|
||||||
'tensor_cores': 'Tensor核心数(数字)',
|
elif field['type'] == 'boolean':
|
||||||
'memory_bandwidth_gbs': '显存带宽(数字,单位GB/s)',
|
field_desc += '(true/false)'
|
||||||
'fp16_tflops': 'FP16性能(数字,单位TF)',
|
elif field['type'] == 'date':
|
||||||
'price_usd': '价格(数字)',
|
field_desc += '(日期格式YYYY-MM-DD)'
|
||||||
'release_year': '发布年份(数字)',
|
elif field['type'] == 'json':
|
||||||
'description': '简介描述',
|
field_desc += '(JSON对象)'
|
||||||
},
|
if field.get('description'):
|
||||||
'cpu': {
|
field_desc += f" - {field['description']}"
|
||||||
'name': 'CPU名称',
|
fields[field['key']] = field_desc
|
||||||
'manufacturer': '厂商',
|
|
||||||
'architecture': '架构',
|
# 如果有子类别,添加子类别的额外字段
|
||||||
'cores': '核心数(数字)',
|
if subcategory_id:
|
||||||
'threads': '线程数(数字)',
|
subcat = next((s for s in cat.get('subcategories', []) if s['id'] == subcategory_id), None)
|
||||||
'base_clock_ghz': '基础频率(数字,单位GHz)',
|
if subcat and 'extra_fields' in subcat:
|
||||||
'boost_clock_ghz': '加速频率(数字,单位GHz)',
|
for field in subcat['extra_fields']:
|
||||||
'l3_cache_mb': 'L3缓存(数字,单位MB)',
|
field_desc = field['label']
|
||||||
'tdp_watts': 'TDP功耗(数字,单位W)',
|
if field['type'] == 'number':
|
||||||
'price_usd': '价格(数字)',
|
field_desc += '(数字)'
|
||||||
'description': '简介描述',
|
elif field['type'] == 'boolean':
|
||||||
},
|
field_desc += '(true/false)'
|
||||||
'dynamic': {
|
elif field['type'] == 'date':
|
||||||
|
field_desc += '(日期格式YYYY-MM-DD)'
|
||||||
|
if field.get('description'):
|
||||||
|
field_desc += f" - {field['description']}"
|
||||||
|
fields[field['key']] = field_desc
|
||||||
|
else:
|
||||||
|
# 兜底:使用默认字段模板
|
||||||
|
fields = {
|
||||||
'name': '名称',
|
'name': '名称',
|
||||||
'brand': '品牌',
|
'brand': '品牌',
|
||||||
'price': '价格(数字)',
|
'price': '价格(数字)',
|
||||||
'year': '年份(数字)',
|
'year': '年份(数字)',
|
||||||
'specs': '规格参数',
|
'specs': '规格参数(JSON对象)',
|
||||||
'description': '简介描述',
|
'description': '简介描述',
|
||||||
},
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fields = field_templates.get(category_type, field_templates['dynamic'])
|
|
||||||
fields_json = json.dumps(fields, ensure_ascii=False, indent=2)
|
fields_json = json.dumps(fields, ensure_ascii=False, indent=2)
|
||||||
|
|
||||||
# 构建消息内容
|
# 构建消息内容
|
||||||
@@ -498,11 +504,13 @@ def api_parse_images():
|
|||||||
"""
|
"""
|
||||||
解析图片中的产品参数(预览模式,不保存)
|
解析图片中的产品参数(预览模式,不保存)
|
||||||
支持多张图片,可能返回多个产品
|
支持多张图片,可能返回多个产品
|
||||||
|
根据类别配置的参数字段进行解析
|
||||||
"""
|
"""
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
text = data.get('text', '')
|
text = data.get('text', '')
|
||||||
images = data.get('images', [])
|
images = data.get('images', [])
|
||||||
category_type = data.get('category_type', 'dynamic')
|
category_type = data.get('category_type', 'dynamic')
|
||||||
|
subcategory_id = data.get('subcategory_id', '')
|
||||||
|
|
||||||
if not text and not images:
|
if not text and not images:
|
||||||
return jsonify({'error': '文本或图片不能都为空'}), 400
|
return jsonify({'error': '文本或图片不能都为空'}), 400
|
||||||
@@ -510,8 +518,12 @@ def api_parse_images():
|
|||||||
if not images:
|
if not images:
|
||||||
return jsonify({'error': '请上传至少一张图片'}), 400
|
return jsonify({'error': '请上传至少一张图片'}), 400
|
||||||
|
|
||||||
# 调用大模型解析
|
# 确定类别ID
|
||||||
parsed_list = parse_with_llm(text, category_type, images)
|
type_to_cat_id = {'model': 'ai-models', 'gpu': 'gpus', 'cpu': 'cpus', 'dynamic': None}
|
||||||
|
category_id = type_to_cat_id.get(category_type)
|
||||||
|
|
||||||
|
# 调用大模型解析(根据类别字段配置)
|
||||||
|
parsed_list = parse_with_llm(text, category_type, images, category_id=category_id, subcategory_id=subcategory_id)
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
'success': True,
|
'success': True,
|
||||||
@@ -691,12 +703,13 @@ def api_smart_add_model():
|
|||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
text = data.get('text', '')
|
text = data.get('text', '')
|
||||||
images = data.get('images', [])
|
images = data.get('images', [])
|
||||||
|
subcategory_id = data.get('subcategory_id', '') # 子类别ID
|
||||||
|
|
||||||
if not text and not images:
|
if not text and not images:
|
||||||
return jsonify({'error': '文本或图片不能都为空'}), 400
|
return jsonify({'error': '文本或图片不能都为空'}), 400
|
||||||
|
|
||||||
# 大模型解析(支持多图)
|
# 大模型解析(根据类别字段配置)
|
||||||
parsed_list = parse_with_llm(text, 'model', images)
|
parsed_list = parse_with_llm(text, 'model', images, category_id='ai-models', subcategory_id=subcategory_id)
|
||||||
|
|
||||||
# 处理多个产品
|
# 处理多个产品
|
||||||
results = []
|
results = []
|
||||||
@@ -707,8 +720,9 @@ def api_smart_add_model():
|
|||||||
parsed['id'] = uuid.uuid4().hex[:12]
|
parsed['id'] = uuid.uuid4().hex[:12]
|
||||||
parsed['created_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
parsed['created_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
parsed['visible'] = True
|
parsed['visible'] = True
|
||||||
parsed['raw_text'] = text # 保存原始文本
|
parsed['raw_text'] = text
|
||||||
parsed['images'] = images # 保存图片
|
parsed['images'] = images
|
||||||
|
parsed['subcategory_id'] = subcategory_id # 保存子类别
|
||||||
parsed['publish_date'] = parsed.get('publish_date', '')
|
parsed['publish_date'] = parsed.get('publish_date', '')
|
||||||
parsed['views'] = 0
|
parsed['views'] = 0
|
||||||
parsed['is_pinned'] = False
|
parsed['is_pinned'] = False
|
||||||
@@ -718,7 +732,6 @@ def api_smart_add_model():
|
|||||||
|
|
||||||
save_data(MODELS_FILE, models)
|
save_data(MODELS_FILE, models)
|
||||||
|
|
||||||
# 返回添加的产品列表
|
|
||||||
return jsonify({'success': True, 'count': len(results), 'products': results})
|
return jsonify({'success': True, 'count': len(results), 'products': results})
|
||||||
|
|
||||||
@app.route('/api/gpus/smart-add', methods=['POST'])
|
@app.route('/api/gpus/smart-add', methods=['POST'])
|
||||||
@@ -727,11 +740,12 @@ def api_smart_add_gpu():
|
|||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
text = data.get('text', '')
|
text = data.get('text', '')
|
||||||
images = data.get('images', [])
|
images = data.get('images', [])
|
||||||
|
subcategory_id = data.get('subcategory_id', '')
|
||||||
|
|
||||||
if not text and not images:
|
if not text and not images:
|
||||||
return jsonify({'error': '文本或图片不能都为空'}), 400
|
return jsonify({'error': '文本或图片不能都为空'}), 400
|
||||||
|
|
||||||
parsed_list = parse_with_llm(text, 'gpu', images)
|
parsed_list = parse_with_llm(text, 'gpu', images, category_id='gpus', subcategory_id=subcategory_id)
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
gpus = load_data(GPUS_FILE)
|
gpus = load_data(GPUS_FILE)
|
||||||
@@ -742,6 +756,7 @@ def api_smart_add_gpu():
|
|||||||
parsed['visible'] = True
|
parsed['visible'] = True
|
||||||
parsed['raw_text'] = text
|
parsed['raw_text'] = text
|
||||||
parsed['images'] = images
|
parsed['images'] = images
|
||||||
|
parsed['subcategory_id'] = subcategory_id
|
||||||
parsed['publish_date'] = parsed.get('publish_date', '')
|
parsed['publish_date'] = parsed.get('publish_date', '')
|
||||||
parsed['views'] = 0
|
parsed['views'] = 0
|
||||||
parsed['is_pinned'] = False
|
parsed['is_pinned'] = False
|
||||||
@@ -759,11 +774,12 @@ def api_smart_add_cpu():
|
|||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
text = data.get('text', '')
|
text = data.get('text', '')
|
||||||
images = data.get('images', [])
|
images = data.get('images', [])
|
||||||
|
subcategory_id = data.get('subcategory_id', '')
|
||||||
|
|
||||||
if not text and not images:
|
if not text and not images:
|
||||||
return jsonify({'error': '文本或图片不能都为空'}), 400
|
return jsonify({'error': '文本或图片不能都为空'}), 400
|
||||||
|
|
||||||
parsed_list = parse_with_llm(text, 'cpu', images)
|
parsed_list = parse_with_llm(text, 'cpu', images, category_id='cpus', subcategory_id=subcategory_id)
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
cpus = load_data(CPUS_FILE)
|
cpus = load_data(CPUS_FILE)
|
||||||
@@ -774,6 +790,7 @@ def api_smart_add_cpu():
|
|||||||
parsed['visible'] = True
|
parsed['visible'] = True
|
||||||
parsed['raw_text'] = text
|
parsed['raw_text'] = text
|
||||||
parsed['images'] = images
|
parsed['images'] = images
|
||||||
|
parsed['subcategory_id'] = subcategory_id
|
||||||
parsed['publish_date'] = parsed.get('publish_date', '')
|
parsed['publish_date'] = parsed.get('publish_date', '')
|
||||||
parsed['views'] = 0
|
parsed['views'] = 0
|
||||||
parsed['is_pinned'] = False
|
parsed['is_pinned'] = False
|
||||||
@@ -791,11 +808,13 @@ def api_smart_add_item(category_id):
|
|||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
text = data.get('text', '')
|
text = data.get('text', '')
|
||||||
images = data.get('images', [])
|
images = data.get('images', [])
|
||||||
|
subcategory_id = data.get('subcategory_id', '')
|
||||||
|
|
||||||
if not text and not images:
|
if not text and not images:
|
||||||
return jsonify({'error': '文本或图片不能都为空'}), 400
|
return jsonify({'error': '文本或图片不能都为空'}), 400
|
||||||
|
|
||||||
parsed_list = parse_with_llm(text, 'dynamic', images)
|
# 使用类别配置的字段解析
|
||||||
|
parsed_list = parse_with_llm(text, 'dynamic', images, category_id=category_id, subcategory_id=subcategory_id)
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
items_file = DATA_DIR / f'items_{category_id}.json'
|
items_file = DATA_DIR / f'items_{category_id}.json'
|
||||||
@@ -808,6 +827,7 @@ def api_smart_add_item(category_id):
|
|||||||
parsed['visible'] = True
|
parsed['visible'] = True
|
||||||
parsed['raw_text'] = text
|
parsed['raw_text'] = text
|
||||||
parsed['images'] = images
|
parsed['images'] = images
|
||||||
|
parsed['subcategory_id'] = subcategory_id
|
||||||
parsed['publish_date'] = parsed.get('publish_date', '')
|
parsed['publish_date'] = parsed.get('publish_date', '')
|
||||||
parsed['views'] = 0
|
parsed['views'] = 0
|
||||||
parsed['is_pinned'] = False
|
parsed['is_pinned'] = False
|
||||||
|
|||||||
@@ -49,5 +49,54 @@
|
|||||||
"is_pinned": false,
|
"is_pinned": false,
|
||||||
"subcategory_id": "90ce312b560d",
|
"subcategory_id": "90ce312b560d",
|
||||||
"updated_at": "2026-04-28 12:32:50"
|
"updated_at": "2026-04-28 12:32:50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EOS R7",
|
||||||
|
"brand": "佳能 (Canon)",
|
||||||
|
"year": 2022,
|
||||||
|
"specs": {
|
||||||
|
"品牌": "佳能 (Canon)",
|
||||||
|
"商品编号": "10090975539899",
|
||||||
|
"店铺": "佳能 (Canon) 数码旗舰店",
|
||||||
|
"外接电源": "支持外接电源",
|
||||||
|
"电池类型": "锂离子电池",
|
||||||
|
"接口": "Wi-Fi 蓝牙 HDMI",
|
||||||
|
"高清摄像": "4K超高清视频",
|
||||||
|
"焦点数量": "5915个",
|
||||||
|
"型号": "EOS R7",
|
||||||
|
"有效像素": "3250万",
|
||||||
|
"传感器类型": "CMOS",
|
||||||
|
"上市时间": "2022-06",
|
||||||
|
"取景器类型": "电子取景器",
|
||||||
|
"液晶屏像素": "162万",
|
||||||
|
"液晶屏尺寸": "3.2英寸",
|
||||||
|
"液晶屏类型": "侧翻屏 旋转屏",
|
||||||
|
"最大光圈": "F3.5",
|
||||||
|
"标准ISO感光度": "ISO 100-32000",
|
||||||
|
"连拍速度": "电子最高约30张/秒,机械最高约15张/秒",
|
||||||
|
"存储介质": "SD卡 SDHC卡 SDXC卡",
|
||||||
|
"功能": "Wi-Fi 4K视频 5轴防抖 高速连拍 翻转自拍",
|
||||||
|
"滤镜直径": "55mm",
|
||||||
|
"视频拍摄能力": "4K 60P",
|
||||||
|
"传感器尺寸": "APS-C",
|
||||||
|
"视频采样": "4:2:2",
|
||||||
|
"像素": "3000-4000万",
|
||||||
|
"镜头卡口": "佳能RF卡口",
|
||||||
|
"RAW照片输出": "14bit",
|
||||||
|
"适用对象": "入门级",
|
||||||
|
"类型": "机身"
|
||||||
|
},
|
||||||
|
"description": "入门级机身",
|
||||||
|
"id": "c8c3f124b2ce",
|
||||||
|
"category_id": "71fa2b4d818f",
|
||||||
|
"created_at": "2026-04-28 16:38:03",
|
||||||
|
"visible": true,
|
||||||
|
"raw_text": "",
|
||||||
|
"images": [
|
||||||
|
"/static/uploads/9703a1d16424_1777365365.png"
|
||||||
|
],
|
||||||
|
"publish_date": "",
|
||||||
|
"views": 0,
|
||||||
|
"is_pinned": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
BIN
static/uploads/9703a1d16424_1777365365.png
Normal file
BIN
static/uploads/9703a1d16424_1777365365.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
@@ -330,12 +330,20 @@
|
|||||||
<div id="smartAddModal" class="fixed inset-0 bg-black/50 z-50 hidden flex items-center justify-center">
|
<div id="smartAddModal" class="fixed inset-0 bg-black/50 z-50 hidden flex items-center justify-center">
|
||||||
<div class="bg-white rounded-xl max-w-4xl w-full mx-4 max-h-[90vh] overflow-auto">
|
<div class="bg-white rounded-xl max-w-4xl w-full mx-4 max-h-[90vh] overflow-auto">
|
||||||
<div class="p-6 border-b flex justify-between items-center sticky top-0 bg-white z-10">
|
<div class="p-6 border-b flex justify-between items-center sticky top-0 bg-white z-10">
|
||||||
<h2 class="text-xl font-bold text-gray-800"><i class="ri-magic-line mr-2 text-orange-600"></i>智能添加(支持多图解析)</h2>
|
<h2 class="text-xl font-bold text-gray-800"><i class="ri-magic-line mr-2 text-orange-600"></i>智能添加(根据参数字段解析)</h2>
|
||||||
<button onclick="closeSmartAddModal()" class="text-gray-400 hover:text-gray-600"><i class="ri-close-line text-2xl"></i></button>
|
<button onclick="closeSmartAddModal()" class="text-gray-400 hover:text-gray-600"><i class="ri-close-line text-2xl"></i></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-6">
|
<div class="p-6">
|
||||||
|
<!-- 子类别选择 -->
|
||||||
|
<div class="mb-4" id="smartAddSubcategoryArea">
|
||||||
|
<label class="text-sm text-gray-600 mb-2 block">选择子类别(可选,用于匹配特定参数字段)</label>
|
||||||
|
<select id="smartAddSubcategory" class="w-full px-3 py-2 border rounded-lg">
|
||||||
|
<option value="">请选择子类别</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
<p class="text-sm text-gray-500 mb-3">上传产品图片,AI将自动识别并解析参数。支持一次上传多张图片,可识别多个产品。</p>
|
<p class="text-sm text-gray-500 mb-3">上传产品图片,AI将根据类别参数字段配置自动识别并解析参数。支持一次上传多张图片,可识别多个产品。</p>
|
||||||
<div class="flex flex-wrap gap-3 mb-3" id="smartImagePreviewArea">
|
<div class="flex flex-wrap gap-3 mb-3" id="smartImagePreviewArea">
|
||||||
<!-- 图片预览区 -->
|
<!-- 图片预览区 -->
|
||||||
</div>
|
</div>
|
||||||
@@ -1905,9 +1913,37 @@
|
|||||||
document.getElementById('smartAddPreview').classList.add('hidden');
|
document.getElementById('smartAddPreview').classList.add('hidden');
|
||||||
document.getElementById('smartImagePreviewArea').innerHTML = '';
|
document.getElementById('smartImagePreviewArea').innerHTML = '';
|
||||||
document.getElementById('smartImageCount').textContent = '0';
|
document.getElementById('smartImageCount').textContent = '0';
|
||||||
|
|
||||||
|
// 加载子类别选项
|
||||||
|
loadSmartAddSubcategories(type);
|
||||||
|
|
||||||
document.getElementById('smartAddModal').classList.remove('hidden');
|
document.getElementById('smartAddModal').classList.remove('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加载智能添加的子类别选项
|
||||||
|
function loadSmartAddSubcategories(type) {
|
||||||
|
const select = document.getElementById('smartAddSubcategory');
|
||||||
|
let categoryId;
|
||||||
|
|
||||||
|
if (type === 'model') categoryId = 'ai-models';
|
||||||
|
else if (type === 'gpu') categoryId = 'gpus';
|
||||||
|
else if (type === 'cpu') categoryId = 'cpus';
|
||||||
|
else if (type === 'dynamic') categoryId = dynamicCategoryId;
|
||||||
|
else categoryId = null;
|
||||||
|
|
||||||
|
const cat = categories.find(c => c.id === categoryId);
|
||||||
|
const subcats = cat ? (cat.subcategories || []) : [];
|
||||||
|
|
||||||
|
if (subcats.length > 0) {
|
||||||
|
document.getElementById('smartAddSubcategoryArea').classList.remove('hidden');
|
||||||
|
select.innerHTML = '<option value="">请选择子类别</option>' +
|
||||||
|
subcats.map(s => `<option value="${s.id}">${s.name}</option>`).join('');
|
||||||
|
} else {
|
||||||
|
document.getElementById('smartAddSubcategoryArea').classList.add('hidden');
|
||||||
|
select.innerHTML = '<option value="">请选择子类别</option>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function closeSmartAddModal() {
|
function closeSmartAddModal() {
|
||||||
document.getElementById('smartAddModal').classList.add('hidden');
|
document.getElementById('smartAddModal').classList.add('hidden');
|
||||||
}
|
}
|
||||||
@@ -2018,6 +2054,7 @@
|
|||||||
// 预览解析结果
|
// 预览解析结果
|
||||||
async function previewSmartParse() {
|
async function previewSmartParse() {
|
||||||
const text = document.getElementById('smartAddText').value.trim();
|
const text = document.getElementById('smartAddText').value.trim();
|
||||||
|
const subcategoryId = document.getElementById('smartAddSubcategory').value;
|
||||||
|
|
||||||
if (!text && smartAddImages.length === 0) {
|
if (!text && smartAddImages.length === 0) {
|
||||||
alert('请上传图片或输入文本');
|
alert('请上传图片或输入文本');
|
||||||
@@ -2035,7 +2072,8 @@
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
text: text,
|
text: text,
|
||||||
images: smartAddImages,
|
images: smartAddImages,
|
||||||
category_type: smartAddType
|
category_type: smartAddType,
|
||||||
|
subcategory_id: subcategoryId
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2074,6 +2112,7 @@
|
|||||||
|
|
||||||
async function smartAddSubmit() {
|
async function smartAddSubmit() {
|
||||||
const text = document.getElementById('smartAddText').value.trim();
|
const text = document.getElementById('smartAddText').value.trim();
|
||||||
|
const subcategoryId = document.getElementById('smartAddSubcategory').value;
|
||||||
|
|
||||||
if (!text && smartAddImages.length === 0) {
|
if (!text && smartAddImages.length === 0) {
|
||||||
alert('请上传图片或输入文本');
|
alert('请上传图片或输入文本');
|
||||||
@@ -2096,6 +2135,8 @@
|
|||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
text: text,
|
text: text,
|
||||||
|
images: smartAddImages,
|
||||||
|
subcategory_id: subcategoryId
|
||||||
images: smartAddImages
|
images: smartAddImages
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user