Files
nxxmdata/bank-backend/controllers/loanReleaseController.js

546 lines
13 KiB
JavaScript

/**
* 贷款解押控制器
* @file loanReleaseController.js
* @description 银行系统贷款解押相关接口控制器
*/
const { LoanRelease, LoanReleaseHistory, User } = require('../models');
const { Op } = require('sequelize');
/**
* 获取解押申请列表
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
const getReleases = async (req, res) => {
try {
const {
page = 1,
pageSize = 10,
searchField = 'application_number',
searchValue = '',
status = '',
sortField = 'created_at',
sortOrder = 'DESC'
} = req.query;
// 构建查询条件
const whereCondition = {};
// 搜索条件
if (searchValue) {
switch (searchField) {
case 'application_number':
whereCondition.application_number = {
[Op.like]: `%${searchValue}%`
};
break;
case 'customer_name':
whereCondition[Op.or] = [
{ customer_name: { [Op.like]: `%${searchValue}%` } },
{ farmer_name: { [Op.like]: `%${searchValue}%` } }
];
break;
case 'product_name':
whereCondition.product_name = {
[Op.like]: `%${searchValue}%`
};
break;
}
}
// 状态筛选
if (status) {
whereCondition.status = status;
}
// 分页参数
const offset = (page - 1) * pageSize;
const limit = parseInt(pageSize);
// 查询数据
const { count, rows } = await LoanRelease.findAndCountAll({
where: whereCondition,
order: [[sortField, sortOrder.toUpperCase()]],
offset,
limit,
include: [
{
model: User,
as: 'processor',
attributes: ['id', 'username', 'real_name']
}
]
});
// 格式化返回数据
const releases = rows.map(release => ({
id: release.id,
applicationNumber: release.application_number,
productName: release.product_name || '养殖贷款',
farmerName: release.farmer_name || release.customer_name,
applicantName: release.customer_name,
applicantIdNumber: release.customer_id_card,
applicantPhone: release.customer_phone,
assetType: release.collateral_type === 'livestock' ? '牛' : '其他',
releaseQuantity: release.release_quantity || '1头',
releaseAmount: parseFloat(release.release_amount),
status: release.status,
applicationTime: release.application_date,
processTime: release.process_date,
completeTime: release.complete_date,
processorName: release.processor?.real_name || release.processor_name,
processComment: release.process_comment,
rejectionReason: release.rejection_reason,
remark: release.remark,
created_at: release.created_at,
updated_at: release.updated_at
}));
res.json({
success: true,
data: {
releases,
pagination: {
current: parseInt(page),
pageSize: limit,
total: count,
totalPages: Math.ceil(count / limit)
}
}
});
} catch (error) {
console.error('获取解押申请列表失败:', error);
res.status(500).json({
success: false,
message: '获取解押申请列表失败'
});
}
};
/**
* 获取解押申请详情
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
const getReleaseDetail = async (req, res) => {
try {
const { id } = req.params;
const release = await LoanRelease.findByPk(id, {
include: [
{
model: User,
as: 'processor',
attributes: ['id', 'username', 'real_name']
}
]
});
if (!release) {
return res.status(404).json({
success: false,
message: '解押申请不存在'
});
}
// 获取历史记录
const history = await LoanReleaseHistory.findAll({
where: { release_id: id },
order: [['operation_time', 'ASC']]
});
const releaseDetail = {
id: release.id,
releaseNumber: release.application_number,
customerName: release.customer_name,
contractNumber: `CONTRACT-${String(release.contract_id || release.id).padStart(6, '0')}`,
status: release.status,
collateralType: release.collateral_type,
collateralDescription: release.collateral_description,
loanAmount: parseFloat(release.loan_amount || 0),
collateralValue: parseFloat(release.collateral_value || 0),
applicationTime: release.application_date,
processTime: release.process_date,
completeTime: release.complete_date,
phone: release.customer_phone,
idCard: release.customer_id_card,
reason: release.application_reason,
remark: release.remark,
history: history.map(h => ({
id: h.id,
action: h.action,
operator: h.operator,
time: h.operation_time,
comment: h.comment
}))
};
res.json({
success: true,
data: releaseDetail
});
} catch (error) {
console.error('获取解押申请详情失败:', error);
res.status(500).json({
success: false,
message: '获取解押申请详情失败'
});
}
};
/**
* 创建解押申请
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
const createRelease = async (req, res) => {
try {
const {
contract_id,
customer_name,
customer_phone,
customer_id_card,
farmer_name,
product_name,
collateral_type,
collateral_description,
collateral_value,
loan_amount,
release_amount,
release_quantity,
application_reason,
remark
} = req.body;
// 生成申请单号
const applicationNumber = `REL-${Date.now()}`;
const release = await LoanRelease.create({
application_number: applicationNumber,
contract_id,
customer_name,
customer_phone,
customer_id_card,
farmer_name,
product_name,
collateral_type,
collateral_description,
collateral_value,
loan_amount,
release_amount,
release_quantity,
application_reason,
remark,
status: 'pending'
});
// 创建历史记录
await LoanReleaseHistory.create({
release_id: release.id,
action: 'apply',
operator: customer_name,
comment: '提交解押申请'
});
res.status(201).json({
success: true,
message: '解押申请创建成功',
data: {
id: release.id,
applicationNumber: release.application_number
}
});
} catch (error) {
console.error('创建解押申请失败:', error);
res.status(500).json({
success: false,
message: '创建解押申请失败'
});
}
};
/**
* 更新解押申请
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
const updateRelease = async (req, res) => {
try {
const { id } = req.params;
const updateData = req.body;
const release = await LoanRelease.findByPk(id);
if (!release) {
return res.status(404).json({
success: false,
message: '解押申请不存在'
});
}
// 更新数据
await release.update(updateData);
res.json({
success: true,
message: '解押申请更新成功'
});
} catch (error) {
console.error('更新解押申请失败:', error);
res.status(500).json({
success: false,
message: '更新解押申请失败'
});
}
};
/**
* 处理解押申请
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
const processRelease = async (req, res) => {
try {
const { id } = req.params;
const { action, comment, remark } = req.body;
if (!req.user || !req.user.userId) {
return res.status(401).json({
success: false,
message: '用户信息无效'
});
}
const release = await LoanRelease.findByPk(id);
if (!release) {
return res.status(404).json({
success: false,
message: '解押申请不存在'
});
}
if (release.status !== 'pending') {
return res.status(400).json({
success: false,
message: '该申请已完成处理,无法重复操作'
});
}
const previousStatus = release.status;
let newStatus = release.status;
// 根据处理动作更新状态
if (action === 'approve') {
newStatus = 'approved';
} else if (action === 'reject') {
newStatus = 'rejected';
}
// 更新申请状态
release.status = newStatus;
release.process_date = new Date();
release.processor_id = req.user.userId;
release.processor_name = req.user.username;
release.process_comment = comment;
release.remark = remark;
if (action === 'reject') {
release.rejection_reason = comment;
}
await release.save();
// 创建历史记录
await LoanReleaseHistory.create({
release_id: release.id,
action: action,
operator: req.user.username,
operator_id: req.user.userId,
comment: comment,
previous_status: previousStatus,
new_status: newStatus
});
res.json({
success: true,
message: `解押申请已${action === 'approve' ? '通过' : '拒绝'}`,
data: {
id: release.id,
status: newStatus,
action,
comment
}
});
} catch (error) {
console.error('处理解押申请失败:', error);
res.status(500).json({
success: false,
message: '处理解押申请失败'
});
}
};
/**
* 完成解押
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
const completeRelease = async (req, res) => {
try {
const { id } = req.params;
const { comment } = req.body;
if (!req.user || !req.user.userId) {
return res.status(401).json({
success: false,
message: '用户信息无效'
});
}
const release = await LoanRelease.findByPk(id);
if (!release) {
return res.status(404).json({
success: false,
message: '解押申请不存在'
});
}
if (release.status !== 'approved') {
return res.status(400).json({
success: false,
message: '只有已通过的解押申请才能完成解押'
});
}
const previousStatus = release.status;
// 更新状态为已完成
release.status = 'completed';
release.complete_date = new Date();
await release.save();
// 创建历史记录
await LoanReleaseHistory.create({
release_id: release.id,
action: 'complete',
operator: req.user.username,
operator_id: req.user.userId,
comment: comment || '解押手续办理完成',
previous_status: previousStatus,
new_status: 'completed'
});
res.json({
success: true,
message: '解押完成',
data: {
id: release.id,
status: 'completed'
}
});
} catch (error) {
console.error('完成解押失败:', error);
res.status(500).json({
success: false,
message: '完成解押失败'
});
}
};
/**
* 删除解押申请
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
const deleteRelease = async (req, res) => {
try {
const { id } = req.params;
const release = await LoanRelease.findByPk(id);
if (!release) {
return res.status(404).json({
success: false,
message: '解押申请不存在'
});
}
// 只有待处理状态的申请才能删除
if (release.status !== 'pending') {
return res.status(400).json({
success: false,
message: '只有待处理状态的申请才能删除'
});
}
await release.destroy();
res.json({
success: true,
message: '解押申请删除成功'
});
} catch (error) {
console.error('删除解押申请失败:', error);
res.status(500).json({
success: false,
message: '删除解押申请失败'
});
}
};
/**
* 获取解押统计信息
* @param {Object} req - 请求对象
* @param {Object} res - 响应对象
*/
const getReleaseStats = async (req, res) => {
try {
const stats = await LoanRelease.findAll({
attributes: [
'status',
[require('sequelize').fn('COUNT', '*'), 'count']
],
group: ['status']
});
const totalCount = await LoanRelease.count();
const pendingCount = await LoanRelease.count({ where: { status: 'pending' } });
const processingCount = await LoanRelease.count({ where: { status: 'processing' } });
const completedCount = await LoanRelease.count({ where: { status: 'completed' } });
res.json({
success: true,
data: {
total: totalCount,
pending: pendingCount,
processing: processingCount,
completed: completedCount,
statusStats: stats
}
});
} catch (error) {
console.error('获取解押统计信息失败:', error);
res.status(500).json({
success: false,
message: '获取解押统计信息失败'
});
}
};
module.exports = {
getReleases,
getReleaseDetail,
createRelease,
updateRelease,
processRelease,
completeRelease,
deleteRelease,
getReleaseStats
};