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
+133
View File
@@ -0,0 +1,133 @@
<template>
<el-container class="admin-layout">
<el-aside width="220px" class="aside">
<div class="aside-logo">
<div class="logo-text">{{ roleLabel }}</div>
<div class="logo-sub">BAHIM 工作台</div>
</div>
<el-menu :default-active="route.path" router class="aside-menu">
<el-menu-item v-for="m in menu" :key="m.path" :index="m.path">
<el-icon><component :is="m.icon" /></el-icon>
<span>{{ m.title }}</span>
</el-menu-item>
</el-menu>
</el-aside>
<el-container>
<el-header class="topbar">
<div class="topbar-left">
<span class="page-title">{{ route.meta?.title || '工作台' }}</span>
</div>
<div class="topbar-right">
<el-button text @click="$router.push('/')">门户首页</el-button>
<el-dropdown trigger="click" @command="onCommand">
<span class="user-name">{{ store.user?.userName || store.user?.displayName }}<el-icon><CaretBottom /></el-icon></span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</el-header>
<el-main class="main">
<router-view />
</el-main>
</el-container>
</el-container>
</template>
<script setup>
import { computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useUserStore } from '@/store/user'
import { logout as logoutApi } from '@/api/auth'
import { House, Document, Calendar, User, List, OfficeBuilding, Setting, Bell, EditPen, DataAnalysis, Tickets, CaretBottom, Folder, Medal, UserFilled, Connection } from '@element-plus/icons-vue'
const route = useRoute()
const router = useRouter()
const store = useUserStore()
const role = computed(() => route.meta?.role || store.role)
const ROLE_LABEL = { leader: '项目负责人', manager: '合规人员', admin: '后台管理员', doctor: '评审专家', executor: '执行人', sponsor: '赞助方' }
const roleLabel = computed(() => ROLE_LABEL[role.value] || '工作台')
const MENU = {
admin: [
{ path: '/admin/workbench', title: '工作台', icon: House },
{ path: '/admin/users', title: '用户管理', icon: User },
{ path: '/admin/roles', title: '角色管理', icon: Setting },
{ path: '/admin/projects', title: '项目全览', icon: Document },
{ path: '/admin/meetings', title: '会议全览', icon: Calendar },
{ path: '/admin/department', title: '科室管理', icon: Folder },
{ path: '/admin/title', title: '职称管理', icon: Medal },
{ path: '/admin/experts', title: '专家管理', icon: UserFilled },
{ path: '/admin/orgs', title: '公司管理', icon: Connection },
{ path: '/admin/account', title: '账号信息', icon: User }
],
leader: [
{ path: '/leader/home', title: '工作台', icon: House },
{ path: '/leader/projects', title: '项目列表', icon: Document },
{ path: '/leader/meetings', title: '会议列表', icon: Calendar },
{ path: '/leader/account', title: '账号信息', icon: User }
],
manager: [
{ path: '/manager/workbench', title: '工作台', icon: House },
{ path: '/manager/plans', title: '项目策划方案', icon: EditPen },
{ path: '/manager/projects', title: '项目管理', icon: Document },
{ path: '/manager/meetings', title: '会议管理', icon: Calendar },
{ path: '/manager/experts', title: '专家审核', icon: User },
{ path: '/manager/orgs', title: '公司管理', icon: OfficeBuilding },
{ path: '/manager/support-intent', title: '支持意向', icon: Tickets },
{ path: '/manager/exec-intent', title: '执行意向', icon: Tickets },
{ path: '/manager/accounts', title: '账号管理', icon: Setting }
],
doctor: [
{ path: '/doctor/home', title: '首页', icon: House },
{ path: '/doctor/meetings', title: '我参与的会议', icon: Calendar },
{ path: '/doctor/projects', title: '我报名的项目', icon: Document },
{ path: '/doctor/messages', title: '消息通知', icon: Bell },
{ path: '/doctor/submissions', title: '我的项目设计投稿', icon: EditPen },
{ path: '/doctor/account', title: '账号信息', icon: User }
],
executor: [
{ path: '/executor/overview', title: '首页', icon: House },
{ path: '/executor/meetings', title: '会议执行', icon: Calendar },
{ path: '/executor/projects', title: '项目列表', icon: Document },
{ path: '/executor/people', title: '人员管理', icon: User, requireMain: true },
{ path: '/executor/account', title: '账号信息', icon: Setting },
{ path: '/executor/labor', title: '劳务凭证', icon: EditPen }
],
sponsor: [
{ path: '/sponsor/home', title: '首页', icon: House },
{ path: '/sponsor/my-projects', title: '我的项目', icon: Document },
{ path: '/sponsor/meetings', title: '会议列表', icon: Calendar },
{ path: '/sponsor/people', title: '人员管理', icon: User, requireMain: true },
{ path: '/sponsor/account', title: '账号信息', icon: Setting }
]
}
const menu = computed(() => (MENU[role.value] || []).filter(item => !item.requireMain || store.isMain))
const logout = async () => {
try { await logoutApi() } catch {}
store.logout()
router.replace('/login')
}
const onCommand = (cmd) => { if (cmd === 'logout') logout() }
</script>
<style scoped>
.admin-layout { height: 100vh; }
.aside { background: #001529; color: #fff; }
.aside-logo { padding: 16px; text-align: center; border-bottom: 1px solid var(--brand-primary-darker); }
.logo-text { color: #fff; font-size: 16px; font-weight: 600; }
.logo-sub { color: #8a99b3; font-size: 12px; }
.aside-menu { background: #001529; border: none; }
:deep(.el-menu-item) { color: #c0c4cc; }
:deep(.el-menu-item.is-active) { background: #1890ff; color: #fff; }
.topbar { background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; border-bottom: 1px solid #ebeef5; }
.topbar-left { display: flex; align-items: center; }
.page-title { font-size: 16px; font-weight: 600; }
.topbar-right { display: flex; align-items: center; gap: 12px; }
.user-name { cursor: pointer; display: inline-flex; align-items: center; gap: 4px; }
.main { background: #f5f7fa; padding: 16px; }
</style>
+13
View File
@@ -0,0 +1,13 @@
<template>
<div class="portal-layout">
<router-view />
</div>
</template>
<script setup>
// 纯 layout 容器 — header / footer 由各页面自己渲染(来自原型 1:1)
</script>
<style scoped>
.portal-layout { min-height: 100vh; background: #fff; }
</style>