保险前后端,养殖端和保险端小程序

This commit is contained in:
xuqiuyun
2025-09-17 19:01:52 +08:00
parent e4287b83fe
commit 473891163c
218 changed files with 109331 additions and 14103 deletions

View File

@@ -0,0 +1,234 @@
const jwt = require('jsonwebtoken');
const { User, Role, sequelize } = require('../models');
const { Op } = require('sequelize');
const responseFormat = require('../utils/response');
// 用户注册
const register = async (req, res) => {
try {
const { username, password, real_name, email, phone, role_id } = req.body;
// 检查用户名是否已存在
const existingUser = await User.findOne({ where: { username } });
if (existingUser) {
return res.status(400).json(responseFormat.error('用户名已存在'));
}
// 检查邮箱是否已存在
const existingEmail = await User.findOne({ where: { email } });
if (existingEmail) {
return res.status(400).json(responseFormat.error('邮箱已存在'));
}
// 检查手机号是否已存在
const existingPhone = await User.findOne({ where: { phone } });
if (existingPhone) {
return res.status(400).json(responseFormat.error('手机号已存在'));
}
// 检查角色是否存在
const role = await Role.findByPk(role_id);
if (!role) {
return res.status(400).json(responseFormat.error('角色不存在'));
}
// 创建用户
const user = await User.create({
username,
password,
real_name,
email,
phone,
role_id
});
res.status(201).json(responseFormat.created(user, '用户注册成功'));
} catch (error) {
console.error('注册错误:', error);
res.status(500).json(responseFormat.error('用户注册失败'));
}
};
// 用户登录
const login = async (req, res) => {
try {
const { username, password } = req.body;
if (!username || !password) {
return res.status(400).json(responseFormat.error('用户名和密码不能为空'));
}
// 查找用户(支持用户名、邮箱、手机号登录)
const user = await User.findOne({
where: {
[Op.or]: [
{ username },
{ email: username },
{ phone: username }
]
},
include: [{
model: Role,
as: 'role',
attributes: ['id', 'name', 'permissions']
}]
});
if (!user) {
return res.status(401).json(responseFormat.error('用户不存在'));
}
if (user.status !== 'active') {
return res.status(401).json(responseFormat.error('账户已被禁用'));
}
// 验证密码
const isValidPassword = await user.validatePassword(password);
if (!isValidPassword) {
return res.status(401).json(responseFormat.error('密码错误'));
}
// 更新最后登录时间
await user.update({ last_login: new Date() });
// 生成JWT令牌
const token = jwt.sign(
{
id: user.id,
username: user.username,
role_id: user.role_id,
permissions: user.role?.permissions || []
},
process.env.JWT_SECRET,
{ expiresIn: process.env.JWT_EXPIRE || '7d' }
);
res.json(responseFormat.success({
user: user.toJSON(),
token,
expires_in: 7 * 24 * 60 * 60 // 7天
}, '登录成功'));
} catch (error) {
console.error('登录错误:', error);
res.status(500).json(responseFormat.error('登录失败'));
}
};
// 获取当前用户信息
const getCurrentUser = async (req, res) => {
try {
const user = await User.findByPk(req.user.id, {
include: [{
model: Role,
as: 'role',
attributes: ['id', 'name', 'permissions']
}]
});
if (!user) {
return res.status(404).json(responseFormat.error('用户不存在'));
}
res.json(responseFormat.success(user, '获取用户信息成功'));
} catch (error) {
console.error('获取用户信息错误:', error);
res.status(500).json(responseFormat.error('获取用户信息失败'));
}
};
// 修改密码
const changePassword = async (req, res) => {
try {
const { currentPassword, newPassword } = req.body;
const userId = req.user.id;
if (!currentPassword || !newPassword) {
return res.status(400).json(responseFormat.error('当前密码和新密码不能为空'));
}
const user = await User.findByPk(userId);
if (!user) {
return res.status(404).json(responseFormat.error('用户不存在'));
}
// 验证当前密码
const isValidPassword = await user.validatePassword(currentPassword);
if (!isValidPassword) {
return res.status(401).json(responseFormat.error('当前密码错误'));
}
// 更新密码
await user.update({ password: newPassword });
res.json(responseFormat.success(null, '密码修改成功'));
} catch (error) {
console.error('修改密码错误:', error);
res.status(500).json(responseFormat.error('密码修改失败'));
}
};
// 刷新令牌
const refreshToken = async (req, res) => {
try {
const { refresh_token } = req.body;
if (!refresh_token) {
return res.status(400).json(responseFormat.error('刷新令牌不能为空'));
}
// 验证刷新令牌(这里简化处理,实际应该使用专门的刷新令牌机制)
const decoded = jwt.verify(refresh_token, process.env.JWT_SECRET);
const user = await User.findByPk(decoded.id, {
include: [{
model: Role,
as: 'role',
attributes: ['permissions']
}]
});
if (!user || user.status !== 'active') {
return res.status(401).json(responseFormat.error('用户不存在或已被禁用'));
}
// 生成新的访问令牌
const newToken = jwt.sign(
{
id: user.id,
username: user.username,
role_id: user.role_id,
permissions: user.role?.permissions || []
},
process.env.JWT_SECRET,
{ expiresIn: process.env.JWT_EXPIRE || '7d' }
);
res.json(responseFormat.success({
token: newToken,
expires_in: 7 * 24 * 60 * 60
}, '令牌刷新成功'));
} catch (error) {
console.error('刷新令牌错误:', error);
res.status(401).json(responseFormat.error('刷新令牌无效'));
}
};
// 用户登出
const logout = async (req, res) => {
try {
// 这里可以添加令牌黑名单逻辑
res.json(responseFormat.success(null, '登出成功'));
} catch (error) {
console.error('登出错误:', error);
res.status(500).json(responseFormat.error('登出失败'));
}
};
module.exports = {
register,
login,
getCurrentUser,
changePassword,
refreshToken,
logout
};

