完善保险前后端、养殖端小程序

This commit is contained in:
xuqiuyun
2025-09-25 19:09:51 +08:00
parent 76b5393182
commit 852adbcfff
199 changed files with 8642 additions and 52333 deletions

View File

@@ -0,0 +1,295 @@
const { Op, sequelize } = require('sequelize');
const { sequelize: dbSequelize } = require('../config/database');
const User = require('../models/User');
const InsuranceApplication = require('../models/InsuranceApplication');
const Policy = require('../models/Policy');
const Claim = require('../models/Claim');
const OperationLog = require('../models/OperationLog');
/**
* 获取仪表板统计数据
*/
const getStats = async (req, res) => {
try {
console.log('获取仪表板统计数据...');
// 获取今日日期范围
const today = new Date();
const startOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate());
const endOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
// 获取本月日期范围
const startOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
const endOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 1);
// 并行查询各种统计数据
const [
totalApplications,
todayApplications,
monthApplications,
totalPolicies,
activePolicies,
totalClaims,
pendingClaims,
totalUsers,
recentActivities
] = await Promise.all([
// 总申请数
InsuranceApplication.count(),
// 今日申请数
InsuranceApplication.count({
where: {
created_at: {
[Op.gte]: startOfDay,
[Op.lt]: endOfDay
}
}
}),
// 本月申请数
InsuranceApplication.count({
where: {
created_at: {
[Op.gte]: startOfMonth,
[Op.lt]: endOfMonth
}
}
}),
// 总保单数
Policy.count(),
// 有效保单数
Policy.count({
where: {
policy_status: 'active'
}
}),
// 总理赔数
Claim.count(),
// 待处理理赔数
Claim.count({
where: {
claim_status: 'pending'
}
}),
// 总用户数
User.count(),
// 最近活动(从系统日志获取)
OperationLog.findAll({
limit: 10,
order: [['created_at', 'DESC']],
attributes: ['id', 'operation_type', 'operation_content', 'created_at', 'user_id']
})
]);
// 计算增长率(简化计算,实际应该与上一期间对比)
const applicationGrowthRate = todayApplications > 0 ?
((todayApplications / Math.max(monthApplications - todayApplications, 1)) * 100).toFixed(1) : 0;
const policyGrowthRate = activePolicies > 0 ?
((activePolicies / Math.max(totalPolicies - activePolicies, 1)) * 100).toFixed(1) : 0;
const statsData = {
// 核心指标
totalApplications,
todayApplications,
monthApplications,
applicationGrowthRate: parseFloat(applicationGrowthRate),
totalPolicies,
activePolicies,
policyGrowthRate: parseFloat(policyGrowthRate),
totalClaims,
pendingClaims,
claimProcessingRate: totalClaims > 0 ?
(((totalClaims - pendingClaims) / totalClaims) * 100).toFixed(1) : 0,
totalUsers,
// 快速统计
quickStats: {
newApplicationsToday: todayApplications,
pendingReviews: pendingClaims,
activeUsers: totalUsers, // 简化处理,实际应该查询活跃用户
systemAlerts: 0 // 简化处理,实际应该查询系统告警
}
};
console.log('统计数据获取成功:', statsData);
res.json({
code: 200,
status: 'success',
data: statsData,
message: '获取仪表板统计数据成功',
timestamp: new Date().toISOString()
});
} catch (error) {
console.error('获取仪表板统计数据失败:', error);
res.status(500).json({
code: 500,
status: 'error',
data: null,
message: '获取仪表板统计数据失败',
timestamp: new Date().toISOString()
});
}
};
/**
* 获取最近活动
*/
const getRecentActivities = async (req, res) => {
try {
console.log('获取最近活动数据...');
const { limit = 20 } = req.query;
// 从系统日志获取最近活动
const activities = await OperationLog.findAll({
limit: parseInt(limit),
order: [['created_at', 'DESC']],
attributes: ['id', 'operation_type', 'operation_content', 'created_at', 'user_id']
});
// 格式化活动数据
const formattedActivities = activities.map(activity => ({
id: activity.id,
type: activity.operation_type,
title: activity.operation_content,
description: `操作用户: ${activity.user_id || '系统'}`,
timestamp: activity.created_at,
user: activity.user_id,
level: activity.operation_type
}));
console.log(`获取到 ${formattedActivities.length} 条最近活动`);
res.json({
code: 200,
status: 'success',
data: formattedActivities,
message: '获取最近活动成功',
timestamp: new Date().toISOString()
});
} catch (error) {
console.error('获取最近活动失败:', error);
res.status(500).json({
code: 500,
status: 'error',
data: null,
message: '获取最近活动失败',
timestamp: new Date().toISOString()
});
}
};
/**
* 获取图表数据
*/
const getChartData = async (req, res) => {
try {
console.log('获取图表数据...');
const { type = 'applications', period = '7d' } = req.query;
let startDate;
const endDate = new Date();
// 根据时间周期设置开始日期
switch (period) {
case '7d':
startDate = new Date(endDate.getTime() - 7 * 24 * 60 * 60 * 1000);
break;
case '30d':
startDate = new Date(endDate.getTime() - 30 * 24 * 60 * 60 * 1000);
break;
case '90d':
startDate = new Date(endDate.getTime() - 90 * 24 * 60 * 60 * 1000);
break;
default:
startDate = new Date(endDate.getTime() - 7 * 24 * 60 * 60 * 1000);
}
let chartData = [];
if (type === 'applications') {
// 获取申请数据趋势
const applications = await InsuranceApplication.findAll({
where: {
created_at: {
[Op.gte]: startDate,
[Op.lte]: endDate
}
},
attributes: [
[dbSequelize.fn('DATE', dbSequelize.col('created_at')), 'date'],
[dbSequelize.fn('COUNT', dbSequelize.col('id')), 'count']
],
group: [dbSequelize.fn('DATE', dbSequelize.col('created_at'))],
order: [[dbSequelize.fn('DATE', dbSequelize.col('created_at')), 'ASC']]
});
chartData = applications.map(item => ({
date: item.dataValues.date,
value: parseInt(item.dataValues.count)
}));
} else if (type === 'policies') {
// 获取保单数据趋势
const policies = await Policy.findAll({
where: {
created_at: {
[Op.gte]: startDate,
[Op.lte]: endDate
}
},
attributes: [
[dbSequelize.fn('DATE', dbSequelize.col('created_at')), 'date'],
[dbSequelize.fn('COUNT', dbSequelize.col('id')), 'count']
],
group: [dbSequelize.fn('DATE', dbSequelize.col('created_at'))],
order: [[dbSequelize.fn('DATE', dbSequelize.col('created_at')), 'ASC']]
});
chartData = policies.map(item => ({
date: item.dataValues.date,
value: parseInt(item.dataValues.count)
}));
}
console.log(`获取到 ${chartData.length} 条图表数据`);
res.json({
code: 200,
status: 'success',
data: chartData,
message: '获取图表数据成功',
timestamp: new Date().toISOString()
});
} catch (error) {
console.error('获取图表数据失败:', error);
res.status(500).json({
code: 500,
status: 'error',
data: null,
message: '获取图表数据失败',
timestamp: new Date().toISOString()
});
}
};
module.exports = {
getStats,
getRecentActivities,
getChartData
};

