feat: 会议ID应用赋值 + 会议表单/详情优化 + admin工作台统计与用户管理

- meetingId 由 DB 自增改为应用赋值 10 位数字 (yyMMdd + 4 位序列, Redis 按日期计数)
- 会议开始时间不能晚于结束时间校验; 参会人表单身份证附件/角色单独一行
- 会议详情左右列比例 7:3 -> 8:2 (材料审核列收窄)
- admin/workbench 用户总数/角色类型数/各角色分布统计修复 (改用 listByRole 按 role_type 过滤)
- 新增 admin 用户管理接口 + 门户页脚 + H5 签到/上传优化
This commit is contained in:
郭庆泰
2026-08-25 23:33:14 +08:00
parent 591a43fe61
commit ea2024d083
66 changed files with 1454 additions and 1228 deletions
+11 -14
View File
@@ -208,14 +208,6 @@ const registerTypes = [
{ value: 'sponsor', name: '项目支持单位', desc: '注册后默认为管理员角色, 可建监察员子账号' }
]
const userTypes = [
{ value: 'admin', name: '系统管理员', desc: '系统配置、用户管理、权限控制' },
{ value: 'manager', name: '项目经理', desc: '项目管理、方案审核、过程监督' },
{ value: 'doctor', name: '评审专家', desc: '项目评审、评分反馈、查看任务' },
{ value: 'executor', name: '执行单位', desc: '会议组织、人员安排、劳务结算' },
{ value: 'sponsor', name: '支持单位', desc: '支持函管理、人员管理、合作记录' },
]
async function loadCaptcha() {
await runCaptchaOnce(async () => {
try {
@@ -245,7 +237,8 @@ async function onSubmit() {
const res = await login({ username: form.username, password: form.password, code: form.code || '', uuid: form.uuid || '' })
await afterLogin(res.token, form.username)
} catch (e) {
// 错误提示已由 utils/request.js 拦截器统一弹 (ElMessage.error), 这里只刷新验证码
// 登录是 POST, 拦截器对写操作不自动 toast, 需在此显式弹 (否则锁定/密码错等 msg 看不到)
ElMessage.error(e?.msg || e?.message || '登录失败')
loadCaptcha()
} finally {
loading.value = false
@@ -283,7 +276,7 @@ async function afterLogin(token, displayName) {
ElMessage.error('获取用户信息失败, 请重新登录')
return router.replace({ name: 'login' })
}
ElMessage.success(`欢迎,${displayName}${userTypes.find(u => u.value === role)?.name || role}`)
ElMessage.success(`欢迎,${displayName}`)
// 角色不在角色首页映射里 → 拒绝
if (!roleHome[role]) return router.replace({ name: 'login' })
// 所有角色统一跳门户首页 '/' (业务方 2026-08-22 要求, 各自角色菜单从导航栏进入)
@@ -331,7 +324,8 @@ async function sendLoginSmsCode() {
}
}, 1000)
} catch (e) {
// request.js 已弹错误, 这里只重置 uuid
// 短信发送是 POST, 拦截器不自动 toast, 显式弹
ElMessage.error(e?.msg || e?.message || '验证码发送失败')
smsForm.uuid = ''
}
})
@@ -347,7 +341,8 @@ async function onSmsLoginSubmit() {
// 短信登录后无 username, 用 phone 作为显示名; fallbackRole 留空, 让 /getInfo 决定
await afterLogin(res.token, smsForm.phone)
} catch (e) {
// request.js 已弹错误
// 短信登录是 POST, 拦截器不自动 toast, 显式弹
ElMessage.error(e?.msg || e?.message || '登录失败')
}
})
}
@@ -437,7 +432,8 @@ async function sendForgotSms() {
}
}, 1000)
} catch (e) {
// request.js 拦截器已弹 ElMessage.error, 这里只重置
// 忘记密码短信是 POST, 拦截器不自动 toast, 显式弹
ElMessage.error(e?.msg || e?.message || '验证码发送失败')
forgotSmsUuid = ''
}
})
@@ -468,7 +464,8 @@ async function onResetSubmit() {
ElMessage.success('密码重置成功, 请用新密码登录')
closeForgot()
} catch (e) {
// request.js 已弹错误
// 重置密码是 POST, 拦截器不自动 toast, 显式弹
ElMessage.error(e?.msg || e?.message || '重置失败')
} finally {
forgotLoading.value = false
}