View File

@@ -0,0 +1,244 @@
const { Claim, Policy, User, InsuranceApplication, InsuranceType } = require('../models');
const responseFormat = require('../utils/response');
const { Op } = require('sequelize');
// 获取理赔列表
const getClaims = async (req, res) => {
try {
const {
claim_no,
customer_name,
claim_status,
dateRange,
page = 1,
limit = 10
} = req.query;
const whereClause = {};
// 理赔编号筛选
if (claim_no) {
whereClause.claim_no = { [Op.like]: `%${claim_no}%` };
}
// 理赔状态筛选
if (claim_status) {
whereClause.claim_status = claim_status;
}
// 日期范围筛选
if (dateRange && dateRange.start && dateRange.end) {
whereClause.claim_date = {
[Op.between]: [new Date(dateRange.start), new Date(dateRange.end)]
};
}
const offset = (page - 1) * limit;
const { count, rows } = await Claim.findAndCountAll({
where: whereClause,
include: [
{
model: Policy,
as: 'policy',
attributes: ['id', 'policy_no', 'coverage_amount'],
include: [
{
model: InsuranceApplication,
as: 'application',
attributes: ['id', 'customer_name'],
include: [
{
model: InsuranceType,
as: 'insurance_type',
attributes: ['id', 'name']
}
]
}
]
},
{
model: User,
as: 'customer',
attributes: ['id', 'real_name', 'username']
},
{
model: User,
as: 'reviewer',
attributes: ['id', 'real_name', 'username']
}
],
order: [['created_at', 'DESC']],
offset,
limit: parseInt(limit)
});
res.json(responseFormat.pagination(rows, {
page: parseInt(page),
limit: parseInt(limit),
total: count
}, '获取理赔列表成功'));
} catch (error) {
console.error('获取理赔列表错误:', error);
res.status(500).json(responseFormat.error('获取理赔列表失败'));
}
};
// 创建理赔申请
const createClaim = async (req, res) => {
try {
const claimData = req.body;
// 生成理赔编号
const claimNo = `CLM${Date.now()}${Math.random().toString(36).substr(2, 6).toUpperCase()}`;
const claim = await Claim.create({
...claimData,
claim_no: claimNo
});
res.status(201).json(responseFormat.created(claim, '理赔申请创建成功'));
} catch (error) {
console.error('创建理赔申请错误:', error);
res.status(500).json(responseFormat.error('创建理赔申请失败'));
}
};
// 获取单个理赔详情
const getClaimById = async (req, res) => {
try {
const { id } = req.params;
const claim = await Claim.findByPk(id, {
include: [
{
model: Policy,
as: 'policy',
include: [
{
model: InsuranceApplication,
as: 'application',
include: [
{
model: InsuranceType,
as: 'insurance_type',
attributes: ['id', 'name', 'description']
}
]
}
]
},
{
model: User,
as: 'customer',
attributes: ['id', 'real_name', 'username', 'phone', 'email']
},
{
model: User,
as: 'reviewer',
attributes: ['id', 'real_name', 'username']
}
]
});
if (!claim) {
return res.status(404).json(responseFormat.error('理赔申请不存在'));
}
res.json(responseFormat.success(claim, '获取理赔详情成功'));
} catch (error) {
console.error('获取理赔详情错误:', error);
res.status(500).json(responseFormat.error('获取理赔详情失败'));
}
};
// 审核理赔申请
const reviewClaim = async (req, res) => {
try {
const { id } = req.params;
const { claim_status, review_notes } = req.body;
const reviewerId = req.user.id;
const claim = await Claim.findByPk(id);
if (!claim) {
return res.status(404).json(responseFormat.error('理赔申请不存在'));
}
if (!['approved', 'rejected', 'processing', 'paid'].includes(claim_status)) {
return res.status(400).json(responseFormat.error('无效的理赔状态'));
}
await claim.update({
claim_status,
review_notes,
reviewer_id: reviewerId,
review_date: new Date()
});
res.json(responseFormat.success(claim, '理赔申请审核成功'));
} catch (error) {
console.error('审核理赔申请错误:', error);
res.status(500).json(responseFormat.error('审核理赔申请失败'));
}
};
// 更新理赔支付状态
const updateClaimPayment = async (req, res) => {
try {
const { id } = req.params;
const claim = await Claim.findByPk(id);
if (!claim) {
return res.status(404).json(responseFormat.error('理赔申请不存在'));
}
if (claim.claim_status !== 'approved') {
return res.status(400).json(responseFormat.error('只有已批准的理赔才能进行支付'));
}
await claim.update({
claim_status: 'paid',
payment_date: new Date()
});
res.json(responseFormat.success(claim, '理赔支付状态更新成功'));
} catch (error) {
console.error('更新理赔支付状态错误:', error);
res.status(500).json(responseFormat.error('更新理赔支付状态失败'));
}
};
// 获取理赔统计
const getClaimStats = async (req, res) => {
try {
const stats = await Claim.findAll({
attributes: [
'claim_status',
[Claim.sequelize.fn('COUNT', Claim.sequelize.col('id')), 'count'],
[Claim.sequelize.fn('SUM', Claim.sequelize.col('claim_amount')), 'total_amount']
],
group: ['claim_status']
});
const total = await Claim.count();
const totalAmount = await Claim.sum('claim_amount');
res.json(responseFormat.success({
stats,
total,
total_amount: totalAmount || 0
}, '获取理赔统计成功'));
} catch (error) {
console.error('获取理赔统计错误:', error);
res.status(500).json(responseFormat.error('获取理赔统计失败'));
}
};
module.exports = {
getClaims,
createClaim,
getClaimById,
reviewClaim,
updateClaimPayment,
getClaimStats
};

