241 lines
7.3 KiB
JavaScript
241 lines
7.3 KiB
JavaScript
const sqlite3 = require('sqlite3').verbose();
|
|||
|
|
const path = require('path');
|
||
|
|
|
||
|
|
const dbPath = path.join(__dirname, 'company_finance.db');
|
||
|
|
const db = new sqlite3.Database(dbPath);
|
||
|
|
|
||
|
|
console.log('检查数据库状态...');
|
||
|
|
|
||
|
|
db.all("SELECT name FROM sqlite_master WHERE type='table'", (err, rows) => {
|
||
|
|
if (err) {
|
||
|
|
console.error('查询失败:', err.message);
|
||
|
|
} else {
|
||
|
|
console.log('当前表:');
|
||
|
|
rows.forEach(row => console.log('-', row.name));
|
||
|
|
}
|
||
|
|
|
||
|
|
// 检查category_tree表
|
||
|
|
db.get("SELECT name FROM sqlite_master WHERE type='table' AND name='category_tree'", (err, row) => {
|
||
|
|
if (row) {
|
||
|
|
console.log('\ncategory_tree表已存在,删除后重新创建...');
|
||
|
|
db.run('DROP TABLE IF EXISTS category_tree', (err) => {
|
||
|
|
if (err) console.error('删除category_tree失败:', err.message);
|
||
|
|
recreateTables();
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
recreateTables();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
function recreateTables() {
|
||
|
|
console.log('\n开始创建表结构...');
|
||
|
|
|
||
|
|
// 创建category_tree表
|
||
|
|
const createCategoryTree = `
|
||
|
|
CREATE TABLE category_tree (
|
||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
|
name TEXT NOT NULL,
|
||
|
|
parent_id INTEGER DEFAULT NULL,
|
||
|
|
level INTEGER DEFAULT 1,
|
||
|
|
sort_order INTEGER DEFAULT 0,
|
||
|
|
description TEXT,
|
||
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
FOREIGN KEY (parent_id) REFERENCES category_tree(id) ON DELETE CASCADE
|
||
|
|
)
|
||
|
|
`;
|
||
|
|
|
||
|
|
db.run(createCategoryTree, (err) => {
|
||
|
|
if (err) {
|
||
|
|
console.error('创建category_tree失败:', err.message);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
console.log('✓ category_tree表创建成功');
|
||
|
|
|
||
|
|
// 创建索引
|
||
|
|
db.run('CREATE INDEX IF NOT EXISTS idx_category_parent ON category_tree(parent_id)');
|
||
|
|
db.run('CREATE INDEX IF NOT EXISTS idx_category_level ON category_tree(level)');
|
||
|
|
|
||
|
|
// 检查products表
|
||
|
|
db.get("SELECT name FROM sqlite_master WHERE type='table' AND name='products'", (err, row) => {
|
||
|
|
if (row) {
|
||
|
|
console.log('\nproducts表已存在,重建...');
|
||
|
|
db.run('DROP TABLE IF EXISTS products_backup', (err) => {
|
||
|
|
db.run('ALTER TABLE products RENAME TO products_backup', (err) => {
|
||
|
|
createProductsTable();
|
||
|
|
});
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
createProductsTable();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
function createProductsTable() {
|
||
|
|
const createProducts = `
|
||
|
|
CREATE TABLE products (
|
||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
|
name TEXT NOT NULL,
|
||
|
|
model TEXT,
|
||
|
|
category_id INTEGER,
|
||
|
|
category_name TEXT,
|
||
|
|
unit TEXT DEFAULT '件',
|
||
|
|
cost_price REAL,
|
||
|
|
price REAL DEFAULT 0,
|
||
|
|
brand TEXT,
|
||
|
|
specification TEXT,
|
||
|
|
source TEXT DEFAULT '老挝',
|
||
|
|
remark TEXT,
|
||
|
|
stock_quantity REAL DEFAULT 0,
|
||
|
|
stock_warning REAL DEFAULT 0,
|
||
|
|
status TEXT DEFAULT 'active',
|
||
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
FOREIGN KEY (category_id) REFERENCES category_tree(id)
|
||
|
|
)
|
||
|
|
`;
|
||
|
|
|
||
|
|
db.run(createProducts, (err) => {
|
||
|
|
if (err) {
|
||
|
|
console.error('创建products失败:', err.message);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
console.log('✓ products表创建成功');
|
||
|
|
|
||
|
|
// 创建索引
|
||
|
|
db.run('CREATE INDEX IF NOT EXISTS idx_products_category ON products(category_id)');
|
||
|
|
db.run('CREATE INDEX IF NOT EXISTS idx_products_name ON products(name)');
|
||
|
|
db.run('CREATE INDEX IF NOT EXISTS idx_products_status ON products(status)');
|
||
|
|
|
||
|
|
// 插入默认分类数据
|
||
|
|
insertDefaultCategories();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
function insertDefaultCategories() {
|
||
|
|
console.log('\n插入默认分类数据...');
|
||
|
|
|
||
|
|
// 一级分类
|
||
|
|
const level1Categories = [
|
||
|
|
['电杆横担', null, 1, 1, '电杆、横担及相关配件'],
|
||
|
|
['电缆电线', null, 1, 2, '各类电缆、电线产品'],
|
||
|
|
['变压器', null, 1, 3, '变压器及相关设备'],
|
||
|
|
['开关设备', null, 1, 4, '开关、断路器等设备'],
|
||
|
|
['金具', null, 1, 5, '电力金具、连接件'],
|
||
|
|
['工具仪器', null, 1, 6, '施工工具、检测仪器'],
|
||
|
|
['劳保用品', null, 1, 7, '安全防护用品'],
|
||
|
|
['其他材料', null, 1, 99, '其他未分类材料']
|
||
|
|
];
|
||
|
|
|
||
|
|
let insertedCount = 0;
|
||
|
|
level1Categories.forEach((cat, index) => {
|
||
|
|
db.run(
|
||
|
|
'INSERT INTO category_tree (name, parent_id, level, sort_order, description) VALUES (?, ?, ?, ?, ?)',
|
||
|
|
cat,
|
||
|
|
function(err) {
|
||
|
|
if (err) console.error('插入一级分类失败:', err.message);
|
||
|
|
insertedCount++;
|
||
|
|
if (insertedCount === level1Categories.length) {
|
||
|
|
insertLevel2Categories();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
function insertLevel2Categories() {
|
||
|
|
// 先获取一级分类的ID
|
||
|
|
db.all('SELECT id, name FROM category_tree WHERE level = 1', (err, level1Cats) => {
|
||
|
|
if (err) {
|
||
|
|
console.error('查询一级分类失败:', err.message);
|
||
|
|
finish();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
const level2Map = {
|
||
|
|
'电杆横担': [
|
||
|
|
['混凝土电杆', 1, '混凝土材质电杆'],
|
||
|
|
['钢管电杆', 2, '钢管材质电杆'],
|
||
|
|
['横担', 3, '各类横担'],
|
||
|
|
['抱箍', 4, '电杆抱箍']
|
||
|
|
],
|
||
|
|
'电缆电线': [
|
||
|
|
['高压电缆', 1, '高压电力电缆'],
|
||
|
|
['低压电缆', 2, '低压电力电缆'],
|
||
|
|
['架空导线', 3, '架空绝缘导线'],
|
||
|
|
['控制电缆', 4, '控制用电缆']
|
||
|
|
],
|
||
|
|
'变压器': [
|
||
|
|
['配电变压器', 1, '配电用变压器'],
|
||
|
|
['箱式变电站', 2, '箱式变电站']
|
||
|
|
],
|
||
|
|
'开关设备': [
|
||
|
|
['断路器', 1, '各类断路器'],
|
||
|
|
['隔离开关', 2, '隔离开关'],
|
||
|
|
['熔断器', 3, '熔断器']
|
||
|
|
],
|
||
|
|
'金具': [
|
||
|
|
['耐张线夹', 1, '耐张线夹'],
|
||
|
|
['悬垂线夹', 2, '悬垂线夹'],
|
||
|
|
['连接金具', 3, '连接金具']
|
||
|
|
],
|
||
|
|
'工具仪器': [
|
||
|
|
['施工工具', 1, '电力施工工具'],
|
||
|
|
['检测仪器', 2, '检测测试仪器']
|
||
|
|
],
|
||
|
|
'劳保用品': [
|
||
|
|
['安全帽', 1, '安全帽'],
|
||
|
|
['安全带', 2, '安全带'],
|
||
|
|
['绝缘手套', 3, '绝缘手套'],
|
||
|
|
['绝缘鞋', 4, '绝缘鞋']
|
||
|
|
],
|
||
|
|
'其他材料': [
|
||
|
|
['标识标牌', 1, '标识标牌'],
|
||
|
|
['接地材料', 2, '接地装置材料'],
|
||
|
|
['其他', 99, '其他未分类']
|
||
|
|
]
|
||
|
|
};
|
||
|
|
|
||
|
|
let totalToInsert = 0;
|
||
|
|
let insertedCount = 0;
|
||
|
|
|
||
|
|
level1Cats.forEach(level1 => {
|
||
|
|
const level2Items = level2Map[level1.name] || [];
|
||
|
|
totalToInsert += level2Items.length;
|
||
|
|
|
||
|
|
level2Items.forEach(item => {
|
||
|
|
db.run(
|
||
|
|
'INSERT INTO category_tree (name, parent_id, level, sort_order, description) VALUES (?, ?, 2, ?, ?)',
|
||
|
|
[item[0], level1.id, item[1], item[2]],
|
||
|
|
function(err) {
|
||
|
|
if (err) console.error(`插入二级分类${item[0]}失败:`, err.message);
|
||
|
|
insertedCount++;
|
||
|
|
if (insertedCount === totalToInsert) {
|
||
|
|
finish();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
if (totalToInsert === 0) finish();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
function finish() {
|
||
|
|
console.log('\n✓ 数据库迁移完成!');
|
||
|
|
|
||
|
|
db.all('SELECT * FROM category_tree ORDER BY level, sort_order', (err, rows) => {
|
||
|
|
if (!err) {
|
||
|
|
console.log(`\n已创建 ${rows.length} 个分类:`);
|
||
|
|
rows.forEach(row => {
|
||
|
|
const indent = ' '.repeat(row.level - 1);
|
||
|
|
console.log(`${indent}${row.name}`);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
db.close();
|
||
|
|
});
|
||
|
|
}
|