-- 工程项目管理系统 - 数据库初始化脚本 -- 基于docs/example.xls中的工程项目管理台账 -- 创建时间: 2026-01-25 -- ======================================== -- 1. 创建数据库(如果不存在) -- ======================================== CREATE DATABASE IF NOT EXISTS project_manager DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci; USE project_manager; -- ======================================== -- 2. 创建用户表 -- ======================================== CREATE TABLE IF NOT EXISTS users ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户ID', username VARCHAR(50) UNIQUE NOT NULL COMMENT '用户名', password_hash VARCHAR(255) NOT NULL COMMENT '密码哈希', real_name VARCHAR(100) NOT NULL COMMENT '真实姓名', department VARCHAR(50) NOT NULL COMMENT '部门(市场部/技术部/财务部等)', role ENUM('admin', 'market', 'other') NOT NULL COMMENT '角色(admin/market/other)', email VARCHAR(100) UNIQUE COMMENT '邮箱', phone VARCHAR(20) COMMENT '电话', is_active BOOLEAN DEFAULT TRUE COMMENT '是否激活', created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', INDEX idx_users_username (username), INDEX idx_users_department (department), INDEX idx_users_role (role) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'; -- ======================================== -- 3. 创建项目表(基于Excel结构) -- ======================================== CREATE TABLE IF NOT EXISTS projects ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT '项目ID', project_no VARCHAR(50) UNIQUE NOT NULL COMMENT '合同编号', power_contract_no VARCHAR(100) COMMENT '供电局项目合同编号', name VARCHAR(200) NOT NULL COMMENT '项目名称', subitem_count INT DEFAULT 0 COMMENT '子项个数', subitem_code VARCHAR(50) COMMENT '子项编码', total_investment DECIMAL(15,2) COMMENT '项目总投资(万元)', contract_amount DECIMAL(15,2) COMMENT '中标合同金额(万元)', warranty_ratio DECIMAL(5,2) COMMENT '质保金比例', settlement_amount DECIMAL(15,2) COMMENT '结算金额(万元)', total_cost_estimated DECIMAL(15,2) COMMENT '总成本测算', voltage_level VARCHAR(50) COMMENT '工程电压等级', engineering_type VARCHAR(50) COMMENT '工程类别(基建/业扩/客户/营销/检修)', owner_unit VARCHAR(200) COMMENT '业主单位', owner_contact VARCHAR(200) COMMENT '业主联系人及电话', bidding_type VARCHAR(50) COMMENT '中标形式', signing_date DATE COMMENT '签订日期', start_date DATE COMMENT '开工日期', planned_end_date DATE COMMENT '计划竣工日期', actual_end_date DATE COMMENT '实际竣工日期', warranty_amount DECIMAL(15,2) DEFAULT 0 COMMENT '质保金(万元)', warranty_expiry_date DATE COMMENT '质保期截止日', actual_warranty_refund_date DATE COMMENT '实际退质保金日期', project_department VARCHAR(100) COMMENT '所属项目部', project_leader VARCHAR(200) COMMENT '项目负责人及电话', payment_method TEXT COMMENT '工程款拨付方式', total_cost_control DECIMAL(15,2) COMMENT '总体成本(控制)', is_adjusted ENUM('是', '否') DEFAULT '否' COMMENT '是否调整', labor_cost_control DECIMAL(15,2) COMMENT '其中:人工成本(控制)', labor_cost_planned DECIMAL(15,2) COMMENT '农民工工资(按进度计划)', labor_cost_paid DECIMAL(15,2) COMMENT '农民工工资(实付)', material_cost_control DECIMAL(15,2) COMMENT '其中:乙供材料费(控制)', material_cost_payable DECIMAL(15,2) COMMENT '应付材料费(按收款比例)', material_cost_actual DECIMAL(15,2) COMMENT '实际发生材料费', material_cost_paid DECIMAL(15,2) COMMENT '实际支付材料费', other_cost_control DECIMAL(15,2) COMMENT '其中:其他费用(控制)', other_cost_payable DECIMAL(15,2) COMMENT '应付其他费', other_cost_actual DECIMAL(15,2) COMMENT '实际其他费用', tax_amount DECIMAL(15,2) COMMENT '税金', profit DECIMAL(15,2) COMMENT '利润(万元)', actual_profit DECIMAL(15,2) COMMENT '实际利润(万元)', cost_settlement_amount DECIMAL(15,2) COMMENT '成本结算金额(万元)', cumulative_progress DECIMAL(5,2) COMMENT '累计进度', receivable_amount DECIMAL(15,2) COMMENT '应收款(完成进度款)', invoice_amount DECIMAL(15,2) COMMENT '开票金额(万元)', actual_receipt_amount DECIMAL(15,2) COMMENT '实际收款金额(万元)', receipt_completion_rate DECIMAL(5,2) COMMENT '实际收款完成率', payable_amount DECIMAL(15,2) COMMENT '应付款金额(万元)', actual_payment_amount DECIMAL(15,2) COMMENT '实际付款金额(万元)', unpaid_amount DECIMAL(15,2) COMMENT '未收款(万元)', payment_completion_rate DECIMAL(5,2) COMMENT '实际付款完成率', labor_debt_amount DECIMAL(15,2) COMMENT '民工工资清欠金额(万元)', settlement_cost_amount DECIMAL(15,2) COMMENT '结算后成本测算金额', settlement_labor_cost DECIMAL(15,2) COMMENT '结算人工费', settlement_material_cost DECIMAL(15,2) COMMENT '结算材料费', settlement_other_cost DECIMAL(15,2) COMMENT '结算其他费', due_settlement_count INT COMMENT '到期应结算项目个数', unsettlement_count INT COMMENT '到期未完成结算个数', problems TEXT COMMENT '存在的问题', suggestions TEXT COMMENT '建议措施', remarks TEXT COMMENT '备注', status VARCHAR(50) DEFAULT '新建' COMMENT '项目状态', created_by INT NOT NULL COMMENT '创建人ID', created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE RESTRICT, INDEX idx_projects_project_no (project_no), INDEX idx_projects_engineering_type (engineering_type), INDEX idx_projects_project_department (project_department), INDEX idx_projects_status (status), INDEX idx_projects_created_by (created_by), INDEX idx_projects_signing_date (signing_date), INDEX idx_projects_planned_end_date (planned_end_date), INDEX idx_projects_type_status (engineering_type, status) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='工程项目表'; -- ======================================== -- 4. 插入初始管理员用户 -- ======================================== INSERT INTO users (username, password_hash, real_name, department, role, email, phone) VALUES ('admin', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewY5GyW5q7K1U1.2', '系统管理员', '管理部', 'admin', 'admin@example.com', '13800000000') ON DUPLICATE KEY UPDATE username=username; -- ======================================== -- 5. 创建视图:项目统计视图 -- ======================================== CREATE OR REPLACE VIEW project_statistics AS SELECT engineering_type AS 工程类别, COUNT(*) AS 项目总数, SUM(contract_amount) AS 合同总金额, SUM(actual_receipt_amount) AS 实际收款总金额, SUM(actual_payment_amount) AS 实际付款总金额, AVG(receipt_completion_rate) AS 平均收款完成率, AVG(payment_completion_rate) AS 平均付款完成率, SUM(CASE WHEN status = '新建' THEN 1 ELSE 0 END) AS 新建项目, SUM(CASE WHEN status = '进行中' THEN 1 ELSE 0 END) AS 进行中项目, SUM(CASE WHEN status = '已完成' THEN 1 ELSE 0 END) AS 已完成项目 FROM projects GROUP BY engineering_type; -- ======================================== -- 6. 创建视图:项目详情视图 -- ======================================== CREATE OR REPLACE VIEW project_detail_view AS SELECT p.id, p.project_no, p.name, p.engineering_type, p.contract_amount, p.actual_receipt_amount, p.actual_payment_amount, p.receipt_completion_rate, p.payment_completion_rate, p.status, p.project_department, p.project_leader, p.signing_date, p.planned_end_date, p.actual_end_date, u.real_name AS created_by_name, p.created_at, p.updated_at FROM projects p LEFT JOIN users u ON p.created_by = u.id; -- ======================================== -- 7. 创建存储过程:更新项目收款完成率 -- ======================================== DELIMITER // CREATE PROCEDURE update_receipt_completion_rate(IN project_id INT) BEGIN UPDATE projects SET receipt_completion_rate = CASE WHEN contract_amount > 0 THEN ROUND(actual_receipt_amount / contract_amount * 100, 2) ELSE 0 END WHERE id = project_id; END // DELIMITER ; -- ======================================== -- 8. 创建存储过程:更新项目付款完成率 -- ======================================== DELIMITER // CREATE PROCEDURE update_payment_completion_rate(IN project_id INT) BEGIN UPDATE projects SET payment_completion_rate = CASE WHEN payable_amount > 0 THEN ROUND(actual_payment_amount / payable_amount * 100, 2) ELSE 0 END WHERE id = project_id; END // DELIMITER ; -- ======================================== -- 9. 创建触发器:插入项目前自动生成合同编号 -- ======================================== DELIMITER // CREATE TRIGGER before_project_insert BEFORE INSERT ON projects FOR EACH ROW BEGIN IF NEW.project_no IS NULL OR NEW.project_no = '' THEN SET NEW.project_no = CONCAT('PRJ', DATE_FORMAT(NOW(), '%Y%m%d'), LPAD((SELECT COUNT(*) + 1 FROM projects), 4, '0')); END IF; END // DELIMITER ; -- ======================================== -- 10. 创建触发器:更新项目时自动更新时间戳 -- ======================================== DELIMITER // CREATE TRIGGER before_project_update BEFORE UPDATE ON projects FOR EACH ROW BEGIN SET NEW.updated_at = NOW(); END // DELIMITER ; -- ======================================== -- 完成 -- ======================================== -- 数据库初始化完成 -- 执行 backend/config/import-excel-data.py 来导入Excel数据