View File

@@ -0,0 +1,218 @@
const { InsuranceApplication, InsuranceType, User } = require('../models');
const responseFormat = require('../utils/response');
const { Op } = require('sequelize');
// 获取保险申请列表
const getApplications = async (req, res) => {
try {
const {
name,
status,
dateRange,
page = 1,
limit = 10
} = req.query;
const whereClause = {};
// 姓名筛选
if (name) {
whereClause.customer_name = { [Op.like]: `%${name}%` };
}
// 状态筛选
if (status) {
whereClause.status = status;
}
// 日期范围筛选
if (dateRange && dateRange.start && dateRange.end) {
whereClause.application_date = {
[Op.between]: [new Date(dateRange.start), new Date(dateRange.end)]
};
}
const offset = (page - 1) * limit;
const { count, rows } = await InsuranceApplication.findAndCountAll({
where: whereClause,
include: [
{
model: InsuranceType,
as: 'insurance_type',
attributes: ['id', 'name', 'description']
},
{
model: User,
as: 'reviewer',
attributes: ['id', 'real_name', 'username']
}
],
order: [['created_at', 'DESC']],
offset,
limit: parseInt(limit)
});
res.json(responseFormat.pagination(rows, {
page: parseInt(page),
limit: parseInt(limit),
total: count
}, '获取保险申请列表成功'));
} catch (error) {
console.error('获取保险申请列表错误:', error);
res.status(500).json(responseFormat.error('获取保险申请列表失败'));
}
};
// 创建保险申请
const createApplication = async (req, res) => {
try {
const applicationData = req.body;
// 生成申请编号
const applicationNo = `INS${Date.now()}${Math.random().toString(36).substr(2, 6).toUpperCase()}`;
const application = await InsuranceApplication.create({
...applicationData,
application_no: applicationNo
});
res.status(201).json(responseFormat.created(application, '保险申请创建成功'));
} catch (error) {
console.error('创建保险申请错误:', error);
res.status(500).json(responseFormat.error('创建保险申请失败'));
}
};
// 获取单个保险申请详情
const getApplicationById = async (req, res) => {
try {
const { id } = req.params;
const application = await InsuranceApplication.findByPk(id, {
include: [
{
model: InsuranceType,
as: 'insurance_type',
attributes: ['id', 'name', 'description']
},
{
model: User,
as: 'reviewer',
attributes: ['id', 'real_name', 'username']
}
]
});
if (!application) {
return res.status(404).json(responseFormat.error('保险申请不存在'));
}
res.json(responseFormat.success(application, '获取保险申请详情成功'));
} catch (error) {
console.error('获取保险申请详情错误:', error);
res.status(500).json(responseFormat.error('获取保险申请详情失败'));
}
};
// 更新保险申请
const updateApplication = async (req, res) => {
try {
const { id } = req.params;
const updateData = req.body;
const application = await InsuranceApplication.findByPk(id);
if (!application) {
return res.status(404).json(responseFormat.error('保险申请不存在'));
}
await application.update(updateData);
res.json(responseFormat.success(application, '保险申请更新成功'));
} catch (error) {
console.error('更新保险申请错误:', error);
res.status(500).json(responseFormat.error('更新保险申请失败'));
}
};
// 审核保险申请
const reviewApplication = async (req, res) => {
try {
const { id } = req.params;
const { status, review_notes } = req.body;
const reviewerId = req.user.id;
const application = await InsuranceApplication.findByPk(id);
if (!application) {
return res.status(404).json(responseFormat.error('保险申请不存在'));
}
if (!['approved', 'rejected', 'under_review'].includes(status)) {
return res.status(400).json(responseFormat.error('无效的审核状态'));
}
await application.update({
status,
review_notes,
reviewer_id: reviewerId,
review_date: new Date()
});
res.json(responseFormat.success(application, '保险申请审核成功'));
} catch (error) {
console.error('审核保险申请错误:', error);
res.status(500).json(responseFormat.error('审核保险申请失败'));
}
};
// 删除保险申请
const deleteApplication = async (req, res) => {
try {
const { id } = req.params;
const application = await InsuranceApplication.findByPk(id);
if (!application) {
return res.status(404).json(responseFormat.error('保险申请不存在'));
}
await application.destroy();
res.json(responseFormat.success(null, '保险申请删除成功'));
} catch (error) {
console.error('删除保险申请错误:', error);
res.status(500).json(responseFormat.error('删除保险申请失败'));
}
};
// 获取保险申请统计
const getApplicationStats = async (req, res) => {
try {
const stats = await InsuranceApplication.findAll({
attributes: [
'status',
[InsuranceApplication.sequelize.fn('COUNT', InsuranceApplication.sequelize.col('id')), 'count']
],
group: ['status']
});
const total = await InsuranceApplication.count();
res.json(responseFormat.success({
stats,
total
}, '获取保险申请统计成功'));
} catch (error) {
console.error('获取保险申请统计错误:', error);
res.status(500).json(responseFormat.error('获取保险申请统计失败'));
}
};
module.exports = {
getApplications,
createApplication,
getApplicationById,
updateApplication,
reviewApplication,
deleteApplication,
getApplicationStats
};

