const path = require('path'); require('dotenv').config({ path: path.join(__dirname, '../.env') }); const db = require('../db'); const bcrypt = require('bcryptjs'); const fs = require('fs'); const setup = async () => { try { console.log('--- 科技成果转化系统 部署工具 ---'); // 1. 执行完整建表语句 console.log('正在初始化数据库表结构...'); const sqlPath = path.join(__dirname, '../../database/schema.sql'); if (!fs.existsSync(sqlPath)) { throw new Error(`找不到 SQL 文件: ${sqlPath}`); } const sql = fs.readFileSync(sqlPath, 'utf8'); // 简单的 SQL 分割逻辑,按分号分割 const statements = sql.split(';').filter(s => s.trim()); for (let statement of statements) { try { await db.query(statement); } catch (e) { // 忽略“已存在”类的错误 if (!e.message.includes('already exists')) { console.log(`执行语句时提示: ${e.message}`); } } } // 2. 初始化默认部门 console.log('正在初始化默认部门...'); const defaultDepts = [ '院领导', '卫星中心综合部', '卫星中心生产部', '卫星中心研发部', '大数据中心', '生产保障部', '生产技术部', '土地调查监测室', '森林调查监测室', '湿地调查监测室', '专业调查室', '权籍调查室', '碳汇研究中心', '权益研究中心', '科技与档案室', '办公室', '党群工作部', '待定' ]; for (const dept of defaultDepts) { await db.query('INSERT INTO departments (name) VALUES ($1) ON CONFLICT (name) DO NOTHING', [dept]); } // 3. 初始化字典表数据 console.log('正在初始化字典表数据...'); const dictData = { dict_organizations: ['黑龙江省自然资源权益调查监测院','黑龙江省自然资源卫星应用技术中心','黑龙江省自然资源权益调查监测院(黑龙江省自然资源卫星应用技术中心)','待定'], dict_award_types: ['国家级', '省部级', '社会力量', '其他', '待定'], dict_award_levels: ['一等奖', '二等奖', '三等奖', '其他', '待定'], dict_paper_types: ['Nature/Science/Cell', 'CCF A类会议','SCI一区期刊','SCI二区期刊', 'CCF B类会议','CCF C类会议','SCI三区期刊','SCI四区期刊','EI源刊', '中文核心期刊', 'EI会议', '普通期刊', '普通会议', '待定'], dict_standard_types: ['国家标准', '国际标准', '行业标准', '地方标准', '待定'], dict_project_categories: ['科技', '财政', '横向', '成果转化', '待定'] }; for (const [tableName, values] of Object.entries(dictData)) { for (const val of values) { await db.query(`INSERT INTO ${tableName} (name) VALUES ($1) ON CONFLICT (name) DO NOTHING`, [val]); } } // 4. 创建初始超级管理员 const adminPhone = '18888888888'; const adminPass = 'admin123'; const salt = await bcrypt.genSalt(10); const passwordHash = await bcrypt.hash(adminPass, salt); console.log('正在创建初始超级管理员...'); await db.query( `INSERT INTO users (username, password_hash, role, real_name, department, dept_status) VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT (username) DO UPDATE SET role = 'super_admin'`, [adminPhone, passwordHash, 'super_admin', '系统管理员', null, 'verified'] ); // 5. 创建初始系统维护员 const maintainerPhone = '19999999999'; const maintainerPass = 'maintainer123'; const maintainerHash = await bcrypt.hash(maintainerPass, salt); console.log('正在创建初始系统维护员...'); await db.query( `INSERT INTO users (username, password_hash, role, real_name, department, dept_status) VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT (username) DO UPDATE SET role = 'maintainer'`, [maintainerPhone, maintainerHash, 'maintainer', '系统维护员', null, 'verified'] ); console.log('\n-----------------------------------'); console.log('部署成功!'); console.log(`初始超管账号: ${adminPhone} / ${adminPass}`); console.log(`初始维护员账号: ${maintainerPhone} / ${maintainerPass}`); console.log('-----------------------------------'); process.exit(0); } catch (err) { console.error('\n部署失败:', err); process.exit(1); } }; setup();