Commit Graph
198 Commits
Author SHA1 Message Date
郭庆泰andClaude 14968d46e5 style(sponsor/PersonDetail): 对齐 executor/PersonDetail 风格
- 加 page-card 包裹 + breadcrumb 三级 '首页 / 人员管理 / 人员详情'
- detail-card → form-card nested (跟 NewPerson 一致)
- detail-actions → form-actions
- max-width: 1000px → 1200px
- 删 :deep(.el-button) { border-radius } (skill 禁忌覆盖 el 默认主题)
- 删 :deep(.el-form-item__label) 颜色覆盖 (让 el 默认)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 21:44:07 +08:00
郭庆泰andClaude d2e7ec110d style(executor/people): 对齐 People.vue 风格 — 加 breadcrumb, 删 page-sub
- 用 breadcrumb (首页 / 人员管理) 替代 page-sub 副标题
- 删 .page-sub / .filter-tip 死样式
- 跟 sponsor/SponsorPeople.vue 一致

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 21:41:40 +08:00
郭庆泰andClaude 13e3e9e1d1 style(executor/people): 去掉批量导入模板提示文案
Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 21:40:37 +08:00
郭庆泰andClaude 4634339bc2 feat(executor/people): 查看改为新页面 (只读, 无账号/状态字段)
- 新建 executor/PersonDetail.vue, 结构与 NewPerson.vue 一致
  (page-card + breadcrumb + el-card form-card + 两列 el-row),
  但只读 + 不显示用户名/初始密码/状态 (6 字段: 姓名/手机号/所属公司/部门/职务/角色)
- router 加 /executor/people/detail/:id → PersonDetail.vue
- People.vue: onView 改为 router.push, 删 view dialog 块 + view/viewOpen refs

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 21:39:58 +08:00
郭庆泰andClaude e59b512e4b fix(person): 子账号继承主账号 role_type + Login 不再硬编 leader
问题: sponsor 主账号新建的子账号 role_type 没写入,
      被 sys_user.role_type DEFAULT 'executor' 覆盖,
      导致子账号进入 executor 视角;另外 Login.vue
      autoRole/短信登录都硬编 'leader' 兜底, getInfo
      失败时静默跳 /leader/home。

修复:
- BizPersonServiceImpl.insert 读主账号 SysUser,
  把 mainUser.getRoleType() 写到新子账号
  (SysUserMapper.xml insertUser 已支持 role_type 列)
- Login.vue: 短信登录 fallbackRole 改 '',
  autoRole 不匹配返回 '', afterLogin 无 role 跳 /login
  (不再 fallback /leader/home)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 21:35:51 +08:00
郭庆泰 40f296b59d refactor(executor): 对齐 sponsor 人员管理模式 + 修 3 个 bug
后端:
- BizAuthController.registerExecutor step 6 同步建 biz_person (主账号自己=管理员, name=unitName, role='admin', unit_type='executor'), 让"人员管理"能看见自己 (跟 registerSponsor 同模式, 走 BizPersonMapper 直插, 绕过 SUB 子账号逻辑)
- BizPersonMapper.xml selectExecutorList 加 OR u.user_id=主账号 (主账号自己能查到), + countAdminByOrgId (校验公司唯一管理员)
- SysUserMapper.xml 手机号正则 1[3-9] → 1[0-9] (允许 10 开头测试号段, 跟 sponsor 一致)

前端 executor/NewPerson.vue 1:1 对齐 sponsor/NewPerson.vue:
- el-card form-card 包裹 + el-row :gutter=12 两列布局
- 用户名/初始密码 行 (v-if=!isEdit)
- 状态改用 el-radio-group, 值 0=正常 1=禁用
- 修了状态值反向 bug: 原 executor 正常→"1" 禁用→"0" 跟 DB/UserStatus enum 相反, 编辑时反向生效 (BizPersonServiceImpl.insert 硬编码 status='0' 掩盖了 bug)
- role 统一 el-select + admin 选项 :disabled=true (管理员只能注册时建)
- 编辑模式 el-select :disabled=true (不能改角色)
- phone 正则 /^1[0-9]\d{9}$/, userName 3-30 模式, password 6-30, department maxlength=100
- 新建成功 ElMessageBox.alert 展示子账号+密码
- 重复手机号走 warning 黄 (isDuplicateError)
- confirmCancel 取消确认
- loadMyOrg 自动带出主账号公司

