Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f7a5dd5a1 | |||
| 146efdf6bd |
@@ -12,7 +12,8 @@
|
||||
"tdp_watts": 360,
|
||||
"price_usd": 11000,
|
||||
"release_year": 2022,
|
||||
"description": "AMD顶级服务器CPU,96核心"
|
||||
"description": "AMD顶级服务器CPU,96核心",
|
||||
"subcategory_id": "server"
|
||||
},
|
||||
{
|
||||
"id": "epyc9554",
|
||||
@@ -27,7 +28,8 @@
|
||||
"tdp_watts": 360,
|
||||
"price_usd": 6800,
|
||||
"release_year": 2022,
|
||||
"description": "64核心高性能服务器CPU"
|
||||
"description": "64核心高性能服务器CPU",
|
||||
"subcategory_id": "server"
|
||||
},
|
||||
{
|
||||
"id": "epyc9454",
|
||||
@@ -42,7 +44,8 @@
|
||||
"tdp_watts": 290,
|
||||
"price_usd": 4100,
|
||||
"release_year": 2022,
|
||||
"description": "48核心服务器CPU"
|
||||
"description": "48核心服务器CPU",
|
||||
"subcategory_id": "server"
|
||||
},
|
||||
{
|
||||
"id": "xeonw9359x",
|
||||
@@ -57,7 +60,8 @@
|
||||
"tdp_watts": 350,
|
||||
"price_usd": 6200,
|
||||
"release_year": 2023,
|
||||
"description": "Intel顶级工作站CPU"
|
||||
"description": "Intel顶级工作站CPU",
|
||||
"subcategory_id": "server"
|
||||
},
|
||||
{
|
||||
"id": "xeonw5345",
|
||||
@@ -72,7 +76,8 @@
|
||||
"tdp_watts": 230,
|
||||
"price_usd": 950,
|
||||
"release_year": 2023,
|
||||
"description": "中端工作站CPU"
|
||||
"description": "中端工作站CPU",
|
||||
"subcategory_id": "server"
|
||||
},
|
||||
{
|
||||
"id": "ryzen97950x",
|
||||
@@ -87,7 +92,8 @@
|
||||
"tdp_watts": 170,
|
||||
"price_usd": 550,
|
||||
"release_year": 2022,
|
||||
"description": "顶级消费级CPU,适合AI开发"
|
||||
"description": "顶级消费级CPU,适合AI开发",
|
||||
"subcategory_id": "desktop"
|
||||
},
|
||||
{
|
||||
"id": "ryzen97950x3d",
|
||||
@@ -102,7 +108,8 @@
|
||||
"tdp_watts": 120,
|
||||
"price_usd": 700,
|
||||
"release_year": 2023,
|
||||
"description": "带3D V-Cache,游戏性能更强"
|
||||
"description": "带3D V-Cache,游戏性能更强",
|
||||
"subcategory_id": "mobile"
|
||||
},
|
||||
{
|
||||
"id": "intel14900k",
|
||||
@@ -117,7 +124,8 @@
|
||||
"tdp_watts": 125,
|
||||
"price_usd": 580,
|
||||
"release_year": 2023,
|
||||
"description": "Intel顶级消费级CPU"
|
||||
"description": "Intel顶级消费级CPU",
|
||||
"subcategory_id": "desktop"
|
||||
},
|
||||
{
|
||||
"name": "AMD 锐龙 AI 9 H 365",
|
||||
@@ -136,6 +144,7 @@
|
||||
"raw_text": "AMD 锐龙 AI 9 H 365\nAMD 锐龙 AI 处理器助力打造卓越 AI PC\n\n \n全部折叠\n一般规格\n名称\nAMD 锐龙 AI 9 H 365\n产品系列\n锐龙\n系列\n锐龙 AI 300 系列\n外形规格\n笔记本电脑 , 台式机\nAMD PRO 技术\n否\n区域供货状况\n中国\n原代号\nStrix Point\n处理器架构\n4x Zen 5 , 6x Zen 5c\nCPU 核心数\n10\n多线程 (SMT)\n是\n线程数\n20\n最高加速时钟频率 \n最高可达 5 GHz\nMax Zen5c Clock \n最高可达 3.3 GHz\n基准时钟频率 \n2 GHz\nZen5 Base Clock\n2 GHz\nZen5c Base Clock\n2 GHz\nL2 高速缓存\n10 MB\nL3 高速缓存\n24 MB\n默认热设计功耗 (TDP)\n28W\nAMD 可配置热设计功耗 (cTDP)\n15-54W\nCPU 核心的处理器工艺\nTSMC 4nm FinFET\n封装芯片计数\n1\nAMD EXPO™ 内存超频技术\n是\n精准频率提升 (PBO)\n是\n曲线优化器电压偏移\n是\nCPU 平台\nFP8\n支持的扩展\nAES , AMD-V , AVX , AVX2 , AVX512 , FMA3 , MMX-plus , SHA , SSE , SSE2 , SSE3 , SSE4.1 , SSE4.2 , SSE4A , SSSE3 , x86-64\n最高工作温度 (Tjmax)\n100°C\n*支持的操作系统\nWindows 11 - 64-Bit Edition , RHEL x86 64-Bit , Ubuntu x86 64-Bit\n连接\nNative USB 4 (40Gbps)\n2\nNative USB 3.2 Gen 2 (10Gbps)\n2\nNative USB 2.0 (480Mbps)\n4\nPCI Express® Version\nPCIe® 4.0\n原生 PCIe® 通道 (总共/可用)\n16 , 16\nNVMe 支持\nBoot , RAID0 , RAID1\n系统内存类型\nDDR5 (FP8) , LPDDR5X (FP8)\n内存通道数\n2\n最大内存\n256 GB\n最高内存速度\n2x2R\tDDR5-5600, LPDDR5x-8000\n支持 ECC\n否\n显卡功能\n显卡型号\nAMD Radeon™ 880M\n显卡核心数\n12\n显卡频率\n2900 MHz\nDirectX® 版本\n12\nDisplayPort™ 版本\n2.1\nDisplayPort 扩展功能\nAdaptive-Sync , HDR Metadata , UHBR10\nDisplayPort 最高刷新率 (SDR)\n7680x4320 @ 60Hz , 3840x2160 @ 240Hz , 3440x1440 @ 360Hz , 2560x1440 @ 480Hz , 1920x1080 @ 600Hz\nDisplayPort 最高刷新率 (HDR)\n7680x4320 @ 60Hz , 3840x2160 @ 240Hz , 3440x1440 @ 360Hz , 2560x1440 @ 480Hz , 1920x1080 @ 600Hz\nHDMI® 版本\n2.1\n支持的 HDCP 版本\n2.3\nUSB Type-C® DisplayPort™ 备用模式\n是\n支持多个显示器\n是\n显示器个数上限\n4\nAMD FreeSync™\n是\n无线显示\nMiracast\n最大视频编码带宽 (SDR)\n1080p630 8bpc H.264, 1440p373 8bpc H.264, 2160p175 8bpc H.264, 1080p630 8bpc H.265, 1440p373 8bpc H.265, 2160p175 8bpc H.265, 4320p43 8bpc H.265, 1080p864 8/10bpc AV1, 1440p513 8/10bpc AV1, 2160p240 8/10bpc AV1, 4320p60 8/10bpc AV1\n\n最大视频解码带宽\n1080p60 8bpc MPEG2, 1080p60 8bpc VC1, 1080p786 8/10bpc VP9, 2160p196 8/10bpc VP9, 4320p49 8/10bpc VP9, 1080p1200 8bpc H.264, 2160p300 8bpc H.264, 4320p75 8bpc H.264, 1080p786 8/10bpc H.265, 2160p196 8/10bpc H.265, 4320p49 8/10bpc H.265, 1080p960 8/10bpc\n\nAMD SmartShift MAX\n是\nAMD 显存智取技术\n支持\nAI 引擎性能\nAMD Ryzen™ AI\n支持\nOverall TOPS\n最高可达 73 TOPS\nNPU TOPS\n最高可达 50 TOPS\n产品 ID\nTray 产品 ID\n100-000001530 (FP8)\n安全\nAMD 增强病毒防护 (NX bit)\n是",
|
||||
"publish_date": "",
|
||||
"views": 0,
|
||||
"is_pinned": false
|
||||
"is_pinned": false,
|
||||
"subcategory_id": "mobile"
|
||||
}
|
||||
]
|
||||
@@ -13,7 +13,8 @@
|
||||
"int8_perf_tops": 3958,
|
||||
"price_usd": 30000,
|
||||
"release_year": 2022,
|
||||
"description": "数据中心顶级GPU,专为AI训练设计"
|
||||
"description": "数据中心顶级GPU,专为AI训练设计",
|
||||
"subcategory_id": "datacenter"
|
||||
},
|
||||
{
|
||||
"id": "a100",
|
||||
@@ -29,7 +30,8 @@
|
||||
"int8_perf_tops": 624,
|
||||
"price_usd": 10000,
|
||||
"release_year": 2020,
|
||||
"description": "数据中心主力GPU,AI训练推理通用"
|
||||
"description": "数据中心主力GPU,AI训练推理通用",
|
||||
"subcategory_id": "datacenter"
|
||||
},
|
||||
{
|
||||
"id": "a10040g",
|
||||
@@ -45,7 +47,8 @@
|
||||
"int8_perf_tops": 624,
|
||||
"price_usd": 6000,
|
||||
"release_year": 2020,
|
||||
"description": "A100 40GB版本,性价比更高"
|
||||
"description": "A100 40GB版本,性价比更高",
|
||||
"subcategory_id": "datacenter"
|
||||
},
|
||||
{
|
||||
"id": "l40s",
|
||||
@@ -61,7 +64,8 @@
|
||||
"int8_perf_tops": 724,
|
||||
"price_usd": 7000,
|
||||
"release_year": 2023,
|
||||
"description": "新一代数据中心GPU,推理优化"
|
||||
"description": "新一代数据中心GPU,推理优化",
|
||||
"subcategory_id": "datacenter"
|
||||
},
|
||||
{
|
||||
"id": "rtx4090",
|
||||
@@ -77,7 +81,8 @@
|
||||
"int8_perf_tops": 660,
|
||||
"price_usd": 1600,
|
||||
"release_year": 2022,
|
||||
"description": "消费级最强GPU,适合个人AI开发"
|
||||
"description": "消费级最强GPU,适合个人AI开发",
|
||||
"subcategory_id": "gaming"
|
||||
},
|
||||
{
|
||||
"id": "rtx4090d",
|
||||
@@ -93,7 +98,8 @@
|
||||
"int8_perf_tops": 588,
|
||||
"price_usd": 1400,
|
||||
"release_year": 2024,
|
||||
"description": "4090中国特供版,性能略降"
|
||||
"description": "4090中国特供版,性能略降",
|
||||
"subcategory_id": "gaming"
|
||||
},
|
||||
{
|
||||
"id": "rtx3090",
|
||||
@@ -109,7 +115,8 @@
|
||||
"int8_perf_tops": 284,
|
||||
"price_usd": 1200,
|
||||
"release_year": 2020,
|
||||
"description": "上一代旗舰,性价比高"
|
||||
"description": "上一代旗舰,性价比高",
|
||||
"subcategory_id": "gaming"
|
||||
},
|
||||
{
|
||||
"id": "rtx3080",
|
||||
@@ -125,7 +132,8 @@
|
||||
"int8_perf_tops": 238,
|
||||
"price_usd": 700,
|
||||
"release_year": 2020,
|
||||
"description": "中高端消费级GPU"
|
||||
"description": "中高端消费级GPU",
|
||||
"subcategory_id": "gaming"
|
||||
},
|
||||
{
|
||||
"id": "v100",
|
||||
@@ -141,7 +149,8 @@
|
||||
"int8_perf_tops": 236,
|
||||
"price_usd": 4000,
|
||||
"release_year": 2017,
|
||||
"description": "上一代数据中心GPU,仍有价值"
|
||||
"description": "上一代数据中心GPU,仍有价值",
|
||||
"subcategory_id": "datacenter"
|
||||
},
|
||||
{
|
||||
"id": "mi300x",
|
||||
@@ -157,7 +166,8 @@
|
||||
"int8_perf_tops": 2614,
|
||||
"price_usd": 15000,
|
||||
"release_year": 2023,
|
||||
"description": "AMD最强AI GPU,192GB显存"
|
||||
"description": "AMD最强AI GPU,192GB显存",
|
||||
"subcategory_id": "datacenter"
|
||||
},
|
||||
{
|
||||
"name": "RTX 6000D",
|
||||
|
||||
@@ -2,11 +2,15 @@
|
||||
{
|
||||
"name": "比亚迪宋plus dmi 2021款",
|
||||
"brand": "比亚迪",
|
||||
"price": "18.87",
|
||||
"price": 18.87,
|
||||
"year": "2021",
|
||||
"category_id": "021dc76d36be",
|
||||
"id": "3d20dbcd4bdd",
|
||||
"created_at": "2026-04-09 10:09:56"
|
||||
"created_at": "2026-04-09 10:09:56",
|
||||
"subcategory_id": "suv",
|
||||
"views": 0,
|
||||
"images": [],
|
||||
"updated_at": "2026-04-28 12:32:13"
|
||||
},
|
||||
{
|
||||
"name": "秦PLUS",
|
||||
@@ -29,6 +33,7 @@
|
||||
"category_id": "021dc76d36be",
|
||||
"created_at": "2026-04-11 02:03:45",
|
||||
"visible": true,
|
||||
"raw_text": "秦PLUS的外观设计极具现代感和运动气息,前脸采用了家族化设计语言,标志性的大尺寸进气格栅占据了前脸的大部分空间,搭配锐利的LED大灯组,营造出强烈的视觉冲击力。车身线条流畅,腰线从车头贯穿至车尾,增强了整车的运动感。车尾部分,简洁大方的设计与前脸相呼应,整体风格时尚而不失稳重。\n\n上海:秦PLUS优惠促销,最新报价5.98万!轻松开新车\n\n秦PLUS拥有4780*1837*1515mm的长宽高尺寸和2718mm的轴距,赋予其宽敞的内部空间。车侧线条流畅且动感十足,从前轮距1580mm到后轮距1590mm,车轮布局合理,增强了车辆的稳定性和操控性。配备的225/60 R16轮胎规格,匹配独特风格的轮圈,为车辆增添了一抹动感与时尚的气息。\n\n上海:秦PLUS优惠促销,最新报价5.98万!轻松开新车\n\n秦PLUS的内饰风格简洁大气,给人以科技感和舒适感。中控台布局合理,配备了10.1英寸的中控屏幕,支持语音识别控制系统,可轻松操作多媒体系统、导航、电话和空调等功能。方向盘采用皮质材料,手感舒适,支持手动上下和前后调节,方便驾驶员调整到最佳驾驶姿势。座椅采用仿皮材质,主驾驶座椅具备前后调节、靠背调节和高低调节功能,而副驾驶座椅则支持前后调节和靠背调节,确保了乘客的舒适度。后排座椅可以按比例放倒,增加储物空间,同时,车内还配备了USB和Type-C接口,方便乘客为电子设备充电。\n\n上海:秦PLUS优惠促销,最新报价5.98万!轻松开新车\n\n秦PLUS搭载了一台1.5L 101马力的L4发动机,最大功率为74kW,最大扭矩为126N·m。与之匹配的是E-CVT无级变速器,这使得车辆在提供平稳的动力输出的同时,还能有效降低油耗。\n\n汽车之家车主@天艺风云 表示,外观设计是他当初选择秦PLUS的原因之一。他赞赏整体造型时尚大气,龙脸设计搭配犀利的大灯,辨识度极高。车身线条流畅,溜背式造型增添了几分运动感。全新的“龙鳞辉熠”格栅,精致又霸气,每次停车都有人问这是什么车,外观确实很吸引人。"
|
||||
"raw_text": "秦PLUS的外观设计极具现代感和运动气息,前脸采用了家族化设计语言,标志性的大尺寸进气格栅占据了前脸的大部分空间,搭配锐利的LED大灯组,营造出强烈的视觉冲击力。车身线条流畅,腰线从车头贯穿至车尾,增强了整车的运动感。车尾部分,简洁大方的设计与前脸相呼应,整体风格时尚而不失稳重。\n\n上海:秦PLUS优惠促销,最新报价5.98万!轻松开新车\n\n秦PLUS拥有4780*1837*1515mm的长宽高尺寸和2718mm的轴距,赋予其宽敞的内部空间。车侧线条流畅且动感十足,从前轮距1580mm到后轮距1590mm,车轮布局合理,增强了车辆的稳定性和操控性。配备的225/60 R16轮胎规格,匹配独特风格的轮圈,为车辆增添了一抹动感与时尚的气息。\n\n上海:秦PLUS优惠促销,最新报价5.98万!轻松开新车\n\n秦PLUS的内饰风格简洁大气,给人以科技感和舒适感。中控台布局合理,配备了10.1英寸的中控屏幕,支持语音识别控制系统,可轻松操作多媒体系统、导航、电话和空调等功能。方向盘采用皮质材料,手感舒适,支持手动上下和前后调节,方便驾驶员调整到最佳驾驶姿势。座椅采用仿皮材质,主驾驶座椅具备前后调节、靠背调节和高低调节功能,而副驾驶座椅则支持前后调节和靠背调节,确保了乘客的舒适度。后排座椅可以按比例放倒,增加储物空间,同时,车内还配备了USB和Type-C接口,方便乘客为电子设备充电。\n\n上海:秦PLUS优惠促销,最新报价5.98万!轻松开新车\n\n秦PLUS搭载了一台1.5L 101马力的L4发动机,最大功率为74kW,最大扭矩为126N·m。与之匹配的是E-CVT无级变速器,这使得车辆在提供平稳的动力输出的同时,还能有效降低油耗。\n\n汽车之家车主@天艺风云 表示,外观设计是他当初选择秦PLUS的原因之一。他赞赏整体造型时尚大气,龙脸设计搭配犀利的大灯,辨识度极高。车身线条流畅,溜背式造型增添了几分运动感。全新的“龙鳞辉熠”格栅,精致又霸气,每次停车都有人问这是什么车,外观确实很吸引人。",
|
||||
"subcategory_id": "sedan"
|
||||
}
|
||||
]
|
||||
@@ -3,75 +3,51 @@
|
||||
"name": "Osmo Pocket 4",
|
||||
"brand": "DJI",
|
||||
"price": 2999,
|
||||
"specs": {
|
||||
"传感器类型": "1英寸CMOS",
|
||||
"镜头": "20mm, f/2.0",
|
||||
"ISO范围": "50-12800",
|
||||
"视频分辨率": "4K 60fps",
|
||||
"照片最大分辨率": "5472×3648",
|
||||
"电池容量": "1545mAh",
|
||||
"工作温度": "0°C至40°C"
|
||||
},
|
||||
"specs": "[object Object]",
|
||||
"id": "597e29af5937",
|
||||
"category_id": "71fa2b4d818f",
|
||||
"created_at": "2026-04-28 00:07:01",
|
||||
"visible": true,
|
||||
"raw_text": "",
|
||||
"images": [
|
||||
"/static/uploads/1ad784e0b3c6_1777305525.png"
|
||||
],
|
||||
"images": [],
|
||||
"publish_date": "",
|
||||
"views": 0,
|
||||
"is_pinned": false
|
||||
"is_pinned": false,
|
||||
"subcategory_id": "90ce312b560d",
|
||||
"updated_at": "2026-04-28 12:32:38"
|
||||
},
|
||||
{
|
||||
"name": "Osmo Pocket 3",
|
||||
"brand": "DJI",
|
||||
"price": 2799,
|
||||
"specs": {
|
||||
"传感器类型": "1英寸CMOS",
|
||||
"镜头": "20mm, f/2.0",
|
||||
"ISO范围": "50-6400",
|
||||
"视频分辨率": "4K 60fps",
|
||||
"照片最大分辨率": "5472×3648",
|
||||
"电池容量": "1300mAh",
|
||||
"工作温度": "0°C至40°C"
|
||||
},
|
||||
"specs": "[object Object]",
|
||||
"id": "ad10ac80827b",
|
||||
"category_id": "71fa2b4d818f",
|
||||
"created_at": "2026-04-28 00:07:01",
|
||||
"visible": true,
|
||||
"raw_text": "",
|
||||
"images": [
|
||||
"/static/uploads/1ad784e0b3c6_1777305525.png"
|
||||
],
|
||||
"images": [],
|
||||
"publish_date": "",
|
||||
"views": 0,
|
||||
"is_pinned": false
|
||||
"is_pinned": false,
|
||||
"subcategory_id": "90ce312b560d",
|
||||
"updated_at": "2026-04-28 12:32:43"
|
||||
},
|
||||
{
|
||||
"name": "DJI Pocket 2",
|
||||
"brand": "DJI",
|
||||
"price": 1999,
|
||||
"specs": {
|
||||
"传感器类型": "1/1.7英寸CMOS",
|
||||
"镜头": "20mm, f/1.8",
|
||||
"ISO范围": "100-3200",
|
||||
"视频分辨率": "4K 60fps",
|
||||
"照片最大分辨率": "6272×4680",
|
||||
"电池容量": "875mAh",
|
||||
"工作温度": "0°C至40°C"
|
||||
},
|
||||
"specs": "[object Object]",
|
||||
"id": "0fde0f10ad96",
|
||||
"category_id": "71fa2b4d818f",
|
||||
"created_at": "2026-04-28 00:07:01",
|
||||
"visible": true,
|
||||
"raw_text": "",
|
||||
"images": [
|
||||
"/static/uploads/1ad784e0b3c6_1777305525.png"
|
||||
],
|
||||
"images": [],
|
||||
"publish_date": "",
|
||||
"views": 0,
|
||||
"is_pinned": false
|
||||
"is_pinned": false,
|
||||
"subcategory_id": "90ce312b560d",
|
||||
"updated_at": "2026-04-28 12:32:50"
|
||||
}
|
||||
]
|
||||
@@ -34,7 +34,8 @@
|
||||
"is_open_source": false,
|
||||
"license": "Proprietary",
|
||||
"description": "GPT-4增强版,128K上下文",
|
||||
"created_at": "2024-01-01"
|
||||
"created_at": "2024-01-01",
|
||||
"subcategory_id": "chat"
|
||||
},
|
||||
{
|
||||
"id": "gpt35",
|
||||
@@ -50,7 +51,8 @@
|
||||
"is_open_source": false,
|
||||
"license": "Proprietary",
|
||||
"description": "性价比高的通用模型",
|
||||
"created_at": "2024-01-01"
|
||||
"created_at": "2024-01-01",
|
||||
"subcategory_id": "chat"
|
||||
},
|
||||
{
|
||||
"id": "claude3opus",
|
||||
@@ -66,7 +68,8 @@
|
||||
"is_open_source": false,
|
||||
"license": "Proprietary",
|
||||
"description": "Anthropic最强模型,200K上下文",
|
||||
"created_at": "2024-01-01"
|
||||
"created_at": "2024-01-01",
|
||||
"subcategory_id": "code"
|
||||
},
|
||||
{
|
||||
"id": "claude3sonnet",
|
||||
@@ -82,7 +85,8 @@
|
||||
"is_open_source": false,
|
||||
"license": "Proprietary",
|
||||
"description": "平衡性能与成本",
|
||||
"created_at": "2024-01-01"
|
||||
"created_at": "2024-01-01",
|
||||
"subcategory_id": "chat"
|
||||
},
|
||||
{
|
||||
"id": "llama270b",
|
||||
@@ -98,7 +102,8 @@
|
||||
"is_open_source": true,
|
||||
"license": "Llama 2 Community",
|
||||
"description": "Meta开源大模型,70B参数",
|
||||
"created_at": "2024-01-01"
|
||||
"created_at": "2024-01-01",
|
||||
"subcategory_id": "chat"
|
||||
},
|
||||
{
|
||||
"id": "llama3",
|
||||
@@ -114,7 +119,8 @@
|
||||
"is_open_source": true,
|
||||
"license": "Llama 3 Community",
|
||||
"description": "Meta最新开源模型,性能接近GPT-4",
|
||||
"created_at": "2024-01-01"
|
||||
"created_at": "2024-01-01",
|
||||
"subcategory_id": "code"
|
||||
},
|
||||
{
|
||||
"id": "mistral7b",
|
||||
@@ -130,7 +136,8 @@
|
||||
"is_open_source": true,
|
||||
"license": "Apache 2.0",
|
||||
"description": "小巧高效的开源模型",
|
||||
"created_at": "2024-01-01"
|
||||
"created_at": "2024-01-01",
|
||||
"subcategory_id": "chat"
|
||||
},
|
||||
{
|
||||
"id": "mixtral8x7b",
|
||||
@@ -146,7 +153,8 @@
|
||||
"is_open_source": true,
|
||||
"license": "Apache 2.0",
|
||||
"description": "MoE架构,高效推理",
|
||||
"created_at": "2024-01-01"
|
||||
"created_at": "2024-01-01",
|
||||
"subcategory_id": "chat"
|
||||
},
|
||||
{
|
||||
"id": "qwen72b",
|
||||
@@ -162,7 +170,8 @@
|
||||
"is_open_source": true,
|
||||
"license": "Apache 2.0",
|
||||
"description": "阿里开源大模型,中文能力强",
|
||||
"created_at": "2024-01-01"
|
||||
"created_at": "2024-01-01",
|
||||
"subcategory_id": "chat"
|
||||
},
|
||||
{
|
||||
"id": "deepseekv3",
|
||||
@@ -178,7 +187,8 @@
|
||||
"is_open_source": true,
|
||||
"license": "MIT",
|
||||
"description": "DeepSeek最新模型,性价比极高",
|
||||
"created_at": "2024-01-01"
|
||||
"created_at": "2024-01-01",
|
||||
"subcategory_id": "code"
|
||||
},
|
||||
{
|
||||
"id": "glm4",
|
||||
@@ -195,6 +205,7 @@
|
||||
"license": "Proprietary",
|
||||
"description": "智谱AI大模型,中文能力强",
|
||||
"created_at": "2024-01-01",
|
||||
"visible": false
|
||||
"visible": true,
|
||||
"subcategory_id": "chat"
|
||||
}
|
||||
]
|
||||
@@ -141,11 +141,12 @@
|
||||
<th class="px-4 py-3 text-left text-sm font-medium text-gray-600">ID</th>
|
||||
<th class="px-4 py-3 text-left text-sm font-medium text-gray-600">名称</th>
|
||||
<th class="px-4 py-3 text-left text-sm font-medium text-gray-600">类型</th>
|
||||
<th class="px-4 py-3 text-left text-sm font-medium text-gray-600">参数字段</th>
|
||||
<th class="px-4 py-3 text-left text-sm font-medium text-gray-600">子类别</th>
|
||||
<th class="px-4 py-3 text-center text-sm font-medium text-gray-600">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="admin-categories-table"><tr><td colspan="6" class="text-center text-gray-400 py-8">加载中...</td></tr></tbody>
|
||||
<tbody id="admin-categories-table"><tr><td colspan="7" class="text-center text-gray-400 py-8">加载中...</td></tr></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
@@ -392,20 +393,53 @@
|
||||
|
||||
<!-- 子类别编辑弹框 -->
|
||||
<div id="subcategoryModal" class="fixed inset-0 bg-black/50 z-50 hidden flex items-center justify-center">
|
||||
<div class="bg-white rounded-xl max-w-lg w-full mx-4">
|
||||
<div class="p-6 border-b flex justify-between items-center">
|
||||
<div class="bg-white rounded-xl max-w-2xl 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">
|
||||
<h2 class="text-xl font-bold text-gray-800" id="subcategoryModalTitle"><i class="ri-folder-line mr-2"></i>添加子类别</h2>
|
||||
<button onclick="closeSubcategoryModal()" class="text-gray-400 hover:text-gray-600"><i class="ri-close-line text-2xl"></i></button>
|
||||
</div>
|
||||
<div id="subcategoryModalContent" class="p-6">
|
||||
<!-- 动态内容 -->
|
||||
</div>
|
||||
<div class="p-6 border-t flex justify-end gap-4">
|
||||
<div class="p-6 border-t flex justify-end gap-4 sticky bottom-0 bg-white">
|
||||
<button onclick="closeSubcategoryModal()" class="px-4 py-2 bg-gray-200 text-gray-600 rounded-lg hover:bg-gray-300">取消</button>
|
||||
<button onclick="saveSubcategory()" class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700"><i class="ri-save-line mr-1"></i>保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 参数字段编辑弹框 -->
|
||||
<div id="fieldModal" class="fixed inset-0 bg-black/50 z-50 hidden flex items-center justify-center">
|
||||
<div class="bg-white rounded-xl max-w-lg w-full mx-4">
|
||||
<div class="p-6 border-b flex justify-between items-center">
|
||||
<h2 class="text-xl font-bold text-gray-800" id="fieldModalTitle"><i class="ri-list-settings-line mr-2"></i>添加参数字段</h2>
|
||||
<button onclick="closeFieldModal()" class="text-gray-400 hover:text-gray-600"><i class="ri-close-line text-2xl"></i></button>
|
||||
</div>
|
||||
<div id="fieldModalContent" class="p-6">
|
||||
<div class="space-y-4">
|
||||
<div><label class="text-sm text-gray-600 mb-1 block">字段名 *</label><input type="text" id="field_key" class="w-full px-3 py-2 border rounded-lg" placeholder="如:context_length"></div>
|
||||
<div><label class="text-sm text-gray-600 mb-1 block">显示名 *</label><input type="text" id="field_label" class="w-full px-3 py-2 border rounded-lg" placeholder="如:上下文长度"></div>
|
||||
<div><label class="text-sm text-gray-600 mb-1 block">字段类型</label><select id="field_type" class="w-full px-3 py-2 border rounded-lg">
|
||||
<option value="text">文本</option>
|
||||
<option value="number">数字</option>
|
||||
<option value="date">日期</option>
|
||||
<option value="boolean">布尔值</option>
|
||||
<option value="json">JSON对象</option>
|
||||
<option value="url">URL链接</option>
|
||||
</select></div>
|
||||
<div><label class="text-sm text-gray-600 mb-1 block">说明</label><textarea id="field_desc" rows="2" class="w-full px-3 py-2 border rounded-lg" placeholder="字段用途说明"></textarea></div>
|
||||
<div class="flex items-center gap-2">
|
||||
<input type="checkbox" id="field_required" class="rounded">
|
||||
<label class="text-sm text-gray-600">必填字段</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-6 border-t flex justify-end gap-4">
|
||||
<button onclick="closeFieldModal()" class="px-4 py-2 bg-gray-200 text-gray-600 rounded-lg hover:bg-gray-300">取消</button>
|
||||
<button onclick="saveField()" class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700"><i class="ri-save-line mr-1"></i>保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 智能补充弹窗 -->
|
||||
<div id="smartUpdateModal" class="fixed inset-0 bg-black/50 z-50 hidden flex items-center justify-center">
|
||||
@@ -859,6 +893,7 @@
|
||||
document.getElementById('admin-categories-table').innerHTML = categories.map(c => {
|
||||
const isBuiltin = builtinCategories.includes(c.id);
|
||||
const subcatCount = (c.subcategories || []).length;
|
||||
const fieldsCount = (c.fields || []).length;
|
||||
return `
|
||||
<tr class="border-b hover:bg-gray-50 ${c.visible === false ? 'bg-gray-100 opacity-60' : ''} ${isBuiltin ? 'bg-indigo-50' : ''}">
|
||||
<td class="px-4 py-3"><div class="w-10 h-10 rounded-lg ${colorMap[c.color] || 'bg-gray-100 text-gray-600'} flex items-center justify-center"><i class="${c.icon} text-xl"></i></div></td>
|
||||
@@ -867,11 +902,14 @@
|
||||
<td class="px-4 py-3 text-sm">
|
||||
${isBuiltin ? '<span class="px-2 py-1 bg-indigo-100 text-indigo-600 rounded text-xs">内置</span>' : '<span class="text-gray-500">自定义</span>'}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-sm">
|
||||
${fieldsCount > 0 ? `<span class="px-2 py-1 bg-blue-100 text-blue-600 rounded text-xs">${fieldsCount} 个</span>` : '<span class="text-gray-400">无</span>'}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-sm">
|
||||
${subcatCount > 0 ? `<span class="px-2 py-1 bg-green-100 text-green-600 rounded text-xs">${subcatCount} 个</span>` : '<span class="text-gray-400">无</span>'}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-center">
|
||||
<button onclick="editItem('category', '${c.id}')" class="text-blue-600 hover:text-blue-800 mr-2" title="编辑子类别"><i class="ri-edit-line"></i></button>
|
||||
<button onclick="editItem('category', '${c.id}')" class="text-blue-600 hover:text-blue-800 mr-2" title="编辑"><i class="ri-edit-line"></i></button>
|
||||
${!isBuiltin ? `<button onclick="deleteItem('category', '${c.id}')" class="text-red-600 hover:text-red-800" title="删除"><i class="ri-delete-bin-line"></i></button>` : '<span class="text-gray-300 cursor-not-allowed"><i class="ri-delete-bin-line"></i></span>'}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -1136,6 +1174,12 @@
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (key === 'fields') {
|
||||
// 解析参数字段JSON
|
||||
try { data[key] = JSON.parse(value); } catch {
|
||||
data[key] = [];
|
||||
}
|
||||
}
|
||||
else data[key] = value;
|
||||
}
|
||||
});
|
||||
@@ -1317,9 +1361,12 @@
|
||||
|
||||
// 内置类别只显示子类别管理
|
||||
if (isBuiltin) {
|
||||
const fields = data.fields || [];
|
||||
window.currentEditingFields = JSON.parse(JSON.stringify(fields));
|
||||
|
||||
return `<form id="itemForm" class="space-y-4">
|
||||
<div class="bg-indigo-50 rounded-lg p-4 mb-4">
|
||||
<p class="text-sm text-indigo-700"><i class="ri-information-line mr-1"></i>内置分类的基础信息不可修改,只可编辑子类别配置。</p>
|
||||
<p class="text-sm text-indigo-700"><i class="ri-information-line mr-1"></i>内置分类的基础信息不可修改,只可编辑参数字段和子类别配置。</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4 bg-gray-50 p-4 rounded-lg">
|
||||
<div><label class="text-sm text-gray-500 mb-1 block">ID</label><div class="text-gray-700 font-mono">${data.id}</div></div>
|
||||
@@ -1335,6 +1382,20 @@
|
||||
<input type="hidden" name="visible" value="${data.visible !== false ? 'true' : 'false'}">
|
||||
<input type="hidden" name="description" value="${data.description || ''}">
|
||||
|
||||
<!-- 参数字段管理 -->
|
||||
<div class="border-t pt-4">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<label class="text-sm font-medium text-gray-700"><i class="ri-list-settings-line mr-1"></i>参数字段管理</label>
|
||||
<button onclick="openFieldAddModal('category')" class="px-3 py-1.5 bg-indigo-600 text-white rounded-lg text-sm hover:bg-indigo-700">
|
||||
<i class="ri-add-line mr-1"></i>添加字段
|
||||
</button>
|
||||
</div>
|
||||
<div id="fieldsList" class="space-y-2">
|
||||
${renderFieldsList(fields)}
|
||||
</div>
|
||||
<input type="hidden" name="fields" id="fieldsHidden" value='${JSON.stringify(fields)}'>
|
||||
</div>
|
||||
|
||||
<!-- 子类别管理 -->
|
||||
<div class="border-t pt-4">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
@@ -1353,6 +1414,9 @@
|
||||
|
||||
// 自定义类别完整编辑表单
|
||||
const autoId = data.id || generateId();
|
||||
const fields = data.fields || [];
|
||||
window.currentEditingFields = JSON.parse(JSON.stringify(fields));
|
||||
|
||||
return `<form id="itemForm" class="space-y-4">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div><label class="text-sm text-gray-600 mb-1 block">ID</label><input type="text" name="id" value="${autoId}" readonly class="w-full px-3 py-2 border rounded-lg bg-gray-100 text-gray-500 font-mono text-xs"><p class="text-xs text-gray-400 mt-1">自动生成,无需填写</p></div>
|
||||
@@ -1374,6 +1438,20 @@
|
||||
</div>
|
||||
<div><label class="text-sm text-gray-600 mb-1 block">描述</label><textarea name="description" rows="2" class="w-full px-3 py-2 border rounded-lg" placeholder="分类描述">${data.description || ''}</textarea></div>
|
||||
|
||||
<!-- 参数字段管理 -->
|
||||
<div class="border-t pt-4">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<label class="text-sm font-medium text-gray-700"><i class="ri-list-settings-line mr-1"></i>参数字段管理(基础字段,所有子类别共享)</label>
|
||||
<button onclick="openFieldAddModal('category')" class="px-3 py-1.5 bg-indigo-600 text-white rounded-lg text-sm hover:bg-indigo-700">
|
||||
<i class="ri-add-line mr-1"></i>添加字段
|
||||
</button>
|
||||
</div>
|
||||
<div id="fieldsList" class="space-y-2">
|
||||
${renderFieldsList(fields)}
|
||||
</div>
|
||||
<input type="hidden" name="fields" id="fieldsHidden" value='${JSON.stringify(fields)}'>
|
||||
</div>
|
||||
|
||||
<!-- 子类别管理 -->
|
||||
<div class="border-t pt-4">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
@@ -1404,7 +1482,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium text-gray-800">${sub.name}</div>
|
||||
<div class="text-xs text-gray-500">ID: ${sub.id} | 特性: ${(sub.key_features || []).join(', ')}</div>
|
||||
<div class="text-xs text-gray-500">ID: ${sub.id} | 特性: ${(sub.key_features || []).join(', ')} | 额外字段: ${(sub.extra_fields || []).length}个</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2 opacity-0 group-hover:opacity-100 transition">
|
||||
@@ -1419,6 +1497,124 @@
|
||||
`).join('');
|
||||
}
|
||||
|
||||
// ============ 参数字段管理 ============
|
||||
|
||||
let currentFieldTarget = ''; // 'category' 或 'subcategory'
|
||||
let currentFieldIndex = -1;
|
||||
|
||||
// 渲染参数字段列表
|
||||
function renderFieldsList(fields) {
|
||||
if (!fields || fields.length === 0) {
|
||||
return '<div class="text-gray-400 text-sm py-4 text-center bg-gray-50 rounded-lg">暂无参数字段,点击上方按钮添加</div>';
|
||||
}
|
||||
|
||||
const typeLabels = {text: '文本', number: '数字', date: '日期', boolean: '布尔', json: 'JSON', url: 'URL'};
|
||||
|
||||
return fields.map((field, index) => `
|
||||
<div class="bg-gray-50 rounded-lg p-3 flex justify-between items-center group hover:bg-gray-100">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-8 h-8 rounded-lg bg-indigo-100 flex items-center justify-center font-mono text-xs text-indigo-600">
|
||||
${field.key ? field.key.substring(0, 4) : '-'}
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium text-gray-800">${field.label || field.key}</div>
|
||||
<div class="text-xs text-gray-500">
|
||||
字段: ${field.key} | 类型: ${typeLabels[field.type] || '文本'} |
|
||||
${field.required ? '<span class="text-red-500">必填</span>' : '可选'}
|
||||
${field.description ? ` | ${field.description}` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2 opacity-0 group-hover:opacity-100 transition">
|
||||
<button onclick="editField(${index})" class="px-2 py-1 text-blue-600 hover:bg-blue-50 rounded text-sm">
|
||||
<i class="ri-edit-line"></i>
|
||||
</button>
|
||||
<button onclick="deleteField(${index})" class="px-2 py-1 text-red-600 hover:bg-red-50 rounded text-sm">
|
||||
<i class="ri-delete-bin-line"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
// 打开添加字段弹框
|
||||
function openFieldAddModal(target) {
|
||||
currentFieldTarget = target;
|
||||
currentFieldIndex = -1;
|
||||
document.getElementById('fieldModalTitle').textContent = '添加参数字段';
|
||||
document.getElementById('field_key').value = '';
|
||||
document.getElementById('field_label').value = '';
|
||||
document.getElementById('field_type').value = 'text';
|
||||
document.getElementById('field_desc').value = '';
|
||||
document.getElementById('field_required').checked = false;
|
||||
document.getElementById('fieldModal').classList.remove('hidden');
|
||||
}
|
||||
|
||||
// 编辑字段
|
||||
function editField(index) {
|
||||
currentFieldTarget = 'category';
|
||||
currentFieldIndex = index;
|
||||
const field = window.currentEditingFields[index];
|
||||
|
||||
document.getElementById('fieldModalTitle').textContent = '编辑参数字段';
|
||||
document.getElementById('field_key').value = field.key || '';
|
||||
document.getElementById('field_label').value = field.label || '';
|
||||
document.getElementById('field_type').value = field.type || 'text';
|
||||
document.getElementById('field_desc').value = field.description || '';
|
||||
document.getElementById('field_required').checked = field.required || false;
|
||||
document.getElementById('fieldModal').classList.remove('hidden');
|
||||
}
|
||||
|
||||
// 删除字段
|
||||
function deleteField(index) {
|
||||
if (!confirm('确定删除此字段?')) return;
|
||||
window.currentEditingFields.splice(index, 1);
|
||||
document.getElementById('fieldsList').innerHTML = renderFieldsList(window.currentEditingFields);
|
||||
document.getElementById('fieldsHidden').value = JSON.stringify(window.currentEditingFields);
|
||||
}
|
||||
|
||||
// 关闭字段弹框
|
||||
function closeFieldModal() {
|
||||
document.getElementById('fieldModal').classList.add('hidden');
|
||||
}
|
||||
|
||||
// 保存字段
|
||||
function saveField() {
|
||||
const key = document.getElementById('field_key').value.trim();
|
||||
const label = document.getElementById('field_label').value.trim();
|
||||
const type = document.getElementById('field_type').value;
|
||||
const description = document.getElementById('field_desc').value.trim();
|
||||
const required = document.getElementById('field_required').checked;
|
||||
|
||||
if (!key || !label) {
|
||||
alert('字段名和显示名不能为空');
|
||||
return;
|
||||
}
|
||||
|
||||
const field = { key, label, type, description, required };
|
||||
|
||||
if (currentFieldTarget === 'subcategory') {
|
||||
// 子类别额外字段
|
||||
if (currentFieldIndex === -1) {
|
||||
window.currentEditingSubcategoryFields.push(field);
|
||||
} else {
|
||||
window.currentEditingSubcategoryFields[currentFieldIndex] = field;
|
||||
}
|
||||
document.getElementById('subcategoryFieldsList').innerHTML = renderFieldsList(window.currentEditingSubcategoryFields);
|
||||
} else {
|
||||
// 类别基础字段
|
||||
if (currentFieldIndex === -1) {
|
||||
window.currentEditingFields.push(field);
|
||||
} else {
|
||||
window.currentEditingFields[currentFieldIndex] = field;
|
||||
}
|
||||
document.getElementById('fieldsList').innerHTML = renderFieldsList(window.currentEditingFields);
|
||||
document.getElementById('fieldsHidden').value = JSON.stringify(window.currentEditingFields);
|
||||
}
|
||||
|
||||
closeFieldModal();
|
||||
}
|
||||
|
||||
// 打开子类别添加弹框
|
||||
function openSubcategoryAddModal() {
|
||||
document.getElementById('subcategoryModalTitle').textContent = '添加子类别';
|
||||
@@ -1450,6 +1646,8 @@
|
||||
const featureLabels = data.feature_labels || {};
|
||||
const featureLabelsStr = Object.entries(featureLabels).map(([k, v]) => `${k}:${v}`).join(', ');
|
||||
const autoSubId = data.id || generateId();
|
||||
const extraFields = data.extra_fields || [];
|
||||
window.currentEditingSubcategoryFields = JSON.parse(JSON.stringify(extraFields));
|
||||
|
||||
return `<div class="space-y-4">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
@@ -1458,18 +1656,44 @@
|
||||
<div><label class="text-sm text-gray-600 mb-1 block">图标</label><input type="text" id="sub_icon" value="${data.icon || 'ri-folder-line'}" class="w-full px-3 py-2 border rounded-lg" placeholder="ri-folder-line"></div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-sm text-gray-600 mb-1 block">关键特性字段</label>
|
||||
<label class="text-sm text-gray-600 mb-1 block">关键特性字段(表格显示的关键列)</label>
|
||||
<input type="text" id="sub_key_features" value="${keyFeatures}" class="w-full px-3 py-2 border rounded-lg" placeholder="context_length, mmlu, input_price">
|
||||
<p class="text-xs text-gray-500 mt-1">逗号分隔,如:context_length, mmlu, input_price</p>
|
||||
<p class="text-xs text-gray-500 mt-1">逗号分隔,选择要重点显示的字段</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-sm text-gray-600 mb-1 block">特性标签(显示名)</label>
|
||||
<label class="text-sm text-gray-600 mb-1 block">特性标签(显示名映射)</label>
|
||||
<input type="text" id="sub_feature_labels" value="${featureLabelsStr}" class="w-full px-3 py-2 border rounded-lg" placeholder="context_length:上下文, mmlu:MMLU">
|
||||
<p class="text-xs text-gray-500 mt-1">格式:字段名:显示名,逗号分隔</p>
|
||||
</div>
|
||||
|
||||
<!-- 额外参数字段(子类别特有) -->
|
||||
<div class="border-t pt-4">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<label class="text-sm font-medium text-gray-700"><i class="ri-list-settings-line mr-1"></i>额外参数字段(子类别特有,继承父类别字段)</label>
|
||||
<button onclick="openSubcategoryFieldAddModal()" class="px-3 py-1.5 bg-indigo-600 text-white rounded-lg text-sm hover:bg-indigo-700">
|
||||
<i class="ri-add-line mr-1"></i>添加字段
|
||||
</button>
|
||||
</div>
|
||||
<div id="subcategoryFieldsList" class="space-y-2">
|
||||
${renderFieldsList(extraFields)}
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// 子类别字段添加弹框
|
||||
function openSubcategoryFieldAddModal() {
|
||||
currentFieldTarget = 'subcategory';
|
||||
currentFieldIndex = -1;
|
||||
document.getElementById('fieldModalTitle').textContent = '添加额外参数字段';
|
||||
document.getElementById('field_key').value = '';
|
||||
document.getElementById('field_label').value = '';
|
||||
document.getElementById('field_type').value = 'text';
|
||||
document.getElementById('field_desc').value = '';
|
||||
document.getElementById('field_required').checked = false;
|
||||
document.getElementById('fieldModal').classList.remove('hidden');
|
||||
}
|
||||
|
||||
// 保存子类别
|
||||
function saveSubcategory() {
|
||||
const id = document.getElementById('sub_id').value.trim();
|
||||
@@ -1483,8 +1707,6 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// ID自动生成,无需校验
|
||||
|
||||
// 解析 key_features
|
||||
const key_features = keyFeaturesStr ? keyFeaturesStr.split(',').map(s => s.trim()).filter(s => s) : [];
|
||||
|
||||
@@ -1504,22 +1726,19 @@
|
||||
name,
|
||||
icon,
|
||||
key_features,
|
||||
feature_labels
|
||||
feature_labels,
|
||||
extra_fields: window.currentEditingSubcategoryFields || []
|
||||
};
|
||||
|
||||
if (window.editingSubcategoryIndex === -1) {
|
||||
// 添加新子类别
|
||||
window.currentEditingSubcategories.push(subcategory);
|
||||
} else {
|
||||
// 编辑现有子类别
|
||||
window.currentEditingSubcategories[window.editingSubcategoryIndex] = subcategory;
|
||||
}
|
||||
|
||||
// 更新显示
|
||||
document.getElementById('subcategoriesList').innerHTML = renderSubcategoriesList(window.currentEditingSubcategories);
|
||||
document.getElementById('subcategoriesHidden').value = JSON.stringify(window.currentEditingSubcategories);
|
||||
|
||||
// 关闭弹框
|
||||
closeSubcategoryModal();
|
||||
}
|
||||
|
||||
@@ -1672,6 +1891,7 @@
|
||||
document.getElementById('rawDataModal').addEventListener('click', function(e) { if (e.target === this) closeRawDataModal(); });
|
||||
document.getElementById('subcategoryModal').addEventListener('click', function(e) { if (e.target === this) closeSubcategoryModal(); });
|
||||
document.getElementById('smartUpdateModal').addEventListener('click', function(e) { if (e.target === this) closeSmartUpdateModal(); });
|
||||
document.getElementById('fieldModal').addEventListener('click', function(e) { if (e.target === this) closeFieldModal(); });
|
||||
|
||||
// ============ 智能添加功能 ============
|
||||
|
||||
|
||||
Reference in New Issue
Block a user