Files
backmanager-server/db.js

426 lines
24 KiB
JavaScript
Raw Normal View History

2026-06-15 20:46:48 +08:00
// db.js —— 只做两件事:导出连接池;启动时建库/建表/插 admin
require('dotenv').config() //自动寻找.env文件并把里面的键值对全部导入进来
const mysql = require('mysql2/promise')
const bcrypt = require('bcryptjs') //用来给密码做哈希加密
// ============ 1. 连接池 ============
// 业务代码里用 pool.query() / pool.execute(),会自动从池里取/还连接
const pool = mysql.createPool({
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT) || 3306,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
waitForConnections: true, // 池里没连接时排队等
connectionLimit: 10, // 最多 10 个连接
decimalNumbers: true,
})
// ============ 2. 启动时初始化 ============
// 思路:先用一个"无 database"的连接建库,再回到 pool 建表、插 admin
async function initDB() {
const { DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME } = process.env
// 2.1 建库(如果不存在)
const conn = await mysql.createConnection({
host: DB_HOST,
port: Number(DB_PORT) || 3306,
user: DB_USER,
password: DB_PASSWORD,
})
await conn.query(
`CREATE DATABASE IF NOT EXISTS \`${DB_NAME}\` DEFAULT CHARACTER SET utf8mb4`
)
await conn.end()
2026-06-22 20:48:29 +08:00
// 2.2 建表(如果不存在)
2026-06-15 20:46:48 +08:00
await pool.query(`
CREATE TABLE IF NOT EXISTS users (
2026-06-22 20:48:29 +08:00
id INT NOT NULL AUTO_INCREMENT COMMENT '用户ID (主键)',
username VARCHAR(50) NOT NULL COMMENT '用户名 (登录账号)',
password VARCHAR(255) NOT NULL COMMENT '登录密码 (应存储加密后的值)',
2026-06-24 22:44:14 +08:00
is_active TINYINT(1) NOT NULL DEFAULT 1 COMMENT '账号状态: 0-禁用, 1-启用',
department_id INT DEFAULT NULL COMMENT '部门ID (关联departments表)',
2026-06-24 22:44:14 +08:00
employee_id INT DEFAULT NULL COMMENT '员工ID (关联employees表)',
2026-06-22 20:48:29 +08:00
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (id),
UNIQUE KEY uk_username (username)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统用户表'
2026-06-15 20:46:48 +08:00
`)
2026-06-22 20:48:29 +08:00
await pool.query(`
CREATE TABLE IF NOT EXISTS customers (
id INT NOT NULL AUTO_INCREMENT COMMENT '加盟商ID (主键)',
name VARCHAR(100) NOT NULL COMMENT '加盟商姓名',
phone VARCHAR(20) DEFAULT NULL COMMENT '联系电话',
province VARCHAR(50) DEFAULT NULL COMMENT '省',
city VARCHAR(50) DEFAULT NULL COMMENT '市',
district VARCHAR(50) DEFAULT NULL COMMENT '区',
address VARCHAR(200) DEFAULT NULL COMMENT '详细地址',
email VARCHAR(100) DEFAULT NULL COMMENT '电子邮箱',
remark TEXT DEFAULT NULL COMMENT '备注信息',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (id),
KEY idx_customers_name (name),
KEY idx_customers_phone (phone)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='加盟商信息表'
`)
await pool.query(`
CREATE TABLE IF NOT EXISTS employees (
id INT NOT NULL AUTO_INCREMENT COMMENT '员工ID (主键)',
name VARCHAR(100) NOT NULL COMMENT '员工姓名',
gender VARCHAR(4) DEFAULT NULL COMMENT '性别: 男/女',
age INT DEFAULT NULL COMMENT '年龄',
education VARCHAR(50) DEFAULT NULL COMMENT '学历: 高中/专科/本科/硕士/博士',
department VARCHAR(100) DEFAULT NULL COMMENT '所属部门',
entry_date DATE DEFAULT NULL COMMENT '入职时间',
position VARCHAR(100) DEFAULT NULL COMMENT '职务/岗位',
salary DECIMAL(10,2) DEFAULT NULL COMMENT '工资金额',
phone VARCHAR(20) DEFAULT NULL COMMENT '联系电话',
email VARCHAR(100) DEFAULT NULL COMMENT '电子邮箱',
status TINYINT(1) NOT NULL DEFAULT 1 COMMENT '在职状态: 0-离职, 1-在职',
remark TEXT DEFAULT NULL COMMENT '备注',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (id),
KEY idx_employees_name (name),
KEY idx_employees_department (department)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='员工信息表'
`)
await pool.query(`
CREATE TABLE IF NOT EXISTS products (
id INT NOT NULL AUTO_INCREMENT COMMENT '产品ID (主键)',
name VARCHAR(200) NOT NULL COMMENT '产品名称',
type VARCHAR(100) DEFAULT NULL COMMENT '产品类型/分类',
quantity INT NOT NULL DEFAULT 0 COMMENT '产品库存数量',
price DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '产品单价',
unit VARCHAR(20) DEFAULT '件' COMMENT '计量单位',
specification VARCHAR(200) DEFAULT NULL COMMENT '产品规格/型号',
supplier VARCHAR(200) DEFAULT NULL COMMENT '供应商',
remark TEXT DEFAULT NULL COMMENT '备注',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (id),
KEY idx_products_name (name),
KEY idx_products_type (type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='产品信息表'
`)
// contracts 依赖 customers 和 employeesafter_sales 同样依赖
await pool.query(`
CREATE TABLE IF NOT EXISTS contracts (
id INT NOT NULL AUTO_INCREMENT COMMENT '合同ID (主键)',
customer_id INT NOT NULL COMMENT '客户ID (关联客户表)',
contract_name VARCHAR(200) NOT NULL COMMENT '合同名称',
contract_no VARCHAR(100) DEFAULT NULL COMMENT '合同编号',
contract_content TEXT DEFAULT NULL COMMENT '合同内容/条款',
amount DECIMAL(12,2) DEFAULT NULL COMMENT '合同金额',
effective_date DATE DEFAULT NULL COMMENT '合同生效日期',
expiry_date DATE DEFAULT NULL COMMENT '合同有效期 (截止日期)',
employee_id INT DEFAULT NULL COMMENT '业务员ID (关联员工表)',
status VARCHAR(20) NOT NULL DEFAULT '生效' COMMENT '合同状态: 草稿/生效/完成/作废',
remark TEXT DEFAULT NULL COMMENT '备注',
2026-06-24 23:12:43 +08:00
type VARCHAR(20) NOT NULL DEFAULT 'franchise' COMMENT '合同类型: franchise-加盟合同, supply-采购合同',
responsible_user_id INT DEFAULT NULL COMMENT '负责人用户ID (用于数据范围隔离)',
2026-06-22 20:48:29 +08:00
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (id),
KEY idx_contracts_customer_id (customer_id),
KEY idx_contracts_employee_id (employee_id),
KEY idx_contracts_effective_date (effective_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='合同信息表'
`)
await pool.query(`
CREATE TABLE IF NOT EXISTS after_sales (
id INT NOT NULL AUTO_INCREMENT COMMENT '售后记录ID (主键)',
customer_id INT NOT NULL COMMENT '客户ID (关联客户表)',
feedback TEXT NOT NULL COMMENT '客户反馈意见/售后内容',
employee_id INT DEFAULT NULL COMMENT '处理业务员ID (关联员工表)',
handle_method TEXT DEFAULT NULL COMMENT '处理方式/解决方案',
handle_status VARCHAR(20) NOT NULL DEFAULT '待处理' COMMENT '处理状态: 待处理/处理中/已完成',
service_date DATE DEFAULT NULL COMMENT '售后日期',
remark TEXT DEFAULT NULL COMMENT '备注',
2026-06-24 23:12:43 +08:00
responsible_user_id INT DEFAULT NULL COMMENT '负责人用户ID (用于数据范围隔离)',
2026-06-22 20:48:29 +08:00
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (id),
KEY idx_after_sales_customer_id (customer_id),
KEY idx_after_sales_employee_id (employee_id),
KEY idx_after_sales_status (handle_status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='售后信息表'
`)
2026-06-25 21:18:13 +08:00
// ============ 2.2.1 添加缺失的字段(兼容已存在的表) ============
// contracts 表允许 customer_id 为空(采购合同可不关联客户)
try {
await pool.query(`ALTER TABLE contracts MODIFY COLUMN customer_id INT DEFAULT NULL COMMENT '客户ID (关联客户表)'`)
console.log('[init] contracts 表 customer_id 已允许为空')
} catch (e) {
// 修改失败则忽略
}
// contracts 表添加 supplier_id采购合同关联供应商
try {
await pool.query(`ALTER TABLE contracts ADD COLUMN supplier_id INT DEFAULT NULL COMMENT '供应商ID (关联供应商表)' AFTER customer_id`)
console.log('[init] contracts 表已添加 supplier_id 字段')
} catch (e) {
// 字段已存在则忽略
}
// customers 表删除 responsible_user_id加盟商不需要负责人字段
try {
await pool.query(`ALTER TABLE customers DROP COLUMN responsible_user_id`)
console.log('[init] customers 表已删除 responsible_user_id 字段')
} catch (e) {
// 列已删除则忽略
}
2026-06-22 20:48:29 +08:00
console.log('[init] 数据表初始化完成')
// ============ 2.3 部门与权限相关表 ============
// 迁移旧表
await pool.query('DROP TABLE IF EXISTS role_permissions')
await pool.query('DROP TABLE IF EXISTS roles')
2026-06-24 22:44:14 +08:00
await pool.query(`
CREATE TABLE IF NOT EXISTS departments (
id INT NOT NULL AUTO_INCREMENT COMMENT '部门ID (主键)',
name VARCHAR(50) NOT NULL COMMENT '部门标识 (英文)',
description VARCHAR(200) DEFAULT NULL COMMENT '部门名称 (中文)',
2026-06-24 22:44:14 +08:00
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (id),
UNIQUE KEY uk_departments_name (name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='部门表'
2026-06-24 22:44:14 +08:00
`)
await pool.query(`
CREATE TABLE IF NOT EXISTS permissions (
id INT NOT NULL AUTO_INCREMENT COMMENT '权限ID (主键)',
name VARCHAR(100) NOT NULL COMMENT '权限标识 (resource:action)',
description VARCHAR(200) DEFAULT NULL COMMENT '权限描述 (中文)',
resource VARCHAR(50) NOT NULL COMMENT '资源名称',
action VARCHAR(50) NOT NULL COMMENT '操作类型: read/create/update/delete',
PRIMARY KEY (id),
UNIQUE KEY uk_permissions_name (name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='权限表'
`)
await pool.query(`
CREATE TABLE IF NOT EXISTS department_permissions (
department_id INT NOT NULL COMMENT '部门ID',
2026-06-24 22:44:14 +08:00
permission_id INT NOT NULL COMMENT '权限ID',
PRIMARY KEY (department_id, permission_id),
KEY idx_dp_permission_id (permission_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='部门-权限关联表'
2026-06-24 22:44:14 +08:00
`)
await pool.query(`
CREATE TABLE IF NOT EXISTS suppliers (
id INT NOT NULL AUTO_INCREMENT COMMENT '供应商ID (主键)',
name VARCHAR(200) NOT NULL COMMENT '供应商名称',
contact VARCHAR(100) DEFAULT NULL COMMENT '联系人',
phone VARCHAR(50) DEFAULT NULL COMMENT '联系电话',
address VARCHAR(500) DEFAULT NULL COMMENT '地址',
type VARCHAR(50) DEFAULT NULL COMMENT '类型: 原材料/包装/设备',
content TEXT DEFAULT NULL COMMENT '备注说明',
status TINYINT(1) NOT NULL DEFAULT 1 COMMENT '状态: 0-停用, 1-正常',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (id),
KEY idx_suppliers_name (name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='供应商信息表'
`)
2026-06-24 23:12:43 +08:00
// ============ 2.4 种子数据 ============
await seedDepartmentsAndPermissions()
2026-06-24 22:44:14 +08:00
await seedDefaultUsers()
2026-06-29 15:07:53 +08:00
// await seedBusinessData()
// // ============ 2.5 数据库迁移(兼容已有数据的旧库) ============
// // 为财务部补上 product:read 权限
// try {
// const [financeDept] = await pool.query("SELECT id FROM departments WHERE name = 'finance' LIMIT 1")
// if (financeDept.length > 0) {
// const [prodPerm] = await pool.query("SELECT id FROM permissions WHERE name = 'product:read' LIMIT 1")
// if (prodPerm.length > 0) {
// await pool.query(
// 'INSERT IGNORE INTO department_permissions (department_id, permission_id) VALUES (?, ?)',
// [financeDept[0].id, prodPerm[0].id]
// )
// console.log('[migrate] 财务部已补上 product:read 权限')
// }
// }
// } catch (e) {
// console.log('[migrate] 财务部权限迁移跳过:', e.message)
// }
2026-06-24 22:44:14 +08:00
}
// ============ 3. 种子数据:部门与权限 ============
async function seedDepartmentsAndPermissions() {
const [depts] = await pool.query('SELECT id FROM departments LIMIT 1')
if (depts.length > 0) return // 已初始化过,跳过
const deptList = [
{ name: 'admin', description: '信息技术部' },
{ name: 'general_manager', description: '总经理办公室' },
{ name: 'franchise_manager', description: '招商部' },
{ name: 'operations_manager', description: '运营部' },
{ name: 'procurement_manager', description: '采购部' },
{ name: 'finance', description: '财务部' },
2026-06-29 11:32:54 +08:00
{ name: 'hr', description: '人力资源部' },
2026-06-24 22:44:14 +08:00
]
for (const d of deptList) {
await pool.query('INSERT INTO departments (name, description) VALUES (?, ?)', [d.name, d.description])
2026-06-24 22:44:14 +08:00
}
2026-06-29 11:32:54 +08:00
console.log('[init] 已初始化 7 个部门')
2026-06-24 22:44:14 +08:00
const permissionList = [
{ name: 'customer:read', description: '查看加盟商', resource: 'customer', action: 'read' },
{ name: 'customer:create', description: '新增加盟商', resource: 'customer', action: 'create' },
{ name: 'customer:update', description: '修改加盟商', resource: 'customer', action: 'update' },
{ name: 'customer:delete', description: '删除加盟商', resource: 'customer', action: 'delete' },
{ name: 'contract:read', description: '查看合同', resource: 'contract', action: 'read' },
{ name: 'contract:create', description: '新增合同', resource: 'contract', action: 'create' },
{ name: 'contract:update', description: '修改合同', resource: 'contract', action: 'update' },
{ name: 'contract:delete', description: '删除合同', resource: 'contract', action: 'delete' },
{ name: 'after_sale:read', description: '查看售后', resource: 'after_sale', action: 'read' },
{ name: 'after_sale:create',description: '新增售后', resource: 'after_sale', action: 'create' },
{ name: 'after_sale:update',description: '修改售后', resource: 'after_sale', action: 'update' },
{ name: 'after_sale:delete',description: '删除售后', resource: 'after_sale', action: 'delete' },
{ name: 'product:read', description: '查看产品原料', resource: 'product', action: 'read' },
{ name: 'product:create', description: '新增产品原料', resource: 'product', action: 'create' },
{ name: 'product:update', description: '修改产品原料', resource: 'product', action: 'update' },
{ name: 'product:delete', description: '删除产品原料', resource: 'product', action: 'delete' },
{ name: 'supplier:read', description: '查看供应商', resource: 'supplier', action: 'read' },
{ name: 'supplier:create', description: '新增供应商', resource: 'supplier', action: 'create' },
{ name: 'supplier:update', description: '修改供应商', resource: 'supplier', action: 'update' },
{ name: 'supplier:delete', description: '删除供应商', resource: 'supplier', action: 'delete' },
{ name: 'employee:read', description: '查看员工', resource: 'employee', action: 'read' },
{ name: 'employee:create', description: '新增员工', resource: 'employee', action: 'create' },
{ name: 'employee:update', description: '修改员工', resource: 'employee', action: 'update' },
{ name: 'employee:delete', description: '删除员工', resource: 'employee', action: 'delete' },
{ name: 'user:manage', description: '管理用户账号', resource: 'user', action: 'manage' },
]
for (const p of permissionList) {
await pool.query(
'INSERT INTO permissions (name, description, resource, action) VALUES (?, ?, ?, ?)',
[p.name, p.description, p.resource, p.action]
)
}
console.log('[init] 已初始化 25 个权限')
// 部门-权限映射
const deptPermMap = {
2026-06-29 11:32:54 +08:00
admin: [
'user:manage',
'customer:read', 'contract:read', 'after_sale:read',
'product:read', 'supplier:read', 'employee:read',
],
2026-06-24 22:44:14 +08:00
general_manager: [
'customer:read', 'contract:read', 'after_sale:read',
2026-06-29 12:52:01 +08:00
'product:read', 'supplier:read',
'employee:read', 'employee:create', 'employee:update', 'employee:delete',
'user:manage',
2026-06-24 22:44:14 +08:00
],
franchise_manager: [
'customer:read', 'customer:create', 'customer:update', 'customer:delete',
'contract:read', 'contract:create', 'contract:update', 'contract:delete',
'employee:read',
],
operations_manager: [
'customer:read',
2026-06-29 11:32:54 +08:00
'contract:read',
2026-06-24 22:44:14 +08:00
'after_sale:read', 'after_sale:create', 'after_sale:update', 'after_sale:delete',
'employee:read',
],
procurement_manager: [
'customer:read',
2026-06-24 22:44:14 +08:00
'contract:read', 'contract:create', 'contract:update', 'contract:delete',
'product:read', 'product:create', 'product:update', 'product:delete',
'supplier:read', 'supplier:create', 'supplier:update', 'supplier:delete',
'employee:read',
],
finance: [
2026-06-28 20:43:14 +08:00
'customer:read', 'contract:read', 'after_sale:read', 'product:read', 'employee:read',
2026-06-29 11:32:54 +08:00
'supplier:read',
],
hr: [
'employee:read', 'employee:create', 'employee:update', 'employee:delete',
'user:manage',
'customer:read',
2026-06-24 22:44:14 +08:00
],
}
const [deptRows] = await pool.query('SELECT id, name FROM departments')
2026-06-24 22:44:14 +08:00
const [permRows] = await pool.query('SELECT id, name FROM permissions')
const deptIdMap = Object.fromEntries(deptRows.map(d => [d.name, d.id]))
2026-06-24 22:44:14 +08:00
const permIdMap = Object.fromEntries(permRows.map(p => [p.name, p.id]))
for (const [deptName, permNames] of Object.entries(deptPermMap)) {
2026-06-24 22:44:14 +08:00
for (const permName of permNames) {
await pool.query(
'INSERT IGNORE INTO department_permissions (department_id, permission_id) VALUES (?, ?)',
[deptIdMap[deptName], permIdMap[permName]]
2026-06-24 22:44:14 +08:00
)
}
}
console.log('[init] 已初始化部门-权限映射')
2026-06-24 22:44:14 +08:00
}
2026-06-29 15:07:53 +08:00
// ============ 4. 种子数据:默认用户(仅保留总经理账号) ============
2026-06-24 22:44:14 +08:00
async function seedDefaultUsers() {
const hash = await bcrypt.hash('123456', 10)
const [deptRows] = await pool.query('SELECT id, name FROM departments')
const deptIdMap = Object.fromEntries(deptRows.map(d => [d.name, d.id]))
2026-06-24 22:44:14 +08:00
2026-06-29 15:07:53 +08:00
// 总经理:张超
const emp = { name: '张超', gender: '男', age: 42, education: '硕士', department: '总经理办公室', entry_date: '2015-03-01', position: '总经理', salary: 50000, phone: '13800001001', email: 'zhangchao@mixue.com' }
const usr = { username: 'zhangchao', deptName: 'general_manager' }
2026-06-24 22:44:14 +08:00
2026-06-29 15:07:53 +08:00
const [userCheck] = await pool.query('SELECT id FROM users WHERE username = ?', [usr.username])
if (userCheck.length === 0) {
2026-06-24 22:44:14 +08:00
const [empResult] = await pool.query(
`INSERT INTO employees (name, gender, age, education, department, entry_date, position, salary, phone, email, status)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1)`,
[emp.name, emp.gender, emp.age, emp.education, emp.department, emp.entry_date, emp.position, emp.salary, emp.phone, emp.email]
)
2026-06-15 20:46:48 +08:00
await pool.query(
`INSERT INTO users (username, password, is_active, department_id, employee_id)
VALUES (?, ?, 1, ?, ?)`,
2026-06-29 15:07:53 +08:00
[usr.username, hash, deptIdMap[usr.deptName], empResult.insertId]
2026-06-15 20:46:48 +08:00
)
2026-06-29 15:07:53 +08:00
console.log(`[init] 已创建用户 ${usr.username} (${emp.name})`)
2026-06-15 20:46:48 +08:00
}
}
2026-06-29 15:07:53 +08:00
// ============ 5. 种子数据:业务数据(已注释,仅保留总经理账号) ============
// async function seedBusinessData() {
// // ---- 5.1 新增员工 ----
// const [empCheck] = await pool.query("SELECT id FROM employees WHERE name = '刘洋' LIMIT 1")
// if (empCheck.length === 0) {
// const extraEmployees = [
// { name: '刘洋', gender: '男', age: 28, education: '本科', department: '招商部', entry_date: '2021-03-15', position: '招商专员', salary: 8000, phone: '13800002001', email: 'liuyang@mixue.com' },
// { name: '孙婷', gender: '女', age: 26, education: '本科', department: '招商部', entry_date: '2022-02-20', position: '招商专员', salary: 7500, phone: '13800002002', email: 'sunting@mixue.com' },
// { name: '周杰', gender: '男', age: 30, education: '本科', department: '运营部', entry_date: '2021-06-01', position: '运营专员', salary: 8500, phone: '13800002003', email: 'zhoujie@mixue.com' },
// { name: '吴敏', gender: '女', age: 25, education: '本科', department: '运营部', entry_date: '2023-01-10', position: '运营专员', salary: 7000, phone: '13800002004', email: 'wumin@mixue.com' },
// { name: '郑伟', gender: '男', age: 32, education: '大专', department: '运营部', entry_date: '2020-08-15', position: '售后工程师', salary: 9000, phone: '13800002005', email: 'zhengwei@mixue.com' },
// { name: '黄磊', gender: '男', age: 29, education: '本科', department: '采购部', entry_date: '2022-04-01', position: '采购专员', salary: 8000, phone: '13800002006', email: 'huanglei@mixue.com' },
// { name: '马丽', gender: '女', age: 27, education: '本科', department: '财务部', entry_date: '2021-09-01', position: '会计', salary: 7500, phone: '13800002007', email: 'mali@mixue.com' },
// { name: '林峰', gender: '男', age: 45, education: '硕士', department: '总经理办公室', entry_date: '2016-05-01', position: '副总经理', salary: 35000, phone: '13800002008', email: 'linfeng@mixue.com' },
// ]
// for (const e of extraEmployees) {
// await pool.query(
// `INSERT INTO employees (name, gender, age, education, department, entry_date, position, salary, phone, email, status)
// VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1)`,
// [e.name, e.gender, e.age, e.education, e.department, e.entry_date, e.position, e.salary, e.phone, e.email]
// )
// }
// console.log('[init] 已初始化 8 条员工数据')
// }
// // ... 其余业务种子数据代码
// }
2026-06-15 20:46:48 +08:00
module.exports = { pool, initDB }