修改保险后端代码,政府前端代码
This commit is contained in:
120
bank-backend/scripts/migrate-reports.js
Normal file
120
bank-backend/scripts/migrate-reports.js
Normal file
@@ -0,0 +1,120 @@
|
||||
const { sequelize } = require('../config/database');
|
||||
const { QueryInterface, DataTypes } = require('sequelize');
|
||||
|
||||
async function createReportsTable() {
|
||||
try {
|
||||
console.log('开始创建报表表...');
|
||||
|
||||
const queryInterface = sequelize.getQueryInterface();
|
||||
|
||||
// 检查表是否已存在
|
||||
const tableExists = await queryInterface.tableExists('reports');
|
||||
if (tableExists) {
|
||||
console.log('报表表已存在,跳过创建');
|
||||
return;
|
||||
}
|
||||
|
||||
await queryInterface.createTable('reports', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
primaryKey: true,
|
||||
autoIncrement: true,
|
||||
allowNull: false
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING(255),
|
||||
allowNull: false,
|
||||
comment: '报表名称'
|
||||
},
|
||||
type: {
|
||||
type: DataTypes.ENUM('transaction', 'account', 'user'),
|
||||
allowNull: false,
|
||||
comment: '报表类型'
|
||||
},
|
||||
format: {
|
||||
type: DataTypes.ENUM('excel', 'pdf', 'csv'),
|
||||
allowNull: false,
|
||||
comment: '报表格式'
|
||||
},
|
||||
status: {
|
||||
type: DataTypes.ENUM('processing', 'completed', 'failed'),
|
||||
allowNull: false,
|
||||
defaultValue: 'processing',
|
||||
comment: '报表状态'
|
||||
},
|
||||
filePath: {
|
||||
type: DataTypes.STRING(500),
|
||||
allowNull: true,
|
||||
comment: '文件路径'
|
||||
},
|
||||
parameters: {
|
||||
type: DataTypes.JSON,
|
||||
allowNull: true,
|
||||
comment: '生成参数'
|
||||
},
|
||||
data: {
|
||||
type: DataTypes.JSON,
|
||||
allowNull: true,
|
||||
comment: '报表数据'
|
||||
},
|
||||
error: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: true,
|
||||
comment: '错误信息'
|
||||
},
|
||||
createdBy: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
comment: '创建人ID'
|
||||
},
|
||||
createdAt: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false,
|
||||
defaultValue: DataTypes.NOW
|
||||
},
|
||||
updatedAt: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false,
|
||||
defaultValue: DataTypes.NOW
|
||||
}
|
||||
});
|
||||
|
||||
// 暂时不添加外键约束,避免兼容性问题
|
||||
// await queryInterface.addConstraint('reports', {
|
||||
// fields: ['createdBy'],
|
||||
// type: 'foreign key',
|
||||
// name: 'fk_reports_createdBy',
|
||||
// references: {
|
||||
// table: 'users',
|
||||
// field: 'id'
|
||||
// },
|
||||
// onDelete: 'CASCADE',
|
||||
// onUpdate: 'CASCADE'
|
||||
// });
|
||||
|
||||
// 添加索引
|
||||
await queryInterface.addIndex('reports', ['type', 'status']);
|
||||
await queryInterface.addIndex('reports', ['createdBy']);
|
||||
await queryInterface.addIndex('reports', ['createdAt']);
|
||||
|
||||
console.log('✅ 报表表创建成功');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 创建报表表失败:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
await createReportsTable();
|
||||
console.log('🎉 数据库迁移完成');
|
||||
} catch (error) {
|
||||
console.error('💥 数据库迁移失败:', error);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
await sequelize.close();
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
297
bank-backend/scripts/seed-basic-data.js
Normal file
297
bank-backend/scripts/seed-basic-data.js
Normal file
@@ -0,0 +1,297 @@
|
||||
const { sequelize, User, Role, Account, Transaction, LoanProduct, Employee, Department, Position } = require('../models');
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
async function seedBasicData() {
|
||||
try {
|
||||
console.log('开始补充基础测试数据...');
|
||||
|
||||
// 1. 创建角色
|
||||
console.log('创建角色...');
|
||||
const roles = await Role.bulkCreate([
|
||||
{ name: 'admin', display_name: '系统管理员', description: '系统管理员,拥有所有权限' },
|
||||
{ name: 'manager', display_name: '经理', description: '部门经理,拥有部门管理权限' },
|
||||
{ name: 'teller', display_name: '柜员', description: '银行柜员,处理日常业务' },
|
||||
{ name: 'user', display_name: '普通用户', description: '普通银行客户' }
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 2. 创建部门
|
||||
console.log('创建部门...');
|
||||
const departments = await Department.bulkCreate([
|
||||
{ name: '行政部', code: 'ADMIN', description: '行政管理部门' },
|
||||
{ name: '财务部', code: 'FINANCE', description: '财务管理部门' },
|
||||
{ name: '技术部', code: 'IT', description: '技术开发部门' },
|
||||
{ name: '人事部', code: 'HR', description: '人力资源部门' },
|
||||
{ name: '销售部', code: 'SALES', description: '销售部门' },
|
||||
{ name: '风控部', code: 'RISK', description: '风险控制部门' },
|
||||
{ name: '客服部', code: 'SERVICE', description: '客户服务部门' }
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 3. 创建职位
|
||||
console.log('创建职位...');
|
||||
const positions = await Position.bulkCreate([
|
||||
{ name: '总经理', code: 'GM', level: 1, description: '总经理职位' },
|
||||
{ name: '副总经理', code: 'DGM', level: 2, description: '副总经理职位' },
|
||||
{ name: '部门经理', code: 'MGR', level: 3, description: '部门经理职位' },
|
||||
{ name: '主管', code: 'SUP', level: 4, description: '主管职位' },
|
||||
{ name: '高级员工', code: 'SENIOR', level: 5, description: '高级员工职位' },
|
||||
{ name: '普通员工', code: 'STAFF', level: 6, description: '普通员工职位' },
|
||||
{ name: '实习生', code: 'INTERN', level: 7, description: '实习生职位' }
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 4. 创建用户
|
||||
console.log('创建用户...');
|
||||
const users = await User.bulkCreate([
|
||||
{
|
||||
username: 'admin',
|
||||
email: 'admin@bank.com',
|
||||
password: await bcrypt.hash('Admin123456', 10),
|
||||
phone: '13800138000',
|
||||
real_name: '系统管理员',
|
||||
id_card: '110101199003071234',
|
||||
role_id: roles.find(r => r.name === 'admin').id,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
username: 'manager1',
|
||||
email: 'manager1@bank.com',
|
||||
password: await bcrypt.hash('Manager123456', 10),
|
||||
phone: '13800138001',
|
||||
real_name: '张经理',
|
||||
id_card: '110101198503071234',
|
||||
role_id: roles.find(r => r.name === 'manager').id,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
username: 'teller1',
|
||||
email: 'teller1@bank.com',
|
||||
password: await bcrypt.hash('Teller123456', 10),
|
||||
phone: '13800138002',
|
||||
real_name: '李柜员',
|
||||
id_card: '110101199203071234',
|
||||
role_id: roles.find(r => r.name === 'teller').id,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
username: 'user1',
|
||||
email: 'user1@bank.com',
|
||||
password: await bcrypt.hash('User123456', 10),
|
||||
phone: '13800138003',
|
||||
real_name: '王客户',
|
||||
id_card: '110101199503071234',
|
||||
role_id: roles.find(r => r.name === 'user').id,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
username: 'user2',
|
||||
email: 'user2@bank.com',
|
||||
password: await bcrypt.hash('User123456', 10),
|
||||
phone: '13800138004',
|
||||
real_name: '赵客户',
|
||||
id_card: '110101199603071234',
|
||||
role_id: roles.find(r => r.name === 'user').id,
|
||||
status: 'active'
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 5. 创建员工
|
||||
console.log('创建员工...');
|
||||
const employees = await Employee.bulkCreate([
|
||||
{
|
||||
name: '张经理',
|
||||
employee_id: 'EMP001',
|
||||
email: 'manager1@bank.com',
|
||||
phone: '13800138001',
|
||||
id_card: '110101198503071234',
|
||||
department_id: departments.find(d => d.name === '财务部').id,
|
||||
position_id: positions.find(p => p.name === '部门经理').id,
|
||||
hire_date: '2020-01-15',
|
||||
salary_level: 'L6',
|
||||
status: 'active',
|
||||
supervisor: '系统管理员'
|
||||
},
|
||||
{
|
||||
name: '李柜员',
|
||||
employee_id: 'EMP002',
|
||||
email: 'teller1@bank.com',
|
||||
phone: '13800138002',
|
||||
id_card: '110101199203071234',
|
||||
department_id: departments.find(d => d.name === '客服部').id,
|
||||
position_id: positions.find(p => p.name === '普通员工').id,
|
||||
hire_date: '2021-03-20',
|
||||
salary_level: 'L4',
|
||||
status: 'active',
|
||||
supervisor: '张经理'
|
||||
},
|
||||
{
|
||||
name: '王技术',
|
||||
employee_id: 'EMP003',
|
||||
email: 'wangtech@bank.com',
|
||||
phone: '13800138005',
|
||||
id_card: '110101199103071234',
|
||||
department_id: departments.find(d => d.name === '技术部').id,
|
||||
position_id: positions.find(p => p.name === '高级员工').id,
|
||||
hire_date: '2019-06-10',
|
||||
salary_level: 'L5',
|
||||
status: 'active',
|
||||
supervisor: '张经理'
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 6. 创建账户
|
||||
console.log('创建账户...');
|
||||
const accounts = await Account.bulkCreate([
|
||||
{
|
||||
account_number: '6225123456789001',
|
||||
account_type: 'savings',
|
||||
balance: 500000, // 5000元
|
||||
user_id: users.find(u => u.username === 'user1').id,
|
||||
status: 'active',
|
||||
interest_rate: 0.0035
|
||||
},
|
||||
{
|
||||
account_number: '6225123456789002',
|
||||
account_type: 'checking',
|
||||
balance: 100000, // 1000元
|
||||
user_id: users.find(u => u.username === 'user1').id,
|
||||
status: 'active',
|
||||
interest_rate: 0.001
|
||||
},
|
||||
{
|
||||
account_number: '6225123456789003',
|
||||
account_type: 'savings',
|
||||
balance: 200000, // 2000元
|
||||
user_id: users.find(u => u.username === 'user2').id,
|
||||
status: 'active',
|
||||
interest_rate: 0.0035
|
||||
},
|
||||
{
|
||||
account_number: '6225123456789004',
|
||||
account_type: 'credit',
|
||||
balance: -50000, // -500元(信用卡欠款)
|
||||
user_id: users.find(u => u.username === 'user2').id,
|
||||
status: 'active',
|
||||
credit_limit: 100000, // 1000元信用额度
|
||||
interest_rate: 0.18
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 7. 创建交易记录
|
||||
console.log('创建交易记录...');
|
||||
const transactions = await Transaction.bulkCreate([
|
||||
{
|
||||
account_id: accounts[0].id,
|
||||
type: 'deposit',
|
||||
amount: 100000, // 1000元
|
||||
balance_after: 600000, // 6000元
|
||||
description: '工资入账',
|
||||
status: 'completed',
|
||||
reference_number: 'TXN001'
|
||||
},
|
||||
{
|
||||
account_id: accounts[0].id,
|
||||
type: 'withdrawal',
|
||||
amount: 50000, // 500元
|
||||
balance_after: 550000, // 5500元
|
||||
description: 'ATM取款',
|
||||
status: 'completed',
|
||||
reference_number: 'TXN002'
|
||||
},
|
||||
{
|
||||
account_id: accounts[1].id,
|
||||
type: 'transfer',
|
||||
amount: 20000, // 200元
|
||||
balance_after: 120000, // 1200元
|
||||
description: '转账到储蓄账户',
|
||||
status: 'completed',
|
||||
reference_number: 'TXN003'
|
||||
},
|
||||
{
|
||||
account_id: accounts[2].id,
|
||||
type: 'deposit',
|
||||
amount: 50000, // 500元
|
||||
balance_after: 250000, // 2500元
|
||||
description: '现金存款',
|
||||
status: 'completed',
|
||||
reference_number: 'TXN004'
|
||||
},
|
||||
{
|
||||
account_id: accounts[3].id,
|
||||
type: 'payment',
|
||||
amount: 30000, // 300元
|
||||
balance_after: -80000, // -800元
|
||||
description: '信用卡消费',
|
||||
status: 'completed',
|
||||
reference_number: 'TXN005'
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 8. 创建贷款产品
|
||||
console.log('创建贷款产品...');
|
||||
const loanProducts = await LoanProduct.bulkCreate([
|
||||
{
|
||||
name: '个人住房贷款',
|
||||
type: 'mortgage',
|
||||
min_amount: 1000000, // 10万元
|
||||
max_amount: 50000000, // 500万元
|
||||
min_term: 12, // 1年
|
||||
max_term: 360, // 30年
|
||||
interest_rate: 0.045, // 4.5%
|
||||
max_interest_rate: 0.055, // 5.5%
|
||||
description: '个人住房按揭贷款,利率优惠',
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
name: '个人消费贷款',
|
||||
type: 'consumer',
|
||||
min_amount: 10000, // 1万元
|
||||
max_amount: 500000, // 50万元
|
||||
min_term: 6, // 6个月
|
||||
max_term: 60, // 5年
|
||||
interest_rate: 0.065, // 6.5%
|
||||
max_interest_rate: 0.085, // 8.5%
|
||||
description: '个人消费贷款,用途广泛',
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
name: '小微企业贷款',
|
||||
type: 'business',
|
||||
min_amount: 50000, // 5万元
|
||||
max_amount: 1000000, // 100万元
|
||||
min_term: 12, // 1年
|
||||
max_term: 60, // 5年
|
||||
interest_rate: 0.055, // 5.5%
|
||||
max_interest_rate: 0.075, // 7.5%
|
||||
description: '小微企业生产经营贷款',
|
||||
status: 'active'
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
console.log('✅ 基础测试数据补充完成');
|
||||
console.log(`- 角色: ${roles.length} 个`);
|
||||
console.log(`- 部门: ${departments.length} 个`);
|
||||
console.log(`- 职位: ${positions.length} 个`);
|
||||
console.log(`- 用户: ${users.length} 个`);
|
||||
console.log(`- 员工: ${employees.length} 个`);
|
||||
console.log(`- 账户: ${accounts.length} 个`);
|
||||
console.log(`- 交易记录: ${transactions.length} 个`);
|
||||
console.log(`- 贷款产品: ${loanProducts.length} 个`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 补充测试数据失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
await seedBasicData();
|
||||
console.log('🎉 基础测试数据补充完成');
|
||||
} catch (error) {
|
||||
console.error('💥 基础测试数据补充失败:', error);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
await sequelize.close();
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
339
bank-backend/scripts/seed-comprehensive-data.js
Normal file
339
bank-backend/scripts/seed-comprehensive-data.js
Normal file
@@ -0,0 +1,339 @@
|
||||
const { sequelize, User, Role, Account, Transaction, LoanProduct, Employee, Department, Position, Report } = require('../models');
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
async function seedComprehensiveData() {
|
||||
try {
|
||||
console.log('开始补充数据库测试数据...');
|
||||
|
||||
// 1. 创建角色
|
||||
console.log('创建角色...');
|
||||
const roles = await Role.bulkCreate([
|
||||
{ name: 'admin', display_name: '系统管理员', description: '系统管理员,拥有所有权限' },
|
||||
{ name: 'manager', display_name: '经理', description: '部门经理,拥有部门管理权限' },
|
||||
{ name: 'teller', display_name: '柜员', description: '银行柜员,处理日常业务' },
|
||||
{ name: 'user', display_name: '普通用户', description: '普通银行客户' }
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 2. 创建部门
|
||||
console.log('创建部门...');
|
||||
const departments = await Department.bulkCreate([
|
||||
{ name: '行政部', code: 'ADMIN', description: '行政管理部门' },
|
||||
{ name: '财务部', code: 'FINANCE', description: '财务管理部门' },
|
||||
{ name: '技术部', code: 'IT', description: '技术开发部门' },
|
||||
{ name: '人事部', code: 'HR', description: '人力资源部门' },
|
||||
{ name: '销售部', code: 'SALES', description: '销售部门' },
|
||||
{ name: '风控部', code: 'RISK', description: '风险控制部门' },
|
||||
{ name: '客服部', code: 'SERVICE', description: '客户服务部门' }
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 3. 创建职位
|
||||
console.log('创建职位...');
|
||||
const positions = await Position.bulkCreate([
|
||||
{ name: '总经理', code: 'GM', level: 1, description: '总经理职位' },
|
||||
{ name: '副总经理', code: 'DGM', level: 2, description: '副总经理职位' },
|
||||
{ name: '部门经理', code: 'MGR', level: 3, description: '部门经理职位' },
|
||||
{ name: '主管', code: 'SUP', level: 4, description: '主管职位' },
|
||||
{ name: '高级员工', code: 'SENIOR', level: 5, description: '高级员工职位' },
|
||||
{ name: '普通员工', code: 'STAFF', level: 6, description: '普通员工职位' },
|
||||
{ name: '实习生', code: 'INTERN', level: 7, description: '实习生职位' }
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 4. 创建用户
|
||||
console.log('创建用户...');
|
||||
const users = await User.bulkCreate([
|
||||
{
|
||||
username: 'admin',
|
||||
email: 'admin@bank.com',
|
||||
password: await bcrypt.hash('Admin123456', 10),
|
||||
phone: '13800138000',
|
||||
real_name: '系统管理员',
|
||||
id_card: '110101199003071234',
|
||||
role_id: roles.find(r => r.name === 'admin').id,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
username: 'manager1',
|
||||
email: 'manager1@bank.com',
|
||||
password: await bcrypt.hash('Manager123456', 10),
|
||||
phone: '13800138001',
|
||||
real_name: '张经理',
|
||||
id_card: '110101198503071234',
|
||||
role_id: roles.find(r => r.name === 'manager').id,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
username: 'teller1',
|
||||
email: 'teller1@bank.com',
|
||||
password: await bcrypt.hash('Teller123456', 10),
|
||||
phone: '13800138002',
|
||||
real_name: '李柜员',
|
||||
id_card: '110101199203071234',
|
||||
role_id: roles.find(r => r.name === 'teller').id,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
username: 'user1',
|
||||
email: 'user1@bank.com',
|
||||
password: await bcrypt.hash('User123456', 10),
|
||||
phone: '13800138003',
|
||||
real_name: '王客户',
|
||||
id_card: '110101199503071234',
|
||||
role_id: roles.find(r => r.name === 'user').id,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
username: 'user2',
|
||||
email: 'user2@bank.com',
|
||||
password: await bcrypt.hash('User123456', 10),
|
||||
phone: '13800138004',
|
||||
real_name: '赵客户',
|
||||
id_card: '110101199603071234',
|
||||
role_id: roles.find(r => r.name === 'user').id,
|
||||
status: 'active'
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 5. 创建员工
|
||||
console.log('创建员工...');
|
||||
const employees = await Employee.bulkCreate([
|
||||
{
|
||||
name: '张经理',
|
||||
employee_id: 'EMP001',
|
||||
email: 'manager1@bank.com',
|
||||
phone: '13800138001',
|
||||
id_card: '110101198503071234',
|
||||
department_id: departments.find(d => d.name === '财务部').id,
|
||||
position_id: positions.find(p => p.name === '部门经理').id,
|
||||
hire_date: '2020-01-15',
|
||||
salary_level: 'L6',
|
||||
status: 'active',
|
||||
supervisor: '系统管理员'
|
||||
},
|
||||
{
|
||||
name: '李柜员',
|
||||
employee_id: 'EMP002',
|
||||
email: 'teller1@bank.com',
|
||||
phone: '13800138002',
|
||||
id_card: '110101199203071234',
|
||||
department_id: departments.find(d => d.name === '客服部').id,
|
||||
position_id: positions.find(p => p.name === '普通员工').id,
|
||||
hire_date: '2021-03-20',
|
||||
salary_level: 'L4',
|
||||
status: 'active',
|
||||
supervisor: '张经理'
|
||||
},
|
||||
{
|
||||
name: '王技术',
|
||||
employee_id: 'EMP003',
|
||||
email: 'wangtech@bank.com',
|
||||
phone: '13800138005',
|
||||
id_card: '110101199103071234',
|
||||
department_id: departments.find(d => d.name === '技术部').id,
|
||||
position_id: positions.find(p => p.name === '高级员工').id,
|
||||
hire_date: '2019-06-10',
|
||||
salary_level: 'L5',
|
||||
status: 'active',
|
||||
supervisor: '张经理'
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 6. 创建账户
|
||||
console.log('创建账户...');
|
||||
const accounts = await Account.bulkCreate([
|
||||
{
|
||||
account_number: '6225123456789001',
|
||||
account_type: 'savings',
|
||||
balance: 500000, // 5000元
|
||||
user_id: users.find(u => u.username === 'user1').id,
|
||||
status: 'active',
|
||||
interest_rate: 0.0035
|
||||
},
|
||||
{
|
||||
account_number: '6225123456789002',
|
||||
account_type: 'checking',
|
||||
balance: 100000, // 1000元
|
||||
user_id: users.find(u => u.username === 'user1').id,
|
||||
status: 'active',
|
||||
interest_rate: 0.001
|
||||
},
|
||||
{
|
||||
account_number: '6225123456789003',
|
||||
account_type: 'savings',
|
||||
balance: 200000, // 2000元
|
||||
user_id: users.find(u => u.username === 'user2').id,
|
||||
status: 'active',
|
||||
interest_rate: 0.0035
|
||||
},
|
||||
{
|
||||
account_number: '6225123456789004',
|
||||
account_type: 'credit',
|
||||
balance: -50000, // -500元(信用卡欠款)
|
||||
user_id: users.find(u => u.username === 'user2').id,
|
||||
status: 'active',
|
||||
credit_limit: 100000, // 1000元信用额度
|
||||
interest_rate: 0.18
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 7. 创建交易记录
|
||||
console.log('创建交易记录...');
|
||||
const transactions = await Transaction.bulkCreate([
|
||||
{
|
||||
account_id: accounts[0].id,
|
||||
type: 'deposit',
|
||||
amount: 100000, // 1000元
|
||||
balance_after: 600000, // 6000元
|
||||
description: '工资入账',
|
||||
status: 'completed',
|
||||
reference_number: 'TXN001'
|
||||
},
|
||||
{
|
||||
account_id: accounts[0].id,
|
||||
type: 'withdrawal',
|
||||
amount: 50000, // 500元
|
||||
balance_after: 550000, // 5500元
|
||||
description: 'ATM取款',
|
||||
status: 'completed',
|
||||
reference_number: 'TXN002'
|
||||
},
|
||||
{
|
||||
account_id: accounts[1].id,
|
||||
type: 'transfer',
|
||||
amount: 20000, // 200元
|
||||
balance_after: 120000, // 1200元
|
||||
description: '转账到储蓄账户',
|
||||
status: 'completed',
|
||||
reference_number: 'TXN003'
|
||||
},
|
||||
{
|
||||
account_id: accounts[2].id,
|
||||
type: 'deposit',
|
||||
amount: 50000, // 500元
|
||||
balance_after: 250000, // 2500元
|
||||
description: '现金存款',
|
||||
status: 'completed',
|
||||
reference_number: 'TXN004'
|
||||
},
|
||||
{
|
||||
account_id: accounts[3].id,
|
||||
type: 'payment',
|
||||
amount: 30000, // 300元
|
||||
balance_after: -80000, // -800元
|
||||
description: '信用卡消费',
|
||||
status: 'completed',
|
||||
reference_number: 'TXN005'
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 8. 创建贷款产品
|
||||
console.log('创建贷款产品...');
|
||||
const loanProducts = await LoanProduct.bulkCreate([
|
||||
{
|
||||
name: '个人住房贷款',
|
||||
type: 'mortgage',
|
||||
min_amount: 1000000, // 10万元
|
||||
max_amount: 50000000, // 500万元
|
||||
min_term: 12, // 1年
|
||||
max_term: 360, // 30年
|
||||
interest_rate: 0.045, // 4.5%
|
||||
max_interest_rate: 0.055, // 5.5%
|
||||
description: '个人住房按揭贷款,利率优惠',
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
name: '个人消费贷款',
|
||||
type: 'consumer',
|
||||
min_amount: 10000, // 1万元
|
||||
max_amount: 500000, // 50万元
|
||||
min_term: 6, // 6个月
|
||||
max_term: 60, // 5年
|
||||
interest_rate: 0.065, // 6.5%
|
||||
max_interest_rate: 0.085, // 8.5%
|
||||
description: '个人消费贷款,用途广泛',
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
name: '小微企业贷款',
|
||||
type: 'business',
|
||||
min_amount: 50000, // 5万元
|
||||
max_amount: 1000000, // 100万元
|
||||
min_term: 12, // 1年
|
||||
max_term: 60, // 5年
|
||||
interest_rate: 0.055, // 5.5%
|
||||
max_interest_rate: 0.075, // 7.5%
|
||||
description: '小微企业生产经营贷款',
|
||||
status: 'active'
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
// 9. 创建报表记录
|
||||
console.log('创建报表记录...');
|
||||
const reports = await Report.bulkCreate([
|
||||
{
|
||||
name: '2024年12月交易报表',
|
||||
type: 'transaction',
|
||||
format: 'excel',
|
||||
status: 'completed',
|
||||
file_path: 'reports/transaction_202412.xlsx',
|
||||
created_by: users.find(u => u.username === 'admin').id,
|
||||
parameters: {
|
||||
dateRange: ['2024-12-01', '2024-12-31'],
|
||||
format: 'excel'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '储蓄账户余额报表',
|
||||
type: 'account',
|
||||
format: 'pdf',
|
||||
status: 'completed',
|
||||
file_path: 'reports/account_balance_202412.pdf',
|
||||
created_by: users.find(u => u.username === 'manager1').id,
|
||||
parameters: {
|
||||
dateRange: ['2024-12-01', '2024-12-31'],
|
||||
format: 'pdf'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '用户活跃度报表',
|
||||
type: 'user',
|
||||
format: 'csv',
|
||||
status: 'completed',
|
||||
file_path: 'reports/user_activity_202412.csv',
|
||||
created_by: users.find(u => u.username === 'admin').id,
|
||||
parameters: {
|
||||
dateRange: ['2024-12-01', '2024-12-31'],
|
||||
format: 'csv'
|
||||
}
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
|
||||
console.log('✅ 数据库测试数据补充完成');
|
||||
console.log(`- 角色: ${roles.length} 个`);
|
||||
console.log(`- 部门: ${departments.length} 个`);
|
||||
console.log(`- 职位: ${positions.length} 个`);
|
||||
console.log(`- 用户: ${users.length} 个`);
|
||||
console.log(`- 员工: ${employees.length} 个`);
|
||||
console.log(`- 账户: ${accounts.length} 个`);
|
||||
console.log(`- 交易记录: ${transactions.length} 个`);
|
||||
console.log(`- 贷款产品: ${loanProducts.length} 个`);
|
||||
console.log(`- 报表记录: ${reports.length} 个`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 补充测试数据失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
await seedComprehensiveData();
|
||||
console.log('🎉 数据库测试数据补充完成');
|
||||
} catch (error) {
|
||||
console.error('💥 数据库测试数据补充失败:', error);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
await sequelize.close();
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
249
bank-backend/scripts/seed-test-data.js
Normal file
249
bank-backend/scripts/seed-test-data.js
Normal file
@@ -0,0 +1,249 @@
|
||||
/**
|
||||
* 数据库种子文件 - 添加测试数据
|
||||
* @file seed-test-data.js
|
||||
* @description 为银行系统添加测试数据
|
||||
*/
|
||||
const { sequelize } = require('../config/database');
|
||||
const { User, Account, Transaction, Role } = require('../models');
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
async function seedTestData() {
|
||||
console.log('🌱 开始添加测试数据...');
|
||||
|
||||
try {
|
||||
// 同步数据库
|
||||
await sequelize.sync({ force: false });
|
||||
console.log('✅ 数据库同步完成');
|
||||
|
||||
// 1. 创建角色数据
|
||||
console.log('📝 创建角色数据...');
|
||||
const roles = await Role.bulkCreate([
|
||||
{
|
||||
name: 'admin',
|
||||
display_name: '系统管理员',
|
||||
description: '系统管理员,拥有所有权限',
|
||||
permissions: JSON.stringify(['*'])
|
||||
},
|
||||
{
|
||||
name: 'manager',
|
||||
display_name: '银行经理',
|
||||
description: '银行经理,管理银行日常运营',
|
||||
permissions: JSON.stringify(['users:read', 'users:write', 'accounts:read', 'accounts:write', 'transactions:read'])
|
||||
},
|
||||
{
|
||||
name: 'teller',
|
||||
display_name: '银行柜员',
|
||||
description: '银行柜员,处理客户业务',
|
||||
permissions: JSON.stringify(['accounts:read', 'transactions:read', 'transactions:write'])
|
||||
},
|
||||
{
|
||||
name: 'user',
|
||||
display_name: '普通用户',
|
||||
description: '普通用户,查看自己的账户信息',
|
||||
permissions: JSON.stringify(['accounts:read:own', 'transactions:read:own'])
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
console.log(`✅ 创建了 ${roles.length} 个角色`);
|
||||
|
||||
// 2. 创建用户数据
|
||||
console.log('👥 创建用户数据...');
|
||||
const users = await User.bulkCreate([
|
||||
{
|
||||
username: 'admin',
|
||||
email: 'admin@bank.com',
|
||||
password: 'admin123',
|
||||
phone: '13800138000',
|
||||
real_name: '系统管理员',
|
||||
id_card: '110101199001010001',
|
||||
role_id: 1,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
username: 'manager1',
|
||||
email: 'manager1@bank.com',
|
||||
password: 'manager123',
|
||||
phone: '13800138001',
|
||||
real_name: '张经理',
|
||||
id_card: '110101199001010002',
|
||||
role_id: 2,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
username: 'teller1',
|
||||
email: 'teller1@bank.com',
|
||||
password: 'teller123',
|
||||
phone: '13800138002',
|
||||
real_name: '李柜员',
|
||||
id_card: '110101199001010003',
|
||||
role_id: 3,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
username: 'user1',
|
||||
email: 'user1@bank.com',
|
||||
password: 'user123',
|
||||
phone: '13800138004',
|
||||
real_name: '王用户',
|
||||
id_card: '110101199001010004',
|
||||
role_id: 4,
|
||||
status: 'active'
|
||||
},
|
||||
{
|
||||
username: 'user2',
|
||||
email: 'user2@bank.com',
|
||||
password: 'user123',
|
||||
phone: '13800138005',
|
||||
real_name: '赵客户',
|
||||
id_card: '110101199001010005',
|
||||
role_id: 4,
|
||||
status: 'active'
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
console.log(`✅ 创建了 ${users.length} 个用户`);
|
||||
|
||||
// 3. 创建账户数据
|
||||
console.log('🏦 创建账户数据...');
|
||||
const accounts = await Account.bulkCreate([
|
||||
{
|
||||
account_number: '6225123456789001',
|
||||
account_name: '王用户储蓄账户',
|
||||
account_type: 'savings',
|
||||
user_id: 4,
|
||||
balance: 5000000, // 50,000元
|
||||
available_balance: 5000000,
|
||||
frozen_amount: 0,
|
||||
status: 'active',
|
||||
currency: 'CNY'
|
||||
},
|
||||
{
|
||||
account_number: '6225123456789002',
|
||||
account_name: '王用户活期账户',
|
||||
account_type: 'checking',
|
||||
user_id: 4,
|
||||
balance: 2000000, // 20,000元
|
||||
available_balance: 2000000,
|
||||
frozen_amount: 0,
|
||||
status: 'active',
|
||||
currency: 'CNY'
|
||||
},
|
||||
{
|
||||
account_number: '6225123456789003',
|
||||
account_name: '赵客户储蓄账户',
|
||||
account_type: 'savings',
|
||||
user_id: 5,
|
||||
balance: 10000000, // 100,000元
|
||||
available_balance: 10000000,
|
||||
frozen_amount: 0,
|
||||
status: 'active',
|
||||
currency: 'CNY'
|
||||
},
|
||||
{
|
||||
account_number: '6225123456789004',
|
||||
account_name: '赵客户信用卡',
|
||||
account_type: 'credit',
|
||||
user_id: 5,
|
||||
balance: -500000, // -5,000元(信用卡欠款)
|
||||
available_balance: 4500000, // 45,000元可用额度
|
||||
frozen_amount: 0,
|
||||
status: 'active',
|
||||
currency: 'CNY'
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
console.log(`✅ 创建了 ${accounts.length} 个账户`);
|
||||
|
||||
// 4. 创建交易记录数据
|
||||
console.log('💳 创建交易记录数据...');
|
||||
const transactions = await Transaction.bulkCreate([
|
||||
{
|
||||
transaction_id: 'T20240922001',
|
||||
type: 'deposit',
|
||||
account_id: 1,
|
||||
amount: 1000000, // 10,000元
|
||||
balance_after: 6000000,
|
||||
description: '现金存款',
|
||||
status: 'completed',
|
||||
channel: 'counter',
|
||||
created_at: new Date('2024-09-22T08:00:00Z')
|
||||
},
|
||||
{
|
||||
transaction_id: 'T20240922002',
|
||||
type: 'withdrawal',
|
||||
account_id: 2,
|
||||
amount: 500000, // 5,000元
|
||||
balance_after: 1500000,
|
||||
description: 'ATM取款',
|
||||
status: 'completed',
|
||||
channel: 'atm',
|
||||
created_at: new Date('2024-09-22T09:30:00Z')
|
||||
},
|
||||
{
|
||||
transaction_id: 'T20240922003',
|
||||
type: 'transfer',
|
||||
account_id: 1,
|
||||
target_account_id: 3,
|
||||
amount: 2000000, // 20,000元
|
||||
balance_after: 4000000,
|
||||
description: '转账给赵客户',
|
||||
status: 'completed',
|
||||
channel: 'online',
|
||||
created_at: new Date('2024-09-22T10:15:00Z')
|
||||
},
|
||||
{
|
||||
transaction_id: 'T20240922004',
|
||||
type: 'payment',
|
||||
account_id: 4,
|
||||
amount: 300000, // 3,000元
|
||||
balance_after: -800000,
|
||||
description: '信用卡消费',
|
||||
status: 'completed',
|
||||
channel: 'pos',
|
||||
created_at: new Date('2024-09-22T11:45:00Z')
|
||||
},
|
||||
{
|
||||
transaction_id: 'T20240922005',
|
||||
type: 'interest',
|
||||
account_id: 1,
|
||||
amount: 5000, // 50元
|
||||
balance_after: 4005000,
|
||||
description: '储蓄利息',
|
||||
status: 'completed',
|
||||
channel: 'system',
|
||||
created_at: new Date('2024-09-22T12:00:00Z')
|
||||
}
|
||||
], { ignoreDuplicates: true });
|
||||
console.log(`✅ 创建了 ${transactions.length} 条交易记录`);
|
||||
|
||||
console.log('');
|
||||
console.log('🎉 测试数据添加完成!');
|
||||
console.log('📊 数据统计:');
|
||||
console.log(` - 角色: ${roles.length} 个`);
|
||||
console.log(` - 用户: ${users.length} 个`);
|
||||
console.log(` - 账户: ${accounts.length} 个`);
|
||||
console.log(` - 交易记录: ${transactions.length} 条`);
|
||||
console.log('');
|
||||
console.log('🔑 测试账号:');
|
||||
console.log(' - 管理员: admin / admin123');
|
||||
console.log(' - 经理: manager1 / manager123');
|
||||
console.log(' - 柜员: teller1 / teller123');
|
||||
console.log(' - 用户: user1 / user123');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 添加测试数据失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果直接运行此脚本
|
||||
if (require.main === module) {
|
||||
seedTestData()
|
||||
.then(() => {
|
||||
console.log('✅ 种子数据脚本执行完成');
|
||||
process.exit(0);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('❌ 种子数据脚本执行失败:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = seedTestData;
|
||||
Reference in New Issue
Block a user