添加银行政府后端接口

This commit is contained in:
2025-09-25 15:53:44 +08:00
parent b17bdcc24c
commit 5b6b7e0a96
60 changed files with 5345 additions and 1920 deletions

View File

@@ -101,9 +101,27 @@ const CompletedSupervision = sequelize.define('CompletedSupervision', {
}, {
tableName: 'completed_supervisions',
timestamps: true,
underscored: false,
createdAt: 'createdAt',
updatedAt: 'updatedAt',
comment: '监管任务已结项表'
});
// 定义关联关系
CompletedSupervision.associate = (models) => {
// 监管任务已结项与用户关联(创建人)
CompletedSupervision.belongsTo(models.User, {
foreignKey: { name: 'createdBy', field: 'createdBy' },
targetKey: 'id',
as: 'creator'
});
// 监管任务已结项与用户关联(更新人)
CompletedSupervision.belongsTo(models.User, {
foreignKey: { name: 'updatedBy', field: 'updatedBy' },
targetKey: 'id',
as: 'updater'
});
};
module.exports = CompletedSupervision;

View File

@@ -1,82 +1,141 @@
/**
* 员工模型
* @file Employee.js
* @description 员工数据模型
*/
const { DataTypes } = require('sequelize');
const { sequelize } = require('../config/database');
const bcrypt = require('bcryptjs');
const Employee = sequelize.define('Employee', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING(50),
allowNull: false,
comment: '员工姓名'
},
employee_id: {
type: DataTypes.STRING(20),
allowNull: false,
unique: true,
comment: '员工编号'
},
department_id: {
type: DataTypes.INTEGER,
allowNull: false,
comment: '部门ID'
},
position_id: {
type: DataTypes.INTEGER,
allowNull: false,
comment: '职位ID'
},
phone: {
type: DataTypes.STRING(20),
allowNull: true,
comment: '联系电话'
},
email: {
type: DataTypes.STRING(100),
allowNull: true,
comment: '邮箱地址'
},
hire_date: {
type: DataTypes.DATEONLY,
allowNull: false,
comment: '入职日期'
},
salary: {
type: DataTypes.BIGINT,
allowNull: false,
defaultValue: 0,
comment: '薪资(分)'
},
status: {
type: DataTypes.ENUM('active', 'inactive', 'resigned'),
allowNull: false,
defaultValue: 'active',
comment: '员工状态:在职、离职、已辞职'
},
created_at: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW
},
updated_at: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW
}
}, {
sequelize,
tableName: 'bank_employees',
modelName: 'Employee',
timestamps: true,
createdAt: 'created_at',
updatedAt: 'updated_at'
});
module.exports = (sequelize) => {
const Employee = sequelize.define('Employee', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
employeeNumber: {
type: DataTypes.STRING(20),
allowNull: false,
unique: true,
comment: '员工编号'
},
name: {
type: DataTypes.STRING(50),
allowNull: false,
comment: '员工姓名'
},
phone: {
type: DataTypes.STRING(20),
allowNull: false,
comment: '联系电话'
},
email: {
type: DataTypes.STRING(100),
allowNull: true,
comment: '邮箱'
},
password: {
type: DataTypes.STRING(255),
allowNull: false,
comment: '密码'
},
isLoanSpecialist: {
type: DataTypes.BOOLEAN,
defaultValue: false,
comment: '是否为贷款专员'
},
department: {
type: DataTypes.STRING(50),
allowNull: true,
comment: '部门'
},
position: {
type: DataTypes.STRING(50),
allowNull: true,
comment: '职位'
},
status: {
type: DataTypes.ENUM('active', 'inactive', 'locked'),
defaultValue: 'active',
comment: '账号状态'
},
lastLogin: {
type: DataTypes.DATE,
allowNull: true,
comment: '最后登录时间'
},
loginAttempts: {
type: DataTypes.INTEGER,
defaultValue: 0,
comment: '登录尝试次数'
},
lockedUntil: {
type: DataTypes.DATE,
allowNull: true,
comment: '锁定到期时间'
},
createdBy: {
type: DataTypes.INTEGER,
allowNull: true,
comment: '创建人ID'
},
updatedBy: {
type: DataTypes.INTEGER,
allowNull: true,
comment: '更新人ID'
}
}, {
tableName: 'bank_employees',
timestamps: true,
paranoid: true,
comment: '银行员工表',
hooks: {
beforeSave: async (employee) => {
if (employee.changed('password')) {
const salt = await bcrypt.genSalt(10);
employee.password = await bcrypt.hash(employee.password, salt);
}
}
}
});
module.exports = Employee;
// 实例方法:验证密码
Employee.prototype.validPassword = async function(password) {
try {
return await bcrypt.compare(password, this.password);
} catch (error) {
console.error('密码验证错误:', error);
return false;
}
};
// 实例方法:检查账号是否被锁定
Employee.prototype.isLocked = function() {
return !!(this.lockedUntil && this.lockedUntil > Date.now());
};
// 实例方法:增加登录尝试次数
Employee.prototype.incLoginAttempts = async function() {
// 如果已经锁定且锁定时间已过,则重置
if (this.lockedUntil && this.lockedUntil < Date.now()) {
return this.update({
loginAttempts: 1,
lockedUntil: null
});
}
const updates = { loginAttempts: this.loginAttempts + 1 };
// 如果达到最大尝试次数,则锁定账号
if (this.loginAttempts + 1 >= 5 && !this.isLocked()) {
updates.lockedUntil = new Date(Date.now() + 30 * 60 * 1000); // 锁定30分钟
}
return this.update(updates);
};
// 实例方法:重置登录尝试次数
Employee.prototype.resetLoginAttempts = async function() {
return this.update({
loginAttempts: 0,
lockedUntil: null
});
};
return Employee;
};