前端 executor/People.vue:
- 状态列对齐 sponsor: row.status === '0' ? '正常' : '禁用' (修原 || '正常' fallback bug 导致显示原始 '0' + 颜色永远红的两个 bug)
- 批量导入 完整实装 (原 downloadTemplate/submitImport 都是 stub, 只弹提示):
  - downloadTemplate GET /business/person/executorImportTemplate + blob 下载 + 解析 Content-Disposition 文件名
  - submitImport POST /business/person/executorImport + FormData + 导入结果 dialog (行号/姓名/手机号/成功+错误信息)
  - el-upload 加 :on-change=:on-remove 自管 file, footer 改 "关闭/开始导入" 带 loading/disabled
  - 新增 onImport 先 clearFiles 再开 dialog
2026-08-18 21:32:10 +08:00
郭庆泰andClaude 6716074eee refactor(sponsor/NewPerson): 角色统一 el-select, 管理员选项禁用, 编辑模式整体置灰
之前: v-if/v-else 二选一 (role='admin' 静态 tag / 其他 el-select)
       历史主账号 role=NULL 时空白显示, UI 不一致

现在: 统一用 el-select
- :disabled=isEdit  (编辑模式整体灰, 不可改)
- 管理员 option :disabled=true 常驻但永远不可选
   (一公司一管理员只在注册时建, 不能从 UI 任命)
- 新建: 下拉只允许选监察员 (管理员 option 禁用)
- 编辑: 整个 select 灰, 显示当前 role (supervisor/admin/null 都能稳定渲染)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 21:09:35 +08:00
郭庆泰andClaude 1cba0d4052 refactor(person/import): 模板精简到 4 列, 所属公司+角色由后端兜底
BizPersonImportVO.java:
- @Excel 注解砍掉 orgName (所属公司) + role (角色), 字段保留兼容老模板
- 部门/职务 sort 序号重排: 3, 4
- 模板列头从 6 列精简到 4 列: 姓名/手机号/部门/职务

BizPersonController.java doImport:
- 删除 orgName 必填校验 + bizOrgMapper 字符串匹配 orgName → orgId 的旧逻辑
- 删除 p.setOrgId(orgId), 让 BizPersonServiceImpl.insert 按 mainUid + unitType
  自动反查主账号 biz_org 兜底 (service 内已有 line 56-70 兜底逻辑)
- p.setRole(row.getRole()) 改成 unitType 写死:
  sponsor → 'supervisor' (监察员), executor → 'meetingExecutor' (会议执行)
- 死代码清理: 删除 BizOrg + BizOrgMapper import + @Autowired (controller 内不再使用)

行为变化:
- 老模板 (6 列) 上传不会报错, 多出的 orgName/role 列值被忽略 (setter 保留)
- sponsor/executor 双端受益, 都不再需要 Excel 提供 orgName/role

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 21:09:05 +08:00
郭庆泰andClaude 25ec74114f feat(sponsor/people): 批量删除自我保护 + 批量导入 UI 用 el-upload 对齐其他页面
1. 批量删除主账号自我保护 (防误删):
   - 复选框 :selectable 排除主账号自己 (row.userId === store.user?.userId)
   - 批量删除按钮 :disabled 在包含主账号时置灰 (computed: hasSelfInSelection)
   - onBatchRemove 函数入口再校验一次 (defense in depth)

