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)
This commit is contained in:
郭庆泰
2026-08-15 12:41:10 +08:00
commit cf5790229a
694 changed files with 102090 additions and 0 deletions
+171
View File
@@ -0,0 +1,171 @@
<!DOCTYPE html>
<!--
============================================================
角色: 🟦 后台 父级: admin.html (iframe#contentFrame)
来源: 原型/设置管理.html + 原型/files/设置管理/styles.css
============================================================
按 top 升序的内容区模块:
框架元素: logo / 侧边栏 10 项菜单 / 张三(顶栏) / 面包屑
内容区: 无 (原型是空壳, 13 个 <p><span> 全部是框架复用元素)
============================================================
新增项 (非原型, 业务语义补, 标准系统设置):
- 5 个设置分组 Tab: 基本设置 / 安全设置 / 邮件设置 / 短信设置 / 通知设置
- 基本设置表单 (默认显示) 7 字段:
站点名称 / 站点 Logo / 域名 / 备案号 / 系统邮箱 / 联系电话 / 关闭注册
- 安全设置 4 字段: 密码最小长度 / 会话超时 / 登录失败锁定 / 启用验证码
- 邮件设置 4 字段: SMTP 服务器 / SMTP 端口 / 邮箱账号 / 授权密码
- 短信设置 3 字段: 服务商 / AccessKey / 短信签名
- 通知设置 3 字段: 系统通知 / 邮件通知 / 短信通知 (3 个开关)
- 各分组底部「保存设置」按钮
============================================================
自检:
✅ 原型内容区为空, 不存在漏读字段
✅ 5 个分组 + 字段均为后台设置常见项
============================================================
-->
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>设置管理 - 后台</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,"PingFang SC","Microsoft YaHei",sans-serif;color:#333;background:#fafafa;min-height:100vh}
.content{padding:24px 32px}
.breadcrumb{font-size:13px;color:#8c8c8c;margin-bottom:16px}
.breadcrumb a{color:#1890ff;text-decoration:none;cursor:pointer}
.breadcrumb a:hover{text-decoration:underline}
.breadcrumb .sep{margin:0 6px;color:#bfbfbf}
.breadcrumb .current{color:#595959}
.page-title{font-size:22px;font-weight:600;color:#1a1a1a;margin-bottom:20px}
.card{background:#fff;border-radius:8px;padding:24px 28px;margin-bottom:16px;border:1px solid #f0f0f0}
.tabs{display:flex;border-bottom:1px solid #e8e8e8;margin-bottom:24px}
.tab{padding:12px 24px;cursor:pointer;color:#595959;font-size:14px;border-bottom:2px solid transparent;transition:all .2s}
.tab:hover{color:#1890ff}
.tab.active{color:#1890ff;border-bottom-color:#1890ff;font-weight:600}
.tab-panel{display:none}
.tab-panel.active{display:block}
.form-row{display:flex;align-items:center;margin-bottom:18px;max-width:680px}
.form-label{flex:0 0 140px;font-size:14px;color:#595959;text-align:right;padding-right:16px;white-space:nowrap}
.form-input,.form-select{flex:1;height:36px;padding:0 12px;border:1px solid #d9d9d9;border-radius:4px;font-size:14px;color:#333;outline:none;background:#fff}
.form-input:focus,.form-select:focus{border-color:#1890ff;box-shadow:0 0 0 3px rgba(24,144,255,0.1)}
.form-textarea{flex:1;min-height:80px;padding:8px 12px;border:1px solid #d9d9d9;border-radius:4px;font-size:14px;color:#333;outline:none;background:#fff;resize:vertical;font-family:inherit}
.form-textarea:focus{border-color:#1890ff;box-shadow:0 0 0 3px rgba(24,144,255,0.1)}
.switch{position:relative;width:44px;height:22px;background:#d9d9d9;border-radius:11px;cursor:pointer;transition:background .2s;flex-shrink:0}
.switch.on{background:#1890ff}
.switch::after{content:'';position:absolute;top:2px;left:2px;width:18px;height:18px;background:#fff;border-radius:50%;transition:transform .2s}
.switch.on::after{transform:translateX(22px)}
.switch-row{display:flex;align-items:center;justify-content:space-between;padding:10px 0;border-bottom:1px solid #f5f5f5}
.switch-row:last-child{border-bottom:none}
.switch-row-text{font-size:14px;color:#1a1a1a}
.switch-row-desc{font-size:12px;color:#8c8c8c;margin-top:2px}
.form-actions{padding-top:20px;border-top:1px solid #f5f5f5;margin-top:20px;max-width:680px}
.btn{height:36px;padding:0 20px;border-radius:4px;font-size:14px;cursor:pointer;border:1px solid #d9d9d9;background:#fff;color:#595959;transition:all .2s}
.btn:hover{color:#1890ff;border-color:#1890ff}
.btn-primary{background:#1890ff;color:#fff;border-color:#1890ff;margin-right:8px}
.btn-primary:hover{background:#096dd9;border-color:#096dd9;color:#fff}
.required{color:#ff4d4f;margin-right:4px}
@media(max-width:768px){.form-row{flex-direction:column;align-items:stretch}.form-label{text-align:left;padding-right:0;margin-bottom:6px}.content{padding:16px}}
</style>
</head>
<body>
<main class="content">
<div class="breadcrumb">
<a href="javascript:void(0)" onclick="navigateTo('admin-home.html')">工作台</a>
<span class="sep">&gt;</span>
<span class="current">设置管理</span>
</div>
<h1 class="page-title">设置管理</h1>
<div class="card">
<div class="tabs">
<div class="tab active" data-tab="basic">基本设置</div>
<div class="tab" data-tab="security">安全设置</div>
<div class="tab" data-tab="email">邮件设置</div>
<div class="tab" data-tab="sms">短信设置</div>
<div class="tab" data-tab="notify">通知设置</div>
</div>
<!-- 基本设置 -->
<div class="tab-panel active" id="panel-basic">
<div class="form-row"><label class="form-label"><span class="required">*</span>站点名称</label><input type="text" class="form-input" value="北京整合医学学会项目管理系统"></div>
<div class="form-row"><label class="form-label">站点 Logo</label><input type="text" class="form-input" placeholder="点击上传图片"></div>
<div class="form-row"><label class="form-label">域名</label><input type="text" class="form-input" value="https://project.bahm.org.cn"></div>
<div class="form-row"><label class="form-label">备案号</label><input type="text" class="form-input" value="京ICP备XXXXXXXX号"></div>
<div class="form-row"><label class="form-label">系统邮箱</label><input type="text" class="form-input" value="contactus@bahim.org.cn"></div>
<div class="form-row"><label class="form-label">联系电话</label><input type="text" class="form-input" value="010-82089470"></div>
<div class="form-row"><label class="form-label">关闭注册</label><div class="switch" data-switch></div></div>
<div class="form-actions"><button class="btn btn-primary">保存设置</button></div>
</div>
<!-- 安全设置 -->
<div class="tab-panel" id="panel-security">
<div class="form-row"><label class="form-label">密码最小长度</label><input type="number" class="form-input" value="8" min="6" max="20"></div>
<div class="form-row"><label class="form-label">会话超时(分钟)</label><input type="number" class="form-input" value="30" min="5" max="480"></div>
<div class="form-row"><label class="form-label">登录失败锁定次数</label><input type="number" class="form-input" value="5" min="3" max="10"></div>
<div class="form-row"><label class="form-label">启用验证码</label><div class="switch on" data-switch></div></div>
<div class="form-actions"><button class="btn btn-primary">保存设置</button></div>
</div>
<!-- 邮件设置 -->
<div class="tab-panel" id="panel-email">
<div class="form-row"><label class="form-label">SMTP 服务器</label><input type="text" class="form-input" value="smtp.exmail.qq.com"></div>
<div class="form-row"><label class="form-label">SMTP 端口</label><input type="number" class="form-input" value="465"></div>
<div class="form-row"><label class="form-label">邮箱账号</label><input type="text" class="form-input" value="noreply@bahim.org.cn"></div>
<div class="form-row"><label class="form-label">授权密码</label><input type="password" class="form-input" placeholder="请输入授权密码"></div>
<div class="form-actions"><button class="btn btn-primary">保存设置</button><button class="btn">发送测试邮件</button></div>
</div>
<!-- 短信设置 -->
<div class="tab-panel" id="panel-sms">
<div class="form-row"><label class="form-label">服务商</label><select class="form-select"><option>阿里云</option><option>腾讯云</option><option>华为云</option></select></div>
<div class="form-row"><label class="form-label">AccessKey</label><input type="text" class="form-input" placeholder="请输入 AccessKey"></div>
<div class="form-row"><label class="form-label">短信签名</label><input type="text" class="form-input" value="北京整合医学学会"></div>
<div class="form-actions"><button class="btn btn-primary">保存设置</button><button class="btn">发送测试短信</button></div>
</div>
<!-- 通知设置 -->
<div class="tab-panel" id="panel-notify">
<div class="switch-row">
<div><div class="switch-row-text">系统通知</div><div class="switch-row-desc">站内消息通知开关</div></div>
<div class="switch on" data-switch></div>
</div>
<div class="switch-row">
<div><div class="switch-row-text">邮件通知</div><div class="switch-row-desc">关键操作通过邮件通知用户</div></div>
<div class="switch on" data-switch></div>
</div>
<div class="switch-row">
<div><div class="switch-row-text">短信通知</div><div class="switch-row-desc">紧急情况通过短信通知用户</div></div>
<div class="switch" data-switch></div>
</div>
<div class="form-actions"><button class="btn btn-primary">保存设置</button></div>
</div>
</div>
</main>
<script>
// Tab 切换
document.querySelectorAll('.tab').forEach(t => {
t.addEventListener('click', () => {
document.querySelectorAll('.tab').forEach(x => x.classList.remove('active'));
document.querySelectorAll('.tab-panel').forEach(x => x.classList.remove('active'));
t.classList.add('active');
document.getElementById('panel-' + t.dataset.tab).classList.add('active');
});
});
// Switch 切换
document.querySelectorAll('[data-switch]').forEach(s => {
s.addEventListener('click', () => s.classList.toggle('on'));
});
function navigateTo(href) {
try {
if (window.parent && window.parent.document.getElementById('contentFrame')) {
window.parent.document.getElementById('contentFrame').src = href;
} else { window.location.href = href; }
} catch (e) { window.location.href = href; }
}
</script>
</body>
</html>