View File

@@ -0,0 +1,199 @@
const { InsuranceType } = require('../models');
const responseFormat = require('../utils/response');
// 获取保险类型列表
const getInsuranceTypes = async (req, res) => {
try {
const { page = 1, pageSize = 10, name, status } = req.query;
const offset = (page - 1) * pageSize;
const whereClause = {};
if (name) {
whereClause.name = { [Op.like]: `%${name}%` };
}
if (status) {
whereClause.status = status;
}
const { count, rows } = await InsuranceType.findAndCountAll({
where: whereClause,
limit: parseInt(pageSize),
offset: offset,
order: [['created_at', 'DESC']]
});
res.json(responseFormat.success({
list: rows,
total: count,
page: parseInt(page),
pageSize: parseInt(pageSize),
pages: Math.ceil(count / pageSize)
}, '获取保险类型列表成功'));
} catch (error) {
console.error('获取保险类型列表错误:', error);
res.status(500).json(responseFormat.error('获取保险类型列表失败'));
}
};
// 获取单个保险类型详情
const getInsuranceTypeById = async (req, res) => {
try {
const { id } = req.params;
const insuranceType = await InsuranceType.findByPk(id);
if (!insuranceType) {
return res.status(404).json(responseFormat.error('保险类型不存在'));
}
res.json(responseFormat.success(insuranceType, '获取保险类型详情成功'));
} catch (error) {
console.error('获取保险类型详情错误:', error);
res.status(500).json(responseFormat.error('获取保险类型详情失败'));
}
};
// 创建保险类型
const createInsuranceType = async (req, res) => {
try {
const {
name,
code,
description,
coverage_amount_min,
coverage_amount_max,
premium_rate,
status = 'active'
} = req.body;
// 检查名称是否已存在
const existingType = await InsuranceType.findOne({ where: { name } });
if (existingType) {
return res.status(400).json(responseFormat.error('保险类型名称已存在'));
}
// 检查代码是否已存在
const existingCode = await InsuranceType.findOne({ where: { code } });
if (existingCode) {
return res.status(400).json(responseFormat.error('保险类型代码已存在'));
}
const insuranceType = await InsuranceType.create({
name,
code,
description,
coverage_amount_min,
coverage_amount_max,
premium_rate,
status
});
res.status(201).json(responseFormat.success(insuranceType, '创建保险类型成功'));
} catch (error) {
console.error('创建保险类型错误:', error);
res.status(500).json(responseFormat.error('创建保险类型失败'));
}
};
// 更新保险类型
const updateInsuranceType = async (req, res) => {
try {
const { id } = req.params;
const {
name,
code,
description,
coverage_amount_min,
coverage_amount_max,
premium_rate,
status
} = req.body;
const insuranceType = await InsuranceType.findByPk(id);
if (!insuranceType) {
return res.status(404).json(responseFormat.error('保险类型不存在'));
}
// 检查名称是否已被其他类型使用
if (name && name !== insuranceType.name) {
const existingType = await InsuranceType.findOne({ where: { name } });
if (existingType) {
return res.status(400).json(responseFormat.error('保险类型名称已存在'));
}
}
// 检查代码是否已被其他类型使用
if (code && code !== insuranceType.code) {
const existingCode = await InsuranceType.findOne({ where: { code } });
if (existingCode) {
return res.status(400).json(responseFormat.error('保险类型代码已存在'));
}
}
await insuranceType.update({
name: name || insuranceType.name,
code: code || insuranceType.code,
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,
status: status || insuranceType.status
});
res.json(responseFormat.success(insuranceType, '更新保险类型成功'));
} catch (error) {
console.error('更新保险类型错误:', error);
res.status(500).json(responseFormat.error('更新保险类型失败'));
}
};
// 删除保险类型
const deleteInsuranceType = async (req, res) => {
try {
const { id } = req.params;
const insuranceType = await InsuranceType.findByPk(id);
if (!insuranceType) {
return res.status(404).json(responseFormat.error('保险类型不存在'));
}
// 检查是否有相关的保险申请或保单
const hasApplications = await insuranceType.countInsuranceApplications();
if (hasApplications > 0) {
return res.status(400).json(responseFormat.error('该保险类型下存在保险申请,无法删除'));
}
await insuranceType.destroy();
res.json(responseFormat.success(null, '删除保险类型成功'));
} catch (error) {
console.error('删除保险类型错误:', error);
res.status(500).json(responseFormat.error('删除保险类型失败'));
}
};
// 更新保险类型状态
const updateInsuranceTypeStatus = async (req, res) => {
try {
const { id } = req.params;
const { status } = req.body;
const insuranceType = await InsuranceType.findByPk(id);
if (!insuranceType) {
return res.status(404).json(responseFormat.error('保险类型不存在'));
}
await insuranceType.update({ status });
res.json(responseFormat.success(insuranceType, '更新保险类型状态成功'));
} catch (error) {
console.error('更新保险类型状态错误:', error);
res.status(500).json(responseFormat.error('更新保险类型状态失败'));
}
};
module.exports = {
getInsuranceTypes,
getInsuranceTypeById,
createInsuranceType,
updateInsuranceType,
deleteInsuranceType,
updateInsuranceTypeStatus
};

