feat: 新增数字员工管理页面与工作台首页重构
后端优化 agent 资产种子初始化和常量配置,前端新增数字员工 视图和调度对话框组件,重构个人工作台首页布局和洞察面板, 完善审计页面数字员工详情和运行时模型,优化侧边栏导航和图 标配置,新增工作台摘要和工作台数据模块,补充单元测试。
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
const DIGITAL_EMPLOYEE_AGENT = 'hermes'
|
||||
export const DIGITAL_EMPLOYEE_SKILL_CATEGORY_OPTIONS = ['积累', '升级', '整理', '评估']
|
||||
|
||||
const TASK_TYPE_LABELS = {
|
||||
daily_risk_scan: '每日风险巡检',
|
||||
@@ -7,11 +8,25 @@ const TASK_TYPE_LABELS = {
|
||||
weekly_expense_report: '周度费用洞察',
|
||||
rule_review_digest: '规则待审摘要',
|
||||
knowledge_index_sync: '知识库归集',
|
||||
llm_wiki_rule_formation: '知识库归集',
|
||||
x_financial_callback: '任务回调上报'
|
||||
}
|
||||
|
||||
const TASK_TYPE_SKILL_CATEGORIES = {
|
||||
daily_risk_scan: '评估',
|
||||
global_risk_scan: '评估',
|
||||
weekly_ar_summary: '整理',
|
||||
weekly_expense_report: '整理',
|
||||
rule_review_digest: '升级',
|
||||
knowledge_index_sync: '积累',
|
||||
llm_wiki_rule_formation: '积累',
|
||||
x_financial_callback: '升级'
|
||||
}
|
||||
|
||||
const CONTENT_LABELS = {
|
||||
task_type: '技能类型',
|
||||
task_type: '任务类型',
|
||||
skill_category: '技能类型',
|
||||
skill_category_options: '技能类型范围',
|
||||
schedule: '执行计划',
|
||||
cron: '调度表达式',
|
||||
folder: '归集范围',
|
||||
@@ -45,6 +60,14 @@ export function sanitizeDigitalEmployeeText(value, fallback = '') {
|
||||
return text || fallback
|
||||
}
|
||||
|
||||
export function sanitizeDigitalEmployeeSource(value, fallback = '') {
|
||||
const text = normalizeDigitalEmployeeText(value)
|
||||
.replace(/hermes/gi, '数字员工')
|
||||
.replace(/赫尔墨斯/g, '数字员工')
|
||||
.trim()
|
||||
return text || fallback
|
||||
}
|
||||
|
||||
export function sanitizeDigitalEmployeeName(value, fallback = '数字员工技能') {
|
||||
const text = sanitizeDigitalEmployeeText(value, fallback)
|
||||
.replace(/^数字员工[\s·::-]*/i, '')
|
||||
@@ -80,6 +103,22 @@ export function resolveDigitalEmployeeTaskType(source = {}, content = {}) {
|
||||
return raw.replace(/[-.]/g, '_')
|
||||
}
|
||||
|
||||
export function resolveDigitalEmployeeSkillCategory(source = {}, content = {}) {
|
||||
const config = source.config_json || source.configJson || {}
|
||||
const taskType = resolveDigitalEmployeeTaskType(source, content)
|
||||
const explicitCategory =
|
||||
normalizeDigitalEmployeeText(config.skill_category) ||
|
||||
normalizeDigitalEmployeeText(config.skillCategory) ||
|
||||
normalizeDigitalEmployeeText(content.skill_category) ||
|
||||
normalizeDigitalEmployeeText(content.skillCategory)
|
||||
|
||||
if (DIGITAL_EMPLOYEE_SKILL_CATEGORY_OPTIONS.includes(explicitCategory)) {
|
||||
return explicitCategory
|
||||
}
|
||||
|
||||
return TASK_TYPE_SKILL_CATEGORIES[taskType] || '整理'
|
||||
}
|
||||
|
||||
export function isDigitalEmployeeAsset(source = {}) {
|
||||
const config = source.config_json || source.configJson || {}
|
||||
const haystack = [
|
||||
@@ -145,10 +184,10 @@ export function formatDigitalEmployeeCron(value) {
|
||||
export function resolveDigitalEmployeeSchedule(source = {}, content = {}) {
|
||||
const config = source.config_json || source.configJson || {}
|
||||
const raw =
|
||||
normalizeDigitalEmployeeText(content.schedule) ||
|
||||
normalizeDigitalEmployeeText(config.cron) ||
|
||||
normalizeDigitalEmployeeText(config.schedule) ||
|
||||
normalizeDigitalEmployeeText(config.cron_expression)
|
||||
normalizeDigitalEmployeeText(config.cron_expression) ||
|
||||
normalizeDigitalEmployeeText(content.schedule)
|
||||
return {
|
||||
value: raw,
|
||||
label: formatDigitalEmployeeCron(raw)
|
||||
@@ -205,9 +244,85 @@ export function buildDigitalEmployeeContentPreview(content = {}) {
|
||||
return sanitizeDigitalEmployeeText(JSON.stringify(visiblePayload, null, 2))
|
||||
}
|
||||
|
||||
function resolveDigitalEmployeeMarkdownFromContent(content = {}, config = {}) {
|
||||
const candidates = [
|
||||
content.skill_markdown,
|
||||
content.skills_markdown,
|
||||
content.source_markdown,
|
||||
content.markdown,
|
||||
content.skill_source,
|
||||
config.skill_markdown,
|
||||
config.skills_markdown,
|
||||
config.source_markdown,
|
||||
config.skill_source
|
||||
]
|
||||
return candidates.find((item) => normalizeDigitalEmployeeText(item)) || ''
|
||||
}
|
||||
|
||||
function buildDefaultDigitalEmployeeSource(source = {}, listMeta = {}, schedule = {}) {
|
||||
const name = listMeta.name || '数字员工技能'
|
||||
const description =
|
||||
listMeta.summary ||
|
||||
sanitizeDigitalEmployeeText(source.description, '该技能用于后台自动执行指定任务。')
|
||||
|
||||
return [
|
||||
'---',
|
||||
`name: ${listMeta.code || 'digital.skill'}`,
|
||||
`description: ${description}`,
|
||||
'---',
|
||||
'',
|
||||
`# ${name}`,
|
||||
'',
|
||||
'## 功能说明',
|
||||
'',
|
||||
description,
|
||||
'',
|
||||
'## 执行方式',
|
||||
'',
|
||||
`- 技能类型:${listMeta.skillCategory || '整理'}`,
|
||||
`- 可选类型:${DIGITAL_EMPLOYEE_SKILL_CATEGORY_OPTIONS.join('、')}`,
|
||||
`- 执行计划:${schedule.label || '手动触发'}`,
|
||||
`- 触发方式:${listMeta.executionMode || '手动触发'}`,
|
||||
'',
|
||||
'## 操作要求',
|
||||
'',
|
||||
'- 按任务参数读取业务数据。',
|
||||
'- 运行完成后写回业务结果或运行日志。'
|
||||
].join('\n')
|
||||
}
|
||||
|
||||
export function buildDigitalEmployeeSourceMarkdown(source = {}, content = {}, listMeta = {}) {
|
||||
const config = source.config_json || source.configJson || {}
|
||||
if (
|
||||
normalizeDigitalEmployeeText(source.current_version_content_type) === 'markdown' &&
|
||||
typeof source.current_version_content === 'string'
|
||||
) {
|
||||
return sanitizeDigitalEmployeeSource(source.current_version_content)
|
||||
}
|
||||
|
||||
const schedule = resolveDigitalEmployeeSchedule(source, content)
|
||||
const sourceMarkdown = resolveDigitalEmployeeMarkdownFromContent(content, config)
|
||||
return sanitizeDigitalEmployeeSource(
|
||||
sourceMarkdown,
|
||||
buildDefaultDigitalEmployeeSource(source, listMeta, schedule)
|
||||
)
|
||||
}
|
||||
|
||||
function buildDigitalEmployeeBasicRows(source = {}, listMeta = {}, schedule = {}) {
|
||||
return [
|
||||
{ label: '技能编号', value: listMeta.code },
|
||||
{ label: '技能类型', value: listMeta.skillCategory },
|
||||
{ label: '维护人', value: listMeta.owner },
|
||||
{ label: '执行计划', value: schedule.label },
|
||||
{ label: '当前版本', value: source.working_version || source.current_version || '-' },
|
||||
{ label: '最近更新', value: source.updated_at || '-' }
|
||||
]
|
||||
}
|
||||
|
||||
export function buildDigitalEmployeeListMeta(source = {}) {
|
||||
const content = parseDigitalEmployeeContent(source.current_version_content)
|
||||
const taskType = resolveDigitalEmployeeTaskType(source, content)
|
||||
const skillCategory = resolveDigitalEmployeeSkillCategory(source, content)
|
||||
const schedule = resolveDigitalEmployeeSchedule(source, content)
|
||||
const enabled = resolveDigitalEmployeeEnabled(source)
|
||||
const fallbackName = TASK_TYPE_LABELS[taskType] || '数字员工技能'
|
||||
@@ -217,6 +332,8 @@ export function buildDigitalEmployeeListMeta(source = {}) {
|
||||
code: resolveDigitalEmployeeDisplayCode(source, content),
|
||||
summary: sanitizeDigitalEmployeeText(source.description, '面向后台自动执行的数字员工技能。'),
|
||||
category: '数字员工',
|
||||
skillCategory,
|
||||
skillCategoryOptions: DIGITAL_EMPLOYEE_SKILL_CATEGORY_OPTIONS,
|
||||
owner: sanitizeDigitalEmployeeText(source.owner, '平台运营'),
|
||||
reviewer: sanitizeDigitalEmployeeText(source.reviewer, '系统'),
|
||||
scope: schedule.label,
|
||||
@@ -237,6 +354,7 @@ export function buildDigitalEmployeeDetailMeta(source = {}) {
|
||||
})
|
||||
const schedule = resolveDigitalEmployeeSchedule(source, content)
|
||||
const contentRows = buildDigitalEmployeeContentRows(content)
|
||||
const sourceMarkdown = buildDigitalEmployeeSourceMarkdown(source, content, listMeta)
|
||||
|
||||
return {
|
||||
...listMeta,
|
||||
@@ -245,13 +363,16 @@ export function buildDigitalEmployeeDetailMeta(source = {}) {
|
||||
source.description,
|
||||
'该技能由后台数字员工按计划执行,并把结果沉淀到对应业务资产或运行日志中。'
|
||||
),
|
||||
sourceMarkdown,
|
||||
basicRows: buildDigitalEmployeeBasicRows(source, listMeta, schedule),
|
||||
contentRows,
|
||||
contentPreview: buildDigitalEmployeeContentPreview(content),
|
||||
scheduleRows: [
|
||||
{ label: '执行计划', value: schedule.label },
|
||||
{ label: '调度表达式', value: schedule.value || '手动触发' },
|
||||
{ label: '启动状态', value: listMeta.enabledLabel, tone: listMeta.enabledTone },
|
||||
{ label: '执行方式', value: listMeta.executionMode }
|
||||
{ label: '执行方式', value: listMeta.executionMode },
|
||||
{ label: '技能类型', value: listMeta.skillCategory }
|
||||
],
|
||||
overviewRows: [
|
||||
{ label: '能力编号', value: listMeta.code },
|
||||
|
||||
Reference in New Issue
Block a user