diff --git a/pages/home/home.js b/pages/home/home.js index 6e2f54b..38e7af9 100644 --- a/pages/home/home.js +++ b/pages/home/home.js @@ -21,8 +21,15 @@ Page({ async loadModules() { try { const result = await request({ url: '/portal/api/modules' }); - if (result && result.success && result.data && Array.isArray(result.data.modules) && result.data.modules.length) { - this.setData({ modules: result.data.modules }); + if (Array.isArray(result) && result.length) { + const defaultMap = new Map(DEFAULT_MODULES.map((item) => [item.path, item])); + const merged = DEFAULT_MODULES.map((item) => { + const remote = result.find((entry) => entry && entry.path === item.path); + return remote ? { ...item, ...remote } : item; + }); + if (merged.length) { + this.setData({ modules: merged }); + } } } catch (e) {} }, diff --git a/pages/prompt/dashboard.js b/pages/prompt/dashboard.js index 5c134c5..48e5172 100644 --- a/pages/prompt/dashboard.js +++ b/pages/prompt/dashboard.js @@ -1,4 +1,12 @@ -const { request } = require('../../utils/request'); +const { request, normalizeResponse } = require('../../utils/request'); + +const TASK_STATUS_TEXT = { + 0: '待开始', + 1: '进行中', + 2: '已完成', + 3: '已暂停', + 4: '已取消' +}; Page({ data: { @@ -10,12 +18,16 @@ Page({ }, async loadData() { try { - const stats = await request({ url: '/api/prompt/dashboard' }); - const running = await request({ url: '/api/prompt/tasks?status=1&page_size=5' }); - this.setData({ - stats: stats && stats.success ? stats.data : null, - running: running && running.list ? running.list : (running && running.data && running.data.list ? running.data.list : []) - }); + const statsResp = await request({ url: '/api/prompt/dashboard' }); + const runningResp = await request({ url: '/api/prompt/tasks?status=1&page_size=5' }); + const stats = normalizeResponse(statsResp).payload || null; + const runningPayload = normalizeResponse(runningResp).payload; + const runningList = runningPayload && runningPayload.list ? runningPayload.list : (Array.isArray(runningPayload) ? runningPayload : []); + const running = runningList.map(item => ({ + ...item, + statusText: TASK_STATUS_TEXT[item.status] || '' + })); + this.setData({ stats, running }); } catch (e) {} } }); diff --git a/pages/prompt/dashboard.wxml b/pages/prompt/dashboard.wxml index 46e9a1a..84715ff 100644 --- a/pages/prompt/dashboard.wxml +++ b/pages/prompt/dashboard.wxml @@ -22,6 +22,14 @@ 已完成 {{stats.completed_tasks}} + + 模板 + {{stats.total_templates}} + + + 对话 + {{stats.total_conversations}} + 暂无统计数据 @@ -32,7 +40,7 @@ {{item.title}} - {{item.status}} + {{item.statusText || item.status}} diff --git a/pages/prompt/import.js b/pages/prompt/import.js index 3068161..7521e5b 100644 --- a/pages/prompt/import.js +++ b/pages/prompt/import.js @@ -1,4 +1,48 @@ -const { request, buildResultView } = require('../../utils/request'); +const { request, buildResultView, normalizeResponse } = require('../../utils/request'); + +const RESULT_PREVIEW_LIMIT = 240; + +function buildResultState(text) { + const content = text || ''; + return { resultHasMore: content.length > RESULT_PREVIEW_LIMIT, resultExpanded: false }; +} + +function buildImportCards(payload) { + const cards = []; + if (!payload || typeof payload !== 'object') return cards; + if (payload.task_id) { + cards.push({ label: '关联任务', value: `#${payload.task_id}` }); + } + if (payload.existing_task) { + const name = payload.existing_task.title || payload.existing_task.id || '已存在任务'; + cards.push({ label: '已存在任务', value: String(name) }); + if (payload.existing_task.conversation_count !== undefined) { + cards.push({ label: '对话数量', value: String(payload.existing_task.conversation_count) }); + } + } + if (Array.isArray(payload.conversations)) { + cards.push({ label: '解析对话', value: String(payload.conversations.length) }); + } + if (payload.summary) { + const summary = payload.summary; + if (summary.total_rounds !== undefined) { + cards.push({ label: '总轮数', value: String(summary.total_rounds) }); + } + if (summary.user_messages !== undefined) { + cards.push({ label: '用户消息', value: String(summary.user_messages) }); + } + if (summary.bot_messages !== undefined) { + cards.push({ label: '机器人消息', value: String(summary.bot_messages) }); + } + if (Array.isArray(summary.keywords) && summary.keywords.length) { + cards.push({ label: '关键词', value: summary.keywords.join('、') }); + } + if (Array.isArray(summary.main_topics) && summary.main_topics.length) { + cards.push({ label: '主要话题', value: summary.main_topics.join('、') }); + } + } + return cards; +} Page({ data: { @@ -9,20 +53,32 @@ Page({ task_name: '', robot_id: '', result: '', - resultCards: [] + resultCards: [], + resultExpanded: false, + resultHasMore: false, + importCards: [] }, onInput(e) { const key = e.currentTarget.dataset.key; this.setData({ [key]: e.detail.value }); }, + toggleResult() { + this.setData({ resultExpanded: !this.data.resultExpanded }); + }, + setResult(result) { + const view = buildResultView(result); + const payload = normalizeResponse(result).payload; + const importCards = buildImportCards(payload); + const state = buildResultState(view.text); + this.setData({ result: view.text, resultCards: view.cards, importCards, ...state }); + }, async parse() { const result = await request({ url: '/api/prompt/import', method: 'POST', data: { content: this.data.content, check_only: true } }); - const view = buildResultView(result); - this.setData({ result: view.text, resultCards: view.cards }); + this.setResult(result); }, async confirm() { const payload = { @@ -34,7 +90,6 @@ Page({ robot_id: this.data.robot_id ? Number(this.data.robot_id) : undefined }; const result = await request({ url: '/api/prompt/import', method: 'POST', data: payload }); - const view = buildResultView(result); - this.setData({ result: view.text, resultCards: view.cards }); + this.setResult(result); } }); diff --git a/pages/prompt/import.wxml b/pages/prompt/import.wxml index 580aad2..90011b5 100644 --- a/pages/prompt/import.wxml +++ b/pages/prompt/import.wxml @@ -26,9 +26,20 @@ 结果 - 原始数据 + + 原始数据 + {{resultExpanded ? '收起' : '展开'}} + 已为你保留完整响应 + + + + {{item.label}} + {{item.value}} + + + @@ -37,6 +48,6 @@ - {{result}} + {{result}} diff --git a/pages/prompt/robots.js b/pages/prompt/robots.js index 825c713..cfb7df1 100644 --- a/pages/prompt/robots.js +++ b/pages/prompt/robots.js @@ -1,17 +1,23 @@ -const { request, buildResultView } = require('../../utils/request'); +const { request, buildResultView, normalizeResponse } = require('../../utils/request'); const RESULT_PREVIEW_LIMIT = 240; +const ROBOT_STATUS_TEXT = { + 0: '禁用', + 1: '启用' +}; function safeParseResult(raw) { - if (raw === null || raw === undefined) return null; - if (typeof raw === 'string') { + const normalized = normalizeResponse(raw); + const payload = normalized.payload; + if (payload === null || payload === undefined) return null; + if (typeof payload === 'string') { try { - return JSON.parse(raw); + return JSON.parse(payload); } catch (e) { return null; } } - return raw; + return payload; } function pickList(obj) { @@ -42,10 +48,12 @@ function buildRobotCards(parsed) { return list.map(item => { const name = item.name || item.title || item.robot_name || ''; const desc = item.description || item.desc || item.detail || ''; + const statusText = ROBOT_STATUS_TEXT[item.status] || ''; return { id: item.id || item.robot_id || item.robotId || '', name: name || (item.id || item.robot_id ? `机器人 ${item.id || item.robot_id}` : '机器人'), status: item.status, + statusText, avatar: item.avatar || item.avatar_url || '', description: desc ? String(desc).slice(0, 80) : '' }; diff --git a/pages/prompt/robots.wxml b/pages/prompt/robots.wxml index 23e0ece..a48c4de 100644 --- a/pages/prompt/robots.wxml +++ b/pages/prompt/robots.wxml @@ -44,7 +44,8 @@ #{{item.id}} - 状态:{{item.status}} + 状态:{{item.statusText}} + 状态:{{item.status}} {{item.description}} diff --git a/pages/prompt/tasks.js b/pages/prompt/tasks.js index 503d4ac..5bef54b 100644 --- a/pages/prompt/tasks.js +++ b/pages/prompt/tasks.js @@ -1,17 +1,26 @@ -const { request, downloadFile, buildResultView } = require('../../utils/request'); +const { request, downloadFile, buildResultView, normalizeResponse } = require('../../utils/request'); const RESULT_PREVIEW_LIMIT = 240; +const TASK_STATUS_TEXT = { + 0: '待开始', + 1: '进行中', + 2: '已完成', + 3: '已暂停', + 4: '已取消' +}; function safeParseResult(raw) { - if (raw === null || raw === undefined) return null; - if (typeof raw === 'string') { + const normalized = normalizeResponse(raw); + const payload = normalized.payload; + if (payload === null || payload === undefined) return null; + if (typeof payload === 'string') { try { - return JSON.parse(raw); + return JSON.parse(payload); } catch (e) { return null; } } - return raw; + return payload; } function pickList(obj) { @@ -41,14 +50,21 @@ function buildTaskCards(parsed) { const list = toArray(parsed).filter(isTaskLike).slice(0, 6); return list.map(item => { const title = item.title || item.name || item.subject || item.task_name || ''; - const content = item.content || item.description || item.desc || item.detail || ''; + const description = item.description || item.implement_path || item.implement_rules || item.initial_prompt || item.content || item.desc || item.detail || ''; + const robot = item.robot || {}; + const tags = Array.isArray(item.tags) ? item.tags.join('、') : ''; + const statusText = TASK_STATUS_TEXT[item.status] || ''; return { id: item.id || item.task_id || item.taskId || '', title: title || (item.id || item.task_id ? `任务 ${item.id || item.task_id}` : '任务'), status: item.status, + statusText, priority: item.priority, + progress: item.progress, robotId: item.robot_id || item.robotId, - contentPreview: content ? String(content).slice(0, 80) : '' + robotName: robot.name || '', + tags, + contentPreview: description ? String(description).slice(0, 80) : '' }; }); } diff --git a/pages/prompt/tasks.wxml b/pages/prompt/tasks.wxml index db69a6c..c7d3784 100644 --- a/pages/prompt/tasks.wxml +++ b/pages/prompt/tasks.wxml @@ -73,9 +73,13 @@ #{{item.id}} - 状态:{{item.status}} + 状态:{{item.statusText}} + 状态:{{item.status}} 优先级:{{item.priority}} - 机器人:{{item.robotId}} + 进度:{{item.progress}}% + 机器人:{{item.robotName}} + 机器人:{{item.robotId}} + 标签:{{item.tags}} {{item.contentPreview}} diff --git a/pages/prompt/templates.js b/pages/prompt/templates.js index 8c52510..dd355b0 100644 --- a/pages/prompt/templates.js +++ b/pages/prompt/templates.js @@ -1,17 +1,23 @@ -const { request, buildResultView } = require('../../utils/request'); +const { request, buildResultView, normalizeResponse } = require('../../utils/request'); const RESULT_PREVIEW_LIMIT = 240; +const TEMPLATE_STATUS_TEXT = { + 0: '禁用', + 1: '启用' +}; function safeParseResult(raw) { - if (raw === null || raw === undefined) return null; - if (typeof raw === 'string') { + const normalized = normalizeResponse(raw); + const payload = normalized.payload; + if (payload === null || payload === undefined) return null; + if (typeof payload === 'string') { try { - return JSON.parse(raw); + return JSON.parse(payload); } catch (e) { return null; } } - return raw; + return payload; } function pickList(obj) { @@ -42,10 +48,14 @@ function buildTemplateCards(parsed) { return list.map(item => { const name = item.name || item.title || item.template_name || ''; const content = item.content || item.body || item.desc || item.description || ''; + const statusText = TEMPLATE_STATUS_TEXT[item.status] || ''; return { id: item.id || item.template_id || item.templateId || '', name: name || (item.id || item.template_id ? `模板 ${item.id || item.template_id}` : '模板'), category: item.category || item.group || '', + usageCount: item.usage_count !== undefined && item.usage_count !== null ? item.usage_count : '', + status: item.status, + statusText, contentPreview: content ? String(content).slice(0, 80) : '' }; }); diff --git a/pages/prompt/templates.wxml b/pages/prompt/templates.wxml index 2c0b9ea..3646f83 100644 --- a/pages/prompt/templates.wxml +++ b/pages/prompt/templates.wxml @@ -41,6 +41,9 @@ 分类:{{item.category}} + 使用次数:{{item.usageCount}} + 状态:{{item.statusText}} + 状态:{{item.status}} {{item.contentPreview}} diff --git a/utils/request.js b/utils/request.js index f036734..9a29108 100644 --- a/utils/request.js +++ b/utils/request.js @@ -85,51 +85,122 @@ function downloadFile(options) { }); } +function normalizeResponse(raw) { + if (raw && typeof raw === 'object' && !Array.isArray(raw)) { + const hasData = Object.prototype.hasOwnProperty.call(raw, 'data'); + const hasCode = typeof raw.code === 'number'; + const hasSuccess = typeof raw.success === 'boolean'; + const hasMessage = typeof raw.message === 'string'; + if (hasData && (hasCode || hasSuccess || hasMessage)) { + return { + payload: raw.data, + meta: { + code: raw.code, + success: raw.success, + message: raw.message + } + }; + } + } + return { payload: raw, meta: null }; +} + +function pickArray(obj) { + if (!obj || typeof obj !== 'object') return null; + const keys = ['list', 'items', 'records', 'rows', 'data', 'result']; + for (let i = 0; i < keys.length; i += 1) { + const value = obj[keys[i]]; + if (Array.isArray(value)) return value; + } + return null; +} + +function buildListCards(list, limit) { + return list.slice(0, limit).map((item, index) => { + if (item && typeof item === 'object') { + const keys = Object.keys(item); + const titleKey = keys.find(k => /name|title|id|task_id|book_id|book_name/i.test(k)) || keys[0] || `item_${index + 1}`; + const titleValue = item[titleKey] !== undefined && item[titleKey] !== null ? item[titleKey] : titleKey; + return { label: String(titleValue), value: `#${index + 1}` }; + } + return { label: `item_${index + 1}`, value: String(item) }; + }); +} + function buildResultView(raw) { const result = { text: '', cards: [] }; if (raw === null || raw === undefined) return result; - if (typeof raw === 'string') { - result.text = raw; + const normalized = normalizeResponse(raw); + const payload = normalized.payload; + + if (payload === undefined && normalized.meta && normalized.meta.message) { + result.text = normalized.meta.message; + } else if (typeof payload === 'string') { + result.text = payload; } else { try { - result.text = JSON.stringify(raw, null, 2); + result.text = JSON.stringify(payload, null, 2); } catch (e) { - result.text = String(raw); + result.text = String(payload); } } - let parsed = raw; - if (typeof raw === 'string') { + let parsed = payload; + if (typeof payload === 'string') { try { - parsed = JSON.parse(raw); + parsed = JSON.parse(payload); } catch (e) { parsed = null; } } if (parsed && typeof parsed === 'object') { + const metaCards = []; + if (normalized.meta) { + if (typeof normalized.meta.code === 'number') { + metaCards.push({ label: 'code', value: String(normalized.meta.code) }); + } + if (typeof normalized.meta.success === 'boolean') { + metaCards.push({ label: 'success', value: String(normalized.meta.success) }); + } + if (normalized.meta.message) { + metaCards.push({ label: 'message', value: String(normalized.meta.message) }); + } + } + if (Array.isArray(parsed)) { - result.cards = parsed.slice(0, 6).map((item, index) => { - if (item && typeof item === 'object') { - const keys = Object.keys(item); - const titleKey = keys.find(k => /name|title|id/i.test(k)) || keys[0] || `item_${index + 1}`; - const titleValue = item[titleKey] !== undefined && item[titleKey] !== null ? item[titleKey] : titleKey; - return { label: String(titleValue), value: `#${index + 1}` }; - } - return { label: `item_${index + 1}`, value: String(item) }; - }); + result.cards = metaCards.concat(buildListCards(parsed, 6)); + return result; + } + + const list = pickArray(parsed); + if (list) { + const headerCards = []; + if (parsed.total !== undefined && parsed.total !== null) { + headerCards.push({ label: 'total', value: String(parsed.total) }); + } + if (parsed.page !== undefined && parsed.page !== null) { + headerCards.push({ label: 'page', value: String(parsed.page) }); + } + if (parsed.page_size !== undefined && parsed.page_size !== null) { + headerCards.push({ label: 'page_size', value: String(parsed.page_size) }); + } + if (parsed.pageSize !== undefined && parsed.pageSize !== null) { + headerCards.push({ label: 'pageSize', value: String(parsed.pageSize) }); + } + result.cards = metaCards.concat(headerCards, buildListCards(list, 6)); return result; } const keys = Object.keys(parsed); - result.cards = keys.slice(0, 8).map(key => ({ + result.cards = metaCards.concat(keys.slice(0, 8).map(key => ({ label: key, value: typeof parsed[key] === 'object' ? '对象' : String(parsed[key]) - })); + }))); } return result; } -module.exports = { request, uploadFile, downloadFile, buildUrl, buildResultView }; +module.exports = { request, uploadFile, downloadFile, buildUrl, buildResultView, normalizeResponse };