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
+13 -3
View File
@@ -54,6 +54,7 @@ import { uploadToOss } from '@/utils/oss'
const props = defineProps({
modelValue: { type: String, default: '' },
name: { type: String, default: '' }, // 原文件名 (v-model:name 回传, 用于显示而非 OSS key)
dir: { type: String, default: 'ry8080/file/' },
placeholder: { type: String, default: '点击上传文件' },
hint: { type: String, default: '' },
@@ -64,16 +65,23 @@ const props = defineProps({
showPreview: { type: Boolean, default: true } // 右侧预览框 (图片/PDF/其他)
})
const emit = defineEmits(['update:modelValue'])
const emit = defineEmits(['update:modelValue', 'update:name'])
const fileInput = ref(null)
const uploading = ref(false)
const fileName = computed(() => {
// 优先用调用方回传的原文件名 (v-model:name); 没有则从 OSS key 还原原名
if (props.name) return props.name
if (!props.modelValue) return ''
// 取 URL 最后一段, 去 query 参数
// 取 URL 最后一段, 去 query 参数; 上传时已对路径做了 encodeURIComponent, 这里先还原
const url = props.modelValue.split('?')[0]
return url.substring(url.lastIndexOf('/') + 1)
let last = url.substring(url.lastIndexOf('/') + 1)
try { last = decodeURIComponent(last) } catch (e) { /* 已解码/旧 key, 原样用 */ }
// 新 key 格式: 原名_时间戳_随机串.扩展名 → 还原 原名.扩展名; 旧 key (无原名) 原样返回
const m = last.match(/^(.+)_\d{13}_[a-z0-9]{6}(\.[^.]+)?$/)
if (m) return m[1] + (m[2] || '')
return last
})
const ext = computed(() => {
const n = fileName.value
@@ -127,6 +135,7 @@ async function onFileChange(e) {
try {
const url = await uploadToOss(file, props.dir)
emit('update:modelValue', url)
emit('update:name', file.name)
ElMessage.success('上传成功')
} catch (err) {
ElMessage.error(err.message || '上传失败')
@@ -137,6 +146,7 @@ async function onFileChange(e) {
function onRemove() {
emit('update:modelValue', '')
emit('update:name', '')
}
</script>