View File

@@ -0,0 +1,210 @@
const { Policy, InsuranceApplication, InsuranceType, User } = require('../models');
const responseFormat = require('../utils/response');
const { Op } = require('sequelize');
// 获取保单列表
const getPolicies = async (req, res) => {
try {
const {
policy_no,
customer_name,
policy_status,
payment_status,
page = 1,
limit = 10
} = req.query;
const whereClause = {};
// 保单编号筛选
if (policy_no) {
whereClause.policy_no = { [Op.like]: `%${policy_no}%` };
}
// 保单状态筛选
if (policy_status) {
whereClause.policy_status = policy_status;
}
// 支付状态筛选
if (payment_status) {
whereClause.payment_status = payment_status;
}
const offset = (page - 1) * limit;
const { count, rows } = await Policy.findAndCountAll({
where: whereClause,
include: [
{
model: InsuranceApplication,
as: 'application',
attributes: ['id', 'customer_name', 'customer_phone'],
include: [
{
model: InsuranceType,
as: 'insurance_type',
attributes: ['id', 'name']
}
]
},
{
model: User,
as: 'customer',
attributes: ['id', 'real_name', 'username']
}
],
order: [['created_at', 'DESC']],
offset,
limit: parseInt(limit)
});
res.json(responseFormat.pagination(rows, {
page: parseInt(page),
limit: parseInt(limit),
total: count
}, '获取保单列表成功'));
} catch (error) {
console.error('获取保单列表错误:', error);
res.status(500).json(responseFormat.error('获取保单列表失败'));
}
};
// 创建保单
const createPolicy = async (req, res) => {
try {
const policyData = req.body;
// 生成保单编号
const policyNo = `POL${Date.now()}${Math.random().toString(36).substr(2, 6).toUpperCase()}`;
const policy = await Policy.create({
...policyData,
policy_no: policyNo
});
res.status(201).json(responseFormat.created(policy, '保单创建成功'));
} catch (error) {
console.error('创建保单错误:', error);
res.status(500).json(responseFormat.error('创建保单失败'));
}
};
// 获取单个保单详情
const getPolicyById = async (req, res) => {
try {
const { id } = req.params;
const policy = await Policy.findByPk(id, {
include: [
{
model: InsuranceApplication,
as: 'application',
include: [
{
model: InsuranceType,
as: 'insurance_type',
attributes: ['id', 'name', 'description', 'premium_rate']
}
]
},
{
model: User,
as: 'customer',
attributes: ['id', 'real_name', 'username', 'phone', 'email']
}
]
});
if (!policy) {
return res.status(404).json(responseFormat.error('保单不存在'));
}
res.json(responseFormat.success(policy, '获取保单详情成功'));
} catch (error) {
console.error('获取保单详情错误:', error);
res.status(500).json(responseFormat.error('获取保单详情失败'));
}
};
// 更新保单
const updatePolicy = async (req, res) => {
try {
const { id } = req.params;
const updateData = req.body;
const policy = await Policy.findByPk(id);
if (!policy) {
return res.status(404).json(responseFormat.error('保单不存在'));
}
await policy.update(updateData);
res.json(responseFormat.success(policy, '保单更新成功'));
} catch (error) {
console.error('更新保单错误:', error);
res.status(500).json(responseFormat.error('更新保单失败'));
}
};
// 更新保单状态
const updatePolicyStatus = async (req, res) => {
try {
const { id } = req.params;
const { policy_status } = req.body;
const policy = await Policy.findByPk(id);
if (!policy) {
return res.status(404).json(responseFormat.error('保单不存在'));
}
if (!['active', 'expired', 'cancelled', 'suspended'].includes(policy_status)) {
return res.status(400).json(responseFormat.error('无效的保单状态'));
}
await policy.update({ policy_status });
res.json(responseFormat.success(policy, '保单状态更新成功'));
} catch (error) {
console.error('更新保单状态错误:', error);
res.status(500).json(responseFormat.error('更新保单状态失败'));
}
};
// 获取保单统计
const getPolicyStats = async (req, res) => {
try {
const stats = await Policy.findAll({
attributes: [
'policy_status',
[Policy.sequelize.fn('COUNT', Policy.sequelize.col('id')), 'count'],
[Policy.sequelize.fn('SUM', Policy.sequelize.col('coverage_amount')), 'total_coverage'],
[Policy.sequelize.fn('SUM', Policy.sequelize.col('premium_amount')), 'total_premium']
],
group: ['policy_status']
});
const total = await Policy.count();
const totalCoverage = await Policy.sum('coverage_amount');
const totalPremium = await Policy.sum('premium_amount');
res.json(responseFormat.success({
stats,
total,
total_coverage: totalCoverage || 0,
total_premium: totalPremium || 0
}, '获取保单统计成功'));
} catch (error) {
console.error('获取保单统计错误:', error);
res.status(500).json(responseFormat.error('获取保单统计失败'));
}
};
module.exports = {
getPolicies,
createPolicy,
getPolicyById,
updatePolicy,
updatePolicyStatus,
getPolicyStats
};