View File

@@ -99,9 +99,27 @@ const InstallationTask = sequelize.define('InstallationTask', {
}, {
tableName: 'installation_tasks',
timestamps: true,
underscored: false,
createdAt: 'createdAt',
updatedAt: 'updatedAt',
comment: '待安装任务表'
});
// 定义关联关系
InstallationTask.associate = (models) => {
// 待安装任务与用户关联(创建人)
InstallationTask.belongsTo(models.User, {
foreignKey: { name: 'createdBy', field: 'createdBy' },
targetKey: 'id',
as: 'creator'
});
// 待安装任务与用户关联(更新人)
InstallationTask.belongsTo(models.User, {
foreignKey: { name: 'updatedBy', field: 'updatedBy' },
targetKey: 'id',
as: 'updater'
});
};
module.exports = InstallationTask;

View File

@@ -13,34 +13,20 @@ class LoanApplication extends BaseModel {
*/
getStatusText() {
const statusMap = {
pending_review: '待审',
verification_pending: '核验待放款',
pending_binding: '待绑定',
pending: '待审',
approved: '已通过',
rejected: '已拒绝'
rejected: '已拒绝',
completed: '已完成'
};
return statusMap[this.status] || this.status;
}
/**
* 获取申请类型文本
* @returns {String} 类型文本
*/
getTypeText() {
const typeMap = {
personal: '个人贷款',
business: '企业贷款',
mortgage: '抵押贷款'
};
return typeMap[this.type] || this.type;
}
/**
* 格式化申请金额
* @returns {String} 格式化后的金额
*/
getFormattedAmount() {
return `${this.amount.toFixed(2)}`;
return `${this.loan_amount.toFixed(2)}`;
}
}
@@ -51,144 +37,55 @@ LoanApplication.init({
primaryKey: true,
autoIncrement: true
},
applicationNumber: {
type: DataTypes.STRING(50),
allowNull: false,
unique: true,
comment: '申请单号'
},
productName: {
type: DataTypes.STRING(200),
allowNull: false,
comment: '贷款产品名称'
},
farmerName: {
customer_name: {
type: DataTypes.STRING(100),
allowNull: false,
comment: '申请养殖户姓名'
comment: '户姓名'
},
borrowerName: {
type: DataTypes.STRING(100),
allowNull: false,
comment: '贷款人姓名'
},
borrowerIdNumber: {
customer_phone: {
type: DataTypes.STRING(20),
allowNull: false,
comment: '贷款人身份证号'
comment: '客户电话'
},
assetType: {
type: DataTypes.STRING(50),
customer_id_card: {
type: DataTypes.STRING(18),
allowNull: false,
comment: '生资种类'
comment: '客户身份证号'
},
applicationQuantity: {
type: DataTypes.STRING(100),
allowNull: false,
comment: '申请数量'
},
amount: {
loan_amount: {
type: DataTypes.DECIMAL(15, 2),
allowNull: false,
comment: '申请额度'
comment: '贷款金额'
},
status: {
type: DataTypes.ENUM(
'pending_review',
'verification_pending',
'pending_binding',
'approved',
'rejected'
),
allowNull: false,
defaultValue: 'pending_review',
comment: '申请状态'
},
type: {
type: DataTypes.ENUM('personal', 'business', 'mortgage'),
allowNull: false,
defaultValue: 'personal',
comment: '申请类型'
},
term: {
loan_term: {
type: DataTypes.INTEGER,
allowNull: false,
comment: '申请期限(月)'
comment: '贷款期限(月)'
},
interestRate: {
interest_rate: {
type: DataTypes.DECIMAL(5, 2),
allowNull: false,
comment: '预计利率'
comment: '贷款利率(%'
},
phone: {
type: DataTypes.STRING(20),
application_date: {
type: DataTypes.DATEONLY,
allowNull: false,
comment: '联系电话'
comment: '申请日期'
},
purpose: {
type: DataTypes.TEXT,
status: {
type: DataTypes.ENUM('pending', 'approved', 'rejected', 'completed'),
allowNull: true,
comment: '申请用途'
},
remark: {
type: DataTypes.TEXT,
allowNull: true,
comment: '备注'
},
applicationTime: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW,
comment: '申请时间'
},
approvedTime: {
type: DataTypes.DATE,
allowNull: true,
comment: '审批通过时间'
},
rejectedTime: {
type: DataTypes.DATE,
allowNull: true,
comment: '审批拒绝时间'
},
approvedBy: {
type: DataTypes.INTEGER,
allowNull: true,
comment: '审批人ID'
},
rejectedBy: {
type: DataTypes.INTEGER,
allowNull: true,
comment: '拒绝人ID'
},
rejectionReason: {
type: DataTypes.TEXT,
allowNull: true,
comment: '拒绝原因'
defaultValue: 'pending',
comment: '申请状态'
}
}, {
sequelize: require('../config/database').sequelize,
modelName: 'LoanApplication',
tableName: 'bank_loan_applications',
tableName: 'loan_applications',
timestamps: true,
createdAt: 'createdAt',
updatedAt: 'updatedAt',
hooks: {
beforeCreate: (application) => {
// 生成申请单号
if (!application.applicationNumber) {
const now = new Date();
const timestamp = now.getFullYear().toString() +
(now.getMonth() + 1).toString().padStart(2, '0') +
now.getDate().toString().padStart(2, '0') +
now.getHours().toString().padStart(2, '0') +
now.getMinutes().toString().padStart(2, '0') +
now.getSeconds().toString().padStart(2, '0');
const random = Math.floor(Math.random() * 1000).toString().padStart(3, '0');
application.applicationNumber = timestamp + random;
}
}
}
underscored: true,
createdAt: 'created_at',
updatedAt: 'updated_at'
});
module.exports = LoanApplication;

View File

@@ -14,7 +14,6 @@ class LoanContract extends BaseModel {
getStatusText() {
const statusMap = {
active: '已放款',
pending: '待放款',
completed: '已完成',
defaulted: '违约',
cancelled: '已取消'
@@ -22,43 +21,12 @@ class LoanContract extends BaseModel {
return statusMap[this.status] || this.status;
}
/**
* 获取合同类型文本
* @returns {String} 类型文本
*/
getTypeText() {
const typeMap = {
livestock_collateral: '畜禽活体抵押',
farmer_loan: '惠农贷',
business_loan: '商业贷款',
personal_loan: '个人贷款'
};
return typeMap[this.type] || this.type;
}
/**
* 格式化合同金额
* @returns {String} 格式化后的金额
*/
getFormattedAmount() {
return `${this.amount.toFixed(2)}`;
}
/**
* 计算剩余还款金额
* @returns {Number} 剩余金额
*/
getRemainingAmount() {
return this.amount - (this.paidAmount || 0);
}
/**
* 计算还款进度百分比
* @returns {Number} 进度百分比
*/
getRepaymentProgress() {
if (this.amount <= 0) return 0;
return Math.round(((this.paidAmount || 0) / this.amount) * 100);
return `${this.loan_amount.toFixed(2)}`;
}
}
@@ -69,167 +37,63 @@ LoanContract.init({
primaryKey: true,
autoIncrement: true
},
contractNumber: {
contract_number: {
type: DataTypes.STRING(50),
allowNull: false,
unique: true,
comment: '合同编号'
},
applicationNumber: {
type: DataTypes.STRING(50),
allowNull: false,
comment: '申请单号'
},
productName: {
type: DataTypes.STRING(200),
allowNull: false,
comment: '贷款产品名称'
},
farmerName: {
customer_name: {
type: DataTypes.STRING(100),
allowNull: false,
comment: '申请养殖户姓名'
comment: '户姓名'
},
borrowerName: {
type: DataTypes.STRING(100),
allowNull: false,
comment: '贷款人姓名'
},
borrowerIdNumber: {
customer_phone: {
type: DataTypes.STRING(20),
allowNull: false,
comment: '贷款人身份证号'
comment: '客户电话'
},
assetType: {
type: DataTypes.STRING(50),
customer_id_card: {
type: DataTypes.STRING(18),
allowNull: false,
comment: '生资种类'
comment: '客户身份证号'
},
applicationQuantity: {
type: DataTypes.STRING(100),
allowNull: false,
comment: '申请数量'
},
amount: {
loan_amount: {
type: DataTypes.DECIMAL(15, 2),
allowNull: false,
comment: '合同金额'
comment: '贷款金额'
},
paidAmount: {
type: DataTypes.DECIMAL(15, 2),
allowNull: false,
defaultValue: 0,
comment: '已还款金额'
},
status: {
type: DataTypes.ENUM(
'active',
'pending',
'completed',
'defaulted',
'cancelled'
),
allowNull: false,
defaultValue: 'pending',
comment: '合同状态'
},
type: {
type: DataTypes.ENUM(
'livestock_collateral',
'farmer_loan',
'business_loan',
'personal_loan'
),
allowNull: false,
comment: '合同类型'
},
term: {
loan_term: {
type: DataTypes.INTEGER,
allowNull: false,
comment: '合同期限(月)'
comment: '贷款期限(月)'
},
interestRate: {
interest_rate: {
type: DataTypes.DECIMAL(5, 2),
allowNull: false,
comment: '利率'
comment: '贷款利率(%'
},
phone: {
type: DataTypes.STRING(20),
contract_date: {
type: DataTypes.DATEONLY,
allowNull: false,
comment: '联系电话'
comment: '合同签订日期'
},
purpose: {
type: DataTypes.TEXT,
status: {
type: DataTypes.ENUM('active', 'completed', 'defaulted', 'cancelled'),
allowNull: true,
comment: '贷款用途'
},
remark: {
type: DataTypes.TEXT,
allowNull: true,
comment: '备注'
},
contractTime: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW,
comment: '合同签订时间'
},
disbursementTime: {
type: DataTypes.DATE,
allowNull: true,
comment: '放款时间'
},
maturityTime: {
type: DataTypes.DATE,
allowNull: true,
comment: '到期时间'
},
completedTime: {
type: DataTypes.DATE,
allowNull: true,
comment: '完成时间'
},
createdBy: {
type: DataTypes.INTEGER,
allowNull: true,
comment: '创建人ID',
references: {
model: 'bank_users',
key: 'id'
}
},
updatedBy: {
type: DataTypes.INTEGER,
allowNull: true,
comment: '更新人ID',
references: {
model: 'bank_users',
key: 'id'
}
defaultValue: 'active',
comment: '合同状态'
}
}, {
sequelize: require('../config/database').sequelize,
modelName: 'LoanContract',
tableName: 'bank_loan_contracts',
tableName: 'loan_contracts',
timestamps: true,
createdAt: 'createdAt',
updatedAt: 'updatedAt',
hooks: {
beforeCreate: (contract) => {
// 生成合同编号
if (!contract.contractNumber) {
const now = new Date();
const timestamp = now.getFullYear().toString() +
(now.getMonth() + 1).toString().padStart(2, '0') +
now.getDate().toString().padStart(2, '0') +
now.getHours().toString().padStart(2, '0') +
now.getMinutes().toString().padStart(2, '0') +
now.getSeconds().toString().padStart(2, '0');
const random = Math.floor(Math.random() * 1000).toString().padStart(3, '0');
contract.contractNumber = 'HT' + timestamp + random;
}
}
}
underscored: true,
createdAt: 'created_at',
updatedAt: 'updated_at',
// 移除不存在的字段
omitNull: true
});
module.exports = LoanContract;
module.exports = LoanContract;

View File

@@ -11,108 +11,127 @@ const LoanProduct = sequelize.define('LoanProduct', {
productName: {
type: DataTypes.STRING(200),
allowNull: false,
field: 'product_name',
comment: '贷款产品名称'
},
loanAmount: {
type: DataTypes.STRING(100),
allowNull: false,
field: 'loan_amount',
comment: '贷款额度'
},
loanTerm: {
type: DataTypes.INTEGER,
allowNull: false,
field: 'loan_term',
comment: '贷款周期(月)'
},
interestRate: {
type: DataTypes.DECIMAL(5, 2),
allowNull: false,
field: 'interest_rate',
comment: '贷款利率(%'
},
serviceArea: {
type: DataTypes.STRING(200),
allowNull: false,
field: 'service_area',
comment: '服务区域'
},
servicePhone: {
type: DataTypes.STRING(20),
allowNull: false,
field: 'service_phone',
comment: '服务电话'
},
totalCustomers: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0,
field: 'total_customers',
comment: '服务客户总数量'
},
supervisionCustomers: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0,
field: 'supervision_customers',
comment: '监管中客户数量'
},
completedCustomers: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0,
field: 'completed_customers',
comment: '已结项客户数量'
},
onSaleStatus: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: true,
field: 'on_sale_status',
comment: '在售状态'
},
productDescription: {
type: DataTypes.TEXT,
allowNull: true,
field: 'product_description',
comment: '产品描述'
},
applicationRequirements: {
type: DataTypes.TEXT,
allowNull: true,
field: 'application_requirements',
comment: '申请条件'
},
requiredDocuments: {
type: DataTypes.TEXT,
allowNull: true,
field: 'required_documents',
comment: '所需材料'
},
approvalProcess: {
type: DataTypes.TEXT,
allowNull: true,
field: 'approval_process',
comment: '审批流程'
},
riskLevel: {
type: DataTypes.ENUM('LOW', 'MEDIUM', 'HIGH'),
allowNull: false,
defaultValue: 'MEDIUM',
field: 'risk_level',
comment: '风险等级'
},
minLoanAmount: {
type: DataTypes.DECIMAL(15, 2),
allowNull: true,
field: 'min_loan_amount',
comment: '最小贷款金额'
},
maxLoanAmount: {
type: DataTypes.DECIMAL(15, 2),
allowNull: true,
field: 'max_loan_amount',
comment: '最大贷款金额'
},
createdBy: {
type: DataTypes.INTEGER,
allowNull: false,
field: 'created_by',
comment: '创建人ID'
},
updatedBy: {
type: DataTypes.INTEGER,
allowNull: true,
field: 'updated_by',
comment: '更新人ID'
}
}, {
tableName: 'loan_products',
timestamps: true,
createdAt: 'createdAt',
updatedAt: 'updatedAt',
createdAt: 'created_at',
updatedAt: 'updated_at',
comment: '贷款商品表'
});

View File

@@ -21,61 +21,72 @@ const Project = sequelize.define('Project', {
farmName: {
type: DataTypes.STRING(200),
allowNull: false,
field: 'farmName',
comment: '养殖场名称'
},
supervisionObject: {
type: DataTypes.STRING(50),
allowNull: false,
field: 'supervisionObject',
comment: '监管对象'
},
supervisionQuantity: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0,
field: 'supervisionQuantity',
comment: '监管数量'
},
supervisionPeriod: {
type: DataTypes.STRING(50),
allowNull: false,
field: 'supervisionPeriod',
comment: '监管周期'
},
supervisionAmount: {
type: DataTypes.DECIMAL(15, 2),
allowNull: false,
defaultValue: 0.00,
field: 'supervisionAmount',
comment: '监管金额'
},
startTime: {
type: DataTypes.DATEONLY,
allowNull: false,
field: 'startTime',
comment: '起始时间'
},
endTime: {
type: DataTypes.DATEONLY,
allowNull: false,
field: 'endTime',
comment: '结束时间'
},
earTag: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0,
field: 'earTag',
comment: '耳标数量'
},
collar: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0,
field: 'collar',
comment: '项圈数量'
},
host: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0,
field: 'host',
comment: '主机数量'
},
loanOfficer: {
type: DataTypes.STRING(100),
allowNull: true,
field: 'loanOfficer',
comment: '贷款专员'
},
description: {
@@ -86,16 +97,19 @@ const Project = sequelize.define('Project', {
createdBy: {
type: DataTypes.INTEGER,
allowNull: true,
field: 'createdBy',
comment: '创建人ID'
},
updatedBy: {
type: DataTypes.INTEGER,
allowNull: true,
field: 'updatedBy',
comment: '更新人ID'
}
}, {
tableName: 'projects',
timestamps: true,
underscored: false,
createdAt: 'createdAt',
updatedAt: 'updatedAt',
comment: '项目清单表'
@@ -105,13 +119,15 @@ const Project = sequelize.define('Project', {
Project.associate = (models) => {
// 项目与用户关联(创建人)
Project.belongsTo(models.User, {
foreignKey: 'createdBy',
foreignKey: { name: 'createdBy', field: 'createdBy' },
targetKey: 'id',
as: 'creator'
});
// 项目与用户关联(更新人)
Project.belongsTo(models.User, {
foreignKey: 'updatedBy',
foreignKey: { name: 'updatedBy', field: 'updatedBy' },
targetKey: 'id',
as: 'updater'
});
};

View File

@@ -19,7 +19,8 @@ SupervisionTask.init({
type: DataTypes.STRING(50),
allowNull: false,
unique: true,
comment: '申请单号'
comment: '申请单号',
field: 'applicationNumber'
},
contractNumber: {
type: DataTypes.STRING(50),
@@ -145,7 +146,7 @@ SupervisionTask.init({
modelName: 'SupervisionTask',
tableName: 'supervision_tasks',
timestamps: true,
underscored: true,
underscored: false,
createdAt: 'createdAt',
updatedAt: 'updatedAt',
comment: '监管任务表'
@@ -155,11 +156,13 @@ SupervisionTask.init({
SupervisionTask.associate = (models) => {
SupervisionTask.belongsTo(models.User, {
foreignKey: 'createdBy',
as: 'creator'
as: 'creator',
targetKey: 'id'
});
SupervisionTask.belongsTo(models.User, {
foreignKey: 'updatedBy',
as: 'updater'
as: 'updater',
targetKey: 'id'
});
};

View File

@@ -172,6 +172,10 @@ User.init({
sequelize,
tableName: 'bank_users',
modelName: 'User',
timestamps: true,
underscored: true,
createdAt: 'created_at',
updatedAt: 'updated_at',
hooks: {
beforeCreate: async (user) => {
if (user.password) {

View File

@@ -11,7 +11,7 @@ const Role = require('./Role');
const Account = require('./Account');
const Transaction = require('./Transaction');
const LoanProduct = require('./LoanProduct');
const Employee = require('./Employee');
const Employee = require('./Employee')(sequelize);
const Department = require('./Department');
const Position = require('./Position');
const Report = require('./Report');
@@ -62,29 +62,7 @@ Transaction.belongsTo(Account, {
// 交易记录与用户关联(通过账户)
// 移除不合理的Transaction->User through Account的belongsTo定义避免错误外键映射
// 员工与部门关联
Employee.belongsTo(Department, {
foreignKey: 'department_id',
as: 'department',
targetKey: 'id'
});
Department.hasMany(Employee, {
foreignKey: 'department_id',
as: 'employees'
});
// 员工与职位关联
Employee.belongsTo(Position, {
foreignKey: 'position_id',
as: 'position',
targetKey: 'id'
});
Position.hasMany(Employee, {
foreignKey: 'position_id',
as: 'employees'
});
// 员工关联关系Employee模型使用字符串字段存储部门和职位不需要关联
// 报表与用户关联
Report.belongsTo(User, {
@@ -100,7 +78,7 @@ User.hasMany(Report, {
// 项目与用户关联(创建人)
Project.belongsTo(User, {
foreignKey: 'createdBy',
foreignKey: { name: 'createdBy', field: 'createdBy' },
as: 'creator',
targetKey: 'id'
});
@@ -112,7 +90,7 @@ User.hasMany(Project, {
// 项目与用户关联(更新人)
Project.belongsTo(User, {
foreignKey: 'updatedBy',
foreignKey: { name: 'updatedBy', field: 'updatedBy' },
as: 'updater',
targetKey: 'id'
});
@@ -218,41 +196,8 @@ User.hasMany(LoanProduct, {
as: 'updatedLoanProducts'
});
// 贷款申请与用户关联(申请人)
LoanApplication.belongsTo(User, {
foreignKey: 'applicantId',
as: 'applicant',
targetKey: 'id'
});
User.hasMany(LoanApplication, {
foreignKey: 'applicantId',
as: 'loanApplications'
});
// 贷款申请与用户关联(审批人)
LoanApplication.belongsTo(User, {
foreignKey: 'approvedBy',
as: 'approver',
targetKey: 'id'
});
User.hasMany(LoanApplication, {
foreignKey: 'approvedBy',
as: 'approvedApplications'
});
// 贷款申请与用户关联(拒绝人)
LoanApplication.belongsTo(User, {
foreignKey: 'rejectedBy',
as: 'rejector',
targetKey: 'id'
});
User.hasMany(LoanApplication, {
foreignKey: 'rejectedBy',
as: 'rejectedApplications'
});
// 贷款申请暂时不关联用户表,因为当前表结构中没有外键字段
// 如果需要关联,需要先添加相应的外键字段到数据库表中
// 审核记录与贷款申请关联
AuditRecord.belongsTo(LoanApplication, {
@@ -278,29 +223,8 @@ User.hasMany(AuditRecord, {
as: 'auditRecords'
});
// 贷款合同与用户关联(创建人)
LoanContract.belongsTo(User, {
foreignKey: 'createdBy',
as: 'creator',
targetKey: 'id'
});
User.hasMany(LoanContract, {
foreignKey: 'createdBy',
as: 'createdLoanContracts'
});
// 贷款合同与用户关联(更新人)
LoanContract.belongsTo(User, {
foreignKey: 'updatedBy',
as: 'updater',
targetKey: 'id'
});
User.hasMany(LoanContract, {
foreignKey: 'updatedBy',
as: 'updatedLoanContracts'
});
// 贷款合同暂时不关联用户表,因为当前表结构中没有外键字段
// 如果需要关联,需要先添加相应的外键字段到数据库表中
// 导出所有模型和数据库实例
module.exports = {