完善项目
This commit is contained in:
@@ -214,6 +214,84 @@ const swaggerDefinition = {
|
||||
updated_at: { type: 'string', format: 'date-time', description: '更新时间' }
|
||||
}
|
||||
},
|
||||
InsuranceType: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'integer', description: '险种ID' },
|
||||
name: { type: 'string', description: '险种名称' },
|
||||
description: { type: 'string', description: '险种描述' },
|
||||
applicable_livestock: { type: 'string', description: '适用牲畜类型' },
|
||||
insurance_term: { type: 'integer', description: '保险期限(月)' },
|
||||
policy_form: { type: 'string', description: '保单形式' },
|
||||
coverage_amount_min: { type: 'number', format: 'decimal', description: '最低保额' },
|
||||
coverage_amount_max: { type: 'number', format: 'decimal', description: '最高保额' },
|
||||
premium_rate: { type: 'number', format: 'decimal', description: '保险费率' },
|
||||
service_area: { type: 'string', description: '服务区域' },
|
||||
add_time: { type: 'string', format: 'date-time', description: '添加时间' },
|
||||
on_sale_status: { type: 'boolean', description: '在售状态' },
|
||||
sort_order: { type: 'integer', description: '排序顺序' },
|
||||
remarks: { type: 'string', description: '备注' },
|
||||
status: { type: 'string', enum: ['active', 'inactive'], description: '险种状态' },
|
||||
created_by: { type: 'integer', description: '创建人ID' },
|
||||
updated_by: { type: 'integer', description: '更新人ID' },
|
||||
created_at: { type: 'string', format: 'date-time', description: '创建时间' },
|
||||
updated_at: { type: 'string', format: 'date-time', description: '更新时间' }
|
||||
}
|
||||
},
|
||||
CreateInsuranceTypeRequest: {
|
||||
type: 'object',
|
||||
required: ['name', 'coverage_amount_min', 'coverage_amount_max', 'premium_rate'],
|
||||
properties: {
|
||||
name: { type: 'string', description: '险种名称', minLength: 1, maxLength: 100 },
|
||||
description: { type: 'string', description: '险种描述' },
|
||||
applicable_livestock: { type: 'string', description: '适用牲畜类型', maxLength: 100 },
|
||||
insurance_term: { type: 'integer', description: '保险期限(月)', minimum: 1 },
|
||||
policy_form: { type: 'string', description: '保单形式', maxLength: 50 },
|
||||
coverage_amount_min: { type: 'number', format: 'decimal', description: '最低保额', minimum: 0 },
|
||||
coverage_amount_max: { type: 'number', format: 'decimal', description: '最高保额', minimum: 0 },
|
||||
premium_rate: { type: 'number', format: 'decimal', description: '保险费率', minimum: 0, maximum: 1 },
|
||||
service_area: { type: 'string', description: '服务区域' },
|
||||
add_time: { type: 'string', format: 'date-time', description: '添加时间' },
|
||||
on_sale_status: { type: 'boolean', description: '在售状态', default: true },
|
||||
sort_order: { type: 'integer', description: '排序顺序', default: 0 },
|
||||
remarks: { type: 'string', description: '备注' },
|
||||
status: { type: 'string', enum: ['active', 'inactive'], description: '险种状态', default: 'active' }
|
||||
}
|
||||
},
|
||||
UpdateInsuranceTypeRequest: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: { type: 'string', description: '险种名称', minLength: 1, maxLength: 100 },
|
||||
description: { type: 'string', description: '险种描述' },
|
||||
applicable_livestock: { type: 'string', description: '适用牲畜类型', maxLength: 100 },
|
||||
insurance_term: { type: 'integer', description: '保险期限(月)', minimum: 1 },
|
||||
policy_form: { type: 'string', description: '保单形式', maxLength: 50 },
|
||||
coverage_amount_min: { type: 'number', format: 'decimal', description: '最低保额', minimum: 0 },
|
||||
coverage_amount_max: { type: 'number', format: 'decimal', description: '最高保额', minimum: 0 },
|
||||
premium_rate: { type: 'number', format: 'decimal', description: '保险费率', minimum: 0, maximum: 1 },
|
||||
service_area: { type: 'string', description: '服务区域' },
|
||||
add_time: { type: 'string', format: 'date-time', description: '添加时间' },
|
||||
on_sale_status: { type: 'boolean', description: '在售状态' },
|
||||
sort_order: { type: 'integer', description: '排序顺序' },
|
||||
remarks: { type: 'string', description: '备注' },
|
||||
status: { type: 'string', enum: ['active', 'inactive'], description: '险种状态' }
|
||||
}
|
||||
},
|
||||
UpdateInsuranceTypeStatusRequest: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
status: { type: 'string', enum: ['active', 'inactive'], description: '险种状态' },
|
||||
on_sale_status: { type: 'boolean', description: '在售状态' }
|
||||
}
|
||||
},
|
||||
Pagination: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
page: { type: 'integer', description: '当前页码' },
|
||||
limit: { type: 'integer', description: '每页数量' },
|
||||
total: { type: 'integer', description: '总记录数' }
|
||||
}
|
||||
},
|
||||
Error: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -293,6 +371,7 @@ const swaggerDefinition = {
|
||||
tags: [
|
||||
{ name: '认证', description: '用户认证相关接口' },
|
||||
{ name: '用户管理', description: '用户管理相关接口' },
|
||||
{ name: '险种管理', description: '保险险种管理相关接口' },
|
||||
{ name: '保险申请', description: '保险申请管理相关接口' },
|
||||
{ name: '保单管理', description: '保单管理相关接口' },
|
||||
{ name: '理赔管理', description: '理赔管理相关接口' },
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
308
insurance_backend/docs/insurance-type-api-examples.md
Normal file
308
insurance_backend/docs/insurance-type-api-examples.md
Normal file
@@ -0,0 +1,308 @@
|
||||
# 险种管理API使用示例
|
||||
|
||||
## 概述
|
||||
|
||||
本文档提供了险种管理API的详细使用示例,包括请求格式、响应格式和错误处理。
|
||||
|
||||
## 基础信息
|
||||
|
||||
- **基础URL**: `http://localhost:3000/api`
|
||||
- **认证方式**: Bearer Token (JWT)
|
||||
- **内容类型**: `application/json`
|
||||
|
||||
## 认证
|
||||
|
||||
所有API请求都需要在请求头中包含有效的JWT令牌:
|
||||
|
||||
```http
|
||||
Authorization: Bearer <your-jwt-token>
|
||||
```
|
||||
|
||||
## API端点
|
||||
|
||||
### 1. 获取险种列表
|
||||
|
||||
**请求**
|
||||
```http
|
||||
GET /api/insurance-types?page=1&pageSize=10&name=牛&status=active
|
||||
Authorization: Bearer <your-jwt-token>
|
||||
```
|
||||
|
||||
**响应示例**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "获取险种列表成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "牛只意外伤害保险",
|
||||
"description": "为牛只提供意外伤害保障",
|
||||
"applicable_livestock": "牛",
|
||||
"insurance_term": "1年",
|
||||
"policy_form": "团体保险",
|
||||
"on_sale_status": true,
|
||||
"coverage_amount_min": 1000.00,
|
||||
"coverage_amount_max": 50000.00,
|
||||
"premium_rate": 0.05,
|
||||
"status": "active",
|
||||
"add_time": "2024-01-15T08:30:00.000Z",
|
||||
"created_at": "2024-01-15T08:30:00.000Z",
|
||||
"updated_at": "2024-01-15T08:30:00.000Z"
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"page": 1,
|
||||
"limit": 10,
|
||||
"total": 1,
|
||||
"totalPages": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 获取单个险种详情
|
||||
|
||||
**请求**
|
||||
```http
|
||||
GET /api/insurance-types/1
|
||||
Authorization: Bearer <your-jwt-token>
|
||||
```
|
||||
|
||||
**响应示例**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "获取险种详情成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"name": "牛只意外伤害保险",
|
||||
"description": "为牛只提供意外伤害保障",
|
||||
"applicable_livestock": "牛",
|
||||
"insurance_term": "1年",
|
||||
"policy_form": "团体保险",
|
||||
"on_sale_status": true,
|
||||
"coverage_amount_min": 1000.00,
|
||||
"coverage_amount_max": 50000.00,
|
||||
"premium_rate": 0.05,
|
||||
"status": "active",
|
||||
"add_time": "2024-01-15T08:30:00.000Z",
|
||||
"created_at": "2024-01-15T08:30:00.000Z",
|
||||
"updated_at": "2024-01-15T08:30:00.000Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 创建险种
|
||||
|
||||
**请求**
|
||||
```http
|
||||
POST /api/insurance-types
|
||||
Authorization: Bearer <your-jwt-token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "羊只疾病保险",
|
||||
"description": "为羊只提供疾病保障",
|
||||
"applicable_livestock": "羊",
|
||||
"insurance_term": "1年",
|
||||
"policy_form": "个体保险",
|
||||
"coverage_amount_min": 500.00,
|
||||
"coverage_amount_max": 20000.00,
|
||||
"premium_rate": 0.08
|
||||
}
|
||||
```
|
||||
|
||||
**响应示例**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "创建险种成功",
|
||||
"data": {
|
||||
"id": 2,
|
||||
"name": "羊只疾病保险",
|
||||
"description": "为羊只提供疾病保障",
|
||||
"applicable_livestock": "羊",
|
||||
"insurance_term": "1年",
|
||||
"policy_form": "个体保险",
|
||||
"on_sale_status": false,
|
||||
"coverage_amount_min": 500.00,
|
||||
"coverage_amount_max": 20000.00,
|
||||
"premium_rate": 0.08,
|
||||
"status": "active",
|
||||
"add_time": "2024-01-15T09:00:00.000Z",
|
||||
"created_at": "2024-01-15T09:00:00.000Z",
|
||||
"updated_at": "2024-01-15T09:00:00.000Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 更新险种
|
||||
|
||||
**请求**
|
||||
```http
|
||||
PUT /api/insurance-types/2
|
||||
Authorization: Bearer <your-jwt-token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "羊只综合保险",
|
||||
"description": "为羊只提供疾病和意外伤害综合保障",
|
||||
"premium_rate": 0.10
|
||||
}
|
||||
```
|
||||
|
||||
**响应示例**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "更新险种成功",
|
||||
"data": {
|
||||
"id": 2,
|
||||
"name": "羊只综合保险",
|
||||
"description": "为羊只提供疾病和意外伤害综合保障",
|
||||
"applicable_livestock": "羊",
|
||||
"insurance_term": "1年",
|
||||
"policy_form": "个体保险",
|
||||
"on_sale_status": false,
|
||||
"coverage_amount_min": 500.00,
|
||||
"coverage_amount_max": 20000.00,
|
||||
"premium_rate": 0.10,
|
||||
"status": "active",
|
||||
"add_time": "2024-01-15T09:00:00.000Z",
|
||||
"created_at": "2024-01-15T09:00:00.000Z",
|
||||
"updated_at": "2024-01-15T09:15:00.000Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 更新险种状态
|
||||
|
||||
**请求**
|
||||
```http
|
||||
PATCH /api/insurance-types/2/status
|
||||
Authorization: Bearer <your-jwt-token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"status": "active",
|
||||
"on_sale_status": true
|
||||
}
|
||||
```
|
||||
|
||||
**响应示例**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "更新险种状态成功",
|
||||
"data": {
|
||||
"id": 2,
|
||||
"name": "羊只综合保险",
|
||||
"description": "为羊只提供疾病和意外伤害综合保障",
|
||||
"applicable_livestock": "羊",
|
||||
"insurance_term": "1年",
|
||||
"policy_form": "个体保险",
|
||||
"on_sale_status": true,
|
||||
"coverage_amount_min": 500.00,
|
||||
"coverage_amount_max": 20000.00,
|
||||
"premium_rate": 0.10,
|
||||
"status": "active",
|
||||
"add_time": "2024-01-15T09:00:00.000Z",
|
||||
"created_at": "2024-01-15T09:00:00.000Z",
|
||||
"updated_at": "2024-01-15T09:20:00.000Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 删除险种
|
||||
|
||||
**请求**
|
||||
```http
|
||||
DELETE /api/insurance-types/2
|
||||
Authorization: Bearer <your-jwt-token>
|
||||
```
|
||||
|
||||
**响应示例**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "删除险种成功"
|
||||
}
|
||||
```
|
||||
|
||||
## 错误处理
|
||||
|
||||
### 常见错误响应
|
||||
|
||||
#### 401 未授权
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "未授权访问",
|
||||
"error": "Unauthorized"
|
||||
}
|
||||
```
|
||||
|
||||
#### 403 权限不足
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "权限不足",
|
||||
"error": "Forbidden"
|
||||
}
|
||||
```
|
||||
|
||||
#### 404 资源不存在
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "险种不存在",
|
||||
"error": "Not Found"
|
||||
}
|
||||
```
|
||||
|
||||
#### 400 请求参数错误
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "险种名称已存在",
|
||||
"error": "Bad Request"
|
||||
}
|
||||
```
|
||||
|
||||
#### 500 服务器内部错误
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "服务器内部错误",
|
||||
"error": "Internal Server Error"
|
||||
}
|
||||
```
|
||||
|
||||
## 查询参数说明
|
||||
|
||||
### 获取险种列表支持的查询参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|
||||
|--------|------|------|--------|------|
|
||||
| page | integer | 否 | 1 | 页码,最小值为1 |
|
||||
| pageSize | integer | 否 | 10 | 每页数量,范围1-100 |
|
||||
| name | string | 否 | - | 险种名称,支持模糊搜索 |
|
||||
| status | string | 否 | - | 险种状态,可选值:active, inactive |
|
||||
| applicable_livestock | string | 否 | - | 适用牲畜类型,支持模糊搜索 |
|
||||
| service_area | string | 否 | - | 服务区域,支持模糊搜索 |
|
||||
| on_sale_status | boolean | 否 | - | 在售状态,true或false |
|
||||
|
||||
## 使用注意事项
|
||||
|
||||
1. **认证令牌**: 所有请求都需要有效的JWT令牌
|
||||
2. **权限检查**: 用户需要具有相应的险种管理权限
|
||||
3. **数据验证**: 创建和更新时会进行数据格式验证
|
||||
4. **唯一性检查**: 险种名称必须唯一
|
||||
5. **分页限制**: 每页最多返回100条记录
|
||||
6. **状态管理**: 险种状态和在售状态可以独立管理
|
||||
|
||||
## 测试工具推荐
|
||||
|
||||
- **Postman**: 用于API测试和调试
|
||||
- **curl**: 命令行工具,适合脚本化测试
|
||||
- **Swagger UI**: 在线API文档和测试界面 (http://localhost:3000/api-docs)
|
||||
690
insurance_backend/docs/insurance-type-api.yaml
Normal file
690
insurance_backend/docs/insurance-type-api.yaml
Normal file
@@ -0,0 +1,690 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: 险种管理API
|
||||
description: 保险系统险种管理功能相关API接口文档
|
||||
version: 1.0.0
|
||||
contact:
|
||||
name: 开发团队
|
||||
email: dev@example.com
|
||||
|
||||
servers:
|
||||
- url: http://localhost:3000/api
|
||||
description: 开发环境
|
||||
|
||||
paths:
|
||||
/insurance-types:
|
||||
get:
|
||||
summary: 获取险种列表
|
||||
description: 分页获取险种列表,支持多种筛选条件
|
||||
tags:
|
||||
- 险种管理
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: page
|
||||
in: query
|
||||
description: 页码
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
default: 1
|
||||
minimum: 1
|
||||
- name: pageSize
|
||||
in: query
|
||||
description: 每页数量
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
default: 10
|
||||
minimum: 1
|
||||
maximum: 100
|
||||
- name: name
|
||||
in: query
|
||||
description: 险种名称(模糊搜索)
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- name: status
|
||||
in: query
|
||||
description: 险种状态
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
enum: [active, inactive]
|
||||
- name: applicable_livestock
|
||||
in: query
|
||||
description: 适用牲畜类型(模糊搜索)
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- name: service_area
|
||||
in: query
|
||||
description: 服务区域(模糊搜索)
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- name: on_sale_status
|
||||
in: query
|
||||
description: 在售状态
|
||||
required: false
|
||||
schema:
|
||||
type: boolean
|
||||
responses:
|
||||
'200':
|
||||
description: 获取成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: true
|
||||
message:
|
||||
type: string
|
||||
example: "获取险种列表成功"
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/InsuranceType'
|
||||
pagination:
|
||||
$ref: '#/components/schemas/Pagination'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
post:
|
||||
summary: 创建险种
|
||||
description: 创建新的保险险种
|
||||
tags:
|
||||
- 险种管理
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreateInsuranceTypeRequest'
|
||||
responses:
|
||||
'201':
|
||||
description: 创建成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: true
|
||||
message:
|
||||
type: string
|
||||
example: "创建险种成功"
|
||||
data:
|
||||
$ref: '#/components/schemas/InsuranceType'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/insurance-types/{id}:
|
||||
get:
|
||||
summary: 获取险种详情
|
||||
description: 根据ID获取单个险种的详细信息
|
||||
tags:
|
||||
- 险种管理
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: 险种ID
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
'200':
|
||||
description: 获取成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: true
|
||||
message:
|
||||
type: string
|
||||
example: "获取保险类型详情成功"
|
||||
data:
|
||||
$ref: '#/components/schemas/InsuranceType'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
put:
|
||||
summary: 更新险种
|
||||
description: 更新指定ID的险种信息
|
||||
tags:
|
||||
- 险种管理
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: 险种ID
|
||||
schema:
|
||||
type: integer
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateInsuranceTypeRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: 更新成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: true
|
||||
message:
|
||||
type: string
|
||||
example: "更新险种成功"
|
||||
data:
|
||||
$ref: '#/components/schemas/InsuranceType'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
delete:
|
||||
summary: 删除险种
|
||||
description: 删除指定ID的险种
|
||||
tags:
|
||||
- 险种管理
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: 险种ID
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
'200':
|
||||
description: 删除成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
example: 200
|
||||
status:
|
||||
type: string
|
||||
example: "success"
|
||||
data:
|
||||
type: null
|
||||
example: null
|
||||
message:
|
||||
type: string
|
||||
example: "删除险种成功"
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2025-09-28T06:28:03.150Z"
|
||||
'400':
|
||||
description: 删除失败 - 外键约束错误
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
code: 400
|
||||
status: error
|
||||
data: null
|
||||
message: "该险种下存在保险申请,无法删除"
|
||||
timestamp: "2025-09-28T06:28:02.881Z"
|
||||
'404':
|
||||
description: 险种不存在
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
code: 404
|
||||
status: error
|
||||
data: null
|
||||
message: "险种不存在"
|
||||
timestamp: "2025-09-28T06:28:02.881Z"
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/insurance-types/{id}/status:
|
||||
patch:
|
||||
summary: 更新险种状态
|
||||
description: 更新指定ID险种的状态或在售状态
|
||||
tags:
|
||||
- 险种管理
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: 险种ID
|
||||
schema:
|
||||
type: integer
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateInsuranceTypeStatusRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: 更新成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: true
|
||||
message:
|
||||
type: string
|
||||
example: "更新险种状态成功"
|
||||
data:
|
||||
$ref: '#/components/schemas/InsuranceType'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
|
||||
schemas:
|
||||
InsuranceType:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
description: 险种ID
|
||||
example: 1
|
||||
name:
|
||||
type: string
|
||||
description: 险种名称
|
||||
example: "牛羊保险"
|
||||
description:
|
||||
type: string
|
||||
description: 险种描述
|
||||
example: "针对牛羊等大型牲畜的综合保险产品"
|
||||
applicable_livestock:
|
||||
type: string
|
||||
description: 适用牲畜类型
|
||||
example: "牛、羊"
|
||||
insurance_term:
|
||||
type: integer
|
||||
description: 保险期限(月)
|
||||
example: 12
|
||||
policy_form:
|
||||
type: string
|
||||
description: 保单形式
|
||||
example: "电子保单"
|
||||
coverage_amount_min:
|
||||
type: number
|
||||
format: decimal
|
||||
description: 最低保额
|
||||
example: 1000.00
|
||||
coverage_amount_max:
|
||||
type: number
|
||||
format: decimal
|
||||
description: 最高保额
|
||||
example: 50000.00
|
||||
premium_rate:
|
||||
type: number
|
||||
format: decimal
|
||||
description: 保险费率
|
||||
example: 0.0350
|
||||
service_area:
|
||||
type: string
|
||||
description: 服务区域
|
||||
example: "宁夏回族自治区"
|
||||
add_time:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 添加时间
|
||||
example: "2024-01-15T10:30:00.000Z"
|
||||
on_sale_status:
|
||||
type: boolean
|
||||
description: 在售状态
|
||||
example: true
|
||||
sort_order:
|
||||
type: integer
|
||||
description: 排序顺序
|
||||
example: 0
|
||||
remarks:
|
||||
type: string
|
||||
description: 备注
|
||||
example: "特殊说明信息"
|
||||
status:
|
||||
type: string
|
||||
enum: [active, inactive]
|
||||
description: 险种状态
|
||||
example: "active"
|
||||
created_by:
|
||||
type: integer
|
||||
description: 创建人ID
|
||||
example: 1
|
||||
updated_by:
|
||||
type: integer
|
||||
description: 更新人ID
|
||||
example: 1
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 创建时间
|
||||
example: "2024-01-15T10:30:00.000Z"
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 更新时间
|
||||
example: "2024-01-15T10:30:00.000Z"
|
||||
|
||||
CreateInsuranceTypeRequest:
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- coverage_amount_min
|
||||
- coverage_amount_max
|
||||
- premium_rate
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: 险种名称
|
||||
example: "牛羊保险"
|
||||
minLength: 1
|
||||
maxLength: 100
|
||||
description:
|
||||
type: string
|
||||
description: 险种描述
|
||||
example: "针对牛羊等大型牲畜的综合保险产品"
|
||||
applicable_livestock:
|
||||
type: string
|
||||
description: 适用牲畜类型
|
||||
example: "牛、羊"
|
||||
maxLength: 100
|
||||
insurance_term:
|
||||
type: integer
|
||||
description: 保险期限(月)
|
||||
example: 12
|
||||
minimum: 1
|
||||
policy_form:
|
||||
type: string
|
||||
description: 保单形式
|
||||
example: "电子保单"
|
||||
maxLength: 50
|
||||
coverage_amount_min:
|
||||
type: number
|
||||
format: decimal
|
||||
description: 最低保额
|
||||
example: 1000.00
|
||||
minimum: 0
|
||||
coverage_amount_max:
|
||||
type: number
|
||||
format: decimal
|
||||
description: 最高保额
|
||||
example: 50000.00
|
||||
minimum: 0
|
||||
premium_rate:
|
||||
type: number
|
||||
format: decimal
|
||||
description: 保险费率
|
||||
example: 0.0350
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
service_area:
|
||||
type: string
|
||||
description: 服务区域
|
||||
example: "宁夏回族自治区"
|
||||
add_time:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 添加时间
|
||||
example: "2024-01-15T10:30:00.000Z"
|
||||
on_sale_status:
|
||||
type: boolean
|
||||
description: 在售状态
|
||||
example: true
|
||||
default: true
|
||||
sort_order:
|
||||
type: integer
|
||||
description: 排序顺序
|
||||
example: 0
|
||||
default: 0
|
||||
remarks:
|
||||
type: string
|
||||
description: 备注
|
||||
example: "特殊说明信息"
|
||||
status:
|
||||
type: string
|
||||
enum: [active, inactive]
|
||||
description: 险种状态
|
||||
example: "active"
|
||||
default: "active"
|
||||
|
||||
UpdateInsuranceTypeRequest:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: 险种名称
|
||||
example: "牛羊保险"
|
||||
minLength: 1
|
||||
maxLength: 100
|
||||
description:
|
||||
type: string
|
||||
description: 险种描述
|
||||
example: "针对牛羊等大型牲畜的综合保险产品"
|
||||
applicable_livestock:
|
||||
type: string
|
||||
description: 适用牲畜类型
|
||||
example: "牛、羊"
|
||||
maxLength: 100
|
||||
insurance_term:
|
||||
type: integer
|
||||
description: 保险期限(月)
|
||||
example: 12
|
||||
minimum: 1
|
||||
policy_form:
|
||||
type: string
|
||||
description: 保单形式
|
||||
example: "电子保单"
|
||||
maxLength: 50
|
||||
coverage_amount_min:
|
||||
type: number
|
||||
format: decimal
|
||||
description: 最低保额
|
||||
example: 1000.00
|
||||
minimum: 0
|
||||
coverage_amount_max:
|
||||
type: number
|
||||
format: decimal
|
||||
description: 最高保额
|
||||
example: 50000.00
|
||||
minimum: 0
|
||||
premium_rate:
|
||||
type: number
|
||||
format: decimal
|
||||
description: 保险费率
|
||||
example: 0.0350
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
service_area:
|
||||
type: string
|
||||
description: 服务区域
|
||||
example: "宁夏回族自治区"
|
||||
add_time:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 添加时间
|
||||
example: "2024-01-15T10:30:00.000Z"
|
||||
on_sale_status:
|
||||
type: boolean
|
||||
description: 在售状态
|
||||
example: true
|
||||
sort_order:
|
||||
type: integer
|
||||
description: 排序顺序
|
||||
example: 0
|
||||
remarks:
|
||||
type: string
|
||||
description: 备注
|
||||
example: "特殊说明信息"
|
||||
status:
|
||||
type: string
|
||||
enum: [active, inactive]
|
||||
description: 险种状态
|
||||
example: "active"
|
||||
|
||||
UpdateInsuranceTypeStatusRequest:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
enum: [active, inactive]
|
||||
description: 险种状态
|
||||
example: "active"
|
||||
on_sale_status:
|
||||
type: boolean
|
||||
description: 在售状态
|
||||
example: true
|
||||
|
||||
Pagination:
|
||||
type: object
|
||||
properties:
|
||||
page:
|
||||
type: integer
|
||||
description: 当前页码
|
||||
example: 1
|
||||
limit:
|
||||
type: integer
|
||||
description: 每页数量
|
||||
example: 10
|
||||
total:
|
||||
type: integer
|
||||
description: 总记录数
|
||||
example: 100
|
||||
|
||||
responses:
|
||||
BadRequest:
|
||||
description: 请求参数错误
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
message:
|
||||
type: string
|
||||
example: "请求参数错误"
|
||||
|
||||
Unauthorized:
|
||||
description: 未授权
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
message:
|
||||
type: string
|
||||
example: "未授权访问"
|
||||
|
||||
Forbidden:
|
||||
description: 权限不足
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
message:
|
||||
type: string
|
||||
example: "权限不足"
|
||||
|
||||
NotFound:
|
||||
description: 资源不存在
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
message:
|
||||
type: string
|
||||
example: "险种不存在"
|
||||
|
||||
InternalServerError:
|
||||
description: 服务器内部错误
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
message:
|
||||
type: string
|
||||
example: "服务器内部错误"
|
||||
@@ -29,6 +29,38 @@ const InsuranceType = sequelize.define('InsuranceType', {
|
||||
allowNull: true,
|
||||
comment: '保险类型描述'
|
||||
},
|
||||
applicable_livestock: {
|
||||
type: DataTypes.STRING(100),
|
||||
allowNull: true,
|
||||
comment: '适用生资(如:牛、羊、猪等)'
|
||||
},
|
||||
insurance_term: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
comment: '保险期限(月)',
|
||||
validate: {
|
||||
min: {
|
||||
args: [1],
|
||||
msg: '保险期限不能小于1个月'
|
||||
}
|
||||
}
|
||||
},
|
||||
policy_form: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: true,
|
||||
comment: '保单形式(电子保单、纸质保单等)'
|
||||
},
|
||||
on_sale_status: {
|
||||
type: DataTypes.BOOLEAN,
|
||||
allowNull: false,
|
||||
defaultValue: true,
|
||||
comment: '在售状态(true-在售,false-停售)'
|
||||
},
|
||||
add_time: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
comment: '添加时间'
|
||||
},
|
||||
coverage_amount_min: {
|
||||
type: DataTypes.DECIMAL(15, 2),
|
||||
allowNull: false,
|
||||
|
||||
@@ -19,6 +19,21 @@ const LivestockClaim = sequelize.define('LivestockClaim', {
|
||||
}
|
||||
}
|
||||
},
|
||||
reporter_name: {
|
||||
type: DataTypes.STRING(100),
|
||||
allowNull: false,
|
||||
comment: '报案人姓名'
|
||||
},
|
||||
contact_phone: {
|
||||
type: DataTypes.STRING(20),
|
||||
allowNull: false,
|
||||
comment: '联系电话'
|
||||
},
|
||||
policy_no: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: false,
|
||||
comment: '保单号'
|
||||
},
|
||||
policy_id: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
@@ -29,9 +44,32 @@ const LivestockClaim = sequelize.define('LivestockClaim', {
|
||||
}
|
||||
},
|
||||
claim_type: {
|
||||
type: DataTypes.ENUM('disease', 'natural_disaster', 'accident', 'theft', 'other'),
|
||||
type: DataTypes.ENUM('death', 'disease', 'accident', 'natural_disaster'),
|
||||
allowNull: false,
|
||||
comment: '理赔类型:disease-疾病,natural_disaster-自然灾害,accident-意外事故,theft-盗窃,other-其他'
|
||||
comment: '理赔类型:death-死亡,disease-疾病,accident-意外事故,natural_disaster-自然灾害'
|
||||
},
|
||||
affected_count: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 1,
|
||||
comment: '受影响牲畜数量',
|
||||
validate: {
|
||||
min: {
|
||||
args: [1],
|
||||
msg: '受影响牲畜数量不能小于1'
|
||||
}
|
||||
}
|
||||
},
|
||||
claim_amount: {
|
||||
type: DataTypes.DECIMAL(15, 2),
|
||||
allowNull: false,
|
||||
comment: '理赔金额',
|
||||
validate: {
|
||||
min: {
|
||||
args: [0],
|
||||
msg: '理赔金额不能小于0'
|
||||
}
|
||||
}
|
||||
},
|
||||
incident_date: {
|
||||
type: DataTypes.DATE,
|
||||
@@ -63,28 +101,6 @@ const LivestockClaim = sequelize.define('LivestockClaim', {
|
||||
}
|
||||
}
|
||||
},
|
||||
affected_count: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
comment: '受影响牲畜数量',
|
||||
validate: {
|
||||
min: {
|
||||
args: [1],
|
||||
msg: '受影响牲畜数量不能小于1'
|
||||
}
|
||||
}
|
||||
},
|
||||
claim_amount: {
|
||||
type: DataTypes.DECIMAL(15, 2),
|
||||
allowNull: false,
|
||||
comment: '理赔金额',
|
||||
validate: {
|
||||
min: {
|
||||
args: [0],
|
||||
msg: '理赔金额不能小于0'
|
||||
}
|
||||
}
|
||||
},
|
||||
claim_status: {
|
||||
type: DataTypes.ENUM('pending', 'investigating', 'approved', 'rejected', 'paid'),
|
||||
allowNull: false,
|
||||
@@ -100,15 +116,10 @@ const LivestockClaim = sequelize.define('LivestockClaim', {
|
||||
key: 'id'
|
||||
}
|
||||
},
|
||||
investigation_notes: {
|
||||
investigation_report: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: true,
|
||||
comment: '调查备注'
|
||||
},
|
||||
investigation_date: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
comment: '调查日期'
|
||||
comment: '调查报告'
|
||||
},
|
||||
reviewer_id: {
|
||||
type: DataTypes.INTEGER,
|
||||
@@ -129,7 +140,12 @@ const LivestockClaim = sequelize.define('LivestockClaim', {
|
||||
allowNull: true,
|
||||
comment: '审核日期'
|
||||
},
|
||||
settlement_amount: {
|
||||
payment_date: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
comment: '赔付日期'
|
||||
},
|
||||
payment_amount: {
|
||||
type: DataTypes.DECIMAL(15, 2),
|
||||
allowNull: true,
|
||||
comment: '实际赔付金额',
|
||||
@@ -140,11 +156,6 @@ const LivestockClaim = sequelize.define('LivestockClaim', {
|
||||
}
|
||||
}
|
||||
},
|
||||
settlement_date: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
comment: '赔付日期'
|
||||
},
|
||||
supporting_documents: {
|
||||
type: DataTypes.JSON,
|
||||
allowNull: true,
|
||||
|
||||
@@ -212,7 +212,7 @@ LivestockClaim.belongsTo(User, {
|
||||
as: 'creator'
|
||||
});
|
||||
LivestockClaim.belongsTo(User, {
|
||||
foreignKey: 'reviewed_by',
|
||||
foreignKey: 'reviewer_id',
|
||||
as: 'reviewer'
|
||||
});
|
||||
|
||||
|
||||
@@ -3,34 +3,328 @@ const router = express.Router();
|
||||
const insuranceTypeController = require('../controllers/insuranceTypeController');
|
||||
const { jwtAuth, checkPermission } = require('../middleware/auth');
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/insurance-types:
|
||||
* get:
|
||||
* summary: 获取险种列表
|
||||
* description: 分页获取险种列表,支持多种筛选条件
|
||||
* tags:
|
||||
* - 险种管理
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - name: page
|
||||
* in: query
|
||||
* description: 页码
|
||||
* required: false
|
||||
* schema:
|
||||
* type: integer
|
||||
* default: 1
|
||||
* minimum: 1
|
||||
* - name: pageSize
|
||||
* in: query
|
||||
* description: 每页数量
|
||||
* required: false
|
||||
* schema:
|
||||
* type: integer
|
||||
* default: 10
|
||||
* minimum: 1
|
||||
* maximum: 100
|
||||
* - name: name
|
||||
* in: query
|
||||
* description: 险种名称(模糊搜索)
|
||||
* required: false
|
||||
* schema:
|
||||
* type: string
|
||||
* - name: status
|
||||
* in: query
|
||||
* description: 险种状态
|
||||
* required: false
|
||||
* schema:
|
||||
* type: string
|
||||
* enum: [active, inactive]
|
||||
* - name: applicable_livestock
|
||||
* in: query
|
||||
* description: 适用牲畜类型(模糊搜索)
|
||||
* required: false
|
||||
* schema:
|
||||
* type: string
|
||||
* - name: service_area
|
||||
* in: query
|
||||
* description: 服务区域(模糊搜索)
|
||||
* required: false
|
||||
* schema:
|
||||
* type: string
|
||||
* - name: on_sale_status
|
||||
* in: query
|
||||
* description: 在售状态
|
||||
* required: false
|
||||
* schema:
|
||||
* type: boolean
|
||||
* responses:
|
||||
* '200':
|
||||
* description: 获取成功
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* success:
|
||||
* type: boolean
|
||||
* example: true
|
||||
* message:
|
||||
* type: string
|
||||
* example: "获取险种列表成功"
|
||||
* data:
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: '#/components/schemas/InsuranceType'
|
||||
* pagination:
|
||||
* $ref: '#/components/schemas/Pagination'
|
||||
* '401':
|
||||
* $ref: '#/components/responses/UnauthorizedError'
|
||||
* '403':
|
||||
* $ref: '#/components/responses/ForbiddenError'
|
||||
* '500':
|
||||
* description: 服务器内部错误
|
||||
* post:
|
||||
* summary: 创建险种
|
||||
* description: 创建新的保险险种
|
||||
* tags:
|
||||
* - 险种管理
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/CreateInsuranceTypeRequest'
|
||||
* responses:
|
||||
* '201':
|
||||
* description: 创建成功
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* success:
|
||||
* type: boolean
|
||||
* example: true
|
||||
* message:
|
||||
* type: string
|
||||
* example: "创建险种成功"
|
||||
* data:
|
||||
* $ref: '#/components/schemas/InsuranceType'
|
||||
* '400':
|
||||
* description: 请求参数错误
|
||||
* '401':
|
||||
* $ref: '#/components/responses/UnauthorizedError'
|
||||
* '403':
|
||||
* $ref: '#/components/responses/ForbiddenError'
|
||||
* '500':
|
||||
* description: 服务器内部错误
|
||||
*/
|
||||
|
||||
// 获取险种列表
|
||||
router.get('/', jwtAuth, checkPermission('insurance_type', 'read'),
|
||||
insuranceTypeController.getInsuranceTypes
|
||||
);
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/insurance-types/{id}:
|
||||
* get:
|
||||
* summary: 获取单个险种
|
||||
* description: 根据ID获取险种详细信息
|
||||
* tags:
|
||||
* - 险种管理
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - name: id
|
||||
* in: path
|
||||
* description: 险种ID
|
||||
* required: true
|
||||
* schema:
|
||||
* type: integer
|
||||
* responses:
|
||||
* '200':
|
||||
* description: 获取成功
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* success:
|
||||
* type: boolean
|
||||
* example: true
|
||||
* message:
|
||||
* type: string
|
||||
* example: "获取险种详情成功"
|
||||
* data:
|
||||
* $ref: '#/components/schemas/InsuranceType'
|
||||
* '401':
|
||||
* $ref: '#/components/responses/UnauthorizedError'
|
||||
* '403':
|
||||
* $ref: '#/components/responses/ForbiddenError'
|
||||
* '404':
|
||||
* description: 险种不存在
|
||||
* '500':
|
||||
* description: 服务器内部错误
|
||||
*/
|
||||
// 获取单个险种详情
|
||||
router.get('/:id', jwtAuth, checkPermission('insurance_type', 'read'),
|
||||
insuranceTypeController.getInsuranceTypeById
|
||||
);
|
||||
|
||||
// 创建险种
|
||||
router.post('/', jwtAuth, checkPermission('insurance_type', 'create'),
|
||||
insuranceTypeController.createInsuranceType
|
||||
);
|
||||
router.post('/', jwtAuth, checkPermission('insurance_type', 'create'), insuranceTypeController.createInsuranceType);
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/insurance-types/{id}:
|
||||
* put:
|
||||
* summary: 更新险种
|
||||
* description: 根据ID更新险种信息
|
||||
* tags:
|
||||
* - 险种管理
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - name: id
|
||||
* in: path
|
||||
* description: 险种ID
|
||||
* required: true
|
||||
* schema:
|
||||
* type: integer
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/UpdateInsuranceTypeRequest'
|
||||
* responses:
|
||||
* '200':
|
||||
* description: 更新成功
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* success:
|
||||
* type: boolean
|
||||
* example: true
|
||||
* message:
|
||||
* type: string
|
||||
* example: "更新险种成功"
|
||||
* data:
|
||||
* $ref: '#/components/schemas/InsuranceType'
|
||||
* '400':
|
||||
* description: 请求参数错误
|
||||
* '401':
|
||||
* $ref: '#/components/responses/UnauthorizedError'
|
||||
* '403':
|
||||
* $ref: '#/components/responses/ForbiddenError'
|
||||
* '404':
|
||||
* description: 险种不存在
|
||||
* '500':
|
||||
* description: 服务器内部错误
|
||||
* delete:
|
||||
* summary: 删除险种
|
||||
* description: 根据ID删除险种
|
||||
* tags:
|
||||
* - 险种管理
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - name: id
|
||||
* in: path
|
||||
* description: 险种ID
|
||||
* required: true
|
||||
* schema:
|
||||
* type: integer
|
||||
* responses:
|
||||
* '200':
|
||||
* description: 删除成功
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* success:
|
||||
* type: boolean
|
||||
* example: true
|
||||
* message:
|
||||
* type: string
|
||||
* example: "删除险种成功"
|
||||
* '401':
|
||||
* $ref: '#/components/responses/UnauthorizedError'
|
||||
* '403':
|
||||
* $ref: '#/components/responses/ForbiddenError'
|
||||
* '404':
|
||||
* description: 险种不存在
|
||||
* '500':
|
||||
* description: 服务器内部错误
|
||||
*/
|
||||
// 更新险种
|
||||
router.put('/:id', jwtAuth, checkPermission('insurance_type', 'update'),
|
||||
insuranceTypeController.updateInsuranceType
|
||||
);
|
||||
router.put('/:id', jwtAuth, checkPermission('insurance_type', 'update'), insuranceTypeController.updateInsuranceType);
|
||||
|
||||
// 删除险种
|
||||
router.delete('/:id', jwtAuth, checkPermission('insurance_type', 'delete'),
|
||||
insuranceTypeController.deleteInsuranceType
|
||||
);
|
||||
router.delete('/:id', jwtAuth, checkPermission('insurance_type', 'delete'), insuranceTypeController.deleteInsuranceType);
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/insurance-types/{id}/status:
|
||||
* patch:
|
||||
* summary: 更新险种状态
|
||||
* description: 更新险种的状态和在售状态
|
||||
* tags:
|
||||
* - 险种管理
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - name: id
|
||||
* in: path
|
||||
* description: 险种ID
|
||||
* required: true
|
||||
* schema:
|
||||
* type: integer
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/UpdateInsuranceTypeStatusRequest'
|
||||
* responses:
|
||||
* '200':
|
||||
* description: 更新成功
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* success:
|
||||
* type: boolean
|
||||
* example: true
|
||||
* message:
|
||||
* type: string
|
||||
* example: "更新险种状态成功"
|
||||
* data:
|
||||
* $ref: '#/components/schemas/InsuranceType'
|
||||
* '400':
|
||||
* description: 请求参数错误
|
||||
* '401':
|
||||
* $ref: '#/components/responses/UnauthorizedError'
|
||||
* '403':
|
||||
* $ref: '#/components/responses/ForbiddenError'
|
||||
* '404':
|
||||
* description: 险种不存在
|
||||
* '500':
|
||||
* description: 服务器内部错误
|
||||
*/
|
||||
// 更新险种状态
|
||||
router.patch('/:id/status', jwtAuth, checkPermission('insurance_type', 'update'),
|
||||
insuranceTypeController.updateInsuranceTypeStatus
|
||||
);
|
||||
router.patch('/:id/status', jwtAuth, checkPermission('insurance_type', 'update'), insuranceTypeController.updateInsuranceTypeStatus);
|
||||
|
||||
module.exports = router;
|
||||
@@ -6,10 +6,27 @@ const {
|
||||
getLivestockClaimById,
|
||||
reviewLivestockClaim,
|
||||
updateLivestockClaimPayment,
|
||||
getLivestockClaimStats
|
||||
getLivestockClaimStats,
|
||||
updateLivestockClaim,
|
||||
deleteLivestockClaim
|
||||
} = require('../controllers/livestockClaimController');
|
||||
const { authenticateToken, requirePermission } = require('../middleware/auth');
|
||||
|
||||
// 测试查询参数端点(无认证)
|
||||
router.get('/test-params', (req, res) => {
|
||||
console.log('🧪 [测试端点] 查询参数测试:');
|
||||
console.log('req.url:', req.url);
|
||||
console.log('req.originalUrl:', req.originalUrl);
|
||||
console.log('req.query:', req.query);
|
||||
console.log('req.params:', req.params);
|
||||
res.json({
|
||||
url: req.url,
|
||||
originalUrl: req.originalUrl,
|
||||
query: req.query,
|
||||
params: req.params
|
||||
});
|
||||
});
|
||||
|
||||
// 获取生资理赔列表
|
||||
router.get('/', authenticateToken, requirePermission('livestock_claim:read'), getLivestockClaims);
|
||||
|
||||
@@ -22,6 +39,12 @@ router.get('/:id', authenticateToken, requirePermission('livestock_claim:read'),
|
||||
// 创建生资理赔申请
|
||||
router.post('/', authenticateToken, requirePermission('livestock_claim:create'), createLivestockClaim);
|
||||
|
||||
// 更新生资理赔信息
|
||||
router.put('/:id', authenticateToken, requirePermission('livestock_claim:update'), updateLivestockClaim);
|
||||
|
||||
// 删除生资理赔
|
||||
router.delete('/:id', authenticateToken, requirePermission('livestock_claim:delete'), deleteLivestockClaim);
|
||||
|
||||
// 审核生资理赔
|
||||
router.patch('/:id/review', authenticateToken, requirePermission('livestock_claim:review'), reviewLivestockClaim);
|
||||
|
||||
|
||||
23
insurance_backend/test_params.js
Normal file
23
insurance_backend/test_params.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const axios = require('axios');
|
||||
|
||||
async function testParams() {
|
||||
try {
|
||||
console.log('🧪 测试查询参数传递...');
|
||||
|
||||
const response = await axios.get('http://localhost:3000/api/livestock-claims/test-params', {
|
||||
params: {
|
||||
claim_no: 'LC2024001',
|
||||
page: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
});
|
||||
|
||||
console.log('✅ 测试端点响应:');
|
||||
console.log(JSON.stringify(response.data, null, 2));
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 测试失败:', error.response?.data || error.message);
|
||||
}
|
||||
}
|
||||
|
||||
testParams();
|
||||
282
insurance_backend/tests/insurance-type-api-test.js
Normal file
282
insurance_backend/tests/insurance-type-api-test.js
Normal file
@@ -0,0 +1,282 @@
|
||||
/**
|
||||
* 险种管理API测试脚本
|
||||
* 使用Node.js和axios进行API测试
|
||||
*/
|
||||
|
||||
const axios = require('axios');
|
||||
|
||||
// 配置
|
||||
const BASE_URL = 'http://localhost:3000/api';
|
||||
const TEST_USER = {
|
||||
username: 'admin',
|
||||
password: '123456'
|
||||
};
|
||||
|
||||
let authToken = '';
|
||||
let testInsuranceTypeId = null;
|
||||
|
||||
// 创建axios实例
|
||||
const api = axios.create({
|
||||
baseURL: BASE_URL,
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
// 请求拦截器 - 添加认证头
|
||||
api.interceptors.request.use(config => {
|
||||
if (authToken) {
|
||||
config.headers.Authorization = `Bearer ${authToken}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
|
||||
// 响应拦截器 - 处理错误
|
||||
api.interceptors.response.use(
|
||||
response => response,
|
||||
error => {
|
||||
console.error('API请求错误:', error.response?.data || error.message);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// 测试函数
|
||||
async function runTests() {
|
||||
console.log('🚀 开始险种管理API测试...\n');
|
||||
|
||||
try {
|
||||
// 1. 用户登录
|
||||
await testLogin();
|
||||
|
||||
// 2. 获取险种列表
|
||||
await testGetInsuranceTypes();
|
||||
|
||||
// 3. 创建险种
|
||||
await testCreateInsuranceType();
|
||||
|
||||
// 4. 获取单个险种
|
||||
await testGetInsuranceTypeById();
|
||||
|
||||
// 5. 更新险种
|
||||
await testUpdateInsuranceType();
|
||||
|
||||
// 6. 更新险种状态
|
||||
await testUpdateInsuranceTypeStatus();
|
||||
|
||||
// 7. 删除险种
|
||||
await testDeleteInsuranceType();
|
||||
|
||||
console.log('✅ 所有测试完成!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 测试失败:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 测试用户登录
|
||||
async function testLogin() {
|
||||
console.log('📝 测试用户登录...');
|
||||
|
||||
try {
|
||||
const response = await api.post('/auth/login', TEST_USER);
|
||||
|
||||
if (response.data.success && response.data.data.token) {
|
||||
authToken = response.data.data.token;
|
||||
console.log('✅ 登录成功');
|
||||
} else {
|
||||
throw new Error('登录失败:未获取到token');
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`登录失败: ${error.response?.data?.message || error.message}`);
|
||||
}
|
||||
|
||||
console.log('');
|
||||
}
|
||||
|
||||
// 2. 测试获取险种列表
|
||||
async function testGetInsuranceTypes() {
|
||||
console.log('📋 测试获取险种列表...');
|
||||
|
||||
try {
|
||||
const response = await api.get('/insurance-types', {
|
||||
params: {
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
status: 'active'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.data.success) {
|
||||
console.log(`✅ 获取险种列表成功,共 ${response.data.pagination.total} 条记录`);
|
||||
console.log(` 当前页: ${response.data.pagination.page}/${response.data.pagination.totalPages}`);
|
||||
} else {
|
||||
throw new Error('获取险种列表失败');
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`获取险种列表失败: ${error.response?.data?.message || error.message}`);
|
||||
}
|
||||
|
||||
console.log('');
|
||||
}
|
||||
|
||||
// 3. 测试创建险种
|
||||
async function testCreateInsuranceType() {
|
||||
console.log('➕ 测试创建险种...');
|
||||
|
||||
const testData = {
|
||||
name: `测试险种_${Date.now()}`,
|
||||
description: '这是一个测试用的险种',
|
||||
applicable_livestock: '牛',
|
||||
insurance_term: '1年',
|
||||
policy_form: '团体保险',
|
||||
coverage_amount_min: 1000.00,
|
||||
coverage_amount_max: 50000.00,
|
||||
premium_rate: 0.05
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await api.post('/insurance-types', testData);
|
||||
|
||||
if (response.data.success && response.data.data.id) {
|
||||
testInsuranceTypeId = response.data.data.id;
|
||||
console.log(`✅ 创建险种成功,ID: ${testInsuranceTypeId}`);
|
||||
console.log(` 险种名称: ${response.data.data.name}`);
|
||||
} else {
|
||||
throw new Error('创建险种失败');
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`创建险种失败: ${error.response?.data?.message || error.message}`);
|
||||
}
|
||||
|
||||
console.log('');
|
||||
}
|
||||
|
||||
// 4. 测试获取单个险种
|
||||
async function testGetInsuranceTypeById() {
|
||||
console.log('🔍 测试获取单个险种...');
|
||||
|
||||
if (!testInsuranceTypeId) {
|
||||
throw new Error('没有可用的测试险种ID');
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await api.get(`/insurance-types/${testInsuranceTypeId}`);
|
||||
|
||||
if (response.data.success && response.data.data) {
|
||||
console.log(`✅ 获取险种详情成功`);
|
||||
console.log(` 险种名称: ${response.data.data.name}`);
|
||||
console.log(` 适用牲畜: ${response.data.data.applicable_livestock}`);
|
||||
console.log(` 保险期限: ${response.data.data.insurance_term}`);
|
||||
} else {
|
||||
throw new Error('获取险种详情失败');
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`获取险种详情失败: ${error.response?.data?.message || error.message}`);
|
||||
}
|
||||
|
||||
console.log('');
|
||||
}
|
||||
|
||||
// 5. 测试更新险种
|
||||
async function testUpdateInsuranceType() {
|
||||
console.log('✏️ 测试更新险种...');
|
||||
|
||||
if (!testInsuranceTypeId) {
|
||||
throw new Error('没有可用的测试险种ID');
|
||||
}
|
||||
|
||||
const updateData = {
|
||||
description: '这是一个更新后的测试险种描述',
|
||||
premium_rate: 0.08
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await api.put(`/insurance-types/${testInsuranceTypeId}`, updateData);
|
||||
|
||||
if (response.data.success && response.data.data) {
|
||||
console.log(`✅ 更新险种成功`);
|
||||
console.log(` 新描述: ${response.data.data.description}`);
|
||||
console.log(` 新费率: ${response.data.data.premium_rate}`);
|
||||
} else {
|
||||
throw new Error('更新险种失败');
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`更新险种失败: ${error.response?.data?.message || error.message}`);
|
||||
}
|
||||
|
||||
console.log('');
|
||||
}
|
||||
|
||||
// 6. 测试更新险种状态
|
||||
async function testUpdateInsuranceTypeStatus() {
|
||||
console.log('🔄 测试更新险种状态...');
|
||||
|
||||
if (!testInsuranceTypeId) {
|
||||
throw new Error('没有可用的测试险种ID');
|
||||
}
|
||||
|
||||
const statusData = {
|
||||
status: 'active',
|
||||
on_sale_status: true
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await api.patch(`/insurance-types/${testInsuranceTypeId}/status`, statusData);
|
||||
|
||||
if (response.data.success && response.data.data) {
|
||||
console.log(`✅ 更新险种状态成功`);
|
||||
console.log(` 状态: ${response.data.data.status}`);
|
||||
console.log(` 在售状态: ${response.data.data.on_sale_status}`);
|
||||
} else {
|
||||
throw new Error('更新险种状态失败');
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`更新险种状态失败: ${error.response?.data?.message || error.message}`);
|
||||
}
|
||||
|
||||
console.log('');
|
||||
}
|
||||
|
||||
// 7. 测试删除险种
|
||||
async function testDeleteInsuranceType() {
|
||||
console.log('🗑️ 测试删除险种...');
|
||||
|
||||
if (!testInsuranceTypeId) {
|
||||
throw new Error('没有可用的测试险种ID');
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await api.delete(`/insurance-types/${testInsuranceTypeId}`);
|
||||
|
||||
if (response.data.success) {
|
||||
console.log(`✅ 删除险种成功,ID: ${testInsuranceTypeId}`);
|
||||
} else {
|
||||
throw new Error('删除险种失败');
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`删除险种失败: ${error.response?.data?.message || error.message}`);
|
||||
}
|
||||
|
||||
console.log('');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
if (require.main === module) {
|
||||
runTests().catch(error => {
|
||||
console.error('测试运行失败:', error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
runTests,
|
||||
testLogin,
|
||||
testGetInsuranceTypes,
|
||||
testCreateInsuranceType,
|
||||
testGetInsuranceTypeById,
|
||||
testUpdateInsuranceType,
|
||||
testUpdateInsuranceTypeStatus,
|
||||
testDeleteInsuranceType
|
||||
};
|
||||
Reference in New Issue
Block a user