feat(safety): support full CRUD for approved commercial places and dynamic sync to uniapp
这个提交包含在:
@@ -1439,6 +1439,40 @@ export class MysqlRepository {
|
||||
return { id, ...data };
|
||||
}
|
||||
|
||||
async updateSafetyPlace(id: string, data: Partial<{ name: string; area: string; category: string; status: string }>): Promise<any> {
|
||||
const fields: string[] = [];
|
||||
const values: any[] = [];
|
||||
if (data.name !== undefined) {
|
||||
fields.push('name = ?');
|
||||
values.push(data.name);
|
||||
}
|
||||
if (data.area !== undefined) {
|
||||
fields.push('area = ?');
|
||||
values.push(data.area);
|
||||
}
|
||||
if (data.category !== undefined) {
|
||||
fields.push('category = ?');
|
||||
values.push(data.category);
|
||||
}
|
||||
if (data.status !== undefined) {
|
||||
fields.push('status = ?');
|
||||
values.push(data.status);
|
||||
}
|
||||
|
||||
if (fields.length > 0) {
|
||||
values.push(id);
|
||||
await pool.query(`UPDATE safety_places SET ${fields.join(', ')} WHERE id = ?`, values);
|
||||
}
|
||||
|
||||
const [rows]: any = await pool.query('SELECT * FROM safety_places WHERE id = ?', [id]);
|
||||
return rows[0] || null;
|
||||
}
|
||||
|
||||
async deleteSafetyPlace(id: string): Promise<boolean> {
|
||||
const [res]: any = await pool.query('DELETE FROM safety_places WHERE id = ?', [id]);
|
||||
return res.affectedRows > 0;
|
||||
}
|
||||
|
||||
async getSafetyAuditLogs(): Promise<any[]> {
|
||||
const [rows]: any = await pool.query(`
|
||||
SELECT
|
||||
|
||||
@@ -1260,6 +1260,14 @@ app.get('/api/safety/places', async (_req: Request, res: Response) => {
|
||||
|
||||
app.post('/api/safety/places', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { name, area, category } = req.body;
|
||||
if (!name || !area) {
|
||||
return res.status(400).json({ code: 40000, message: '场所名称和商圈不能为空' });
|
||||
}
|
||||
const sec = contentSecurityService.checkText(`${name} ${area}`);
|
||||
if (!sec.pass) {
|
||||
return res.status(400).json({ code: sec.code, message: sec.message });
|
||||
}
|
||||
const place = await repo.createSafetyPlace(req.body);
|
||||
res.json({
|
||||
code: 20000,
|
||||
@@ -1271,6 +1279,41 @@ app.post('/api/safety/places', async (req: Request, res: Response) => {
|
||||
}
|
||||
});
|
||||
|
||||
// 管理后台: 修改场所信息
|
||||
app.put('/api/safety/places/:id', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const placeId = String(req.params.id);
|
||||
const { name, area, category, status } = req.body;
|
||||
if (name || area) {
|
||||
const sec = contentSecurityService.checkText(`${name || ''} ${area || ''}`);
|
||||
if (!sec.pass) {
|
||||
return res.status(400).json({ code: sec.code, message: sec.message });
|
||||
}
|
||||
}
|
||||
const updated = await repo.updateSafetyPlace(placeId, { name, area, category, status });
|
||||
if (!updated) {
|
||||
return res.status(404).json({ code: 40400, message: '场所不存在' });
|
||||
}
|
||||
res.json({ code: 20000, data: updated, message: '场所信息已更新' });
|
||||
} catch (err: any) {
|
||||
res.status(400).json({ code: 40000, message: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 管理后台: 删除场所
|
||||
app.delete('/api/safety/places/:id', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const placeId = String(req.params.id);
|
||||
const ok = await repo.deleteSafetyPlace(placeId);
|
||||
if (!ok) {
|
||||
return res.status(404).json({ code: 40400, message: '场所不存在或已被移除' });
|
||||
}
|
||||
res.json({ code: 20000, data: null, message: '场所已移除' });
|
||||
} catch (err: any) {
|
||||
res.status(400).json({ code: 40000, message: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/api/safety/audit-logs', async (_req: Request, res: Response) => {
|
||||
try {
|
||||
const logs = await repo.getSafetyAuditLogs();
|
||||
|
||||
在新工单中引用
屏蔽一个用户