备份:修复前完整项目快照 2026-04-19
This commit is contained in:
@@ -0,0 +1,896 @@
|
||||
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(`ALTER TABLE subcontracts ADD COLUMN work_days INTEGER`, (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,
|
||||
condition 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 {
|
||||
// 添加condition列(如果不存在)
|
||||
db.run(`ALTER TABLE project_milestones ADD COLUMN condition TEXT`, (err) => {
|
||||
if (err) {
|
||||
// 忽略列已存在的错误
|
||||
}
|
||||
});
|
||||
// 创建项目财务信息表
|
||||
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,
|
||||
percentage REAL DEFAULT 5,
|
||||
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 {
|
||||
// 添加 percentage 字段到已存在的表
|
||||
db.run(`ALTER TABLE warranty_deposits ADD COLUMN percentage REAL DEFAULT 5`, (err) => {
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加 percentage 字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
// 创建施工日志表
|
||||
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 payment_nodes (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
project_id INTEGER,
|
||||
node_name TEXT NOT NULL,
|
||||
due_date DATE,
|
||||
amount REAL NOT NULL,
|
||||
currency TEXT DEFAULT 'CNY',
|
||||
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 payment_records (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
node_id INTEGER,
|
||||
payment_date DATE,
|
||||
amount REAL NOT NULL,
|
||||
currency TEXT DEFAULT 'CNY',
|
||||
payment_method TEXT,
|
||||
status TEXT DEFAULT 'completed',
|
||||
description TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (node_id) REFERENCES payment_nodes(id)
|
||||
)
|
||||
`, (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,
|
||||
total_reimbursed REAL DEFAULT 0,
|
||||
reason TEXT NOT NULL,
|
||||
advance_date DATE,
|
||||
advance_code TEXT UNIQUE NOT NULL,
|
||||
status TEXT DEFAULT 'pending',
|
||||
applicant TEXT,
|
||||
attachments TEXT,
|
||||
approval_remark 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,
|
||||
approval_remark 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',
|
||||
approval_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 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,
|
||||
expense_type TEXT NOT NULL,
|
||||
project_id INTEGER,
|
||||
settlement INTEGER DEFAULT 0,
|
||||
settlement_amount REAL DEFAULT 0,
|
||||
detail_items TEXT,
|
||||
attachments TEXT,
|
||||
status TEXT DEFAULT 'pending',
|
||||
approval_remark 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 {
|
||||
// 添加approval_remark字段到所有表
|
||||
db.run(`ALTER TABLE advances ADD COLUMN approval_remark TEXT`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加advances表approval_remark字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
db.run(`ALTER TABLE reimbursements ADD COLUMN approval_remark TEXT`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加reimbursements表approval_remark字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
db.run(`ALTER TABLE payment_requests ADD COLUMN approval_remark TEXT`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加payment_requests表approval_remark字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
db.run(`ALTER TABLE verifications ADD COLUMN approval_remark TEXT`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加verifications表approval_remark字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
|
||||
// 添加execute_date和execute_method字段到所有申请表
|
||||
db.run(`ALTER TABLE advances ADD COLUMN execute_date DATE`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加advances表execute_date字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
db.run(`ALTER TABLE advances ADD COLUMN execute_method TEXT`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加advances表execute_method字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
|
||||
// 添加total_reimbursed字段到advances表
|
||||
db.run(`ALTER TABLE advances ADD COLUMN total_reimbursed REAL DEFAULT 0`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加advances表total_reimbursed字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
|
||||
db.run(`ALTER TABLE reimbursements ADD COLUMN execute_date DATE`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加reimbursements表execute_date字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
db.run(`ALTER TABLE reimbursements ADD COLUMN execute_method TEXT`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加reimbursements表execute_method字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
|
||||
db.run(`ALTER TABLE payment_requests ADD COLUMN execute_date DATE`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加payment_requests表execute_date字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
db.run(`ALTER TABLE payment_requests ADD COLUMN execute_method TEXT`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加payment_requests表execute_method字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
|
||||
db.run(`ALTER TABLE verifications ADD COLUMN execute_date DATE`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加verifications表execute_date字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
db.run(`ALTER TABLE verifications ADD COLUMN execute_method TEXT`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加verifications表execute_method字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
|
||||
// 添加expense_type和project_id字段到verifications表
|
||||
db.run(`ALTER TABLE verifications ADD COLUMN expense_type TEXT DEFAULT 'company'`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加verifications表expense_type字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
|
||||
db.run(`ALTER TABLE verifications ADD COLUMN project_id INTEGER`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加verifications表project_id字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
|
||||
// 添加user_id字段到verifications表
|
||||
db.run(`ALTER TABLE verifications ADD COLUMN user_id INTEGER`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加verifications表user_id字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
|
||||
// 添加advance_id字段到verifications表
|
||||
db.run(`ALTER TABLE verifications ADD COLUMN advance_id INTEGER`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加verifications表advance_id字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
|
||||
// 添加settlement和settlement_amount字段到verifications表
|
||||
db.run(`ALTER TABLE verifications ADD COLUMN settlement INTEGER DEFAULT 0`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加verifications表settlement字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
|
||||
db.run(`ALTER TABLE verifications ADD COLUMN settlement_amount REAL DEFAULT 0`, (err) => {
|
||||
// 忽略字段已存在的错误
|
||||
if (err && !err.message.includes('duplicate column name')) {
|
||||
console.error('添加verifications表settlement_amount字段失败:', err.message);
|
||||
}
|
||||
});
|
||||
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 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 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;
|
||||
Reference in New Issue
Block a user