修改养殖端小程序,保险前后端和小程序
This commit is contained in:
210
insurance_backend/controllers/dataWarehouseController.js
Normal file
210
insurance_backend/controllers/dataWarehouseController.js
Normal file
@@ -0,0 +1,210 @@
|
||||
const { User, Role, InsuranceApplication, Policy, Claim, InsuranceType } = require('../models');
|
||||
const responseFormat = require('../utils/response');
|
||||
const { Op } = require('sequelize');
|
||||
|
||||
// 获取数据览仓概览数据
|
||||
const getOverview = async (req, res) => {
|
||||
try {
|
||||
const [
|
||||
totalUsers,
|
||||
totalApplications,
|
||||
totalPolicies,
|
||||
totalClaims,
|
||||
activePolicies,
|
||||
approvedClaims,
|
||||
pendingClaims
|
||||
] = await Promise.all([
|
||||
User.count(),
|
||||
InsuranceApplication.count(),
|
||||
Policy.count(),
|
||||
Claim.count(),
|
||||
Policy.count({ where: { policy_status: 'active' } }),
|
||||
Claim.count({ where: { claim_status: 'approved' } }),
|
||||
Claim.count({ where: { claim_status: 'pending' } })
|
||||
]);
|
||||
|
||||
res.json(responseFormat.success({
|
||||
totalUsers,
|
||||
totalApplications,
|
||||
totalPolicies,
|
||||
totalClaims,
|
||||
activePolicies,
|
||||
approvedClaims,
|
||||
pendingClaims
|
||||
}, '获取数据览仓概览成功'));
|
||||
} catch (error) {
|
||||
console.error('获取数据览仓概览错误:', error);
|
||||
res.status(500).json(responseFormat.error('获取数据览仓概览失败'));
|
||||
}
|
||||
};
|
||||
|
||||
// 获取保险类型分布数据
|
||||
const getInsuranceTypeDistribution = async (req, res) => {
|
||||
try {
|
||||
const types = await InsuranceType.findAll({
|
||||
attributes: ['id', 'name', 'description'],
|
||||
where: { status: 'active' }
|
||||
});
|
||||
|
||||
const distribution = await Promise.all(
|
||||
types.map(async type => {
|
||||
const count = await InsuranceApplication.count({
|
||||
where: { insurance_type_id: type.id }
|
||||
});
|
||||
return {
|
||||
id: type.id,
|
||||
name: type.name,
|
||||
description: type.description,
|
||||
count
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
res.json(responseFormat.success(distribution, '获取保险类型分布成功'));
|
||||
} catch (error) {
|
||||
console.error('获取保险类型分布错误:', error);
|
||||
res.status(500).json(responseFormat.error('获取保险类型分布失败'));
|
||||
}
|
||||
};
|
||||
|
||||
// 获取申请状态分布数据
|
||||
const getApplicationStatusDistribution = async (req, res) => {
|
||||
try {
|
||||
const [
|
||||
pendingCount,
|
||||
approvedCount,
|
||||
rejectedCount,
|
||||
underReviewCount
|
||||
] = await Promise.all([
|
||||
InsuranceApplication.count({ where: { status: 'pending' } }),
|
||||
InsuranceApplication.count({ where: { status: 'approved' } }),
|
||||
InsuranceApplication.count({ where: { status: 'rejected' } }),
|
||||
InsuranceApplication.count({ where: { status: 'under_review' } })
|
||||
]);
|
||||
|
||||
res.json(responseFormat.success([
|
||||
{ status: 'pending', name: '待处理', count: pendingCount },
|
||||
{ status: 'under_review', name: '审核中', count: underReviewCount },
|
||||
{ status: 'approved', name: '已批准', count: approvedCount },
|
||||
{ status: 'rejected', name: '已拒绝', count: rejectedCount }
|
||||
], '获取申请状态分布成功'));
|
||||
} catch (error) {
|
||||
console.error('获取申请状态分布错误:', error);
|
||||
res.status(500).json(responseFormat.error('获取申请状态分布失败'));
|
||||
}
|
||||
};
|
||||
|
||||
// 获取近7天趋势数据
|
||||
const getTrendData = async (req, res) => {
|
||||
try {
|
||||
const sevenDaysAgo = new Date();
|
||||
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
|
||||
|
||||
// 生成近7天的日期数组
|
||||
const dateArray = [];
|
||||
for (let i = 6; i >= 0; i--) {
|
||||
const date = new Date(sevenDaysAgo);
|
||||
date.setDate(date.getDate() + i);
|
||||
dateArray.push(date.toISOString().split('T')[0]); // 格式化为YYYY-MM-DD
|
||||
}
|
||||
|
||||
// 获取每天的新增数据
|
||||
const dailyData = await Promise.all(
|
||||
dateArray.map(async date => {
|
||||
const startDate = new Date(`${date} 00:00:00`);
|
||||
const endDate = new Date(`${date} 23:59:59`);
|
||||
|
||||
const [newApplications, newPolicies, newClaims] = await Promise.all([
|
||||
InsuranceApplication.count({
|
||||
where: {
|
||||
created_at: {
|
||||
[Op.between]: [startDate, endDate]
|
||||
}
|
||||
}
|
||||
}),
|
||||
Policy.count({
|
||||
where: {
|
||||
created_at: {
|
||||
[Op.between]: [startDate, endDate]
|
||||
}
|
||||
}
|
||||
}),
|
||||
Claim.count({
|
||||
where: {
|
||||
created_at: {
|
||||
[Op.between]: [startDate, endDate]
|
||||
}
|
||||
}
|
||||
})
|
||||
]);
|
||||
|
||||
return {
|
||||
date,
|
||||
newApplications,
|
||||
newPolicies,
|
||||
newClaims
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
res.json(responseFormat.success(dailyData, '获取趋势数据成功'));
|
||||
} catch (error) {
|
||||
console.error('获取趋势数据错误:', error);
|
||||
res.status(500).json(responseFormat.error('获取趋势数据失败'));
|
||||
}
|
||||
};
|
||||
|
||||
// 获取赔付统计数据
|
||||
const getClaimStats = async (req, res) => {
|
||||
try {
|
||||
const claims = await Claim.findAll({
|
||||
attributes: ['id', 'claim_amount', 'policy_id'],
|
||||
include: [{
|
||||
model: Policy,
|
||||
as: 'policy',
|
||||
attributes: ['policy_no', 'insurance_type_id']
|
||||
}]
|
||||
});
|
||||
|
||||
// 按保险类型分组统计赔付金额
|
||||
const typeStats = {};
|
||||
claims.forEach(claim => {
|
||||
const typeId = claim.policy?.insurance_type_id;
|
||||
if (typeId) {
|
||||
if (!typeStats[typeId]) {
|
||||
typeStats[typeId] = { id: typeId, totalAmount: 0, count: 0 };
|
||||
}
|
||||
typeStats[typeId].totalAmount += parseFloat(claim.claim_amount || 0);
|
||||
typeStats[typeId].count += 1;
|
||||
}
|
||||
});
|
||||
|
||||
// 获取保险类型名称
|
||||
const typeIds = Object.keys(typeStats).map(id => parseInt(id));
|
||||
const types = await InsuranceType.findAll({
|
||||
attributes: ['id', 'name'],
|
||||
where: { id: typeIds }
|
||||
});
|
||||
|
||||
types.forEach(type => {
|
||||
if (typeStats[type.id]) {
|
||||
typeStats[type.id].name = type.name;
|
||||
}
|
||||
});
|
||||
|
||||
const result = Object.values(typeStats);
|
||||
|
||||
res.json(responseFormat.success(result, '获取赔付统计成功'));
|
||||
} catch (error) {
|
||||
console.error('获取赔付统计错误:', error);
|
||||
res.status(500).json(responseFormat.error('获取赔付统计失败'));
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getOverview,
|
||||
getInsuranceTypeDistribution,
|
||||
getApplicationStatusDistribution,
|
||||
getTrendData,
|
||||
getClaimStats
|
||||
};
|
||||
161
insurance_backend/controllers/menuController.js
Normal file
161
insurance_backend/controllers/menuController.js
Normal file
@@ -0,0 +1,161 @@
|
||||
const { User, Role, Menu } = require('../models');
|
||||
|
||||
/**
|
||||
* 获取菜单列表
|
||||
* @param {Object} req - Express请求对象
|
||||
* @param {Object} res - Express响应对象
|
||||
*/
|
||||
exports.getMenus = async (req, res) => {
|
||||
try {
|
||||
// 获取用户ID(从JWT中解析或通过其他方式获取)
|
||||
const userId = req.user?.id; // 假设通过认证中间件解析后存在
|
||||
|
||||
// 如果没有用户ID,返回基础菜单
|
||||
if (!userId) {
|
||||
const menus = await Menu.findAll({
|
||||
where: {
|
||||
parent_id: null,
|
||||
show: true,
|
||||
status: 'active'
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: Menu,
|
||||
as: 'children',
|
||||
where: {
|
||||
show: true,
|
||||
status: 'active'
|
||||
},
|
||||
required: false,
|
||||
order: [['order', 'ASC']]
|
||||
}
|
||||
],
|
||||
order: [['order', 'ASC']]
|
||||
});
|
||||
|
||||
return res.json({
|
||||
code: 200,
|
||||
status: 'success',
|
||||
data: menus,
|
||||
message: '获取菜单成功'
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户信息和角色
|
||||
const user = await User.findByPk(userId, {
|
||||
include: [
|
||||
{
|
||||
model: Role,
|
||||
attributes: ['id', 'name', 'permissions']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
status: 'error',
|
||||
message: '用户不存在'
|
||||
});
|
||||
}
|
||||
|
||||
// 获取角色的权限列表
|
||||
const userPermissions = user.Role?.permissions || [];
|
||||
|
||||
// 查询菜单,这里简化处理,实际应用中可能需要根据权限过滤
|
||||
const menus = await Menu.findAll({
|
||||
where: {
|
||||
parent_id: null,
|
||||
show: true,
|
||||
status: 'active'
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: Menu,
|
||||
as: 'children',
|
||||
where: {
|
||||
show: true,
|
||||
status: 'active'
|
||||
},
|
||||
required: false,
|
||||
order: [['order', 'ASC']]
|
||||
}
|
||||
],
|
||||
order: [['order', 'ASC']]
|
||||
});
|
||||
|
||||
// 这里可以添加根据权限过滤菜单的逻辑
|
||||
// 简化示例,假设所有用户都能看到所有激活的菜单
|
||||
|
||||
return res.json({
|
||||
code: 200,
|
||||
status: 'success',
|
||||
data: menus,
|
||||
message: '获取菜单成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取菜单失败:', error);
|
||||
return res.status(500).json({
|
||||
code: 500,
|
||||
status: 'error',
|
||||
message: '服务器内部错误'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取所有菜单(包括非激活状态,仅管理员可用)
|
||||
* @param {Object} req - Express请求对象
|
||||
* @param {Object} res - Express响应对象
|
||||
*/
|
||||
exports.getAllMenus = async (req, res) => {
|
||||
try {
|
||||
// 检查用户是否为管理员(简化示例)
|
||||
const user = await User.findByPk(req.user?.id, {
|
||||
include: [
|
||||
{
|
||||
model: Role,
|
||||
attributes: ['id', 'name', 'permissions']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
if (!user || !user.Role || !user.Role.permissions.includes('*:*')) {
|
||||
return res.status(403).json({
|
||||
code: 403,
|
||||
status: 'error',
|
||||
message: '没有权限查看所有菜单'
|
||||
});
|
||||
}
|
||||
|
||||
// 查询所有菜单
|
||||
const menus = await Menu.findAll({
|
||||
where: {
|
||||
parent_id: null
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: Menu,
|
||||
as: 'children',
|
||||
required: false,
|
||||
order: [['order', 'ASC']]
|
||||
}
|
||||
],
|
||||
order: [['order', 'ASC']]
|
||||
});
|
||||
|
||||
return res.json({
|
||||
code: 200,
|
||||
status: 'success',
|
||||
data: menus,
|
||||
message: '获取所有菜单成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取所有菜单失败:', error);
|
||||
return res.status(500).json({
|
||||
code: 500,
|
||||
status: 'error',
|
||||
message: '服务器内部错误'
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user