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:
@@ -45,8 +45,14 @@ function getMimeByExt(name) {
|
||||
|
||||
export async function uploadToOss(file, dir) {
|
||||
const sign = await getOssSign(dir)
|
||||
const ext = (file.name || '').split('.').pop() || 'bin'
|
||||
const key = sign.dir + Date.now() + '_' + Math.random().toString(36).slice(2, 8) + '.' + ext
|
||||
// 原文件名进 OSS key: 原始名称_时间戳_随机串.原扩展名 (保留中文, 仅清洗 URL/路径危险字符)
|
||||
// 这样上传控件能从 URL 里还原原名显示, 无需额外 name 字段/列
|
||||
const rawName = file.name || 'file'
|
||||
const dot = rawName.lastIndexOf('.')
|
||||
const ext = (dot > 0 ? rawName.slice(dot) : '').replace(/[\\/:*?"<>|%\s]+/g, '')
|
||||
const base = (dot > 0 ? rawName.slice(0, dot) : rawName)
|
||||
.replace(/[\\/:*?"<>|%\s]+/g, '_') || 'file'
|
||||
const key = sign.dir + base + '_' + Date.now() + '_' + Math.random().toString(36).slice(2, 8) + ext
|
||||
// 显式传 Content-Type,让 OSS 按此存文件元数据, 浏览器拿到 application/pdf 即可内嵌预览
|
||||
const mime = getMimeByExt(file.name)
|
||||
|
||||
@@ -68,5 +74,7 @@ export async function uploadToOss(file, dir) {
|
||||
if (!resp.ok) {
|
||||
throw new Error('OSS 上传失败: HTTP ' + resp.status)
|
||||
}
|
||||
return sign.host + '/' + key
|
||||
// 返回 URL 时对路径逐段编码 (保留 / 分隔), 让含中文/特殊字符的 key 在所有下载场景下都是 ASCII 安全 URL
|
||||
// OSS 对象 key 本身仍是原始值 (FormData 的 key 字段未编码), 下载时 OSS 会自动把 %XX 还原
|
||||
return sign.host + '/' + key.split('/').map(encodeURIComponent).join('/')
|
||||
}
|
||||
Reference in New Issue
Block a user