feat: 邀请函邮件发送 + 首次设密/密码为空 + 姓名单一可信源

邀请发送 (菜单暂隐藏, 待确认参数见 发送邀请-待确认参数.md):
- 后端: BizInvite / BizInviteRecipient + Controller/Service/Mapper/XML
- 邮件: InviteMailSender (spring-boot-starter-mail SMTP) + application*.yml 邮件配置
- 上传进度: UploadProgressRegistry + UploadProgressController
- 前端: InviteList / InviteNew / InviteDetail / InviteView + api/business/invite.js
- 原型: proto/html/components/invite-detail / new-invitation / send-invitation

登录/账号:
- 首次设密: /getInfo 返回 isPasswordEmpty, SysProfileController 密码为空时跳过旧密码校验, ForcePasswordDialog 强制弹窗
- 姓名单一可信源 resolveDisplayName: doctor→biz_expert.name, sponsor/executor→biz_person.name, 其余回退 nick_name
- OA compliance 门禁改为按手机号查 ecology 视图 (不再限定 manager/leader)

其它:
- OSS zip 在线查看 (列清单+取单文件, 公开只读) + SecurityConfig permitAll
- doctor 项目详情 ProjectDetail.vue
- 数据库/测试/设计文档 (md) 入库
This commit is contained in:
郭庆泰
2026-09-10 20:40:49 +08:00
parent 56615f9806
commit 5a0a892574
171 changed files with 11032 additions and 876 deletions
@@ -61,6 +61,8 @@ public class SecurityConfig
requests.requestMatchers("/login", "/register", "/captchaImage").permitAll()
// OSS 文件代理 (PDF/图片内嵌预览, 重写 Content-Disposition 为 inline)
.requestMatchers(HttpMethod.GET, "/common/oss/proxy").permitAll()
// zip 在线查看 (服务端解压: 列清单 + 取单文件), 公开只读
.requestMatchers(HttpMethod.GET, "/common/oss/zip/entries", "/common/oss/zip/file").permitAll()
// OSS 直传签名 (注册场景需匿名访问: 专家/执行方/支持方上传证书时还没 token)
// 安全性: OssController 已用 policy 限定 dir 前缀 + 文件大小, key 含时间戳+随机串防覆盖
.requestMatchers(HttpMethod.GET, "/common/oss/sign").permitAll()
@@ -50,7 +50,8 @@ public class GlobalExceptionHandler
{
String requestURI = request.getRequestURI();
log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
return AjaxResult.error(e.getMessage());
// 不暴露 e.getMessage() (含 supported methods 等内部细节), 统一友好兜底
return AjaxResult.error("请求方式不支持");
}
/**
@@ -113,7 +114,8 @@ public class GlobalExceptionHandler
{
String requestURI = request.getRequestURI();
log.error("请求地址'{}',发生未知异常.", requestURI, e);
return AjaxResult.error(e.getMessage());
// 不暴露 e.getMessage() (NPE/IllegalState/SQL 等 Java 内部细节), 统一友好兜底; 详情已落日志
return AjaxResult.error("系统繁忙,请稍后再试或联系管理员");
}
/**
@@ -124,7 +126,8 @@ public class GlobalExceptionHandler
{
String requestURI = request.getRequestURI();
log.error("请求地址'{}',发生系统异常.", requestURI, e);
return AjaxResult.error(e.getMessage());
// 同上: 不暴露 e.getMessage(), 统一友好兜底; 详情已落日志
return AjaxResult.error("系统繁忙,请稍后再试或联系管理员");
}
/**