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
+7
View File
@@ -0,0 +1,7 @@
html, body, #app { height: 100%; margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; }
:root { --theme-color: #409eff; --theme-color-light: #66b1ff; --theme-color-dark: #3a8ee6; }
.page-wrap { padding: 16px; }
.page-card { background: #fff; border-radius: 6px; padding: 16px; box-shadow: 0 1px 4px rgba(0,21,41,.08); margin-bottom: 16px; }
.page-title { font-size: 18px; font-weight: 600; margin-bottom: 12px; color: #1f1f1f; }
.filter-bar { margin-bottom: 12px; }
.toolbar { margin-bottom: 12px; display: flex; gap: 8px; }
+116
View File
@@ -0,0 +1,116 @@
/**
* 品牌主题色切换工具
* ----------------------------------------
* 用法:
* import { setBrand } from '@/assets/theme'
* setBrand('#0f766e') // 改主题色(自动重算变体)
* setBrand('#1E3A8A') // 改回默认
* setBrand('#1E3A8A', { persist: true }) // 写 localStorage
* applyStoredBrand() // 应用持久化的颜色
*
* 派生色算法(HSL 空间调整,比简单 hex 加减更稳):
* deep: lightness -= 12
* darker: lightness -= 22
* light: lightness += 12
* lighter: lightness += 35
* text: lightness += 22
* mix: 50% alpha + white (用于 focus border)
*/
const KEY = 'brand-primary'
/** hex -> {r,g,b} */
function hexToRgb(hex) {
const h = hex.replace('#', '')
const v = h.length === 3
? h.split('').map(c => c + c).join('')
: h
return {
r: parseInt(v.slice(0, 2), 16),
g: parseInt(v.slice(2, 4), 16),
b: parseInt(v.slice(4, 6), 16)
}
}
/** {r,g,b} -> {h,s,l} (h: 0..360, s: 0..100, l: 0..100) */
function rgbToHsl({ r, g, b }) {
r /= 255; g /= 255; b /= 255
const max = Math.max(r, g, b), min = Math.min(r, g, b)
let h = 0, s = 0
const l = (max + min) / 2
if (max !== min) {
const d = max - min
s = l > 0.5 ? d / (2 - max - min) : d / (max + min)
switch (max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break
case g: h = (b - r) / d + 2; break
case b: h = (r - g) / d + 4; break
}
h *= 60
}
return { h, s: s * 100, l: l * 100 }
}
/** {h,s,l} -> {r,g,b} */
function hslToRgb({ h, s, l }) {
s /= 100; l /= 100
const k = n => (n + h / 30) % 12
const a = s * Math.min(l, 1 - l)
const f = n => {
const x = l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)))
return Math.round(x * 255)
}
return { r: f(0), g: f(8), b: f(4) }
}
/** {h,s,l} -> '#rrggbb' */
function hslToHex({ h, s, l }) {
const { r, g, b } = hslToRgb({ h, s, l })
return '#' + [r, g, b].map(v => v.toString(16).padStart(2, '0')).join('')
}
/** 把 lightness 限制在 8..92 之间 */
function clampL(l) { return Math.max(8, Math.min(92, l)) }
/**
* 根据主色算出 7 个派生色 hex
*/
export function derivePalette(primary) {
const hsl = rgbToHsl(hexToRgb(primary))
return {
'--brand-primary': primary,
'--brand-primary-deep': hslToHex({ ...hsl, l: clampL(hsl.l - 12) }),
'--brand-primary-darker': hslToHex({ ...hsl, l: clampL(hsl.l - 22) }),
'--brand-primary-light': hslToHex({ ...hsl, l: clampL(hsl.l + 12) }),
'--brand-primary-lighter': hslToHex({ ...hsl, l: clampL(hsl.l + 35) }),
'--brand-primary-text': hslToHex({ ...hsl, l: clampL(hsl.l + 22) }),
'--brand-primary-mix': hslToHex({ ...hsl, l: clampL(hsl.l + 45) })
}
}
/**
* 设置 :root 上 7 个 CSS 变量
* @param {string} primary 主色 hex
* @param {object} [opts] { persist: bool } 是否写 localStorage
*/
export function setBrand(primary, opts = {}) {
const palette = derivePalette(primary)
const root = document.documentElement
for (const [k, v] of Object.entries(palette)) root.style.setProperty(k, v)
if (opts.persist) localStorage.setItem(KEY, primary)
}
/**
* 应用持久化在 localStorage 的颜色(无则保持现状)
*/
export function applyStoredBrand() {
const stored = localStorage.getItem(KEY)
if (stored) setBrand(stored)
}
/**
* 当前 :root 的主色(只读)
*/
export function getBrand() {
return getComputedStyle(document.documentElement).getPropertyValue('--brand-primary').trim()
}
+39
View File
@@ -0,0 +1,39 @@
/* =============================================================
品牌主题色(Brand Theme
------------------------------------------------------------
所有色值都是 HSL/HEX 函数动态计算的派生色。
改 :root 里的 --brand-primary 即可全局换色。
派生色算法(hex → HSL → 调整亮度/饱和 → 转回 hex):
--brand-primary 主色
--brand-primary-deep 暗 12% hover / active / 标题强调)
--brand-primary-darker 暗 22% (顶部导航 / 深底)
--brand-primary-light 浅 22% (背景 / disabled
--brand-primary-lighter 浅 55% hover-bg / 选中态)
--brand-primary-text 浅 35% (链接默认)
--brand-primary-mix 50% 透明 + 白 (输入框 focus border
Element Plus 同步:main.js 在启动时读取 --brand-primary
并通过 ElMessage / ElButton 的 --el-color-primary 联动。
============================================================= */
:root {
--brand-primary: #1E3A8A;
--brand-primary-deep: #152a66;
--brand-primary-darker: #0d1d4d;
--brand-primary-light: #3a55a3;
--brand-primary-lighter: #c1cbe6;
--brand-primary-text: #4f6dbf;
--brand-primary-mix: #8e9ad1;
}
/* Element Plus 联动:把品牌色同步给 Element Plus 内置变量。
这样所有 <el-button type="primary"> 等都跟主题色。 */
:root {
--el-color-primary: var(--brand-primary);
--el-color-primary-light-3: var(--brand-primary-light);
--el-color-primary-light-5: var(--brand-primary-lighter);
--el-color-primary-light-7: var(--brand-primary-lighter);
--el-color-primary-light-9: var(--brand-primary-lighter);
--el-color-primary-dark-2: var(--brand-primary-deep);
}