View File

@@ -4,6 +4,9 @@ const { Op, Sequelize } = require('sequelize');
// 获取数据仓库概览
const getOverview = async (req, res) => {
try {
// 获取总用户数
const totalUsers = await User.count();
// 获取总申请数
const totalApplications = await InsuranceApplication.count();
@@ -43,6 +46,7 @@ const getOverview = async (req, res) => {
res.json({
success: true,
data: {
totalUsers,
totalApplications,
totalPolicies,
totalClaims,

View File

@@ -23,12 +23,10 @@ const getInsuranceTypes = async (req, res) => {
order: [['created_at', 'DESC']]
});
res.json(responseFormat.success({
list: rows,
total: count,
res.json(responseFormat.pagination(rows, {
page: parseInt(page),
pageSize: parseInt(pageSize),
pages: Math.ceil(count / pageSize)
limit: parseInt(pageSize),
total: count
}, '获取险种列表成功'));
} catch (error) {
console.error('获取险种列表错误:', error);

View File

@@ -0,0 +1,415 @@
const { Permission, Role, Menu, RolePermission, MenuPermission } = require('../models');
const responseFormat = require('../utils/response');
const { Op } = require('sequelize');
/**
* 构建权限树形结构
*/
function buildPermissionTree(permissions, parentId = null) {
const tree = [];
for (const permission of permissions) {
if (permission.parent_id === parentId) {
const children = buildPermissionTree(permissions, permission.id);
const node = {
...permission.toJSON(),
children: children.length > 0 ? children : undefined
};
tree.push(node);
}
}
return tree;
}
/**
* 权限管理控制器
*/
class PermissionController {
/**
* 获取权限列表
*/
async getPermissions(req, res) {
try {
const {
page = 1,
limit = 10,
module,
type,
status = 'active',
keyword
} = req.query;
const offset = (page - 1) * limit;
const where = { status };
// 模块筛选
if (module) {
where.module = module;
}
// 类型筛选
if (type) {
where.type = type;
}
// 关键词搜索
if (keyword) {
where[Op.or] = [
{ name: { [Op.like]: `%${keyword}%` } },
{ code: { [Op.like]: `%${keyword}%` } },
{ description: { [Op.like]: `%${keyword}%` } }
];
}
const { count, rows } = await Permission.findAndCountAll({
where,
include: [
{
model: Permission,
as: 'parent',
attributes: ['id', 'name', 'code']
},
{
model: Permission,
as: 'children',
attributes: ['id', 'name', 'code', 'type']
}
],
order: [['sort_order', 'ASC'], ['id', 'ASC']],
limit: parseInt(limit),
offset: parseInt(offset)
});
res.json(responseFormat.success({
permissions: rows,
pagination: {
total: count,
page: parseInt(page),
limit: parseInt(limit),
pages: Math.ceil(count / limit)
}
}, '获取权限列表成功'));
} catch (error) {
console.error('获取权限列表失败:', error);
res.status(500).json(responseFormat.error('获取权限列表失败'));
}
}
/**
* 获取权限树形结构
*/
async getPermissionTree(req, res) {
try {
const { module, type } = req.query;
const where = { status: 'active' };
if (module) {
where.module = module;
}
if (type) {
where.type = type;
}
const permissions = await Permission.findAll({
where,
order: [['sort_order', 'ASC'], ['id', 'ASC']]
});
// 构建树形结构
const tree = buildPermissionTree(permissions);
res.json(responseFormat.success(tree, '获取权限树成功'));
} catch (error) {
console.error('获取权限树失败:', error);
res.status(500).json(responseFormat.error('获取权限树失败'));
}
}
/**
* 获取单个权限详情
*/
async getPermissionById(req, res) {
try {
const { id } = req.params;
const permission = await Permission.findByPk(id, {
include: [
{
model: Permission,
as: 'parent',
attributes: ['id', 'name', 'code']
},
{
model: Permission,
as: 'children',
attributes: ['id', 'name', 'code', 'type']
}
]
});
if (!permission) {
return res.status(404).json(responseFormat.error('权限不存在'));
}
res.json(responseFormat.success(permission, '获取权限详情成功'));
} catch (error) {
console.error('获取权限详情失败:', error);
res.status(500).json(responseFormat.error('获取权限详情失败'));
}
}
/**
* 创建权限
*/
async createPermission(req, res) {
try {
const {
name,
code,
description,
module,
type = 'operation',
parent_id,
sort_order = 0
} = req.body;
// 验证必填字段
if (!name || !code || !module) {
return res.status(400).json(responseFormat.error('权限名称、权限代码和所属模块为必填项'));
}
// 检查权限代码是否已存在
const existingPermission = await Permission.findOne({ where: { code } });
if (existingPermission) {
return res.status(400).json(responseFormat.error('权限代码已存在'));
}
// 如果有父权限,验证父权限是否存在
if (parent_id) {
const parentPermission = await Permission.findByPk(parent_id);
if (!parentPermission) {
return res.status(400).json(responseFormat.error('父权限不存在'));
}
}
const permission = await Permission.create({
name,
code,
description,
module,
type,
parent_id,
sort_order,
status: 'active'
});
res.status(201).json(responseFormat.created(permission, '创建权限成功'));
} catch (error) {
console.error('创建权限失败:', error);
res.status(500).json(responseFormat.error('创建权限失败'));
}
}
/**
* 更新权限
*/
async updatePermission(req, res) {
try {
const { id } = req.params;
const {
name,
code,
description,
module,
type,
parent_id,
sort_order,
status
} = req.body;
const permission = await Permission.findByPk(id);
if (!permission) {
return res.status(404).json(responseFormat.error('权限不存在'));
}
// 如果修改了权限代码,检查是否与其他权限冲突
if (code && code !== permission.code) {
const existingPermission = await Permission.findOne({
where: {
code,
id: { [Op.ne]: id }
}
});
if (existingPermission) {
return res.status(400).json(responseFormat.error('权限代码已存在'));
}
}
// 如果有父权限,验证父权限是否存在且不是自己
if (parent_id) {
if (parent_id == id) {
return res.status(400).json(responseFormat.error('不能将自己设为父权限'));
}
const parentPermission = await Permission.findByPk(parent_id);
if (!parentPermission) {
return res.status(400).json(responseFormat.error('父权限不存在'));
}
}
await permission.update({
name: name || permission.name,
code: code || permission.code,
description: description !== undefined ? description : permission.description,
module: module || permission.module,
type: type || permission.type,
parent_id: parent_id !== undefined ? parent_id : permission.parent_id,
sort_order: sort_order !== undefined ? sort_order : permission.sort_order,
status: status || permission.status
});
res.json(responseFormat.success(permission, '更新权限成功'));
} catch (error) {
console.error('更新权限失败:', error);
res.status(500).json(responseFormat.error('更新权限失败'));
}
}
/**
* 删除权限
*/
async deletePermission(req, res) {
try {
const { id } = req.params;
const permission = await Permission.findByPk(id);
if (!permission) {
return res.status(404).json(responseFormat.error('权限不存在'));
}
// 检查是否有子权限
const childrenCount = await Permission.count({ where: { parent_id: id } });
if (childrenCount > 0) {
return res.status(400).json(responseFormat.error('该权限下还有子权限,无法删除'));
}
// 检查是否有角色在使用该权限
const rolePermissionCount = await RolePermission.count({ where: { permission_id: id } });
if (rolePermissionCount > 0) {
return res.status(400).json(responseFormat.error('该权限正在被角色使用,无法删除'));
}
// 检查是否有菜单在使用该权限
const menuPermissionCount = await MenuPermission.count({ where: { permission_id: id } });
if (menuPermissionCount > 0) {
return res.status(400).json(responseFormat.error('该权限正在被菜单使用,无法删除'));
}
await permission.destroy();
res.json(responseFormat.success(null, '删除权限成功'));
} catch (error) {
console.error('删除权限失败:', error);
res.status(500).json(responseFormat.error('删除权限失败'));
}
}
/**
* 获取角色权限
*/
async getRolePermissions(req, res) {
try {
const { roleId } = req.params;
const role = await Role.findByPk(roleId, {
include: [
{
model: Permission,
as: 'rolePermissions',
through: {
attributes: ['granted']
}
}
]
});
if (!role) {
return res.status(404).json(responseFormat.error('角色不存在'));
}
res.json(responseFormat.success({
role: {
id: role.id,
name: role.name,
description: role.description
},
permissions: role.rolePermissions
}, '获取角色权限成功'));
} catch (error) {
console.error('获取角色权限失败:', error);
res.status(500).json(responseFormat.error('获取角色权限失败'));
}
}
/**
* 分配角色权限
*/
async assignRolePermissions(req, res) {
try {
const { roleId } = req.params;
const { permissionIds } = req.body;
if (!Array.isArray(permissionIds)) {
return res.status(400).json(responseFormat.error('权限ID列表格式错误'));
}
const role = await Role.findByPk(roleId);
if (!role) {
return res.status(404).json(responseFormat.error('角色不存在'));
}
// 删除现有的角色权限关联
await RolePermission.destroy({ where: { role_id: roleId } });
// 创建新的角色权限关联
if (permissionIds.length > 0) {
const rolePermissions = permissionIds.map(permissionId => ({
role_id: roleId,
permission_id: permissionId,
granted: true
}));
await RolePermission.bulkCreate(rolePermissions);
}
res.json(responseFormat.success(null, '分配角色权限成功'));
} catch (error) {
console.error('分配角色权限失败:', error);
res.status(500).json(responseFormat.error('分配角色权限失败'));
}
}
/**
* 获取模块列表
*/
async getModules(req, res) {
try {
const modules = await Permission.findAll({
attributes: ['module'],
group: ['module'],
order: [['module', 'ASC']]
});
const moduleList = modules.map(item => item.module);
res.json(responseFormat.success(moduleList, '获取模块列表成功'));
} catch (error) {
console.error('获取模块列表失败:', error);
res.status(500).json(responseFormat.error('获取模块列表失败'));
}
}
}
module.exports = new PermissionController();

View File

@@ -0,0 +1,420 @@
const { Role, Permission, RolePermission, User } = require('../models');
const responseFormat = require('../utils/response');
const { Op } = require('sequelize');
/**
* 角色权限管理控制器
* 专门处理角色权限的分配、管理和动态调用
*/
class RolePermissionController {
/**
* 获取所有角色及其权限
*/
async getAllRolesWithPermissions(req, res) {
try {
const roles = await Role.findAll({
order: [['id', 'ASC']]
});
const rolesData = roles.map(role => {
let permissions = [];
if (Array.isArray(role.permissions)) {
permissions = role.permissions;
} else if (typeof role.permissions === 'string') {
try {
permissions = JSON.parse(role.permissions);
} catch (e) {
permissions = [];
}
}
return {
id: role.id,
name: role.name,
description: role.description,
status: role.status,
permissions: permissions,
permissionCount: permissions.length
};
});
res.json(responseFormat.success({
roles: rolesData,
total: rolesData.length
}, '获取角色权限列表成功'));
} catch (error) {
console.error('获取角色权限列表失败:', error);
res.status(500).json(responseFormat.error('获取角色权限列表失败'));
}
}
/**
* 获取所有权限
*/
async getAllPermissions(req, res) {
try {
const permissions = await Permission.findAll({
order: [['id', 'ASC']]
});
res.json(responseFormat.success(permissions, '获取权限列表成功'));
} catch (error) {
console.error('获取权限列表失败:', error);
res.status(500).json(responseFormat.error('获取权限列表失败'));
}
}
/**
* 获取指定角色的权限详情
*/
async getRolePermissionDetail(req, res) {
try {
const { roleId } = req.params;
const role = await Role.findByPk(roleId);
if (!role) {
return res.status(404).json(responseFormat.error('角色不存在'));
}
// 获取所有权限用于对比
const allPermissions = await Permission.findAll({
attributes: ['id', 'name', 'code', 'description', 'module', 'type', 'parent_id'],
order: [['module', 'ASC'], ['id', 'ASC']]
});
// 构建权限树结构
const controller = this;
const permissionTree = controller.buildPermissionTree(allPermissions);
// 获取角色已分配的权限代码
let assignedPermissionCodes = [];
if (Array.isArray(role.permissions)) {
assignedPermissionCodes = role.permissions;
} else if (typeof role.permissions === 'string') {
try {
assignedPermissionCodes = JSON.parse(role.permissions);
} catch (e) {
assignedPermissionCodes = [];
}
}
// 标记已分配的权限
const markedPermissions = controller.markAssignedPermissionsByCode(permissionTree, assignedPermissionCodes);
res.json(responseFormat.success({
role: {
id: role.id,
name: role.name,
description: role.description,
status: role.status
},
assignedPermissions: assignedPermissionCodes,
allPermissions: markedPermissions,
assignedCount: assignedPermissionCodes.length,
totalCount: allPermissions.length
}, '获取角色权限详情成功'));
} catch (error) {
console.error('获取角色权限详情失败:', error);
res.status(500).json(responseFormat.error('获取角色权限详情失败'));
}
}
/**
* 批量分配角色权限
*/
async batchAssignPermissions(req, res) {
try {
const { roleId } = req.params;
const { permissionIds, operation = 'replace' } = req.body;
if (!Array.isArray(permissionIds)) {
return res.status(400).json(responseFormat.error('权限ID列表格式错误'));
}
const role = await Role.findByPk(roleId);
if (!role) {
return res.status(404).json(responseFormat.error('角色不存在'));
}
// 验证权限ID是否存在
const validPermissions = await Permission.findAll({
where: { id: { [Op.in]: permissionIds } },
attributes: ['id']
});
const validPermissionIds = validPermissions.map(p => p.id);
const invalidIds = permissionIds.filter(id => !validPermissionIds.includes(id));
if (invalidIds.length > 0) {
return res.status(400).json(responseFormat.error(`无效的权限ID: ${invalidIds.join(', ')}`));
}
// 根据操作类型处理权限分配
if (operation === 'replace') {
// 替换模式:删除现有权限,添加新权限
await RolePermission.destroy({ where: { role_id: roleId } });
if (permissionIds.length > 0) {
const rolePermissions = permissionIds.map(permissionId => ({
role_id: roleId,
permission_id: permissionId,
granted: true
}));
await RolePermission.bulkCreate(rolePermissions);
}
} else if (operation === 'add') {
// 添加模式:只添加新权限
const existingPermissions = await RolePermission.findAll({
where: { role_id: roleId },
attributes: ['permission_id']
});
const existingIds = existingPermissions.map(p => p.permission_id);
const newPermissionIds = permissionIds.filter(id => !existingIds.includes(id));
if (newPermissionIds.length > 0) {
const rolePermissions = newPermissionIds.map(permissionId => ({
role_id: roleId,
permission_id: permissionId,
granted: true
}));
await RolePermission.bulkCreate(rolePermissions);
}
} else if (operation === 'remove') {
// 移除模式:删除指定权限
await RolePermission.destroy({
where: {
role_id: roleId,
permission_id: { [Op.in]: permissionIds }
}
});
}
res.json(responseFormat.success(null, `${operation === 'replace' ? '替换' : operation === 'add' ? '添加' : '移除'}角色权限成功`));
} catch (error) {
console.error('批量分配角色权限失败:', error);
res.status(500).json(responseFormat.error('批量分配角色权限失败'));
}
}
/**
* 复制角色权限
*/
async copyRolePermissions(req, res) {
try {
const { sourceRoleId, targetRoleId } = req.body;
if (!sourceRoleId || !targetRoleId) {
return res.status(400).json(responseFormat.error('源角色ID和目标角色ID不能为空'));
}
if (sourceRoleId === targetRoleId) {
return res.status(400).json(responseFormat.error('源角色和目标角色不能相同'));
}
// 验证角色存在
const [sourceRole, targetRole] = await Promise.all([
Role.findByPk(sourceRoleId),
Role.findByPk(targetRoleId)
]);
if (!sourceRole) {
return res.status(404).json(responseFormat.error('源角色不存在'));
}
if (!targetRole) {
return res.status(404).json(responseFormat.error('目标角色不存在'));
}
// 获取源角色的权限
const sourcePermissions = await RolePermission.findAll({
where: { role_id: sourceRoleId },
attributes: ['permission_id']
});
// 删除目标角色现有权限
await RolePermission.destroy({ where: { role_id: targetRoleId } });
// 复制权限到目标角色
if (sourcePermissions.length > 0) {
const targetPermissions = sourcePermissions.map(p => ({
role_id: targetRoleId,
permission_id: p.permission_id,
granted: true
}));
await RolePermission.bulkCreate(targetPermissions);
}
res.json(responseFormat.success(null, `成功将 ${sourceRole.name} 的权限复制到 ${targetRole.name}`));
} catch (error) {
console.error('复制角色权限失败:', error);
res.status(500).json(responseFormat.error('复制角色权限失败'));
}
}
/**
* 检查用户权限
*/
async checkUserPermission(req, res) {
try {
const { userId, permissionCode } = req.params;
const user = await User.findByPk(userId, {
include: [
{
model: Role,
as: 'role',
include: [
{
model: Permission,
as: 'rolePermissions',
where: { code: permissionCode },
required: false,
through: {
attributes: ['granted']
}
}
]
}
]
});
if (!user) {
return res.status(404).json(responseFormat.error('用户不存在'));
}
const hasPermission = user.role &&
user.role.rolePermissions &&
user.role.rolePermissions.length > 0 &&
user.role.rolePermissions[0].RolePermission.granted;
res.json(responseFormat.success({
userId: user.id,
username: user.username,
roleName: user.role ? user.role.name : null,
permissionCode,
hasPermission,
checkTime: new Date()
}, '权限检查完成'));
} catch (error) {
console.error('检查用户权限失败:', error);
res.status(500).json(responseFormat.error('检查用户权限失败'));
}
}
/**
* 获取权限统计信息
*/
async getPermissionStats(req, res) {
try {
// 统计各种数据
const [
totalRoles,
totalPermissions,
moduleStats,
roles
] = await Promise.all([
Role.count(),
Permission.count(),
Permission.findAll({
attributes: [
'module',
[Permission.sequelize.fn('COUNT', Permission.sequelize.col('id')), 'count']
],
group: ['module'],
order: [['module', 'ASC']]
}),
Role.findAll({
attributes: ['id', 'name', 'permissions'],
order: [['name', 'ASC']]
})
]);
// 计算总分配数和角色权限分布
let totalAssignments = 0;
const roleDistribution = roles.map(role => {
let permissions = [];
if (Array.isArray(role.permissions)) {
permissions = role.permissions;
} else if (typeof role.permissions === 'string') {
try {
permissions = JSON.parse(role.permissions);
} catch (e) {
permissions = [];
}
}
const permissionCount = permissions.length;
totalAssignments += permissionCount;
return {
roleId: role.id,
roleName: role.name,
permissionCount
};
});
res.json(responseFormat.success({
overview: {
totalRoles,
totalPermissions,
totalAssignments,
averagePermissionsPerRole: totalRoles > 0 ? Math.round(totalAssignments / totalRoles) : 0
},
moduleDistribution: moduleStats.map(stat => ({
module: stat.module,
count: parseInt(stat.dataValues.count)
})),
roleDistribution
}, '获取权限统计成功'));
} catch (error) {
console.error('获取权限统计失败:', error);
res.status(500).json(responseFormat.error('获取权限统计失败'));
}
}
/**
* 构建权限树
*/
buildPermissionTree(permissions, parentId = null) {
const tree = [];
for (const permission of permissions) {
if (permission.parent_id === parentId) {
const children = this.buildPermissionTree(permissions, permission.id);
const node = {
...(permission.toJSON ? permission.toJSON() : permission),
children: children.length > 0 ? children : undefined
};
tree.push(node);
}
}
return tree;
}
/**
* 标记已分配的权限
*/
markAssignedPermissions(permissions, assignedIds) {
return permissions.map(permission => ({
...permission,
assigned: assignedIds.includes(permission.id),
children: permission.children ?
this.markAssignedPermissions(permission.children, assignedIds) :
undefined
}));
}
/**
* 根据权限代码标记已分配的权限
*/
markAssignedPermissionsByCode(permissions, assignedCodes) {
return permissions.map(permission => ({
...permission,
assigned: assignedCodes.includes(permission.code),
children: permission.children ?
this.markAssignedPermissionsByCode(permission.children, assignedCodes) :
undefined
}));
}
}
module.exports = new RolePermissionController();

View File

@@ -77,7 +77,7 @@ const getSystemLogs = async (req, res) => {
const { page = 1, limit = 50, level, start_date, end_date } = req.query;
const offset = (page - 1) * limit;
// 模拟日志数据
// 模拟日志数据 - 扩展更多有意义的日志记录
const mockLogs = [
{
id: 1,
@@ -96,9 +96,93 @@ const getSystemLogs = async (req, res) => {
{
id: 3,
level: 'warning',
message: 'Redis连接失败',
message: 'Redis连接失败,使用内存缓存',
timestamp: new Date(Date.now() - 1000 * 120).toISOString(),
user: 'system'
},
{
id: 4,
level: 'info',
message: '用户 admin 登录成功',
timestamp: new Date(Date.now() - 1000 * 180).toISOString(),
user: 'admin'
},
{
id: 5,
level: 'info',
message: '新增保险申请:车险申请 - 申请人:张三',
timestamp: new Date(Date.now() - 1000 * 240).toISOString(),
user: 'zhangsan'
},
{
id: 6,
level: 'info',
message: '保单生效:保单号 POL-2024-001 - 投保人:李四',
timestamp: new Date(Date.now() - 1000 * 300).toISOString(),
user: 'lisi'
},
{
id: 7,
level: 'warning',
message: '理赔申请待审核:理赔号 CLM-2024-001 - 申请人:王五',
timestamp: new Date(Date.now() - 1000 * 360).toISOString(),
user: 'wangwu'
},
{
id: 8,
level: 'info',
message: '新用户注册:用户名 zhaoliu',
timestamp: new Date(Date.now() - 1000 * 420).toISOString(),
user: 'system'
},
{
id: 9,
level: 'error',
message: '支付接口调用失败:订单号 ORD-2024-001',
timestamp: new Date(Date.now() - 1000 * 480).toISOString(),
user: 'system'
},
{
id: 10,
level: 'info',
message: '保险类型更新:新增意外险产品',
timestamp: new Date(Date.now() - 1000 * 540).toISOString(),
user: 'admin'
},
{
id: 11,
level: 'info',
message: '系统备份完成:数据库备份成功',
timestamp: new Date(Date.now() - 1000 * 600).toISOString(),
user: 'system'
},
{
id: 12,
level: 'warning',
message: '磁盘空间不足警告:剩余空间 15%',
timestamp: new Date(Date.now() - 1000 * 660).toISOString(),
user: 'system'
},
{
id: 13,
level: 'info',
message: '理赔审核通过:理赔号 CLM-2024-002 - 赔付金额 ¥5000',
timestamp: new Date(Date.now() - 1000 * 720).toISOString(),
user: 'admin'
},
{
id: 14,
level: 'info',
message: '保单续费成功:保单号 POL-2024-002 - 续费期限 1年',
timestamp: new Date(Date.now() - 1000 * 780).toISOString(),
user: 'system'
},
{
id: 15,
level: 'error',
message: '短信发送失败:手机号 138****8888',
timestamp: new Date(Date.now() - 1000 * 840).toISOString(),
user: 'system'
}
];
@@ -125,7 +209,7 @@ const getSystemLogs = async (req, res) => {
page: parseInt(page),
limit: parseInt(limit),
total: filteredLogs.length,
pages: Math.ceil(filteredLogs.length / limit)
pages: Math.ceil(filteredLogs.length / parseInt(limit))
}
}, '获取系统日志成功'));
} catch (error) {

View File

@@ -1,6 +1,7 @@
const { User, Role } = require('../models');
const { Op } = require('sequelize');
const responseFormat = require('../utils/response');
const crypto = require('crypto');
// 获取用户列表
const getUsers = async (req, res) => {
@@ -379,6 +380,112 @@ const uploadAvatar = async (req, res) => {
}
};
// 生成固定token
const generateFixedToken = async (req, res) => {
try {
const { id } = req.params;
const user = await User.findByPk(id);
if (!user) {
return res.status(404).json(responseFormat.error('用户不存在'));
}
// 生成32位随机token
const fixedToken = crypto.randomBytes(32).toString('hex');
// 更新用户的固定token
await user.update({ fixed_token: fixedToken });
res.json(responseFormat.success({
fixed_token: fixedToken,
user_id: user.id,
username: user.username
}, '固定Token生成成功'));
} catch (error) {
console.error('生成固定Token错误:', error);
if (error.name === 'SequelizeUniqueConstraintError') {
return res.status(400).json(responseFormat.error('Token生成失败请重试'));
}
res.status(500).json(responseFormat.error('生成固定Token失败'));
}
};
// 重新生成固定token
const regenerateFixedToken = async (req, res) => {
try {
const { id } = req.params;
const user = await User.findByPk(id);
if (!user) {
return res.status(404).json(responseFormat.error('用户不存在'));
}
// 生成新的32位随机token
const newFixedToken = crypto.randomBytes(32).toString('hex');
// 更新用户的固定token
await user.update({ fixed_token: newFixedToken });
res.json(responseFormat.success({
fixed_token: newFixedToken,
user_id: user.id,
username: user.username
}, '固定Token重新生成成功'));
} catch (error) {
console.error('重新生成固定Token错误:', error);
if (error.name === 'SequelizeUniqueConstraintError') {
return res.status(400).json(responseFormat.error('Token生成失败请重试'));
}
res.status(500).json(responseFormat.error('重新生成固定Token失败'));
}
};
// 删除固定token
const deleteFixedToken = async (req, res) => {
try {
const { id } = req.params;
const user = await User.findByPk(id);
if (!user) {
return res.status(404).json(responseFormat.error('用户不存在'));
}
// 清除用户的固定token
await user.update({ fixed_token: null });
res.json(responseFormat.success(null, '固定Token删除成功'));
} catch (error) {
console.error('删除固定Token错误:', error);
res.status(500).json(responseFormat.error('删除固定Token失败'));
}
};
// 获取用户的固定token信息
const getFixedTokenInfo = async (req, res) => {
try {
const { id } = req.params;
const user = await User.findByPk(id, {
attributes: ['id', 'username', 'fixed_token']
});
if (!user) {
return res.status(404).json(responseFormat.error('用户不存在'));
}
res.json(responseFormat.success({
userId: user.id,
username: user.username,
hasToken: !!user.fixed_token,
tokenPreview: user.fixed_token ? `${user.fixed_token.substring(0, 8)}...` : null,
createdAt: user.fixed_token ? new Date().toISOString() : null
}, '获取固定Token信息成功'));
} catch (error) {
console.error('获取固定Token信息错误:', error);
res.status(500).json(responseFormat.error('获取固定Token信息失败'));
}
};
module.exports = {
getUsers,
getUser,
@@ -389,5 +496,9 @@ module.exports = {
getProfile,
updateProfile,
changePassword,
uploadAvatar
uploadAvatar,
generateFixedToken,
regenerateFixedToken,
deleteFixedToken,
getFixedTokenInfo
};