修复: aichat advance_task渲染显任务名 + 审批防双击 + time.ts销账

- UX-260618-14: advance_task 工具结果/审批卡显任务名替代UUID
  前端 ToolCard 取 r.title fallback r.id + TASK_ID_TOOL_ARG 审批卡 task_id→title 回显 + i18n
  后端 audit resolve_task_label 查 tasks 表(原误查 projects恒报不存在) + 删 tool_display_hint 短路让模板生效
- UX-260618-16: time.ts formatDate .value 已修(CR-24/25闭环),漏销账补登
- UX-260618-17: ProjectDetail handleApprovalMulti 补 submitting try/finally + 模板联动防双击
This commit is contained in:
2026-06-19 00:52:20 +08:00
parent 6d2244c03b
commit 1dc8b12ec4
8 changed files with 94 additions and 19 deletions

View File

@@ -473,9 +473,10 @@ function formatToolResult(tc: AiToolCallInfo): string {
: t('aiTool.updated')
case 'advance_task':
// UX-260618-09: review_rounds>0 显退回累加轮数,=0 回退原文案(首推无噪音)
// UX-260618-14: 后端返 TaskRecord(含 title),优先显 title,无则回退 id(防裸 UUID)
return typeof r.review_rounds === 'number' && r.review_rounds > 0
? t('aiTool.advancedTaskWithRounds', { id: r.id || '', status: r.status || '', n: r.review_rounds })
: t('aiTool.advancedTask', { id: r.id || '', status: r.status || '' })
? t('aiTool.advancedTaskWithRounds', { title: r.title || r.id || '', status: r.status || '', n: r.review_rounds })
: t('aiTool.advancedTask', { title: r.title || r.id || '', status: r.status || '' })
case 'delete_task':
return r.deleted ? t('aiTool.deleted') : t('aiTool.deleteIneffective')
case 'delete_file':
@@ -796,6 +797,16 @@ function projectNameById(id: string): string | undefined {
?? projectStore.deletedProjects.find(p => p.id === id)?.name
}
/**
* 按 id 查任务标题:审批 advance_task/run_workflow 的 task_id 时,把裸 UUID 转标题。
* 复用 project store 已加载的 state.tasks(仅当前项目范围),不新增网络请求。
* state.tasks 非「全量」(按当前项目/筛选加载),查不到时调用方走裸 id fallback——
* 审批卡 task_id 多属当前活动项目,命中率足够,跨项目任务降级显 id 可接受。
*/
function taskNameById(id: string): string | undefined {
return projectStore.tasks.find(t => t.id === id)?.title
}
/** 工具名 → 该工具中代表项目 id 的参数 key(仅项目类工具特化;delete_task 的 id 是任务 id,不在此列) */
const PROJECT_ID_TOOL_ARG: Record<string, 'id' | 'project_id'> = {
delete_project: 'id',
@@ -806,6 +817,15 @@ const PROJECT_ID_TOOL_ARG: Record<string, 'id' | 'project_id'> = {
create_task: 'project_id',
}
/**
* 工具名 → 该工具中代表任务 id 的参数 key(任务类工具特化)。
* advance_task 的任务 id 在 "id" key,run_workflow 在 "task_id" key。
*/
const TASK_ID_TOOL_ARG: Record<string, 'id' | 'task_id'> = {
advance_task: 'id',
run_workflow: 'task_id',
}
/**
* 审批参数值展示(AR-3):对项目类工具的 id/project_id 特化——优先回显项目名,查不到则显示
* 「项目已不存在」提示 + 原 id,避免用户只看到一串裸 id 不知道是什么数据。
@@ -821,6 +841,16 @@ function displayArgValue(arg: { key: string; val: unknown }): string {
return t('aiTool.projectIdNotFound', { id })
}
}
// UX-260618-14:advance_task/run_workflow 的 task_id → 任务标题(store.tasks 查,无则标 id)
const taskArgKey = TASK_ID_TOOL_ARG[props.tc.name]
if (taskArgKey && arg.key === taskArgKey) {
const id = typeof arg.val === 'string' ? arg.val : ''
if (id) {
const name = taskNameById(id)
if (name) return t('aiTool.taskLabel', { name })
return t('aiTool.taskIdNotFound', { id })
}
}
return formatArgValue(arg.val)
}
@@ -889,8 +919,9 @@ function toolResultSummary(tc: AiToolCallInfo): string {
? t('aiTool.updatedTaskField', { id: r.id || '', field: r.field || '' })
: t('aiTool.updated')
case 'advance_task': return typeof r.review_rounds === 'number' && r.review_rounds > 0
? t('aiTool.advancedTaskWithRounds', { id: r.id || '', status: r.status || '', n: r.review_rounds })
: t('aiTool.advancedTask', { id: r.id || '', status: r.status || '' })
// UX-260618-14: 优先显 title(后端返 TaskRecord),无则回退 id,防裸 UUID
? t('aiTool.advancedTaskWithRounds', { title: r.title || r.id || '', status: r.status || '', n: r.review_rounds })
: t('aiTool.advancedTask', { title: r.title || r.id || '', status: r.status || '' })
case 'delete_project':
case 'delete_task': return r.deleted ? t('aiTool.deleted') : t('aiTool.deleteIneffective')
case 'delete_file': return r.permanent