2. 批量导入 dialog 用 el-upload 对齐 manager/admin/executor:
   - 替换手写 <input type=file> + 浏览/上传 button, 改用标准 el-upload
     (:auto-upload=false :limit=1 :on-change :on-remove)
   - footer 加'开始导入'按钮 (disabled by !importFile)
   - 文件名显示 + 删除按钮 el-upload 自带, 不再手写
   - uploadFile() 改 submitImport(), 语义更准
   - onImport() 开头 clearFiles() 防止关闭再打开时残留

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 21:08:01 +08:00
郭庆泰andClaude 8aba05aa0f docs(review): sponsor/account 端到端审查报告
11 章穿透审查:
- 四跳定位 (AdminLayout → router → Account.vue → proto)
- 后端链路: SysProfileController → SysUserMapper
- DB 实测 sys_user DDL + 索引
- 与原型 sponsor-account.html 对比
- 发现 P1: 改手机号未走短信验证码 (后端 /changePhone 已实现但前端未用)
- 发现 P3: sys_user 缺 uk_user_name / idx_phonenumber

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 20:47:23 +08:00
郭庆泰andClaude 76dd4d7306 feat(sponsor/people): 主账号同步建 biz_person (admin/总负责人), 列表可见 + 操作列对本人隐藏 + 新建下拉不包含 admin
后端:
- BizAuthController.registerSponsor step 6: 为主账号同步建 biz_person
  (走 BizPersonMapper 直插, 绕过 BizPersonServiceImpl 创 SUB 子账号的逻辑;
   SnowflakeId 注入 personId; department=管理部, position=总负责人, role=admin,
   unit_type=sponsor, user_id=主账号自己)
- BizPersonMapper.java + xml 新增 countAdminByOrgId: 校验某 org 下是否已有 admin
  (注册场景下天然返回 0, 是给未来 bug 兜底, registerSponsor 暂不调用)
- BizPersonMapper.xml selectSponsorList: WHERE 加 OR u.user_id=#{sponsorOwnerUid},
  让主账号自己的 biz_person (parent_user_id=NULL) 也能被自身 list 看到

前端:
- utils/roleMap.js: PERSON_ROLE_LABEL 加 admin:'管理员'
- sponsor/SponsorPeople.vue: 角色列改用 translatePersonRole, tag type 按 role 动态
  (admin=warning, supervisor=primary); 操作列本人隐藏 禁用/恢复 + 删除
  (v-if=row.userId !== store.user?.userId, 防主账号把自己禁用/误删)
- sponsor/NewPerson.vue: 编辑模式 role=admin 显示静态 el-tag, 新建下拉仍只含 supervisor
- sponsor/PersonDetail.vue: 角色展示同步用 translatePersonRole
- auth/Login.vue + portal/Home.vue: 文案 监察员 → 管理员 (注册即管理员, 可建监察员子账号)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 20:46:42 +08:00
郭庆泰 50c2678ec6 refactor(executor/people): 加 executorList 兜底, SQL 硬编码 unit_type='executor' (跟 sponsor 同模式)
- mapper BizPersonMapper.xml 新增 selectExecutorList, SQL 内硬编码 unit_type + parent_user_id=当前主账号
- controller 加 GET /business/person/executorList
- service / mapper 接口同步声明 selectExecutorList
- 前端 api/business/person.js 加 listExecutorPerson
- executor/People.vue 改调 listExecutorPerson, 删 bizList + unitType 参数

效果: executor 端人员列表也走专属接口, 前端传 unitType 绕不开 SQL 兜底
2026-08-18 01:42:05 +08:00
郭庆泰 ce9de7c880 refactor(executor/overview): 整改对齐 manager/Workbench 风格
UI 风格:
- 5 个 KPI 卡 (从 3 个补到 5 个: + 已执行会议 + 未执行会议)
- 卡片改深色底 + 白字 (var(--brand-primary) 不用硬编码)
- 消息通知加"更多 →"链接 + 更多链接样式
- breadcrumb '首页' → '首页 / 工作台'
- notices 改用 listMyMessages API (从写死数据改为真接口, 跟 manager 一致)
- section-title 改 div (不写 h2, 跟 SKILL 一致; manager 自己也违规但本次顺手按 SKILL 写对)

业务逻辑:
- 删 page-title 隐藏 (display:none)
- loadStats 与 manager 完全一致 (简化掉无效的 executorList: true 参数)
2026-08-18 01:27:17 +08:00
郭庆泰 c74c238ef0 refactor(layout): executor 菜单"账号信息"移到最后一位
之前: ...人员管理 / 账号信息 / 劳务凭证
现在: ...人员管理 / 劳务凭证 / 账号信息

