1120 lines
54 KiB
JavaScript
1120 lines
54 KiB
JavaScript
const sqlite3 = require('sqlite3').verbose();
|
|
const path = require('path');
|
|
|
|
// 创建SQLite数据库连接
|
|
const dbPath = path.join(__dirname, 'company_finance.db');
|
|
const db = new sqlite3.Database(dbPath, (err) => {
|
|
if (err) {
|
|
console.error('数据库连接失败:', err.message);
|
|
} else {
|
|
console.log('SQLite数据库连接成功');
|
|
initializeDatabase();
|
|
}
|
|
});
|
|
|
|
// 初始化数据库
|
|
function initializeDatabase() {
|
|
// 创建用户表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
username TEXT UNIQUE NOT NULL,
|
|
password TEXT NOT NULL,
|
|
name TEXT,
|
|
role TEXT NOT NULL DEFAULT 'user',
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建用户表失败:', err.message);
|
|
} else {
|
|
// 创建项目表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS projects (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
code TEXT UNIQUE NOT NULL,
|
|
customer_id INTEGER,
|
|
manager_id INTEGER,
|
|
contract_amount REAL DEFAULT 0.0,
|
|
start_date DATE,
|
|
end_date DATE,
|
|
description TEXT,
|
|
status TEXT DEFAULT 'active',
|
|
location TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (manager_id) REFERENCES users(id)
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建项目表失败:', err.message);
|
|
} else {
|
|
// 创建客户表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS customers (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
contact TEXT,
|
|
position TEXT,
|
|
phone TEXT,
|
|
email TEXT,
|
|
address TEXT,
|
|
remark TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建客户表失败:', err.message);
|
|
} else {
|
|
// 创建供应商表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS suppliers (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
contact TEXT,
|
|
position TEXT,
|
|
phone TEXT,
|
|
email TEXT,
|
|
address TEXT,
|
|
supply_category TEXT,
|
|
country TEXT,
|
|
remark TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建供应商表失败:', err.message);
|
|
} else {
|
|
// 创建分包商表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS subcontractors (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
contact TEXT,
|
|
position TEXT,
|
|
phone TEXT,
|
|
email TEXT,
|
|
address TEXT,
|
|
scope TEXT,
|
|
features TEXT,
|
|
country TEXT,
|
|
remark TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建分包商表失败:', err.message);
|
|
} else {
|
|
// 创建商品表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS products (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
category_id INTEGER,
|
|
unit TEXT,
|
|
price REAL,
|
|
description TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建商品表失败:', err.message);
|
|
} else {
|
|
// 创建分类表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS categories (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
parent_id INTEGER,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建分类表失败:', err.message);
|
|
} else {
|
|
// 创建预算项目表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS budget_projects (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
customer_id INTEGER,
|
|
manager_id INTEGER,
|
|
location TEXT,
|
|
survey_date DATE,
|
|
intermediary TEXT,
|
|
intermediary_fee_type TEXT,
|
|
intermediary_fee_value REAL,
|
|
customer_requirements TEXT,
|
|
project_overview TEXT,
|
|
attachments TEXT,
|
|
survey_photos TEXT,
|
|
status TEXT DEFAULT 'negotiating',
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (customer_id) REFERENCES customers(id),
|
|
FOREIGN KEY (manager_id) REFERENCES users(id)
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建预算项目表失败:', err.message);
|
|
} else {
|
|
// 创建报价表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS budget_quotations (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
project_id INTEGER,
|
|
version INTEGER,
|
|
quotation_date DATE,
|
|
amount REAL,
|
|
currency TEXT DEFAULT 'CNY',
|
|
status TEXT DEFAULT 'draft',
|
|
file_url TEXT,
|
|
remark TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (project_id) REFERENCES budget_projects(id)
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建报价表失败:', err.message);
|
|
} else {
|
|
// 创建项目合同表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS project_contracts (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
project_id INTEGER,
|
|
contract_code TEXT UNIQUE NOT NULL,
|
|
contract_amount REAL NOT NULL,
|
|
currency TEXT DEFAULT 'CNY',
|
|
settlement_method TEXT,
|
|
contract_period INTEGER,
|
|
start_date DATE,
|
|
end_date DATE,
|
|
warranty_deposit_percentage REAL DEFAULT 5,
|
|
warranty_period INTEGER DEFAULT 12,
|
|
contract_file TEXT,
|
|
other_info TEXT,
|
|
tax_included INTEGER DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (project_id) REFERENCES projects(id)
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建项目合同表失败:', err.message);
|
|
} else {
|
|
// 创建分包合同表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS subcontracts (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
project_id INTEGER,
|
|
subcontractor_id INTEGER,
|
|
subcontractor_name TEXT,
|
|
contract_amount REAL NOT NULL,
|
|
currency TEXT DEFAULT 'CNY',
|
|
settlement_type TEXT DEFAULT 'lump_sum',
|
|
other_terms TEXT,
|
|
payment_description TEXT,
|
|
start_date DATE,
|
|
end_date DATE,
|
|
paid_amount REAL DEFAULT 0,
|
|
status TEXT DEFAULT 'active',
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (project_id) REFERENCES projects(id),
|
|
FOREIGN KEY (subcontractor_id) REFERENCES subcontractors(id)
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建分包合同表失败:', err.message);
|
|
} else {
|
|
// 添加新列到分包合同表
|
|
db.run(`ALTER TABLE subcontracts ADD COLUMN settlement_type TEXT DEFAULT 'lump_sum'`, (err) => {
|
|
if (err) {
|
|
// 忽略列已存在的错误
|
|
}
|
|
});
|
|
db.run(`ALTER TABLE subcontracts ADD COLUMN other_terms TEXT`, (err) => {
|
|
if (err) {
|
|
// 忽略列已存在的错误
|
|
}
|
|
});
|
|
db.run(`ALTER TABLE subcontracts ADD COLUMN payment_description TEXT`, (err) => {
|
|
if (err) {
|
|
// 忽略列已存在的错误
|
|
}
|
|
});
|
|
db.run(`ALTER TABLE subcontracts ADD COLUMN unit_price_items TEXT`, (err) => {
|
|
if (err) {
|
|
// 忽略列已存在的错误
|
|
}
|
|
});
|
|
|
|
// 创建项目材料表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS project_materials (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
project_id INTEGER,
|
|
product_id INTEGER,
|
|
product_name TEXT,
|
|
unit TEXT,
|
|
budget_quantity REAL,
|
|
purchase_quantity REAL,
|
|
used_quantity REAL,
|
|
average_price REAL,
|
|
total_amount REAL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (project_id) REFERENCES projects(id),
|
|
FOREIGN KEY (product_id) REFERENCES products(id)
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建项目材料表失败:', err.message);
|
|
} else {
|
|
// 创建施工节点表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS project_milestones (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
project_id INTEGER,
|
|
milestone_name TEXT,
|
|
percentage REAL,
|
|
amount REAL,
|
|
expected_date DATE,
|
|
actual_date DATE,
|
|
completion_progress INTEGER DEFAULT 0,
|
|
status TEXT DEFAULT 'pending',
|
|
voucher TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (project_id) REFERENCES projects(id)
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建施工节点表失败:', err.message);
|
|
} else {
|
|
// 创建项目财务信息表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS project_finances (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
project_id INTEGER,
|
|
payment_type TEXT,
|
|
amount REAL DEFAULT 0,
|
|
currency TEXT DEFAULT 'CNY',
|
|
payment_date DATE,
|
|
status TEXT DEFAULT 'pending',
|
|
description TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (project_id) REFERENCES projects(id)
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建项目财务信息表失败:', err.message);
|
|
} else {
|
|
// 创建质保金表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS warranty_deposits (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
project_id INTEGER,
|
|
amount REAL NOT NULL,
|
|
currency TEXT DEFAULT 'CNY',
|
|
warranty_period INTEGER DEFAULT 12,
|
|
start_date DATE,
|
|
end_date DATE,
|
|
status TEXT DEFAULT 'active',
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (project_id) REFERENCES projects(id)
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建质保金表失败:', err.message);
|
|
} else {
|
|
// 创建施工日志表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS construction_logs (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
project_id INTEGER,
|
|
log_date DATE,
|
|
weather TEXT,
|
|
work_content TEXT,
|
|
photos TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (project_id) REFERENCES projects(id)
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建施工日志表失败:', err.message);
|
|
} else {
|
|
// 创建联系人表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS contacts (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
entity_id INTEGER NOT NULL,
|
|
entity_type TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
position TEXT,
|
|
phone TEXT,
|
|
is_primary INTEGER DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建联系人表失败:', err.message);
|
|
} else {
|
|
// 创建汇率表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS exchange_rates (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
pair_key TEXT NOT NULL,
|
|
rate REAL NOT NULL,
|
|
effective_date DATE NOT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建汇率表失败:', err.message);
|
|
} else {
|
|
// 创建预支款表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS advances (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER,
|
|
project_id INTEGER,
|
|
amount REAL NOT NULL,
|
|
currency TEXT DEFAULT 'CNY',
|
|
amount_cny REAL DEFAULT 0,
|
|
reason TEXT NOT NULL,
|
|
advance_date DATE,
|
|
advance_code TEXT UNIQUE NOT NULL,
|
|
status TEXT DEFAULT 'pending',
|
|
applicant TEXT,
|
|
attachments TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (user_id) REFERENCES users(id),
|
|
FOREIGN KEY (project_id) REFERENCES projects(id)
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建预支款表失败:', err.message);
|
|
} else {
|
|
// 创建报销表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS reimbursements (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER,
|
|
project_id INTEGER,
|
|
amount REAL NOT NULL,
|
|
currency TEXT DEFAULT 'CNY',
|
|
amount_cny REAL DEFAULT 0,
|
|
reason TEXT NOT NULL,
|
|
reimbursement_date DATE,
|
|
reimbursement_code TEXT UNIQUE NOT NULL,
|
|
status TEXT DEFAULT 'pending',
|
|
applicant TEXT,
|
|
expense_type TEXT NOT NULL,
|
|
detail_items TEXT,
|
|
attachments TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (user_id) REFERENCES users(id),
|
|
FOREIGN KEY (project_id) REFERENCES projects(id)
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建报销表失败:', err.message);
|
|
} else {
|
|
// 创建付款申请表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS payment_requests (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
request_code TEXT UNIQUE NOT NULL,
|
|
applicant TEXT NOT NULL,
|
|
payee TEXT NOT NULL,
|
|
bank_account TEXT NOT NULL,
|
|
bank_name TEXT NOT NULL,
|
|
amount REAL NOT NULL,
|
|
amount_cny REAL DEFAULT 0,
|
|
currency TEXT DEFAULT 'CNY',
|
|
payment_date DATE NOT NULL,
|
|
reason TEXT NOT NULL,
|
|
detail_items TEXT,
|
|
attachments TEXT,
|
|
status TEXT DEFAULT 'pending',
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建付款申请表失败:', err.message);
|
|
} else {
|
|
// 创建核销申请表
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS verifications (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
verification_code TEXT UNIQUE NOT NULL,
|
|
applicant TEXT NOT NULL,
|
|
advance_code TEXT NOT NULL,
|
|
advance_amount REAL NOT NULL,
|
|
amount REAL NOT NULL,
|
|
amount_cny REAL DEFAULT 0,
|
|
currency TEXT DEFAULT 'CNY',
|
|
verification_date DATE NOT NULL,
|
|
reason TEXT NOT NULL,
|
|
detail_items TEXT,
|
|
attachments TEXT,
|
|
status TEXT DEFAULT 'pending',
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`, (err) => {
|
|
if (err) {
|
|
console.error('创建核销申请表失败:', err.message);
|
|
} else {
|
|
console.log('所有表创建成功');
|
|
// 暂时注释掉测试数据插入,以便用户使用真实数据
|
|
// insertTestData();
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// 插入测试数据
|
|
function insertTestData() {
|
|
// 检查是否已有用户数据
|
|
db.get('SELECT COUNT(*) as count FROM users', (err, row) => {
|
|
if (err) {
|
|
console.error('查询用户数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
// 插入测试用户(与前端界面一致)
|
|
const users = [
|
|
['admin', 'X123c321@', '系统管理员', 'admin'],
|
|
['finance', 'X123c321@', '财务专员', 'finance'],
|
|
['manager', 'X123c321@', '项目经理', 'manager'],
|
|
['employee', 'X123c321@', '普通员工', 'employee']
|
|
];
|
|
|
|
users.forEach(user => {
|
|
db.run(
|
|
'INSERT INTO users (username, password, name, role) VALUES (?, ?, ?, ?)',
|
|
user,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入用户数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试客户数据
|
|
db.get('SELECT COUNT(*) as count FROM customers', (err, row) => {
|
|
if (err) {
|
|
console.error('查询客户数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const customers = [
|
|
['老挝电力公司', '张三', '13800138001', 'zhangsan@example.com', '老挝万象市'],
|
|
['泰国能源集团', '李四', '13900139001', 'lisi@example.com', '泰国曼谷市'],
|
|
['越南电力局', '王五', '13700137001', 'wangwu@example.com', '越南河内市']
|
|
];
|
|
|
|
customers.forEach(customer => {
|
|
db.run(
|
|
'INSERT INTO customers (name, contact, phone, email, address) VALUES (?, ?, ?, ?, ?)',
|
|
customer,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入客户数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试供应商数据
|
|
db.get('SELECT COUNT(*) as count FROM suppliers', (err, row) => {
|
|
if (err) {
|
|
console.error('查询供应商数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const suppliers = [
|
|
['中国电力设备有限公司', '赵六', '13600136001', 'zhaoliu@example.com', '中国北京市'],
|
|
['东南亚建材贸易公司', '孙七', '13500135001', 'sunqi@example.com', '泰国曼谷市'],
|
|
['老挝本地供应商', '周八', '13400134001', 'zhouba@example.com', '老挝万象市']
|
|
];
|
|
|
|
suppliers.forEach(supplier => {
|
|
db.run(
|
|
'INSERT INTO suppliers (name, contact, phone, email, address) VALUES (?, ?, ?, ?, ?)',
|
|
supplier,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入供应商数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试分包商数据
|
|
db.get('SELECT COUNT(*) as count FROM subcontractors', (err, row) => {
|
|
if (err) {
|
|
console.error('查询分包商数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const subcontractors = [
|
|
['老挝施工队A', '吴九', '13300133001', 'wujing@example.com', '老挝万象市'],
|
|
['泰国施工队B', '郑十', '13200132001', 'zhengshi@example.com', '泰国清迈市'],
|
|
['越南施工队C', '王十一', '13100131001', 'wangshiyi@example.com', '越南河内市']
|
|
];
|
|
|
|
subcontractors.forEach(subcontractor => {
|
|
db.run(
|
|
'INSERT INTO subcontractors (name, contact, phone, email, address) VALUES (?, ?, ?, ?, ?)',
|
|
subcontractor,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入分包商数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试分类数据
|
|
db.get('SELECT COUNT(*) as count FROM categories', (err, row) => {
|
|
if (err) {
|
|
console.error('查询分类数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const categories = [
|
|
['电线电缆', null],
|
|
['高压绝缘线', 1],
|
|
['低压电缆', 1],
|
|
['钢绞线', 1],
|
|
['绝缘子', null],
|
|
['陶瓷绝缘子', 5],
|
|
['复合绝缘子', 5],
|
|
['金具', null],
|
|
['线夹', 8],
|
|
['间隔棒', 8]
|
|
];
|
|
|
|
categories.forEach(category => {
|
|
db.run(
|
|
'INSERT INTO categories (name, parent_id) VALUES (?, ?)',
|
|
category,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入分类数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试商品数据
|
|
db.get('SELECT COUNT(*) as count FROM products', (err, row) => {
|
|
if (err) {
|
|
console.error('查询商品数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const products = [
|
|
['JKLYJ-35-22kV', 2, '米', 15.5, '高压绝缘线'],
|
|
['JKLYJ-50-22kV', 2, '米', 18.8, '高压绝缘线'],
|
|
['VV-3x25+1x16', 3, '米', 22.5, '低压电缆'],
|
|
['GJ-35', 4, '米', 8.2, '钢绞线'],
|
|
['XP-70', 6, '个', 25.0, '陶瓷绝缘子'],
|
|
['FXBW-10/70', 7, '个', 85.0, '复合绝缘子'],
|
|
['NLL-1', 9, '个', 12.5, '线夹'],
|
|
['JGX-35', 9, '个', 18.0, '线夹'],
|
|
['FJB-2', 10, '个', 22.0, '间隔棒']
|
|
];
|
|
|
|
products.forEach(product => {
|
|
db.run(
|
|
'INSERT INTO products (name, category_id, unit, price, description) VALUES (?, ?, ?, ?, ?)',
|
|
product,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入商品数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试项目数据
|
|
db.get('SELECT COUNT(*) as count FROM projects', (err, row) => {
|
|
if (err) {
|
|
console.error('查询项目数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const projects = [
|
|
['老挝万象市电力线路改造项目', 'PROJ-2024-001', 1, 5000000.0, '2024-01-01', '2024-06-30', '对老挝万象市的电力线路进行改造升级'],
|
|
['泰国清迈市变电站建设项目', 'PROJ-2024-002', 2, 8000000.0, '2024-02-01', '2024-08-31', '在泰国清迈市建设一座新的变电站'],
|
|
['越南河内市电网扩容项目', 'PROJ-2024-003', 3, 6500000.0, '2024-03-01', '2024-09-30', '对越南河内市的电网进行扩容升级']
|
|
];
|
|
|
|
projects.forEach(project => {
|
|
db.run(
|
|
'INSERT INTO projects (name, code, customer_id, contract_amount, start_date, end_date, description) VALUES (?, ?, ?, ?, ?, ?, ?)',
|
|
project,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入项目数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试预算项目数据
|
|
db.get('SELECT COUNT(*) as count FROM budget_projects', (err, row) => {
|
|
if (err) {
|
|
console.error('查询预算项目数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const budgetProjects = [
|
|
['老挝琅勃拉邦电力线路项目', 1, 1, '老挝琅勃拉邦市', '2024-01-15', '张三', 'fixed', 50000.0, '需要建设10公里电力线路', '项目位于老挝琅勃拉邦市,需要建设10公里的110kV电力线路'],
|
|
['泰国普吉岛变电站项目', 2, 2, '泰国普吉岛', '2024-02-10', '李四', 'percentage', 5.0, '需要建设一座35kV变电站', '项目位于泰国普吉岛,需要建设一座35kV变电站,满足当地旅游区的用电需求'],
|
|
['越南胡志明市电网改造项目', 3, 3, '越南胡志明市', '2024-03-05', '王五', 'fixed', 80000.0, '需要对现有电网进行改造升级', '项目位于越南胡志明市,需要对现有10kV电网进行改造升级,提高供电可靠性']
|
|
];
|
|
|
|
budgetProjects.forEach(project => {
|
|
db.run(
|
|
'INSERT INTO budget_projects (name, customer_id, manager_id, location, survey_date, intermediary, intermediary_fee_type, intermediary_fee_value, customer_requirements, project_overview) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
|
project,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入预算项目数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试报价数据
|
|
db.get('SELECT COUNT(*) as count FROM budget_quotations', (err, row) => {
|
|
if (err) {
|
|
console.error('查询报价数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const quotations = [
|
|
[1, 1, '2024-01-20', 4500000.0, 'CNY', 'sent', null, '初始报价'],
|
|
[1, 2, '2024-01-25', 4200000.0, 'CNY', 'approved', null, '最终报价'],
|
|
[2, 1, '2024-02-15', 7500000.0, 'CNY', 'draft', null, '初始报价'],
|
|
[3, 1, '2024-03-10', 6000000.0, 'CNY', 'sent', null, '初始报价']
|
|
];
|
|
|
|
quotations.forEach(quotation => {
|
|
db.run(
|
|
'INSERT INTO budget_quotations (project_id, version, quotation_date, amount, currency, status, file_url, remark) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
|
quotation,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入报价数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试项目合同数据
|
|
db.get('SELECT COUNT(*) as count FROM project_contracts', (err, row) => {
|
|
if (err) {
|
|
console.error('查询项目合同数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const contracts = [
|
|
[1, 'CONTRACT-2024-001', 5000000.0, 'CNY', '按月结算', 180, '2024-01-01', '2024-06-30', 5, 12, null],
|
|
[2, 'CONTRACT-2024-002', 8000000.0, 'CNY', '按节点结算', 210, '2024-02-01', '2024-08-31', 5, 12, null],
|
|
[3, 'CONTRACT-2024-003', 6500000.0, 'CNY', '按进度结算', 210, '2024-03-01', '2024-09-30', 5, 12, null]
|
|
];
|
|
|
|
contracts.forEach(contract => {
|
|
db.run(
|
|
'INSERT INTO project_contracts (project_id, contract_code, contract_amount, currency, settlement_method, contract_period, start_date, end_date, warranty_deposit_percentage, warranty_period, contract_file) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
|
contract,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入项目合同数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试分包合同数据
|
|
db.get('SELECT COUNT(*) as count FROM subcontracts', (err, row) => {
|
|
if (err) {
|
|
console.error('查询分包合同数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const subcontracts = [
|
|
[1, 1, '老挝施工队A', 1500000.0, 'CNY', '2024-01-01', '2024-06-30', 500000.0, 'active'],
|
|
[1, 2, '泰国施工队B', 1000000.0, 'CNY', '2024-01-15', '2024-06-15', 300000.0, 'active'],
|
|
[2, 1, '老挝施工队A', 2500000.0, 'CNY', '2024-02-01', '2024-08-31', 800000.0, 'active'],
|
|
[3, 3, '越南施工队C', 2000000.0, 'CNY', '2024-03-01', '2024-09-30', 600000.0, 'active']
|
|
];
|
|
|
|
subcontracts.forEach(subcontract => {
|
|
db.run(
|
|
'INSERT INTO subcontracts (project_id, subcontractor_id, subcontractor_name, contract_amount, currency, start_date, end_date, paid_amount, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
|
subcontract,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入分包合同数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试项目材料数据
|
|
db.get('SELECT COUNT(*) as count FROM project_materials', (err, row) => {
|
|
if (err) {
|
|
console.error('查询项目材料数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const materials = [
|
|
[1, 1, 'JKLYJ-35-22kV', '米', 10000, 10500, 5000, 15.5, 162750],
|
|
[1, 4, 'GJ-35', '米', 8000, 8500, 4000, 8.2, 69700],
|
|
[1, 5, 'XP-70', '个', 500, 520, 200, 25.0, 13000],
|
|
[2, 2, 'JKLYJ-50-22kV', '米', 15000, 15500, 6000, 18.8, 291400],
|
|
[2, 6, 'FXBW-10/70', '个', 300, 320, 100, 85.0, 27200],
|
|
[3, 3, 'VV-3x25+1x16', '米', 12000, 12500, 5000, 22.5, 281250],
|
|
[3, 7, 'NLL-1', '个', 800, 850, 300, 12.5, 10625],
|
|
[3, 9, 'FJB-2', '个', 400, 420, 150, 22.0, 9240]
|
|
];
|
|
|
|
materials.forEach(material => {
|
|
db.run(
|
|
'INSERT INTO project_materials (project_id, product_id, product_name, unit, budget_quantity, purchase_quantity, used_quantity, average_price, total_amount) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
|
material,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入项目材料数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试施工节点数据
|
|
db.get('SELECT COUNT(*) as count FROM project_milestones', (err, row) => {
|
|
if (err) {
|
|
console.error('查询施工节点数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const milestones = [
|
|
[1, '项目启动', 10, 500000.0, '2024-01-01', '2024-01-01', 100, 'completed', null],
|
|
[1, '基础施工', 30, 1500000.0, '2024-01-15', '2024-02-15', 100, 'completed', null],
|
|
[1, '线路架设', 40, 2000000.0, '2024-02-20', '2024-04-20', 60, 'in_progress', null],
|
|
[1, '竣工验收', 20, 1000000.0, '2024-06-15', null, 0, 'pending', null],
|
|
[2, '项目启动', 10, 800000.0, '2024-02-01', '2024-02-01', 100, 'completed', null],
|
|
[2, '基础施工', 30, 2400000.0, '2024-02-15', '2024-03-15', 100, 'completed', null],
|
|
[2, '设备安装', 40, 3200000.0, '2024-03-20', '2024-06-20', 70, 'in_progress', null],
|
|
[2, '竣工验收', 20, 1600000.0, '2024-08-15', null, 0, 'pending', null],
|
|
[3, '项目启动', 10, 650000.0, '2024-03-01', '2024-03-01', 100, 'completed', null],
|
|
[3, '线路改造', 50, 3250000.0, '2024-03-15', '2024-06-15', 80, 'in_progress', null],
|
|
[3, '设备升级', 30, 1950000.0, '2024-06-20', '2024-08-20', 30, 'in_progress', null],
|
|
[3, '竣工验收', 10, 650000.0, '2024-09-15', null, 0, 'pending', null]
|
|
];
|
|
|
|
milestones.forEach(milestone => {
|
|
db.run(
|
|
'INSERT INTO project_milestones (project_id, milestone_name, percentage, amount, expected_date, actual_date, completion_progress, status, voucher) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
|
milestone,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入施工节点数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试项目财务信息数据
|
|
db.get('SELECT COUNT(*) as count FROM project_finances', (err, row) => {
|
|
if (err) {
|
|
console.error('查询项目财务信息数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const finances = [
|
|
[1, 'income', 500000.0, 'CNY', '2024-01-01', 'completed', '项目启动款'],
|
|
[1, 'income', 1500000.0, 'CNY', '2024-02-15', 'completed', '基础施工款'],
|
|
[1, 'expense', 500000.0, 'CNY', '2024-01-10', 'completed', '材料采购'],
|
|
[1, 'expense', 300000.0, 'CNY', '2024-02-20', 'completed', '分包款'],
|
|
[2, 'income', 800000.0, 'CNY', '2024-02-01', 'completed', '项目启动款'],
|
|
[2, 'income', 2400000.0, 'CNY', '2024-03-15', 'completed', '基础施工款'],
|
|
[2, 'expense', 800000.0, 'CNY', '2024-02-10', 'completed', '材料采购'],
|
|
[3, 'income', 650000.0, 'CNY', '2024-03-01', 'completed', '项目启动款'],
|
|
[3, 'expense', 600000.0, 'CNY', '2024-03-10', 'completed', '材料采购']
|
|
];
|
|
|
|
finances.forEach(finance => {
|
|
db.run(
|
|
'INSERT INTO project_finances (project_id, payment_type, amount, currency, payment_date, status, description) VALUES (?, ?, ?, ?, ?, ?, ?)',
|
|
finance,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入项目财务信息数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试质保金数据
|
|
db.get('SELECT COUNT(*) as count FROM warranty_deposits', (err, row) => {
|
|
if (err) {
|
|
console.error('查询质保金数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const warrantyDeposits = [
|
|
[1, 250000.0, 'CNY', 12, '2024-06-30', '2025-06-30', 'active'],
|
|
[2, 400000.0, 'CNY', 12, '2024-08-31', '2025-08-31', 'active'],
|
|
[3, 325000.0, 'CNY', 12, '2024-09-30', '2025-09-30', 'active']
|
|
];
|
|
|
|
warrantyDeposits.forEach(deposit => {
|
|
db.run(
|
|
'INSERT INTO warranty_deposits (project_id, amount, currency, warranty_period, start_date, end_date, status) VALUES (?, ?, ?, ?, ?, ?, ?)',
|
|
deposit,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入质保金数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试联系人数据
|
|
db.get('SELECT COUNT(*) as count FROM contacts', (err, row) => {
|
|
if (err) {
|
|
console.error('查询联系人数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const contacts = [
|
|
// 供应商联系人
|
|
[1, 'supplier', '赵六', '经理', '13600136001', 1],
|
|
[1, 'supplier', '钱七', '销售', '13500135001', 0],
|
|
[2, 'supplier', '孙八', '技术', '13400134001', 1],
|
|
// 客户联系人
|
|
[1, 'customer', '张三', '采购', '13800138001', 1],
|
|
[1, 'customer', '李四', '经理', '13900139001', 0],
|
|
[2, 'customer', '王五', '财务', '13700137001', 1],
|
|
// 分包商联系人
|
|
[1, 'subcontractor', '吴九', '项目经理', '13300133001', 1],
|
|
[1, 'subcontractor', '郑十', '技术主管', '13200132001', 0],
|
|
[2, 'subcontractor', '王十一', '施工队长', '13100131001', 1]
|
|
];
|
|
|
|
contacts.forEach(contact => {
|
|
db.run(
|
|
'INSERT INTO contacts (entity_id, entity_type, name, position, phone, is_primary) VALUES (?, ?, ?, ?, ?, ?)',
|
|
contact,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入联系人数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试施工日志数据
|
|
db.get('SELECT COUNT(*) as count FROM construction_logs', (err, row) => {
|
|
if (err) {
|
|
console.error('查询施工日志数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const logs = [
|
|
[1, '2024-01-01', 'sunny', '项目启动,召开开工会议', ''],
|
|
[1, '2024-01-02', 'sunny', '开始基础施工,开挖基坑', ''],
|
|
[1, '2024-01-03', 'cloudy', '继续基础施工,浇筑混凝土', ''],
|
|
[2, '2024-02-01', 'sunny', '项目启动,召开开工会议', ''],
|
|
[2, '2024-02-02', 'rainy', '进行场地平整,准备施工材料', ''],
|
|
[3, '2024-03-01', 'sunny', '项目启动,召开开工会议', ''],
|
|
[3, '2024-03-02', 'sunny', '开始线路改造,拆除旧线路', '']
|
|
];
|
|
|
|
logs.forEach(log => {
|
|
db.run(
|
|
'INSERT INTO construction_logs (project_id, log_date, weather, work_content, photos) VALUES (?, ?, ?, ?, ?)',
|
|
log,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入施工日志数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
|
|
// 插入测试汇率数据
|
|
db.get('SELECT COUNT(*) as count FROM exchange_rates', (err, row) => {
|
|
if (err) {
|
|
console.error('查询汇率数据失败:', err.message);
|
|
return;
|
|
}
|
|
|
|
if (row.count === 0) {
|
|
const rates = [
|
|
['CNY_LAK', 2900, '2024-01-01'],
|
|
['CNY_USD', 0.143, '2024-01-01'],
|
|
['CNY_THB', 4.8, '2024-01-01'],
|
|
['USD_LAK', 20300, '2024-01-01'],
|
|
['THB_LAK', 604, '2024-01-01']
|
|
];
|
|
|
|
rates.forEach(rate => {
|
|
db.run(
|
|
'INSERT INTO exchange_rates (pair_key, rate, effective_date) VALUES (?, ?, ?)',
|
|
rate,
|
|
(err) => {
|
|
if (err) {
|
|
console.error('插入汇率数据失败:', err.message);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// 为sqlite3.Database添加query方法,使其与PostgreSQL的接口兼容
|
|
db.query = function(text, params) {
|
|
return new Promise((resolve, reject) => {
|
|
if (text.trim().startsWith('SELECT')) {
|
|
// 处理SELECT查询
|
|
db.all(text, params, (err, rows) => {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve({ rows });
|
|
}
|
|
});
|
|
} else {
|
|
// 处理其他类型的查询
|
|
db.run(text, params, function(err) {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve({ rows: [], lastID: this.lastID, changes: this.changes });
|
|
}
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
// 导出数据库连接
|
|
module.exports = db; |