feat(web): 统一平台管理员判定与 AI 工作台申请预览动作接入

- authUser 抽出 resolveAuthUserAdminFlag,统一 isAdmin 解析(含 superadmin、role_codes、中英文角色名),accessControl 复用同一逻辑
- 登录态、应用外壳路由、系统状态接入统一管理员判定,LoginView 与相关 composable 配套调整
- AI 工作台申请提交改为调用新的 /application-preview-action 接口,草稿保存仍走 orchestrator;预审模型补充重叠冲突提示与阻断判断
- 同步更新 accessControl/api-request/ai 预览动作等前端测试
This commit is contained in:
caoxiaozhu
2026-06-20 14:42:04 +08:00
parent 729d833edb
commit 96c2e1099a
21 changed files with 1364 additions and 331 deletions

View File

@@ -4,7 +4,9 @@ import test from 'node:test'
import {
buildAiApplicationPrecheck,
buildAiApplicationPrecheckMessage,
buildAiApplicationPrecheckThinkingEvents
buildAiApplicationPrecheckThinkingEvents,
buildAiApplicationSubmitConflictMessage,
isAiApplicationPrecheckBlocking
} from '../src/utils/aiApplicationPrecheckModel.js'
const preview = {
@@ -71,6 +73,42 @@ test('application precheck blocks application generation when existing applicati
assert.doesNotMatch(message, /出差申请表草稿已生成/)
})
test('application submit precheck blocks submit and keeps application detail action link', () => {
const precheck = buildAiApplicationPrecheck(preview, {
currentUser: { name: '曹笑竹', departmentName: '技术部' },
claimsPayload: {
items: [
{
claim_no: 'AP-OVERLAP',
document_type: 'expense_application',
expense_type: 'travel_application',
employee_name: '曹笑竹',
status: 'submitted',
risk_flags_json: [
{
source: 'application_detail',
application_detail: {
business_time: '2026-02-20 至 2026-02-23',
reason: '辅助国网仿生产服务器部署',
location: '上海'
}
}
]
}
]
}
})
assert.equal(isAiApplicationPrecheckBlocking(precheck), true)
const message = buildAiApplicationSubmitConflictMessage(preview, precheck)
assert.match(message, /### 发现相同日期已有申请单/)
assert.match(message, /当前不能继续提交/)
assert.match(message, /请先核对申请时间是否填写正确/)
assert.match(message, /\[查看\]\(#ai-open-application-detail:AP-OVERLAP\)/)
assert.doesNotMatch(message, /生成新的出差申请表/)
})
test('application precheck emits thinking events for overlap, budget, and form generation', () => {
const precheck = buildAiApplicationPrecheck(preview, {
currentUser: { name: '曹笑竹' },