From 892f0c50023d5ee538d763b436ee44867f9e1f50 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Tue, 9 Jun 2026 13:36:07 +0800 Subject: [PATCH] bugfix --- wwwroot/llm_launch_check.ui | 119 ++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 60 deletions(-) diff --git a/wwwroot/llm_launch_check.ui b/wwwroot/llm_launch_check.ui index 31dd1bd..1430675 100644 --- a/wwwroot/llm_launch_check.ui +++ b/wwwroot/llm_launch_check.ui @@ -5,67 +5,66 @@ "options": { "width": "100%", "height": "100%", - "spacing": 10, - "children": [ - { - "widgettype": "Title", - "options": { - "text": "模型上线检查", - "level": 2 - } - }, - { - "widgettype": "Text", - "options": { - "name": "check_status", - "text": "检查中...", - "i18n": false - } - }, - { - "widgettype": "VBox", - "options": { - "name": "checks_list", - "spacing": 5 - } - }, - { - "widgettype": "Button", - "options": { - "name": "test_btn", - "text": "体验一次", - "i18n": false, - "disabled": true - } - }, - { - "widgettype": "Text", - "options": { - "name": "test_result", - "text": "", - "i18n": false - } - }, - { - "widgettype": "Button", - "options": { - "name": "check_charging_btn", - "text": "检查计费", - "i18n": false, - "disabled": true - } - }, - { - "widgettype": "Text", - "options": { - "name": "charging_result", - "text": "", - "i18n": false - } + "spacing": 10 + }, + "subwidgets": [ + { + "widgettype": "Title", + "options": { + "text": "模型上线检查", + "level": 2 } - ], - "init": "async function(self) {\n const llmid = '{{llmid}}';\n const statusEl = self.children.check_status;\n const listEl = self.children.checks_list;\n const testBtn = self.children.test_btn;\n const testResult = self.children.test_result;\n const checkChargingBtn = self.children.check_charging_btn;\n const chargingResult = self.children.charging_result;\n let lastUsage = null;\n \n async function runCheck() {\n statusEl.setText('检查中...');\n listEl.clear();\n testBtn.setDisabled(true);\n checkChargingBtn.setDisabled(true);\n \n try {\n const url = bricks.absurl('../api/llm_launch_check_api.dspy?llmid=' + llmid, self);\n const resp = await fetch(url);\n const data = await resp.json();\n \n if (data.error) {\n statusEl.setText('错误: ' + data.error);\n return;\n }\n \n statusEl.setText(data.all_passed ? '✓ 所有检查通过' : '✗ 存在未通过项');\n statusEl.setStyle({color: data.all_passed ? '#4CAF50' : '#F44336', fontSize: '16px', fontWeight: 'bold'});\n \n data.checks.forEach(check => {\n const row = bricks.createWidget('HBox', {\n spacing: 10,\n children: [\n {widgettype: 'Text', options: {text: check.passed ? '✓' : '✗', style: {color: check.passed ? '#4CAF50' : '#F44336', fontSize: '18px', width: '30px'}}},\n {widgettype: 'Text', options: {text: check.name, style: {fontWeight: 'bold', width: '200px'}}},\n {widgettype: 'Text', options: {text: check.detail, style: {color: '#666'}}}\n ]\n });\n listEl.addChild(row);\n });\n \n if (data.all_passed) {\n testBtn.setDisabled(false);\n }\n } catch (e) {\n statusEl.setText('请求失败: ' + e.message);\n }\n }\n \n testBtn.on('click', async () => {\n testResult.setText('体验中...');\n testResult.setStyle({color: '#666'});\n checkChargingBtn.setDisabled(true);\n lastUsage = null;\n \n try {\n const url = bricks.absurl('../api/llm_launch_check_api.dspy?llmid=' + llmid + '&action=inference', self);\n const resp = await fetch(url);\n const data = await resp.json();\n \n if (data.success) {\n const usageStr = data.usage ? JSON.stringify(data.usage, null, 2) : '无';\n testResult.setText('✓ 响应: ' + (data.response || '(空)') + '\\n用量: ' + usageStr);\n testResult.setStyle({color: '#4CAF50'});\n lastUsage = data.usage;\n if (lastUsage) {\n checkChargingBtn.setDisabled(false);\n }\n } else {\n testResult.setText('✗ 失败: ' + data.error);\n testResult.setStyle({color: '#F44336'});\n }\n } catch (e) {\n testResult.setText('请求失败: ' + e.message);\n testResult.setStyle({color: '#F44336'});\n }\n });\n \n checkChargingBtn.on('click', async () => {\n if (!lastUsage) {\n chargingResult.setText('无用量数据');\n return;\n }\n \n chargingResult.setText('检查计费中...');\n chargingResult.setStyle({color: '#666'});\n \n try {\n const usagesJson = encodeURIComponent(JSON.stringify(lastUsage));\n const url = bricks.absurl('../api/llm_launch_check_api.dspy?llmid=' + llmid + '&action=check_charging&usages=' + usagesJson, self);\n const resp = await fetch(url);\n const data = await resp.json();\n \n if (data.error) {\n chargingResult.setText('✗ 错误: ' + data.error);\n chargingResult.setStyle({color: '#F44336'});\n return;\n }\n \n if (data.success) {\n let text = '✓ 计费检查通过\\n';\n text += '定价项目: ' + data.pp_name + ' (ppid=' + data.ppid + ')\\n';\n text += '用量: ' + JSON.stringify(data.usages) + '\\n';\n text += '总金额: ¥' + data.total_amount.toFixed(4) + '\\n';\n text += '总成本: ¥' + data.total_cost.toFixed(4) + '\\n';\n if (data.breakdown && data.breakdown.length > 0) {\n text += '明细:\\n';\n data.breakdown.forEach(b => {\n text += ' ' + (b.factor || '项目') + ': ¥' + b.amount.toFixed(4) + ' (成本¥' + (b.cost || 0).toFixed(4) + ')\\n';\n });\n }\n chargingResult.setText(text);\n chargingResult.setStyle({color: '#4CAF50'});\n } else {\n chargingResult.setText('✗ ' + data.error);\n chargingResult.setStyle({color: '#F44336'});\n }\n } catch (e) {\n chargingResult.setText('请求失败: ' + e.message);\n chargingResult.setStyle({color: '#F44336'});\n }\n });\n \n await runCheck();\n}" - } + }, + { + "widgettype": "Text", + "options": { + "name": "check_status", + "text": "检查中...", + "i18n": false + } + }, + { + "widgettype": "VBox", + "options": { + "name": "checks_list", + "spacing": 5 + } + }, + { + "widgettype": "Button", + "options": { + "name": "test_btn", + "text": "体验一次", + "i18n": false, + "disabled": true + } + }, + { + "widgettype": "Text", + "options": { + "name": "test_result", + "text": "", + "i18n": false + } + }, + { + "widgettype": "Button", + "options": { + "name": "check_charging_btn", + "text": "检查计费", + "i18n": false, + "disabled": true + } + }, + { + "widgettype": "Text", + "options": { + "name": "charging_result", + "text": "", + "i18n": false + } + } + ], } {% else %} {