View File

@@ -0,0 +1,232 @@
const { User, Role, InsuranceApplication, Policy, Claim } = require('../models');
const responseFormat = require('../utils/response');
const { Op } = require('sequelize');
// 获取系统统计信息
const getSystemStats = async (req, res) => {
try {
const [
totalUsers,
totalRoles,
totalApplications,
totalPolicies,
totalClaims,
activeUsers,
pendingApplications,
approvedApplications,
activePolicies,
pendingClaims,
approvedClaims
] = await Promise.all([
User.count(),
Role.count(),
InsuranceApplication.count(),
Policy.count(),
Claim.count(),
User.count({ where: { status: 'active' } }),
InsuranceApplication.count({ where: { status: 'pending' } }),
InsuranceApplication.count({ where: { status: 'approved' } }),
Policy.count({ where: { policy_status: 'active' } }),
Claim.count({ where: { claim_status: 'pending' } }),
Claim.count({ where: { claim_status: 'approved' } })
]);
// 获取最近7天的数据趋势
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
const recentStats = await Promise.all([
User.count({ where: { created_at: { [Op.gte]: sevenDaysAgo } } }),
InsuranceApplication.count({ where: { created_at: { [Op.gte]: sevenDaysAgo } } }),
Policy.count({ where: { created_at: { [Op.gte]: sevenDaysAgo } } }),
Claim.count({ where: { created_at: { [Op.gte]: sevenDaysAgo } } })
]);
res.json(responseFormat.success({
overview: {
users: totalUsers,
roles: totalRoles,
applications: totalApplications,
policies: totalPolicies,
claims: totalClaims
},
status: {
active_users: activeUsers,
pending_applications: pendingApplications,
approved_applications: approvedApplications,
active_policies: activePolicies,
pending_claims: pendingClaims,
approved_claims: approvedClaims
},
recent: {
new_users: recentStats[0],
new_applications: recentStats[1],
new_policies: recentStats[2],
new_claims: recentStats[3]
}
}, '获取系统统计信息成功'));
} catch (error) {
console.error('获取系统统计信息错误:', error);
res.status(500).json(responseFormat.error('获取系统统计信息失败'));
}
};
// 获取系统日志(模拟)
const getSystemLogs = async (req, res) => {
try {
const { page = 1, limit = 50, level, start_date, end_date } = req.query;
const offset = (page - 1) * limit;
// 模拟日志数据
const mockLogs = [
{
id: 1,
level: 'info',
message: '系统启动成功',
timestamp: new Date().toISOString(),
user: 'system'
},
{
id: 2,
level: 'info',
message: '数据库连接成功',
timestamp: new Date(Date.now() - 1000 * 60).toISOString(),
user: 'system'
},
{
id: 3,
level: 'warning',
message: 'Redis连接失败',
timestamp: new Date(Date.now() - 1000 * 120).toISOString(),
user: 'system'
}
];
// 简单的过滤逻辑
let filteredLogs = mockLogs;
if (level) {
filteredLogs = filteredLogs.filter(log => log.level === level);
}
if (start_date) {
const startDate = new Date(start_date);
filteredLogs = filteredLogs.filter(log => new Date(log.timestamp) >= startDate);
}
if (end_date) {
const endDate = new Date(end_date);
filteredLogs = filteredLogs.filter(log => new Date(log.timestamp) <= endDate);
}
// 分页
const paginatedLogs = filteredLogs.slice(offset, offset + parseInt(limit));
res.json(responseFormat.success({
logs: paginatedLogs,
pagination: {
page: parseInt(page),
limit: parseInt(limit),
total: filteredLogs.length,
pages: Math.ceil(filteredLogs.length / limit)
}
}, '获取系统日志成功'));
} catch (error) {
console.error('获取系统日志错误:', error);
res.status(500).json(responseFormat.error('获取系统日志失败'));
}
};
// 获取系统配置(模拟)
const getSystemConfig = async (req, res) => {
try {
const config = {
site_name: '保险端口管理系统',
version: '1.0.0',
environment: process.env.NODE_ENV || 'development',
max_file_size: '10MB',
allowed_file_types: ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx'],
session_timeout: 3600,
backup_enabled: true,
backup_schedule: '0 2 * * *', // 每天凌晨2点
email_notifications: true,
sms_notifications: false,
maintenance_mode: false
};
res.json(responseFormat.success(config, '获取系统配置成功'));
} catch (error) {
console.error('获取系统配置错误:', error);
res.status(500).json(responseFormat.error('获取系统配置失败'));
}
};
// 更新系统配置(模拟)
const updateSystemConfig = async (req, res) => {
try {
const { maintenance_mode, email_notifications, sms_notifications } = req.body;
// 模拟更新配置
const updatedConfig = {
maintenance_mode: maintenance_mode !== undefined ? maintenance_mode : false,
email_notifications: email_notifications !== undefined ? email_notifications : true,
sms_notifications: sms_notifications !== undefined ? sms_notifications : false,
updated_at: new Date().toISOString()
};
res.json(responseFormat.success(updatedConfig, '系统配置更新成功'));
} catch (error) {
console.error('更新系统配置错误:', error);
res.status(500).json(responseFormat.error('更新系统配置失败'));
}
};
// 备份数据库(模拟)
const backupDatabase = async (req, res) => {
try {
// 模拟备份过程
const backupInfo = {
id: `backup_${Date.now()}`,
filename: `backup_${new Date().toISOString().replace(/:/g, '-')}.sql`,
size: '2.5MB',
status: 'completed',
created_at: new Date().toISOString(),
download_url: '/api/system/backup/download/backup.sql'
};
res.json(responseFormat.success(backupInfo, '数据库备份成功'));
} catch (error) {
console.error('数据库备份错误:', error);
res.status(500).json(responseFormat.error('数据库备份失败'));
}
};
// 恢复数据库(模拟)
const restoreDatabase = async (req, res) => {
try {
const { backup_id } = req.body;
if (!backup_id) {
return res.status(400).json(responseFormat.error('备份ID不能为空'));
}
// 模拟恢复过程
const restoreInfo = {
backup_id,
status: 'completed',
restored_at: new Date().toISOString(),
message: '数据库恢复成功'
};
res.json(responseFormat.success(restoreInfo, '数据库恢复成功'));
} catch (error) {
console.error('数据库恢复错误:', error);
res.status(500).json(responseFormat.error('数据库恢复失败'));
}
};
module.exports = {
getSystemStats,
getSystemLogs,
getSystemConfig,
updateSystemConfig,
backupDatabase,
restoreDatabase
};

