添加银行后端接口,前端代码
This commit is contained in:
460
bank-backend/controllers/projectController.js
Normal file
460
bank-backend/controllers/projectController.js
Normal file
@@ -0,0 +1,460 @@
|
||||
const { Project, User } = require('../models');
|
||||
const { Op } = require('sequelize');
|
||||
|
||||
// 获取项目列表
|
||||
const getProjects = async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
page = 1,
|
||||
limit = 10,
|
||||
search = '',
|
||||
status = '',
|
||||
sortBy = 'createdAt',
|
||||
sortOrder = 'DESC'
|
||||
} = req.query;
|
||||
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
// 构建查询条件
|
||||
const where = {};
|
||||
|
||||
// 搜索条件
|
||||
if (search) {
|
||||
where[Op.or] = [
|
||||
{ name: { [Op.like]: `%${search}%` } },
|
||||
{ farmName: { [Op.like]: `%${search}%` } },
|
||||
{ loanOfficer: { [Op.like]: `%${search}%` } }
|
||||
];
|
||||
}
|
||||
|
||||
// 状态筛选
|
||||
if (status) {
|
||||
where.status = status;
|
||||
}
|
||||
|
||||
// 查询项目列表
|
||||
const { count, rows: projects } = await Project.findAndCountAll({
|
||||
where,
|
||||
include: [
|
||||
{
|
||||
model: User,
|
||||
as: 'creator',
|
||||
attributes: ['id', 'username', 'real_name']
|
||||
},
|
||||
{
|
||||
model: User,
|
||||
as: 'updater',
|
||||
attributes: ['id', 'username', 'real_name']
|
||||
}
|
||||
],
|
||||
order: [[sortBy, sortOrder.toUpperCase()]],
|
||||
limit: parseInt(limit),
|
||||
offset: parseInt(offset)
|
||||
});
|
||||
|
||||
// 计算分页信息
|
||||
const totalPages = Math.ceil(count / limit);
|
||||
const hasNextPage = page < totalPages;
|
||||
const hasPrevPage = page > 1;
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
projects,
|
||||
pagination: {
|
||||
current: parseInt(page),
|
||||
pageSize: parseInt(limit),
|
||||
total: count,
|
||||
totalPages,
|
||||
hasNextPage,
|
||||
hasPrevPage
|
||||
}
|
||||
},
|
||||
message: '获取项目列表成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取项目列表失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取项目列表失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 获取项目详情
|
||||
const getProjectById = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const project = await Project.findByPk(id, {
|
||||
include: [
|
||||
{
|
||||
model: User,
|
||||
as: 'creator',
|
||||
attributes: ['id', 'username', 'name']
|
||||
},
|
||||
{
|
||||
model: User,
|
||||
as: 'updater',
|
||||
attributes: ['id', 'username', 'name']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
if (!project) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '项目不存在'
|
||||
});
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: project,
|
||||
message: '获取项目详情成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取项目详情失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取项目详情失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 创建项目
|
||||
const createProject = async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
name,
|
||||
status = 'supervision',
|
||||
farmName,
|
||||
supervisionObject,
|
||||
supervisionQuantity = 0,
|
||||
supervisionPeriod,
|
||||
supervisionAmount = 0.00,
|
||||
startTime,
|
||||
endTime,
|
||||
earTag = 0,
|
||||
collar = 0,
|
||||
host = 0,
|
||||
loanOfficer,
|
||||
description
|
||||
} = req.body;
|
||||
|
||||
// 验证必填字段
|
||||
const requiredFields = ['name', 'farmName', 'supervisionObject', 'supervisionPeriod', 'startTime', 'endTime'];
|
||||
const missingFields = requiredFields.filter(field => !req.body[field]);
|
||||
|
||||
if (missingFields.length > 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: `请填写所有必填字段: ${missingFields.join(', ')}`
|
||||
});
|
||||
}
|
||||
|
||||
// 验证字段长度
|
||||
if (name.length > 100) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '项目名称不能超过100个字符'
|
||||
});
|
||||
}
|
||||
|
||||
if (farmName.length > 200) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '养殖场名称不能超过200个字符'
|
||||
});
|
||||
}
|
||||
|
||||
// 验证数值字段
|
||||
if (supervisionQuantity < 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '监管数量不能为负数'
|
||||
});
|
||||
}
|
||||
|
||||
if (supervisionAmount < 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '监管金额不能为负数'
|
||||
});
|
||||
}
|
||||
|
||||
if (earTag < 0 || collar < 0 || host < 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '设备数量不能为负数'
|
||||
});
|
||||
}
|
||||
|
||||
// 验证状态
|
||||
if (!['supervision', 'completed'].includes(status)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '项目状态只能是 supervision 或 completed'
|
||||
});
|
||||
}
|
||||
|
||||
// 验证日期格式和逻辑
|
||||
const startDate = new Date(startTime);
|
||||
const endDate = new Date(endTime);
|
||||
|
||||
if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '日期格式不正确'
|
||||
});
|
||||
}
|
||||
|
||||
if (startDate >= endDate) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '结束时间必须晚于开始时间'
|
||||
});
|
||||
}
|
||||
|
||||
// 检查项目名称是否已存在
|
||||
const existingProject = await Project.findOne({
|
||||
where: { name }
|
||||
});
|
||||
|
||||
if (existingProject) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '项目名称已存在,请使用其他名称'
|
||||
});
|
||||
}
|
||||
|
||||
// 创建项目
|
||||
const project = await Project.create({
|
||||
name,
|
||||
status,
|
||||
farmName,
|
||||
supervisionObject,
|
||||
supervisionQuantity: parseInt(supervisionQuantity),
|
||||
supervisionPeriod,
|
||||
supervisionAmount: parseFloat(supervisionAmount),
|
||||
startTime,
|
||||
endTime,
|
||||
earTag: parseInt(earTag),
|
||||
collar: parseInt(collar),
|
||||
host: parseInt(host),
|
||||
loanOfficer,
|
||||
description,
|
||||
createdBy: req.user?.userId || req.user?.id,
|
||||
updatedBy: req.user?.userId || req.user?.id
|
||||
});
|
||||
|
||||
// 获取创建的项目详情(包含关联信息)
|
||||
const createdProject = await Project.findByPk(project.id, {
|
||||
include: [
|
||||
{
|
||||
model: User,
|
||||
as: 'creator',
|
||||
attributes: ['id', 'username', 'real_name']
|
||||
},
|
||||
{
|
||||
model: User,
|
||||
as: 'updater',
|
||||
attributes: ['id', 'username', 'real_name']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: createdProject,
|
||||
message: '创建项目成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('创建项目失败:', error);
|
||||
|
||||
// 处理数据库约束错误
|
||||
if (error.name === 'SequelizeValidationError') {
|
||||
const validationErrors = error.errors.map(err => err.message).join(', ');
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: `数据验证失败: ${validationErrors}`
|
||||
});
|
||||
}
|
||||
|
||||
if (error.name === 'SequelizeUniqueConstraintError') {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '项目名称已存在,请使用其他名称'
|
||||
});
|
||||
}
|
||||
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '创建项目失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 更新项目
|
||||
const updateProject = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const updateData = req.body;
|
||||
|
||||
// 验证日期
|
||||
if (updateData.startTime && updateData.endTime) {
|
||||
if (new Date(updateData.startTime) >= new Date(updateData.endTime)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '结束时间必须晚于开始时间'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const project = await Project.findByPk(id);
|
||||
if (!project) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '项目不存在'
|
||||
});
|
||||
}
|
||||
|
||||
// 更新项目
|
||||
await project.update({
|
||||
...updateData,
|
||||
updatedBy: req.user?.id
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: project,
|
||||
message: '更新项目成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('更新项目失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '更新项目失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 删除项目
|
||||
const deleteProject = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const project = await Project.findByPk(id);
|
||||
if (!project) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '项目不存在'
|
||||
});
|
||||
}
|
||||
|
||||
await project.destroy();
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: '删除项目成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('删除项目失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '删除项目失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 获取项目统计
|
||||
const getProjectStats = async (req, res) => {
|
||||
try {
|
||||
const totalProjects = await Project.count();
|
||||
const supervisionProjects = await Project.count({ where: { status: 'supervision' } });
|
||||
const completedProjects = await Project.count({ where: { status: 'completed' } });
|
||||
|
||||
// 计算总监管金额
|
||||
const totalAmount = await Project.sum('supervisionAmount');
|
||||
|
||||
// 计算总监管数量
|
||||
const totalQuantity = await Project.sum('supervisionQuantity');
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
total: totalProjects,
|
||||
supervision: supervisionProjects,
|
||||
completed: completedProjects,
|
||||
totalAmount: totalAmount || 0,
|
||||
totalQuantity: totalQuantity || 0
|
||||
},
|
||||
message: '获取项目统计成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取项目统计失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取项目统计失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 批量更新项目状态
|
||||
const batchUpdateStatus = async (req, res) => {
|
||||
try {
|
||||
const { projectIds, status } = req.body;
|
||||
|
||||
if (!projectIds || !Array.isArray(projectIds) || projectIds.length === 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '请选择要更新的项目'
|
||||
});
|
||||
}
|
||||
|
||||
if (!['supervision', 'completed'].includes(status)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '无效的项目状态'
|
||||
});
|
||||
}
|
||||
|
||||
await Project.update(
|
||||
{
|
||||
status,
|
||||
updatedBy: req.user?.id
|
||||
},
|
||||
{
|
||||
where: { id: { [Op.in]: projectIds } }
|
||||
}
|
||||
);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: `成功更新 ${projectIds.length} 个项目的状态`
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('批量更新项目状态失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '批量更新项目状态失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getProjects,
|
||||
getProjectById,
|
||||
createProject,
|
||||
updateProject,
|
||||
deleteProject,
|
||||
getProjectStats,
|
||||
batchUpdateStatus
|
||||
};
|
||||
573
bank-backend/controllers/supervisionTaskController.js
Normal file
573
bank-backend/controllers/supervisionTaskController.js
Normal file
@@ -0,0 +1,573 @@
|
||||
/**
|
||||
* 监管任务控制器
|
||||
* @file supervisionTaskController.js
|
||||
* @description 监管任务相关的API控制器
|
||||
*/
|
||||
const { SupervisionTask, User } = require('../models');
|
||||
const { Op } = require('sequelize');
|
||||
|
||||
// 获取监管任务列表
|
||||
const getSupervisionTasks = async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
page = 1,
|
||||
limit = 10,
|
||||
search = '',
|
||||
supervisionStatus = '',
|
||||
dateRange = '',
|
||||
sortBy = 'createdAt',
|
||||
sortOrder = 'DESC'
|
||||
} = req.query;
|
||||
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
// 构建查询条件
|
||||
const where = {};
|
||||
|
||||
// 搜索条件
|
||||
if (search) {
|
||||
where[Op.or] = [
|
||||
{ applicationNumber: { [Op.like]: `%${search}%` } },
|
||||
{ contractNumber: { [Op.like]: `%${search}%` } },
|
||||
{ customerName: { [Op.like]: `%${search}%` } },
|
||||
{ productName: { [Op.like]: `%${search}%` } }
|
||||
];
|
||||
}
|
||||
|
||||
// 状态筛选
|
||||
if (supervisionStatus) {
|
||||
where.supervisionStatus = supervisionStatus;
|
||||
}
|
||||
|
||||
// 日期范围筛选
|
||||
if (dateRange) {
|
||||
const [startDate, endDate] = dateRange.split(',');
|
||||
if (startDate && endDate) {
|
||||
where.importTime = {
|
||||
[Op.between]: [new Date(startDate), new Date(endDate)]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 查询监管任务列表
|
||||
const { count, rows: tasks } = await SupervisionTask.findAndCountAll({
|
||||
where,
|
||||
include: [
|
||||
{
|
||||
model: User,
|
||||
as: 'creator',
|
||||
attributes: ['id', 'username', 'real_name']
|
||||
},
|
||||
{
|
||||
model: User,
|
||||
as: 'updater',
|
||||
attributes: ['id', 'username', 'real_name']
|
||||
}
|
||||
],
|
||||
order: [[sortBy, sortOrder.toUpperCase()]],
|
||||
limit: parseInt(limit),
|
||||
offset: parseInt(offset)
|
||||
});
|
||||
|
||||
// 计算分页信息
|
||||
const totalPages = Math.ceil(count / limit);
|
||||
const hasNextPage = page < totalPages;
|
||||
const hasPrevPage = page > 1;
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: '监管任务列表获取成功',
|
||||
data: {
|
||||
tasks,
|
||||
pagination: {
|
||||
total: count,
|
||||
currentPage: parseInt(page),
|
||||
pageSize: parseInt(limit),
|
||||
totalPages,
|
||||
hasNextPage,
|
||||
hasPrevPage
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取监管任务列表失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取监管任务列表失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 获取监管任务详情
|
||||
const getSupervisionTaskById = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const task = await SupervisionTask.findByPk(id, {
|
||||
include: [
|
||||
{
|
||||
model: User,
|
||||
as: 'creator',
|
||||
attributes: ['id', 'username', 'real_name']
|
||||
},
|
||||
{
|
||||
model: User,
|
||||
as: 'updater',
|
||||
attributes: ['id', 'username', 'real_name']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
if (!task) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '监管任务不存在'
|
||||
});
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: '监管任务详情获取成功',
|
||||
data: task
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取监管任务详情失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取监管任务详情失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 创建监管任务
|
||||
const createSupervisionTask = async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
applicationNumber,
|
||||
contractNumber,
|
||||
productName,
|
||||
customerName,
|
||||
idType = 'id_card',
|
||||
idNumber,
|
||||
assetType = 'cattle',
|
||||
assetQuantity = 0,
|
||||
supervisionStatus = 'pending',
|
||||
startTime,
|
||||
endTime,
|
||||
loanAmount = 0,
|
||||
interestRate = 0,
|
||||
loanTerm = 12,
|
||||
supervisorName,
|
||||
supervisorPhone,
|
||||
farmAddress,
|
||||
remarks
|
||||
} = req.body;
|
||||
|
||||
// 验证必填字段
|
||||
const requiredFields = ['applicationNumber', 'contractNumber', 'productName', 'customerName', 'idNumber', 'startTime', 'endTime'];
|
||||
const missingFields = requiredFields.filter(field => !req.body[field]);
|
||||
|
||||
if (missingFields.length > 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: `请填写所有必填字段: ${missingFields.join(', ')}`
|
||||
});
|
||||
}
|
||||
|
||||
// 验证字段长度
|
||||
if (applicationNumber.length > 50) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '申请单号不能超过50个字符'
|
||||
});
|
||||
}
|
||||
|
||||
if (contractNumber.length > 50) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '放款合同编号不能超过50个字符'
|
||||
});
|
||||
}
|
||||
|
||||
if (productName.length > 100) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '产品名称不能超过100个字符'
|
||||
});
|
||||
}
|
||||
|
||||
if (customerName.length > 50) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '客户姓名不能超过50个字符'
|
||||
});
|
||||
}
|
||||
|
||||
// 验证数值字段
|
||||
if (assetQuantity < 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '监管生资数量不能为负数'
|
||||
});
|
||||
}
|
||||
|
||||
if (loanAmount < 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '贷款金额不能为负数'
|
||||
});
|
||||
}
|
||||
|
||||
if (interestRate < 0 || interestRate > 1) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '利率必须在0-1之间'
|
||||
});
|
||||
}
|
||||
|
||||
if (loanTerm < 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '贷款期限不能为负数'
|
||||
});
|
||||
}
|
||||
|
||||
// 验证状态和类型
|
||||
if (!['pending', 'supervising', 'completed', 'suspended'].includes(supervisionStatus)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '监管状态无效'
|
||||
});
|
||||
}
|
||||
|
||||
if (!['id_card', 'passport', 'other'].includes(idType)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '证件类型无效'
|
||||
});
|
||||
}
|
||||
|
||||
if (!['cattle', 'sheep', 'pig', 'poultry', 'other'].includes(assetType)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '养殖生资种类无效'
|
||||
});
|
||||
}
|
||||
|
||||
// 验证日期格式和逻辑
|
||||
const startDate = new Date(startTime);
|
||||
const endDate = new Date(endTime);
|
||||
|
||||
if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '日期格式不正确'
|
||||
});
|
||||
}
|
||||
|
||||
if (startDate >= endDate) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '监管结束时间必须晚于开始时间'
|
||||
});
|
||||
}
|
||||
|
||||
// 检查申请单号和合同编号是否已存在
|
||||
const existingTask = await SupervisionTask.findOne({
|
||||
where: {
|
||||
[Op.or]: [
|
||||
{ applicationNumber },
|
||||
{ contractNumber }
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
if (existingTask) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: existingTask.applicationNumber === applicationNumber ?
|
||||
'申请单号已存在' : '放款合同编号已存在'
|
||||
});
|
||||
}
|
||||
|
||||
// 创建监管任务
|
||||
const task = await SupervisionTask.create({
|
||||
applicationNumber,
|
||||
contractNumber,
|
||||
productName,
|
||||
customerName,
|
||||
idType,
|
||||
idNumber,
|
||||
assetType,
|
||||
assetQuantity: parseInt(assetQuantity),
|
||||
supervisionStatus,
|
||||
startTime,
|
||||
endTime,
|
||||
loanAmount: parseFloat(loanAmount),
|
||||
interestRate: parseFloat(interestRate),
|
||||
loanTerm: parseInt(loanTerm),
|
||||
supervisorName,
|
||||
supervisorPhone,
|
||||
farmAddress,
|
||||
remarks,
|
||||
createdBy: req.user?.userId || req.user?.id,
|
||||
updatedBy: req.user?.userId || req.user?.id
|
||||
});
|
||||
|
||||
// 获取创建的任务详情(包含关联信息)
|
||||
const createdTask = await SupervisionTask.findByPk(task.id, {
|
||||
include: [
|
||||
{
|
||||
model: User,
|
||||
as: 'creator',
|
||||
attributes: ['id', 'username', 'real_name']
|
||||
},
|
||||
{
|
||||
model: User,
|
||||
as: 'updater',
|
||||
attributes: ['id', 'username', 'real_name']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: createdTask,
|
||||
message: '监管任务创建成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('创建监管任务失败:', error);
|
||||
|
||||
// 处理数据库约束错误
|
||||
if (error.name === 'SequelizeValidationError') {
|
||||
const validationErrors = error.errors.map(err => err.message).join(', ');
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: `数据验证失败: ${validationErrors}`
|
||||
});
|
||||
}
|
||||
|
||||
if (error.name === 'SequelizeUniqueConstraintError') {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '申请单号或放款合同编号已存在'
|
||||
});
|
||||
}
|
||||
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '创建监管任务失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 更新监管任务
|
||||
const updateSupervisionTask = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const updateData = req.body;
|
||||
|
||||
// 验证日期
|
||||
if (updateData.startTime && updateData.endTime) {
|
||||
const startDate = new Date(updateData.startTime);
|
||||
const endDate = new Date(updateData.endTime);
|
||||
if (startDate >= endDate) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '监管结束时间必须晚于开始时间'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const task = await SupervisionTask.findByPk(id);
|
||||
|
||||
if (!task) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '监管任务不存在'
|
||||
});
|
||||
}
|
||||
|
||||
// 如果更新申请单号或合同编号,检查是否重复
|
||||
if (updateData.applicationNumber || updateData.contractNumber) {
|
||||
const whereCondition = { id: { [Op.ne]: id } };
|
||||
if (updateData.applicationNumber) {
|
||||
whereCondition.applicationNumber = updateData.applicationNumber;
|
||||
}
|
||||
if (updateData.contractNumber) {
|
||||
whereCondition.contractNumber = updateData.contractNumber;
|
||||
}
|
||||
|
||||
const existingTask = await SupervisionTask.findOne({ where: whereCondition });
|
||||
if (existingTask) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '申请单号或放款合同编号已存在'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await task.update({
|
||||
...updateData,
|
||||
updatedBy: req.user?.userId || req.user?.id
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: task,
|
||||
message: '监管任务更新成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('更新监管任务失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '更新监管任务失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 删除监管任务
|
||||
const deleteSupervisionTask = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const task = await SupervisionTask.findByPk(id);
|
||||
|
||||
if (!task) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '监管任务不存在'
|
||||
});
|
||||
}
|
||||
|
||||
await task.destroy();
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: '监管任务删除成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('删除监管任务失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '删除监管任务失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 获取监管任务统计
|
||||
const getSupervisionTaskStats = async (req, res) => {
|
||||
try {
|
||||
const total = await SupervisionTask.count();
|
||||
const pending = await SupervisionTask.count({ where: { supervisionStatus: 'pending' } });
|
||||
const supervising = await SupervisionTask.count({ where: { supervisionStatus: 'supervising' } });
|
||||
const completed = await SupervisionTask.count({ where: { supervisionStatus: 'completed' } });
|
||||
const suspended = await SupervisionTask.count({ where: { supervisionStatus: 'suspended' } });
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: '监管任务统计获取成功',
|
||||
data: {
|
||||
total,
|
||||
pending,
|
||||
supervising,
|
||||
completed,
|
||||
suspended
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取监管任务统计失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取监管任务统计失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 批量更新监管任务状态
|
||||
const batchUpdateStatus = async (req, res) => {
|
||||
try {
|
||||
const { ids, supervisionStatus } = req.body;
|
||||
|
||||
if (!Array.isArray(ids) || ids.length === 0 || !supervisionStatus) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '请求参数无效'
|
||||
});
|
||||
}
|
||||
|
||||
if (!['pending', 'supervising', 'completed', 'suspended'].includes(supervisionStatus)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '监管状态无效'
|
||||
});
|
||||
}
|
||||
|
||||
const [updatedCount] = await SupervisionTask.update(
|
||||
{
|
||||
supervisionStatus,
|
||||
updatedBy: req.user?.userId || req.user?.id
|
||||
},
|
||||
{ where: { id: { [Op.in]: ids } } }
|
||||
);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: `成功更新 ${updatedCount} 个监管任务状态`,
|
||||
data: { updatedCount }
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('批量更新监管任务状态失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '批量更新监管任务状态失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 批量删除监管任务
|
||||
const batchDeleteTasks = async (req, res) => {
|
||||
try {
|
||||
const { ids } = req.body;
|
||||
|
||||
if (!Array.isArray(ids) || ids.length === 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '请求参数无效'
|
||||
});
|
||||
}
|
||||
|
||||
const deletedCount = await SupervisionTask.destroy({
|
||||
where: { id: { [Op.in]: ids } }
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: `成功删除 ${deletedCount} 个监管任务`,
|
||||
data: { deletedCount }
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('批量删除监管任务失败:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '批量删除监管任务失败',
|
||||
error: process.env.NODE_ENV === 'development' ? error.message : undefined
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getSupervisionTasks,
|
||||
getSupervisionTaskById,
|
||||
createSupervisionTask,
|
||||
updateSupervisionTask,
|
||||
deleteSupervisionTask,
|
||||
getSupervisionTaskStats,
|
||||
batchUpdateStatus,
|
||||
batchDeleteTasks
|
||||
};
|
||||
Reference in New Issue
Block a user