feat: 引入 ECharts 统一图表并完善员工画像标签分页

后端优化员工行为画像服务和辅助函数,完善系统设置模型和
配置持久化,前端引入 ECharts 替换所有图表组件实现统一
渲染,新增员工画像标签分页器和数字员工工作记录组件,优
化工作台响应式布局和登录页过渡动画,完善预算中心和数字
员工页面样式细节。
This commit is contained in:
caoxiaozhu
2026-05-28 16:24:59 +08:00
parent 8a4a777be7
commit e384318046
53 changed files with 4698 additions and 2468 deletions

View File

@@ -0,0 +1,107 @@
import {
formatAgentRunElapsed,
formatAgentRunProgress,
resolveAgentRunHeartbeat,
resolveAgentRunStatus
} from '../../utils/agentRunMonitor.js'
const SOURCE_LABELS = {
schedule: '定时任务',
system_event: '系统事件',
user_message: '用户触发'
}
const KNOWLEDGE_JOB_TYPES = new Set([
'knowledge_index_sync',
'llm_wiki_sync',
'finance_policy_knowledge_organize'
])
export function formatWorkRecordDateTime(value) {
if (!value) {
return '未结束'
}
const date = new Date(value)
if (Number.isNaN(date.getTime())) {
return String(value)
}
return date.toLocaleString('zh-CN', { hour12: false })
}
export function formatWorkRecordSummary(summary) {
const text = String(summary || '').trim()
if (!text) {
return '暂无摘要。'
}
if (text.length <= 64) {
return text
}
return `${text.slice(0, 64)}...`
}
export function resolveWorkRecordSourceLabel(source) {
return SOURCE_LABELS[source] || source || '未标记'
}
export function resolveWorkRecordModuleLabel(run) {
const routeJson = run?.route_json || {}
if (KNOWLEDGE_JOB_TYPES.has(routeJson.job_type)) {
return '知识制度整理'
}
if (routeJson.selected_agent) {
return '数字员工'
}
if (routeJson.folder) {
return String(routeJson.folder)
}
return resolveWorkRecordSourceLabel(run?.source)
}
export function resolveWorkRecordTitle(run) {
const routeJson = run?.route_json || {}
if (KNOWLEDGE_JOB_TYPES.has(routeJson.job_type)) {
return `知识制度整理 · ${routeJson.folder || '未指定目录'}`
}
return `数字员工调用 · ${resolveWorkRecordModuleLabel(run)}`
}
export function resolveWorkRecordStatusLabel(run) {
return resolveAgentRunStatus(run).label
}
export function resolveWorkRecordStatusTone(run) {
return resolveAgentRunStatus(run).tone
}
export function resolveWorkRecordStatusNote(run) {
const statusInfo = resolveAgentRunStatus(run)
if (statusInfo.note) {
return statusInfo.note
}
const heartbeat = resolveAgentRunHeartbeat(run)
if (heartbeat.at !== null) {
return `最后心跳 ${formatWorkRecordDateTime(heartbeat.at)}`
}
return '暂无额外状态'
}
export function resolveWorkRecordSummaryMeta(run) {
const statusInfo = resolveAgentRunStatus(run)
const progressText = formatAgentRunProgress(run)
const elapsedLabel = run?.status === 'running' ? '已运行' : '耗时'
const elapsedText = formatAgentRunElapsed(run)
const parts = [`阶段 ${statusInfo.phaseLabel}`]
if (progressText) {
parts.push(progressText)
}
if (elapsedText !== '—') {
parts.push(`${elapsedLabel} ${elapsedText}`)
}
return parts.join(' · ')
}