完善项目

This commit is contained in:
xuqiuyun
2025-09-28 17:58:43 +08:00
parent ec3f472641
commit 5b615473e0
59 changed files with 5428 additions and 593 deletions

View File

@@ -5,7 +5,15 @@ const responseFormat = require('../utils/response');
// 获取保险类型列表
const getInsuranceTypes = async (req, res) => {
try {
const { page = 1, pageSize = 10, name, status } = req.query;
const {
page = 1,
pageSize = 10,
name,
status,
applicable_livestock,
service_area,
on_sale_status
} = req.query;
const offset = (page - 1) * pageSize;
const whereClause = {};
@@ -15,12 +23,21 @@ const getInsuranceTypes = async (req, res) => {
if (status) {
whereClause.status = status;
}
if (applicable_livestock) {
whereClause.applicable_livestock = { [Op.like]: `%${applicable_livestock}%` };
}
if (service_area) {
whereClause.service_area = { [Op.like]: `%${service_area}%` };
}
if (on_sale_status !== undefined && on_sale_status !== '') {
whereClause.on_sale_status = on_sale_status === 'true';
}
const { count, rows } = await InsuranceType.findAndCountAll({
where: whereClause,
limit: parseInt(pageSize),
offset: offset,
order: [['created_at', 'DESC']]
order: [['add_time', 'DESC'], ['created_at', 'DESC']]
});
res.json(responseFormat.pagination(rows, {
@@ -57,9 +74,17 @@ const createInsuranceType = async (req, res) => {
const {
name,
description,
applicable_livestock,
insurance_term,
policy_form,
coverage_amount_min,
coverage_amount_max,
premium_rate,
service_area,
add_time,
on_sale_status = true,
sort_order = 0,
remarks,
status = 'active'
} = req.body;
@@ -72,9 +97,17 @@ const createInsuranceType = async (req, res) => {
const insuranceType = await InsuranceType.create({
name,
description,
applicable_livestock,
insurance_term,
policy_form,
coverage_amount_min,
coverage_amount_max,
premium_rate,
service_area,
add_time: add_time || new Date(),
on_sale_status,
sort_order,
remarks,
status,
created_by: req.user?.id
});
@@ -97,9 +130,17 @@ const updateInsuranceType = async (req, res) => {
const {
name,
description,
applicable_livestock,
insurance_term,
policy_form,
coverage_amount_min,
coverage_amount_max,
premium_rate,
service_area,
add_time,
on_sale_status,
sort_order,
remarks,
status
} = req.body;
@@ -123,10 +164,18 @@ const updateInsuranceType = async (req, res) => {
await insuranceType.update({
name: name || insuranceType.name,
description: description || insuranceType.description,
coverage_amount_min: coverage_amount_min || insuranceType.coverage_amount_min,
coverage_amount_max: coverage_amount_max || insuranceType.coverage_amount_max,
premium_rate: premium_rate || insuranceType.premium_rate,
description: description !== undefined ? description : insuranceType.description,
applicable_livestock: applicable_livestock !== undefined ? applicable_livestock : insuranceType.applicable_livestock,
insurance_term: insurance_term !== undefined ? insurance_term : insuranceType.insurance_term,
policy_form: policy_form !== undefined ? policy_form : insuranceType.policy_form,
coverage_amount_min: coverage_amount_min !== undefined ? coverage_amount_min : insuranceType.coverage_amount_min,
coverage_amount_max: coverage_amount_max !== undefined ? coverage_amount_max : insuranceType.coverage_amount_max,
premium_rate: premium_rate !== undefined ? premium_rate : insuranceType.premium_rate,
service_area: service_area !== undefined ? service_area : insuranceType.service_area,
add_time: add_time !== undefined ? add_time : insuranceType.add_time,
on_sale_status: on_sale_status !== undefined ? on_sale_status : insuranceType.on_sale_status,
sort_order: sort_order !== undefined ? sort_order : insuranceType.sort_order,
remarks: remarks !== undefined ? remarks : insuranceType.remarks,
status: status || insuranceType.status,
updated_by: req.user?.id
});
@@ -152,16 +201,22 @@ const deleteInsuranceType = async (req, res) => {
return res.status(404).json(responseFormat.error('险种不存在'));
}
// 检查是否有相关的保险申请或保单
// const hasApplications = await insuranceType.countInsuranceApplications();
// if (hasApplications > 0) {
// return res.status(400).json(responseFormat.error('该险种下存在保险申请,无法删除'));
// }
// 检查是否有相关的保险申请
const hasApplications = await insuranceType.countApplications();
if (hasApplications > 0) {
return res.status(400).json(responseFormat.error('该险种下存在保险申请,无法删除', 400));
}
await insuranceType.destroy();
res.json(responseFormat.success(null, '删除险种成功'));
} catch (error) {
console.error('删除险种错误:', error);
// 处理外键约束错误
if (error.name === 'SequelizeForeignKeyConstraintError') {
return res.status(400).json(responseFormat.error('该险种下存在相关数据,无法删除', 400));
}
res.status(500).json(responseFormat.error('删除险种失败'));
}
};
@@ -170,14 +225,18 @@ const deleteInsuranceType = async (req, res) => {
const updateInsuranceTypeStatus = async (req, res) => {
try {
const { id } = req.params;
const { status } = req.body;
const { status, on_sale_status } = req.body;
const insuranceType = await InsuranceType.findByPk(id);
if (!insuranceType) {
return res.status(404).json(responseFormat.error('险种不存在'));
}
await insuranceType.update({ status, updated_by: req.user?.id });
const updateData = { updated_by: req.user?.id };
if (status !== undefined) updateData.status = status;
if (on_sale_status !== undefined) updateData.on_sale_status = on_sale_status;
await insuranceType.update(updateData);
res.json(responseFormat.success(insuranceType, '更新险种状态成功'));
} catch (error) {
console.error('更新险种状态错误:', error);

View File

@@ -8,10 +8,35 @@ const { Op } = require('sequelize');
// 获取生资理赔列表
const getLivestockClaims = async (req, res) => {
try {
console.log('🚀 [后端] 开始处理理赔列表查询请求');
console.log('📥 [后端] 接收到的查询参数:', {
接收时间: new Date().toLocaleString(),
完整URL: req.originalUrl,
查询字符串: req.url,
原始查询参数: JSON.stringify(req.query, null, 2),
查询参数类型: typeof req.query,
查询参数键: Object.keys(req.query),
请求方法: req.method,
请求路径: req.path,
用户信息: req.user ? { id: req.user.id, username: req.user.username } : '未登录'
});
console.log('🔍 [详细调试] 请求信息:');
console.log('req.url:', req.url);
console.log('req.originalUrl:', req.originalUrl);
console.log('req.baseUrl:', req.baseUrl);
console.log('req.path:', req.path);
console.log('查询字符串:', req.url.split('?')[1] || '无');
console.log('原始查询参数:', req.query);
console.log('查询参数类型:', typeof req.query);
console.log('查询参数键:', Object.keys(req.query));
console.log('查询参数JSON:', JSON.stringify(req.query));
const {
claim_no,
policy_no,
farmer_name,
reporter_name,
contact_phone,
claim_status,
claim_type,
start_date,
@@ -20,21 +45,49 @@ const getLivestockClaims = async (req, res) => {
limit = 10
} = req.query;
console.log('🔍 [后端] 解析后的查询参数:', {
理赔单号: claim_no,
保单号: policy_no,
报案人: reporter_name,
联系电话: contact_phone,
理赔状态: claim_status,
理赔类型: claim_type,
开始日期: start_date,
结束日期: end_date,
页码: page,
每页条数: limit
});
const whereClause = {};
// 理赔编号筛选
// 理赔编号筛选 - 精确匹配
if (claim_no) {
whereClause.claim_no = { [Op.like]: `%${claim_no}%` };
whereClause.claim_no = claim_no;
console.log('🔍 [后端] 添加理赔编号筛选条件(精确匹配):', whereClause.claim_no);
}
// 理赔状态筛选
if (claim_status) {
whereClause.claim_status = claim_status;
console.log('🔍 [后端] 添加理赔状态筛选条件:', whereClause.claim_status);
}
// 理赔类型筛选
if (claim_type) {
whereClause.claim_type = claim_type;
console.log('🔍 [后端] 添加理赔类型筛选条件:', whereClause.claim_type);
}
// 报案人筛选
if (reporter_name) {
whereClause.reporter_name = { [Op.like]: `%${reporter_name}%` };
console.log('🔍 [后端] 添加报案人筛选条件:', whereClause.reporter_name);
}
// 联系电话筛选
if (contact_phone) {
whereClause.contact_phone = { [Op.like]: `%${contact_phone}%` };
console.log('🔍 [后端] 添加联系电话筛选条件:', whereClause.contact_phone);
}
// 日期范围筛选
@@ -42,17 +95,30 @@ const getLivestockClaims = async (req, res) => {
whereClause.incident_date = {
[Op.between]: [new Date(start_date), new Date(end_date)]
};
console.log('🔍 [后端] 添加日期范围筛选条件:', whereClause.incident_date);
}
const offset = (page - 1) * limit;
const { count, rows } = await LivestockClaim.findAndCountAll({
console.log('📊 [后端] 构建的查询条件:', {
构建时间: new Date().toLocaleString(),
WHERE条件: JSON.stringify(whereClause, null, 2),
分页信息: {
页码: page,
每页条数: limit,
偏移量: offset
}
});
console.log('🗄️ [后端] 开始执行数据库查询...');
const queryConfig = {
where: whereClause,
include: [
{
model: LivestockPolicy,
as: 'policy',
attributes: ['id', 'policy_no', 'farmer_name', 'farmer_phone', 'livestock_count'],
attributes: ['id', 'policy_no', 'policyholder_name', 'policyholder_phone', 'livestock_count'],
where: policy_no ? { policy_no: { [Op.like]: `%${policy_no}%` } } : {},
required: !!policy_no,
include: [
@@ -77,23 +143,66 @@ const getLivestockClaims = async (req, res) => {
order: [['created_at', 'DESC']],
offset,
limit: parseInt(limit)
};
console.log('🗄️ [后端] 数据库查询配置:', {
查询时间: new Date().toLocaleString(),
查询配置: JSON.stringify(queryConfig, null, 2)
});
// 如果有农户姓名筛选,需要在关联查询后再过滤
let filteredRows = rows;
if (farmer_name) {
filteredRows = rows.filter(claim =>
claim.policy && claim.policy.farmer_name.includes(farmer_name)
);
}
console.log('🚀 [后端] 即将执行查询,最终配置:', JSON.stringify(queryConfig, null, 2));
res.json(responseFormat.pagination(filteredRows, {
const { count, rows } = await LivestockClaim.findAndCountAll(queryConfig);
console.log('✅ [后端] 数据库查询完成:', {
查询时间: new Date().toLocaleString(),
返回总数: count,
返回记录数: rows.length,
记录ID列表: rows.map(r => ({ id: r.id, claim_no: r.claim_no }))
});
console.log('📋 [后端] 详细查询结果:', {
查询完成时间: new Date().toLocaleString(),
查询结果统计: {
总记录数: count,
当前页记录数: rows.length,
查询耗时: '已完成'
},
数据样例: rows.length > 0 ? {
第一条记录ID: rows[0].id,
第一条记录理赔单号: rows[0].claim_no,
第一条记录状态: rows[0].claim_status
} : '无数据'
});
const responseData = responseFormat.pagination(rows, {
page: parseInt(page),
limit: parseInt(limit),
total: count
}, '获取生资理赔列表成功'));
}, '获取生资理赔列表成功');
console.log('📤 [后端->前端] 准备发送响应:', {
响应时间: new Date().toLocaleString(),
响应状态: 'success',
响应数据结构: {
status: responseData.status,
message: responseData.message,
data类型: Array.isArray(responseData.data) ? 'Array' : typeof responseData.data,
data长度: responseData.data?.length,
pagination: responseData.pagination
},
完整响应: JSON.stringify(responseData, null, 2)
});
res.json(responseData);
} catch (error) {
console.error('获取生资理赔列表错误:', error);
console.error('💥 [后端] 获取生资理赔列表错误:', {
错误时间: new Date().toLocaleString(),
错误类型: error.name,
错误信息: error.message,
错误堆栈: error.stack,
SQL错误: error.sql || '无SQL信息'
});
res.status(500).json(responseFormat.error('获取生资理赔列表失败'));
}
};
@@ -355,10 +464,88 @@ const getLivestockClaimStats = async (req, res) => {
}
};
// 更新生资理赔
const updateLivestockClaim = async (req, res) => {
try {
const { id } = req.params;
const updateData = req.body;
const claim = await LivestockClaim.findByPk(id);
if (!claim) {
return res.status(404).json(responseFormat.error('生资理赔不存在'));
}
// 更新理赔信息
await claim.update({
...updateData,
updated_by: req.user?.id
});
// 获取更新后的完整信息
const updatedClaim = await LivestockClaim.findByPk(id, {
include: [
{
model: LivestockPolicy,
as: 'policy',
attributes: ['id', 'policy_no', 'policyholder_name', 'policyholder_phone'],
include: [
{
model: LivestockType,
as: 'livestock_type',
attributes: ['id', 'name']
}
]
},
{
model: User,
as: 'creator',
attributes: ['id', 'real_name', 'username']
},
{
model: User,
as: 'reviewer',
attributes: ['id', 'real_name', 'username']
}
]
});
res.json(responseFormat.success(updatedClaim, '生资理赔更新成功'));
} catch (error) {
console.error('更新生资理赔错误:', error);
res.status(500).json(responseFormat.error('更新生资理赔失败'));
}
};
// 删除生资理赔
const deleteLivestockClaim = async (req, res) => {
try {
const { id } = req.params;
const claim = await LivestockClaim.findByPk(id);
if (!claim) {
return res.status(404).json(responseFormat.error('生资理赔不存在'));
}
// 检查是否可以删除(只有待处理状态的理赔可以删除)
if (claim.claim_status !== 'pending') {
return res.status(400).json(responseFormat.error('只有待处理状态的理赔可以删除'));
}
await claim.destroy();
res.json(responseFormat.success(null, '生资理赔删除成功'));
} catch (error) {
console.error('删除生资理赔错误:', error);
res.status(500).json(responseFormat.error('删除生资理赔失败'));
}
};
module.exports = {
getLivestockClaims,
createLivestockClaim,
getLivestockClaimById,
updateLivestockClaim,
deleteLivestockClaim,
reviewLivestockClaim,
updateLivestockClaimPayment,
getLivestockClaimStats