(其它角色菜单的账号信息位置不变)
2026-08-18 01:25:52 +08:00
郭庆泰 7573b4180e fix(account): 手机号正则 1[3-9] → 1[0-9], 允许 10 开头测试号段
3 个账号页 (manager/sponsor/executor) 同步修
2026-08-18 01:25:09 +08:00
郭庆泰 ff8b172f7e refactor(executor/account): 重写为与 manager/Accounts.vue 完全一致
原差异 (现在都消除了):
- breadcrumb: '账号信息' → '账号管理'
- 删 page-sub 副标题
- form 字段: name/phone/oldPwd/newPwd/confirmPwd → nickName/phonenumber/oldPassword/newPassword/confirmPassword
- 加 :rules + ref="formRef" (之前无校验, 只占位 ElMessage)
- 真调用 /system/user/profile (PUT) + /system/user/profile/updatePwd (之前只占位)
- onSave 用 formRef.validate + saving loading
- onMounted 调 loadProfile() (之前从 store.user 读, 没有 PUT 接口)
- account-form max-width 520 → 600
- 加 filter-tip 密码长度提示
- 加 .page-card max-width 1200px
2026-08-18 01:24:21 +08:00
郭庆泰 7386168789 refactor(sponsor/account): 重写为与 manager/Accounts.vue 完全一致
裁掉 sponsor 专属功能:
- 头像上传 (avatar-circle / uploadToOss)
- 修改手机号 dialog (短信验证 / phoneSmsUuid)
- 所属公司 (主账号/子账号/isOwner)
- Tab 切换 (改单页 form)
- EditPen icon / useAsyncLock / useUserStore

保留:
- breadcrumb '首页 / 账号管理'
- 姓名 + 手机号 (form.nickName / phonenumber)
- 原密码 + 新密码 + 确认密码
- 保存 + 取消
- '密码长度 6-20 位' 提示
- 调 /system/user/profile + /system/user/profile/updatePwd

UI 100% 对齐 manager/Accounts.vue:
- page-card max-width 1200px
- form class='account-form' max-width 600px
- filter-tip padding-left 120px 跟 el-input 对齐
2026-08-18 01:23:08 +08:00
郭庆泰 dd39fdba5c style(manager/accounts): 对齐 SKILL — page-card max-width 1200px + form class 限宽
- page-card 加 max-width: 1200px (表单页标准)
- form 上 inline style='max-width:600px' → class='account-form' (避 SKILL 禁忌 inline style)
- CSS 加 .account-form { max-width: 600px } (跟 admin/Account.vue 同款)
2026-08-18 01:20:12 +08:00
郭庆泰 a112ecbbbb style(manager/accounts): filter-tip 加 padding-left:120px 跟 el-input 对齐 2026-08-18 01:18:57 +08:00
郭庆泰 8bf5264ea8 refactor(manager/accounts): 删两个 section-title + 删邮箱字段
template:
- 删 '修改个人信息' / '修改密码' 两个 section-title
- 删邮箱 form-item
- 个人信息只剩:姓名 + 手机号

script:
- form 删 email 字段
- rules 删 email 校验
- loadProfile 不再读 email
- onSave 提交 data 删 email
- onCancel 不再重置 email

style:
- 删 .section-title CSS (不再用)
2026-08-18 01:18:05 +08:00
郭庆泰 6d38a262dc refactor(manager/accounts): 彻底删 page-sub 副标题 (跟 el-descriptions 一起清理) 2026-08-18 01:17:07 +08:00
郭庆泰 675421619d refactor(manager/accounts): 删 el-descriptions (账号信息展示), 改 page-sub 文案 2026-08-18 01:16:55 +08:00
郭庆泰 5711e9cd7a refactor(manager/plans): 删操作列下载按钮 (跟设计文件列下载重复)
- 表格操作列 width 240 → 200
- 删 el-button onDownload (操作列里)
- downloadFile() 函数保留 (设计文件列仍用)
2026-08-18 01:14:55 +08:00
郭庆泰 81e91ee808 refactor(manager/plans): 设计文件查看改 OSS 代理 + 新窗口打开 (与 PublicityDetail 一致)
PDF 体验问题:
- 旧: Preview dialog iframe 内嵌 PDF (70vh 矮, OSS attachment 头让 iframe 强制下载)
- 新: window.open 浏览器原生 PDF viewer (Chrome 工具栏/缩放/分页/搜索全有)

