feat: redesign leadership operations dashboard

This commit is contained in:
inman committed 2026-09-01 19:52:56 +08:00
1 parent 08725b2de9
commit 823d1cb630
7 files changed
+1320 -366

No files matched your search

+52 -16
View File
@@ -1836,17 +1836,50 @@ function operationsDashboardOutcomeKind(statusValue: unknown): OperationsDashboa
function operationsDashboardOutcomeLabel(kind: OperationsDashboardOutcomeKind): string {
if (kind === 'completed') return '已完成';
if (kind === 'attention') return '待处理';
if (kind === 'failed') return '异常';
if (kind === 'attention') return '待跟进';
if (kind === 'failed') return '未完成';
if (kind === 'cancelled') return '已取消';
return '处理中';
return '进行中';
}
function operationsDashboardBusiness(routeId: unknown): { id: string | null; label: string } {
const route = businessRouteById(routeId);
return route
? { id: route.routeId, label: route.directive }
: { id: null, label: '未识别业务' };
: { id: null, label: '其他任务' };
}
function operationsDashboardLeadershipResultText(
kind: OperationsDashboardOutcomeKind,
value: unknown
): string {
const result = text(value).trim();
if (!result) {
if (kind === 'completed') return '工作已经完成。';
if (kind === 'attention') return '正在等待补充信息或确认。';
if (kind === 'failed') return '本次工作未完成,需要检查后重新处理。';
if (kind === 'cancelled') return '这项工作已取消。';
return '正在处理中。';
}
const containsTechnicalLanguage = /(?:\b(?:agent|api|dom|frame|iframe|json|native|operation|parser|payload|plugin|projection|requery|schema|stack|trace|write)\b|[a-z][a-z0-9]*(?:_[a-z0-9]+)+|data\.[a-z]|插件|解析服务|技术上下文|错误码|接口|ERP)/i.test(result);
if (!containsTechnicalLanguage) return result;
if (/不确定|核验|请勿重复/.test(result)) return '当前结果需要人工确认,请勿重复提交。';
if (/未找到|不存在|不匹配|mismatch/i.test(result)) return '未完成:没有找到符合指令条件的业务记录。';
if (/登录|连接|网络|超时/i.test(result)) return '未完成:业务系统暂时无法完成处理,请稍后再试。';
if (/补充|缺少|必填|日期|年份/.test(result)) return '待跟进:需要补充完整的业务信息。';
if (/不支持|超出.*范围/.test(result)) return '未完成:这项要求暂不在当前业务处理范围内。';
if (kind === 'completed') return '工作已经完成,结果已记录。';
if (kind === 'attention') return '正在等待补充信息或确认。';
if (kind === 'cancelled') return '这项工作已取消。';
return '未完成:当前业务条件未满足,需要检查后重新处理。';
}
function operationsDashboardLeadershipInstructionText(value: unknown): string {
const instruction = text(value).trim();
if (!instruction) return '未记录输入内容';
const looksLikeTechnicalPayload = /^[\[{]/.test(instruction)
|| /(?:"(?:action|operation|payload|schema|submit_mode)"\s*:|[a-z][a-z0-9]*(?:_[a-z0-9]+){2,}|data\.[a-z])/i.test(instruction);
return looksLikeTechnicalPayload ? '该历史任务没有可展示的业务指令。' : instruction;
}
function operationsDashboardSuccessText(receipt: PublicTaskSuccessReceipt): string {
@@ -1876,11 +1909,11 @@ function operationsDashboardOutcome(row: Record<string, unknown>): {
resultText = operationsDashboardSuccessText(receipt);
recordedAt = receipt.recorded_at;
} else if (status === 'dry_run') {
resultText = '业务方案已完成,未写入 ERP。';
resultText = '业务方案已完成,尚未正式提交。';
}
} else if (kind === 'failed') {
const error = publicErrorSummary(row, null);
resultText = error?.message ? `本次指令未完成:${error.message}` : '本次指令未完成。';
resultText = error?.message ? `本次工作未完成:${error.message}` : '本次工作未完成。';
if (error) recordedAt = error.recorded_at;
} else if (kind === 'attention') {
if (status === 'awaiting_user_input') {
@@ -1890,19 +1923,20 @@ function operationsDashboardOutcome(row: Record<string, unknown>): {
} else if (status === 'awaiting_confirmation') {
resultText = '业务方案已生成,等待提交确认。';
} else {
resultText = '业务结果待核验,请勿重复提交。';
resultText = '当前结果需要人工确认,请勿重复提交。';
}
} else if (kind === 'cancelled') {
resultText = '指令已取消,未形成业务结果。';
resultText = '这项工作已取消。';
} else {
resultText = '正在处理,尚未形成业务结果。';
}
if (!resultText) {
if (kind === 'completed') resultText = '业务处理已完成,未记录可展示的结果摘要。';
if (kind === 'completed') resultText = '工作已经完成。';
else if (kind === 'attention') resultText = '等待业务人员补充或确认。';
else if (kind === 'cancelled') resultText = '任务已取消。';
else if (kind === 'cancelled') resultText = '这项工作已取消。';
else resultText = '正在处理,尚未形成业务结果。';
}
resultText = operationsDashboardLeadershipResultText(kind, resultText);
return {
kind,
label: operationsDashboardOutcomeLabel(kind),
@@ -1921,10 +1955,10 @@ function operationsDashboardTaskProjection(
config: AppConfig,
row: Record<string, unknown>
): OperationsDashboardTaskProjection {
const instruction = decryptText(
const instruction = operationsDashboardLeadershipInstructionText(decryptText(
config,
row.original_text_ciphertext as string | null | undefined
).trim();
));
const outcome = operationsDashboardOutcome(row);
const business = operationsDashboardBusiness(row.business_route_id);
const instructionPreview = instruction.replace(/\s+/g, ' ').trim();
@@ -4592,7 +4626,7 @@ export class TaskService {
const pool = getPool(this.config);
const businessOptions = [
...BUSINESS_ROUTES.map((route) => ({ key: route.routeId, label: route.directive })),
{ key: 'unclassified', label: '未识别业务' }
{ key: 'unclassified', label: '其他任务' }
];
const actorQuery = () => pool.query(
`SELECT id, username, role, is_active
@@ -4655,7 +4689,9 @@ export class TaskService {
const values = searchValuesByTask.get(key) || [];
values.push(
text(row.actor_username),
decryptText(this.config, row.content_ciphertext as string | null | undefined)
operationsDashboardLeadershipInstructionText(
decryptText(this.config, row.content_ciphertext as string | null | undefined)
)
);
searchValuesByTask.set(key, values);
}
@@ -4836,7 +4872,7 @@ export class TaskService {
));
const businesses = (businessResult.rows as Record<string, unknown>[]).map((row) => {
const key = text(row.dimension_key);
return breakdown(row, key === 'unclassified' ? '未识别业务' : operationsDashboardBusiness(key).label);
return breakdown(row, key === 'unclassified' ? '其他任务' : operationsDashboardBusiness(key).label);
});
const tasks = (listResult.rows as Record<string, unknown>[]).map((row) => (
operationsDashboardTaskProjection(this.config, row).task
@@ -4891,7 +4927,7 @@ export class TaskService {
.filter((message) => message.source !== 'reparse')
.map((message) => ({
turn_no: message.turn_no,
content: message.content,
content: operationsDashboardLeadershipInstructionText(message.content),
actor: message.actor,
created_at: message.created_at
} satisfies PublicOperationsDashboardInstruction));