feat: 新增预算后端服务与差旅风险规则库

后端新增预算模型、端点和服务模块,支持预算 CRUD 和余额
查询,清理旧生成规则文件并替换为按严重等级分类的差旅风
险规则库,优化认证权限和报销单访问策略,新增财务规则目
录和演示数据构建脚本,前端预算中心增加对话框交互,完善
审计页面运行时模型和元数据展示,补充单元测试。
This commit is contained in:
caoxiaozhu
2026-05-26 17:29:35 +08:00
parent e1e515ecae
commit e7bef0883d
85 changed files with 6443 additions and 1497 deletions

View File

@@ -107,7 +107,7 @@ function buildAnonymousUser() {
}
}
function buildLegacyAdminUser(username = '') {
function buildLegacyAdminUser(username = '') {
const normalized = String(username || '').trim()
const name = normalized || DEFAULT_USER_NAME
@@ -129,10 +129,25 @@ function buildLegacyAdminUser(username = '') {
email: '',
avatar: name.slice(0, 1).toUpperCase(),
isAdmin: true
}
}
function readStoredUser() {
}
}
function resolvePlatformAdminFlag(payload, roleCodes = []) {
const username = String(payload?.username || payload?.account || '').trim().toLowerCase()
const role = String(payload?.role || '').trim().toLowerCase()
const normalizedRoleCodes = roleCodes.map((item) => String(item || '').trim().toLowerCase()).filter(Boolean)
return (
Boolean(payload?.isAdmin)
|| username === 'admin'
|| role === 'admin'
|| role === '管理员'
|| role === '系统管理员'
|| normalizedRoleCodes.includes('admin')
)
}
function readStoredUser() {
if (typeof window === 'undefined') {
return buildAnonymousUser()
}
@@ -164,9 +179,9 @@ function readStoredUser() {
roleCodes,
email: String(payload.email || ''),
avatar: String(payload.avatar || name.slice(0, 1).toUpperCase()),
isAdmin: Boolean(payload.isAdmin)
}
}
isAdmin: resolvePlatformAdminFlag(payload, roleCodes)
}
}
} catch {
return buildLegacyAdminUser(readStoredUsername())
}
@@ -609,8 +624,14 @@ async function handleLogin(credentials) {
password: credentials.password
})
const user = response?.user || buildAnonymousUser()
loggedIn.value = true
const responseUser = response?.user || buildAnonymousUser()
const responseRoleCodes = Array.isArray(responseUser.roleCodes) ? responseUser.roleCodes.filter(Boolean) : []
const user = {
...responseUser,
roleCodes: responseRoleCodes,
isAdmin: resolvePlatformAdminFlag(responseUser, responseRoleCodes)
}
loggedIn.value = true
persistAuthState(true, user)
currentUser.value = user
touchAuthActivity(true)