实现:
- 加 proxyUrl() 函数: OSS URL 走 /common/oss/proxy 后端代理重写 inline + #toolbar=0&zoom=page-width
- 加 openDesign(): window.open(proxyUrl(row.designFileUrl), '_blank')
- 删 Preview 组件 import + onFile + previewOpen/Url/Title refs + <Preview> 标签
- 表格"查看"按钮 @click 改 openDesign(row)
- '下载'按钮保留 (downloadFile() 仍用 OSS 原始 URL)
2026-08-18 01:13:35 +08:00
郭庆泰 55f3147463 refactor(manager/plans): 删表格项目ID 列 (不在页面上展示)
planId 仍保留在 auditForm (后端 WHERE 用), 只是表格不渲染
2026-08-18 01:11:09 +08:00
郭庆泰 8bee167704 feat(manager/plans + biz-project): 审核 dialog 项目编号改远程 el-select
后端 (BizProjectController):
- 新增 GET /business/project/projectNoOptions
- 返回 [{projectNo, projectName}], 仅 project_no 非空, 按 projectNo 倒序
- 不加 @PreAuthorize (manager 是业务角色, 与 specialPlan/options 一致)

前端 (manager/Plans.vue):
- 模板: 项目编号 el-input → el-select (filterable, 显示 projectNo / projectName)
- script: 加 projectNoOptions ref + loadProjectNoOptions() 函数
- onAudit: 每次打开 dialog 调 loadProjectNoOptions 拿最新 options
2026-08-18 01:08:28 +08:00
郭庆泰 1d288fbe6c feat(manager/plans): 加项目ID列 + 项目编号debounce搜索 + 审核dialog动态规则
表格:
- 加项目ID 列 (width=80, 居中)
- 项目编号 input 加 @input/@clear 触发 onProjectNoSearch (debounce 300ms)

