fix: 修复奖品图片和赞助商logo删除bug
- 修复编辑奖品时删除图片后保存,图片仍存在的问题 - 修复编辑赞助商时删除logo后保存,logo仍存在的问题 - 前端添加删除检测逻辑,传递removeImage/removeLogo标记 - 后端处理删除标记,将对应字段设为null
This commit is contained in:
+148
-6
@@ -3,6 +3,7 @@ const router = express.Router();
|
||||
const bcrypt = require('bcryptjs');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const auth = require('../middleware/auth');
|
||||
const authSuper = require('../middleware/authSuper');
|
||||
const { upload, getFileUrls } = require('../middleware/upload');
|
||||
const { Admin, Activity, Registration, Expense, Photo, Sponsor, Prize } = require('../models');
|
||||
const fs = require('fs');
|
||||
@@ -17,7 +18,132 @@ router.post('/login', async (req, res) => {
|
||||
return res.status(401).json({ error: '用户名或密码错误' });
|
||||
}
|
||||
const token = jwt.sign({ id: admin.id }, process.env.JWT_SECRET, { expiresIn: '7d' });
|
||||
res.json({ token, admin: { id: admin.id, username: admin.username, name: admin.name } });
|
||||
res.json({
|
||||
token,
|
||||
admin: {
|
||||
id: admin.id,
|
||||
username: admin.username,
|
||||
name: admin.name,
|
||||
role: admin.role
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// ========== 管理员管理API(仅超级管理员) ==========
|
||||
|
||||
// 获取管理员列表
|
||||
router.get('/admins', authSuper, async (req, res) => {
|
||||
try {
|
||||
const admins = await Admin.findAll({
|
||||
attributes: ['id', 'username', 'name', 'role', 'createdAt'],
|
||||
order: [['createdAt', 'ASC']],
|
||||
raw: true
|
||||
});
|
||||
res.json(admins);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 创建管理员
|
||||
router.post('/admins', authSuper, async (req, res) => {
|
||||
try {
|
||||
const { username, password, name, role } = req.body;
|
||||
|
||||
if (!username || !password) {
|
||||
return res.status(400).json({ error: '用户名和密码不能为空' });
|
||||
}
|
||||
|
||||
const existing = await Admin.findOne({ where: { username } });
|
||||
if (existing) {
|
||||
return res.status(400).json({ error: '用户名已存在' });
|
||||
}
|
||||
|
||||
const hashedPassword = bcrypt.hashSync(password, 10);
|
||||
const admin = await Admin.create({
|
||||
username,
|
||||
password: hashedPassword,
|
||||
name: name || username,
|
||||
role: role || 'admin'
|
||||
});
|
||||
|
||||
res.json({
|
||||
id: admin.id,
|
||||
username: admin.username,
|
||||
name: admin.name,
|
||||
role: admin.role
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 修改管理员信息
|
||||
router.put('/admins/:id', authSuper, async (req, res) => {
|
||||
try {
|
||||
const { name, role } = req.body;
|
||||
const admin = await Admin.findByPk(req.params.id);
|
||||
|
||||
if (!admin) {
|
||||
return res.status(404).json({ error: '管理员不存在' });
|
||||
}
|
||||
|
||||
const updateData = {};
|
||||
if (name !== undefined) updateData.name = name;
|
||||
if (role !== undefined) updateData.role = role;
|
||||
|
||||
await Admin.update(updateData, { where: { id: req.params.id } });
|
||||
const updated = await Admin.findByPk(req.params.id, {
|
||||
attributes: ['id', 'username', 'name', 'role']
|
||||
});
|
||||
|
||||
res.json(updated);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 修改管理员密码
|
||||
router.put('/admins/:id/password', authSuper, async (req, res) => {
|
||||
try {
|
||||
const { newPassword } = req.body;
|
||||
|
||||
if (!newPassword) {
|
||||
return res.status(400).json({ error: '新密码不能为空' });
|
||||
}
|
||||
|
||||
const admin = await Admin.findByPk(req.params.id);
|
||||
if (!admin) {
|
||||
return res.status(404).json({ error: '管理员不存在' });
|
||||
}
|
||||
|
||||
const hashedPassword = bcrypt.hashSync(newPassword, 10);
|
||||
await Admin.update({ password: hashedPassword }, { where: { id: req.params.id } });
|
||||
|
||||
res.json({ message: '密码修改成功' });
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 删除管理员
|
||||
router.delete('/admins/:id', authSuper, async (req, res) => {
|
||||
try {
|
||||
const admin = await Admin.findByPk(req.params.id);
|
||||
if (!admin) {
|
||||
return res.status(404).json({ error: '管理员不存在' });
|
||||
}
|
||||
|
||||
// 防止删除超级管理员
|
||||
if (admin.role === 'super') {
|
||||
return res.status(403).json({ error: '不能删除超级管理员' });
|
||||
}
|
||||
|
||||
await Admin.destroy({ where: { id: req.params.id } });
|
||||
res.json({ message: '删除成功' });
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
@@ -93,6 +219,16 @@ router.get('/registrations', auth, async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// 删除报名
|
||||
router.delete('/registrations/:id', auth, async (req, res) => {
|
||||
try {
|
||||
await Registration.destroy({ where: { id: req.params.id } });
|
||||
res.json({ message: '删除成功' });
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 上传经费明细
|
||||
router.post('/expenses', auth, upload.array('media', 5), async (req, res) => {
|
||||
try {
|
||||
@@ -274,7 +410,7 @@ router.post('/sponsors', auth, upload.single('logo'), async (req, res) => {
|
||||
// 更新赞助商
|
||||
router.put('/sponsors/:id', auth, upload.single('logo'), async (req, res) => {
|
||||
try {
|
||||
const { name, type, link, sortOrder } = req.body;
|
||||
const { name, type, link, sortOrder, removeLogo } = req.body;
|
||||
const updateData = { name, type, link };
|
||||
|
||||
if (sortOrder !== undefined) {
|
||||
@@ -284,6 +420,8 @@ router.put('/sponsors/:id', auth, upload.single('logo'), async (req, res) => {
|
||||
if (req.file) {
|
||||
const [uploaded] = getFileUrls(req.file);
|
||||
updateData.logo = uploaded.url;
|
||||
} else if (removeLogo === 'true') {
|
||||
updateData.logo = null;
|
||||
}
|
||||
|
||||
await Sponsor.update(updateData, { where: { id: req.params.id } });
|
||||
@@ -307,7 +445,7 @@ router.delete('/sponsors/:id', auth, async (req, res) => {
|
||||
// 添加奖品
|
||||
router.post('/prizes', auth, upload.single('image'), async (req, res) => {
|
||||
try {
|
||||
const { activityId, name, level, description, quantity, sortOrder } = req.body;
|
||||
const { activityId, name, level, description, quantity, sortOrder, source, sponsor } = req.body;
|
||||
let image = null;
|
||||
if (req.file) {
|
||||
const [uploaded] = getFileUrls([req.file]);
|
||||
@@ -320,7 +458,9 @@ router.post('/prizes', auth, upload.single('image'), async (req, res) => {
|
||||
description,
|
||||
image,
|
||||
quantity: quantity || 1,
|
||||
sortOrder: sortOrder || 0
|
||||
sortOrder: sortOrder || 0,
|
||||
source: source || 'purchase',
|
||||
sponsor: sponsor || null
|
||||
});
|
||||
res.json(prize);
|
||||
} catch (error) {
|
||||
@@ -331,12 +471,14 @@ router.post('/prizes', auth, upload.single('image'), async (req, res) => {
|
||||
// 更新奖品
|
||||
router.put('/prizes/:id', auth, upload.single('image'), async (req, res) => {
|
||||
try {
|
||||
const { name, level, description, quantity, sortOrder } = req.body;
|
||||
const updateData = { name, level, description, quantity, sortOrder };
|
||||
const { name, level, description, quantity, sortOrder, source, sponsor, removeImage } = req.body;
|
||||
const updateData = { name, level, description, quantity, sortOrder, source, sponsor };
|
||||
|
||||
if (req.file) {
|
||||
const [uploaded] = getFileUrls([req.file]);
|
||||
updateData.image = uploaded.url;
|
||||
} else if (removeImage === 'true') {
|
||||
updateData.image = null;
|
||||
}
|
||||
|
||||
await Prize.update(updateData, { where: { id: req.params.id } });
|
||||
|
||||
Reference in New Issue
Block a user