保险前后端,养殖端和保险端小程序
This commit is contained in:
234
insurance_backend/controllers/authController.js
Normal file
234
insurance_backend/controllers/authController.js
Normal 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
|
||||
};
|
||||
244
insurance_backend/controllers/claimController.js
Normal file
244
insurance_backend/controllers/claimController.js
Normal 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
|
||||
};
|
||||
218
insurance_backend/controllers/insuranceController.js
Normal file
218
insurance_backend/controllers/insuranceController.js
Normal 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
|
||||
};
|
||||
199
insurance_backend/controllers/insuranceTypeController.js
Normal file
199
insurance_backend/controllers/insuranceTypeController.js
Normal 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
|
||||
};
|
||||
210
insurance_backend/controllers/policyController.js
Normal file
210
insurance_backend/controllers/policyController.js
Normal 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
|
||||
};
|
||||
232
insurance_backend/controllers/systemController.js
Normal file
232
insurance_backend/controllers/systemController.js
Normal 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
|
||||
};
|
||||
232
insurance_backend/controllers/userController.js
Normal file
232
insurance_backend/controllers/userController.js
Normal 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
|
||||
};
|
||||
Reference in New Issue
Block a user