审核 dialog:
- 加项目编号 input (v-if result==='2' 通过时显示, 退回时隐藏)
- 审核意见去掉 prop='opinion' (永远非必填, placeholder 改'可选')
- auditForm 加 projectNo 字段
- auditRules 改 reactive + watch result 切换 projectNo 校验 (通过必填, 退回清校验状态)
- onAudit 重置 projectNo
- submitAudit: isPass 时 payload 加 projectNo
2026-08-18 01:05:22 +08:00
郭庆泰 6eccc6eab2 feat(manager/plans): 审核 dialog 支持通过/退回 (不再固定退回)
- template: 删"投稿ID"行(冗余); "审核结果"改 el-radio-group (通过 '2' / 退回 '3')
- auditForm: 加 result 字段 (默认 '2')
- auditRules: 加 result 必选校验; opinion 文案改为'请填写审核意见'
- onAudit: 重置 result='2'
- submitAudit: 用 auditForm.result 替换硬编码 '3'; 成功消息根据 result 显示'已通过'/'已退回'
2026-08-18 01:01:36 +08:00
郭庆泰 396a631880 refactor(submissions): 删操作列下载按钮 (跟设计文件列下载重复)
- 表格操作列 width 220 → 180
- 删 el-button onDownload
- 删 onDownload() 函数 (window.open designFileUrl)
2026-08-18 00:58:20 +08:00
郭庆泰 ada60e3b23 style(submission-detail): breadcrumb margin-bottom 16px → 20px (再宽一点) 2026-08-18 00:56:58 +08:00
郭庆泰 3d5cd87441 style(submission-detail): breadcrumb margin-bottom 12px → 16px (留白) 2026-08-18 00:56:37 +08:00
郭庆泰 b6428dc5c8 style(submission-detail): 回退 el-descriptions 改回 el-form readonly
- template: el-descriptions → el-form + el-input readonly + readonly-cell
- script: 恢复 fmt / display computed
- style: 恢复 readonly-form / readonly-cell CSS
- 保留: page-card + 标准 breadcrumb + max-width 1200px
2026-08-18 00:55:45 +08:00
郭庆泰 3de26199b1 style(submission-detail): 对齐 People.vue 风格 — page-card + el-descriptions + max-width 1200px
- template: 1 层 page-card 包全部, 删 el-card 嵌套
- template: 标准 breadcrumb (首页 / 分类 / 当前页), 删 inline <a> 链接
- template: 只读信息改用 el-descriptions (column=2, border), 删 el-input readonly 那一坨
- template: el-link 下载 (上一提交已加, 保留)
- script: 删 fmt/display (el-descriptions 内联 {{ xxx || '-' }})
- style: 3 行 (max-width 1200px / breadcrumb / detail-actions), 删 readonly-form/readonly-cell/.detail-card/:deep(.el-button) 全部
2026-08-18 00:54:49 +08:00
郭庆泰 ad3aac0e68 refactor(submission-detail): 设计文件改 el-link + 下载 (删 Preview 组件) 2026-08-18 00:53:02 +08:00
郭庆泰 67be5345ad refactor(submissions): 方案A — mapper submitter_name + 页面样式对齐 + 紧急迁移
- mapper: selectFields 加 COALESCE(bp.name, u.user_name), LEFT JOIN biz_person (uk_person_user_id 防笛卡尔积)
- mapper: insert 补 7 字段 (plan_name/plan_direction/plan_category/project_form/design_file_url/is_settled/project_no), plan_name NOT NULL 缺默认
- SQL: 紧急迁移脚本 add submitter_id + idx + biz_person UNIQUE (ALTER, 不 DROP)
- SubmissionNew: page-card + breadcrumb + max-width 1200px, accept=.pdf/.png/.jpg/.jpeg, __silentError 防双 toast
- SubmissionNew: el-upload drag 模式 A (对齐 Meetings.vue, 删 design-uploader 自定义 CSS)
- SubmissionDetail: 删状态/投稿人/投稿时间/审计, 改 Preview 组件展示设计文件
2026-08-18 00:51:53 +08:00
郭庆泰 b52a334184 chore: biz_org 合并 / BizProject 重构 / 各角色页面调整 (上次重构遗留)
涵盖改动范围:
- 后端 BizOrg / BizProject / BizProjectRating / BizSpecialPlan controller + domain + mapper + service
- 前端 admin (BizSpecialPlanAdmin, ProjectCategory) / executor / leader / manager / sponsor 多页调整
- api/dict.js + AdminLayout.vue 同步
2026-08-18 00:30:34 +08:00
郭庆泰 c9fc6ebdb8 refactor(doctor/submissions): 合并到 biz_project_plan + 删除 biz_submission 死代码
- /doctor/submissions 改走 biz_project_plan,与 /manager/plans 字段/组件/状态字典完全对齐
- BizProjectPlan 加 submitter_id (BIGINT) + submitter_name (LEFT JOIN 查询字段)
- mapper 改 LEFT JOIN biz_person + sys_user,COALESCE(bp.name, u.user_name) 兜底
- biz_person.user_id 加 UNIQUE 索引 (1:1 LEFT JOIN 无笛卡尔积)
- controller 加 doctor 角色自动过滤: list 按 submitter_id, add/edit 强制 submitter_id
- 删除 7 个 BizSubmission 死代码 (Controller/Service/Mapper/Domain/XML/Enum) + 1 utils
- 路由参数 :subId → :planId (路径名 submission 保留产品文案)
- 新增 migration_submission_to_projectPlan_2026_08_18.sql
2026-08-18 00:28:40 +08:00
郭庆泰 b41cf77cac feat(publicity): 公示页支持/执行意向 (匿名提交 + 管理审核)
- 新增 biz_publicity_support_intent / biz_publicity_execution_intent 两张独立表
  (与已登录视角的 biz_support_intent / biz_execution_intent 解耦, 避免匿名数据污染强绑表)
- 后端 BizPublicityIntentController: 公开提交 + 公开查重 (按 project_id+phone+source) + 管理 CRUD
  已登录直接取 user_id, 未登录但 phone 命中 sys_user 仍自动关联 user_id (不回强制登录)