View File

@@ -0,0 +1,232 @@
const { User, Role } = require('../models');
const responseFormat = require('../utils/response');
// 获取用户列表
const getUsers = async (req, res) => {
try {
const { page = 1, limit = 10, search, role_id, status } = req.query;
const offset = (page - 1) * limit;
const whereClause = {};
if (search) {
whereClause[Op.or] = [
{ username: { [Op.like]: `%${search}%` } },
{ real_name: { [Op.like]: `%${search}%` } },
{ email: { [Op.like]: `%${search}%` } },
{ phone: { [Op.like]: `%${search}%` } }
];
}
if (role_id) whereClause.role_id = role_id;
if (status) whereClause.status = status;
const { count, rows: users } = await User.findAndCountAll({
where: whereClause,
include: [{
model: Role,
as: 'role',
attributes: ['id', 'name']
}],
attributes: { exclude: ['password'] },
limit: parseInt(limit),
offset: parseInt(offset),
order: [['created_at', 'DESC']]
});
res.json(responseFormat.success({
users,
pagination: {
page: parseInt(page),
limit: parseInt(limit),
total: count,
pages: Math.ceil(count / limit)
}
}, '获取用户列表成功'));
} catch (error) {
console.error('获取用户列表错误:', error);
res.status(500).json(responseFormat.error('获取用户列表失败'));
}
};
// 获取单个用户信息
const getUser = async (req, res) => {
try {
const { id } = req.params;
const user = await User.findByPk(id, {
include: [{
model: Role,
as: 'role',
attributes: ['id', 'name', 'permissions']
}],
attributes: { exclude: ['password'] }
});
if (!user) {
return res.status(404).json(responseFormat.error('用户不存在'));
}
res.json(responseFormat.success(user, '获取用户信息成功'));
} catch (error) {
console.error('获取用户信息错误:', error);
res.status(500).json(responseFormat.error('获取用户信息失败'));
}
};
// 创建用户
const createUser = async (req, res) => {
try {
const { username, password, real_name, email, phone, role_id, status = 'active' } = req.body;
// 检查用户名是否已存在
const existingUser = await User.findOne({ where: { username } });
if (existingUser) {
return res.status(400).json(responseFormat.error('用户名已存在'));
}
// 检查邮箱是否已存在
const existingEmail = await User.findOne({ where: { email } });
if (existingEmail) {
return res.status(400).json(responseFormat.error('邮箱已存在'));
}
// 检查手机号是否已存在
const existingPhone = await User.findOne({ where: { phone } });
if (existingPhone) {
return res.status(400).json(responseFormat.error('手机号已存在'));
}
// 检查角色是否存在
const role = await Role.findByPk(role_id);
if (!role) {
return res.status(400).json(responseFormat.error('角色不存在'));
}
// 创建用户
const user = await User.create({
username,
password,
real_name,
email,
phone,
role_id,
status
});
res.status(201).json(responseFormat.created(user, '用户创建成功'));
} catch (error) {
console.error('创建用户错误:', error);
res.status(500).json(responseFormat.error('创建用户失败'));
}
};
// 更新用户信息
const updateUser = async (req, res) => {
try {
const { id } = req.params;
const { real_name, email, phone, role_id } = req.body;
const user = await User.findByPk(id);
if (!user) {
return res.status(404).json(responseFormat.error('用户不存在'));
}
// 检查邮箱是否已被其他用户使用
if (email && email !== user.email) {
const existingEmail = await User.findOne({ where: { email } });
if (existingEmail) {
return res.status(400).json(responseFormat.error('邮箱已被其他用户使用'));
}
}
// 检查手机号是否已被其他用户使用
if (phone && phone !== user.phone) {
const existingPhone = await User.findOne({ where: { phone } });
if (existingPhone) {
return res.status(400).json(responseFormat.error('手机号已被其他用户使用'));
}
}
// 检查角色是否存在
if (role_id) {
const role = await Role.findByPk(role_id);
if (!role) {
return res.status(400).json(responseFormat.error('角色不存在'));
}
}
// 更新用户信息
await user.update({
real_name: real_name || user.real_name,
email: email || user.email,
phone: phone || user.phone,
role_id: role_id || user.role_id
});
res.json(responseFormat.success(user, '用户信息更新成功'));
} catch (error) {
console.error('更新用户信息错误:', error);
res.status(500).json(responseFormat.error('更新用户信息失败'));
}
};
// 删除用户
const deleteUser = async (req, res) => {
try {
const { id } = req.params;
const user = await User.findByPk(id);
if (!user) {
return res.status(404).json(responseFormat.error('用户不存在'));
}
// 不能删除自己
if (user.id === req.user.id) {
return res.status(400).json(responseFormat.error('不能删除自己的账户'));
}
await user.destroy();
res.json(responseFormat.success(null, '用户删除成功'));
} catch (error) {
console.error('删除用户错误:', error);
res.status(500).json(responseFormat.error('删除用户失败'));
}
};
// 更新用户状态
const updateUserStatus = async (req, res) => {
try {
const { id } = req.params;
const { status } = req.body;
if (!['active', 'inactive', 'suspended'].includes(status)) {
return res.status(400).json(responseFormat.error('状态值无效'));
}
const user = await User.findByPk(id);
if (!user) {
return res.status(404).json(responseFormat.error('用户不存在'));
}
// 不能禁用自己
if (user.id === req.user.id && status !== 'active') {
return res.status(400).json(responseFormat.error('不能禁用自己的账户'));
}
await user.update({ status });
res.json(responseFormat.success(user, '用户状态更新成功'));
} catch (error) {
console.error('更新用户状态错误:', error);
res.status(500).json(responseFormat.error('更新用户状态失败'));
}
};
module.exports = {
getUsers,
getUser,
createUser,
updateUser,
deleteUser,
updateUserStatus
};