- /business/publicity/** 加 Spring Security permitAll
- 前端 PublicityDetail.vue: 右侧 2 个意向按钮 (已登录/匿名都弹 dialog 填 5 字段),
  已提交状态用 hasPublicityIntent 按 phonenumber 持久化查回
- 重写 manager/SupportIntent.vue + manager/ExecIntent.vue: 列表/筛选/CSV导出/状态变更/批量删除
2026-08-17 01:15:16 +08:00
郭庆泰andClaude a1c54842e2 feat(manager/experts): 审核状态后加启用状态列
新增 el-table-column "启用状态", 显示 正常(绿) / 禁用(红) el-tag,
数据由 row.status === 'N' 区分, 1:1 抄 admin/Experts.vue 同列实现。

列顺序: 姓名 手机号 工作单位 科室 职称 执业证书 职称证明 审核状态 [启用状态] 审批时间 审批人 操作

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-17 00:51:11 +08:00
郭庆泰andClaude 95cc230d0f refactor(manager/experts): 操作列去掉"下载"按钮
操作列含义应当是"对专家本人的管理动作"(审核/修改/查看/启用-禁用/已拒绝意见),
证书下载已经分别在执业证书/职称证明列里有专门的"下载"按钮, 操作列里再放一份
属于重复入口, 用户要求移除。

清理:
- 操作列 el-button "下载" 删除 (按 执业证书 > 职称证明 > 简历 优先级)
- 同步删除 onDownloadAll (仅此按钮调用, 现已无用)
- onDownloadCert 保留 (列内下载按钮 + 预览 dialog 底部下载)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-17 00:50:27 +08:00
郭庆泰andClaude 3bf1581c64 feat(manager): 专家证书查看改为 dialog 预览 (同步 admin)
admin/Experts.vue 之前已经把 执业证书/职称证明 的"查看"从 window.open 新 tab
改为 dialog 内嵌 el-image (可点放大 + 失败可下载), 体验更好。

manager/Experts.vue 同步改造:
- 新增 previewOpen/previewUrl + onPreviewCert (替代原 onViewCert 的 window.open)
- 新增证书预览 dialog 模板 (1:1 抄 admin 版, 含失败兜底"图片加载失败, 请下载查看")
- 表格 2 列"查看"按钮: onViewCert → onPreviewCert
- 详情 dialog 内 2 个"查看证书"链接: 同样改 onPreviewCert
- 加 .cert-preview / .cert-preview-error 样式

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-17 00:48:57 +08:00
郭庆泰andClaude 0f1d130397 fix(expert): 编辑保存失败 Updates:0 + 错误 toast 弹两次
两个根因:

1. 后端 Updates: 0
   - ExpertNew.vue (admin+manager) onSave 编辑分支里 delete payload.expertId
   - 后端 BizExpertMapper.updateByPrimaryKey 是 where expert_id = #{expertId}
   - 没有 expertId → WHERE 不匹配 → 0 updates → 抛 "操作失败" 500
   - 修复: 不再 delete expertId (后端 insert/update 都依赖该字段)

2. 前端操作失败弹两次
   - request.js 响应拦截器在 code != 200 时自动 ElMessage.error
   - onSave 的 catch 又 ElMessage.error 一次
   - 修复: 加 __silentError 请求配置项, 拦截器遇此 flag 不自动 toast
   - api/public.js bizAdd/bizUpdate 加第 3 参数 opts 透传给 request
   - ExpertNew.vue onSave 调用时传 __silentError: true, 由 catch 块按业务语义
     决定 黄警 (手机号重复) 还是 红错 (其它)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-17 00:43:40 +08:00
郭庆泰andClaude 15fd26af30 feat(manager): 专家审核页修改按钮跳转独立编辑页
参考 /admin/experts/new 模式:
- 新建 ry-vue3/src/views/manager/ExpertNew.vue (15 字段, 1:1 抄 admin 版, 仅 goBack 跳 /manager/experts)
- router 加 /manager/experts/new 和 /manager/experts/edit/:id 两条路由, 复用 ExpertNew 组件
- manager/Experts.vue 操作列 "修改" 按钮 → router.push('/manager/experts/edit/:id')
- 加 route watcher, 从编辑页返回时自动重载列表
- 新建专家按钮保留原 dialog (按用户当前只要求改修改按钮)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-17 00:40:45 +08:00
郭庆泰andClaude e099211cbd feat(项目管理): 招标字段/负责人/导出/下拉/登录短信 完整链路
后端 (ruoyi-business)
- BizProject: +is_bid_project, +execOrgNames(GROUP_CONCAT派生), +leadUserName
- BizProjectMapper.xml: 上述字段全部贯通 selectFields/insert/update, 列表加 exec_org_names 子查询 + lead_user_name JOIN
- BizSysUserQueryMapper (新): 干净查 sys_user by role_type, 避开 @DataScope 切面污染, 用于项目负责人下拉
- BizOrgMapper.selectExecutorOrgOptions (新): JOIN sys_user (parent_user_id IS NULL) 限定 MAIN 账号, 排除同公司普通员工子账号
- BizOrgController: +/business/org/executorOptions 端点
- BizExecutionIntentController: +exportSignupExperts 端点 (POST /business/executionIntent/export)
- BizSignupExpertExportVo (新): 中文列头 Excel 导出 VO (专家姓名/科室/医院/职称/报名时间/手机号)
- BizProjectAssign / SponsorAssign 重命名 + Service 实现调整
- 删除 sql/ 下所有迁移脚本 (按用户要求不再保存 SQL 文件)

前端 (ry-vue3)
- api/system.js: +listExecutorOrgs 走新接口, listExecutor/listSupporters/listManagers 保持 listByRole 兼容
- views/manager/Projects.vue: 执行方下拉改 label=u.orgName / value=u.userId, 数据源走 listExecutorOrgs
  +execOrgNames 列展示 +导出报名专家 dropdown 项 +is_bid_project 表单字段
- views/manager/ProjectsNew.vue + ManagerProjectDetail.vue: +is_bid_project 表单/展示
- views/auth/Login.vue: +手机号验证码登录 tab (复用 SysSmsService, dev 模式 10 开头手机号固定码 1234)
- 路由/布局/角色视角多页面整理 (SponsorOrgs/People/SponsorPersonNew 等)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-17 00:34:13 +08:00
郭庆泰 ccfd03a6eb 批量推送 2026-08-16 21:24:53 +08:00
郭庆泰 0c093076a4 批量推送 2026-08-16 13:42:26 +08:00
郭庆泰 c612d4297a feat: 统一角色枚举 (meetingExecutor/supervisor) + 子账号数据隔离 + Login 读取后端 role_type
后端:
- SysUser 加 roleType 字段 (entity + mapper selectUserVo + service 接口/实现)
- SysUserMapper 新增 selectUserIdsByParent (按 parent_user_id 取子账号列表)
- BizPersonController.list 自动注入 MAIN 业务用户可见性: 仅查 user_id IN (子账号列表)
- BizPersonMapper 加 params.subUserIds foreach 过滤
- BizPerson/BizPersonServiceImpl 配合 getParams().put

前端:
- Login.vue 改用后端 sys_user.roleType 替代 username 前缀 autoRole, 修复 exe01 错入 leader 菜单
- utils/roleMap.js 新增: meetingExecutor->会议执行, supervisor->监察员
- executor/People.vue / sponsor/NewPerson.vue / sponsor/Projects.vue / sponsor/SponsorProjects.vue /
  manager/ManagerProjectDetail.vue / manager/{Executor,Sponsor}PersonNew.vue /
  admin/{Executor,Sponsor}PersonNew.vue 全部改为 enum key

SQL:
- migration_unify_role_type_2026_08_16.sql 清洗 biz_person.role 从中文到 enum key
2026-08-16 13:41:42 +08:00
郭庆泰 cf5790229a refactor: 合并 biz_support_unit/biz_execution_unit/biz_service_org 为 biz_org, 删除 2 张孤儿表, 改 biz_person.work_unit → org_id FK
主要改动:
- SQL: biz_support_unit → biz_org, 加 org_type, 加 business_nature; 删 biz_execution_unit, biz_service_org
- SQL: biz_project.support_unit_id/name + service_org_id/name → org_id/name/type
- SQL: biz_meeting.support_unit_name → org_name
- SQL: biz_person.work_unit → org_id (FK)
- 后端: 新 BizOrg entity/mapper/service/controller
- 后端: BizProject/BizMeeting 字段重命名
- 后端: 删 12 个 BizSupportUnit/BizExecutionUnit/BizServiceOrg Java 文件
- 后端: BizPersonImportVO.workUnit → orgName (导入时查 biz_org 取 org_id)
- 后端: BizAuthController.registerExecutor 完整实现 (原 registerSupplier stub)
- 前端: 新 admin/Orgs.vue + manager/Orgs.vue (原 SupportUnits)
- 前端: RegisterExecutor.vue (原 RegisterSupplier, 单页 2 步)
- 前端: sponsor/executor/manager 多个文件 workUnit → orgId/orgName 重命名
- 前端: 统一 supplier → executor, 业务命名 sponsor(赞助方) / executor(执行方=供应商)
- 前端: 全工程 execution → executor (company type / role / person unit_type)
2026-08-15 12:41:10 +08:00