feat(nav-category): support dynamic home grid categories in admin and uniapp
这个提交包含在:
@@ -739,6 +739,130 @@ app.delete('/api/admin/banners/:id', async (req: Request, res: Response) => {
|
||||
}
|
||||
});
|
||||
|
||||
// 首页金刚区活动品类导航列表 (小程序端读取上架状态)
|
||||
app.get('/api/nav-categories', async (_req: Request, res: Response) => {
|
||||
try {
|
||||
const list = await repo.getNavCategories();
|
||||
res.json({ code: 20000, data: list });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ code: 50000, message: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 管理后台: 获取全部品类导航列表 (含停用状态)
|
||||
app.get('/api/admin/nav-categories', async (_req: Request, res: Response) => {
|
||||
try {
|
||||
const list = await repo.getAdminNavCategories();
|
||||
res.json({ code: 20000, data: list });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ code: 50000, message: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 管理后台: 新增品类导航
|
||||
app.post('/api/admin/nav-categories', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { code, name, icon, bgClass, cat, targetUrl, badgeText, sortOrder, status } = req.body;
|
||||
if (!name || !name.trim()) {
|
||||
return res.status(400).json({ code: 40000, message: '品类名称不能为空' });
|
||||
}
|
||||
if (!icon || !icon.trim()) {
|
||||
return res.status(400).json({ code: 40000, message: '品类图标不能为空' });
|
||||
}
|
||||
|
||||
// 微信内容安全检测
|
||||
const secCheck = contentSecurityService.checkText(name + ' ' + (badgeText || ''));
|
||||
if (!secCheck.pass) {
|
||||
return res.status(400).json({ code: secCheck.code, message: secCheck.message });
|
||||
}
|
||||
|
||||
const item = await repo.createNavCategory({
|
||||
code,
|
||||
name: name.trim(),
|
||||
icon: icon.trim(),
|
||||
bgClass,
|
||||
cat,
|
||||
targetUrl,
|
||||
badgeText,
|
||||
sortOrder: sortOrder !== undefined ? Number(sortOrder) : 0,
|
||||
status: status !== undefined ? Number(status) : 1
|
||||
});
|
||||
|
||||
res.json({ code: 20000, data: item, message: '品类导航创建成功' });
|
||||
} catch (err: any) {
|
||||
res.status(400).json({ code: 40000, message: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 管理后台: 修改品类导航
|
||||
app.put('/api/admin/nav-categories/:id', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const catId = String(req.params.id);
|
||||
const { name, icon, bgClass, cat, targetUrl, badgeText, sortOrder, status } = req.body;
|
||||
|
||||
if (name) {
|
||||
const secCheck = contentSecurityService.checkText(name + ' ' + (badgeText || ''));
|
||||
if (!secCheck.pass) {
|
||||
return res.status(400).json({ code: secCheck.code, message: secCheck.message });
|
||||
}
|
||||
}
|
||||
|
||||
const updated = await repo.updateNavCategory(catId, {
|
||||
name,
|
||||
icon,
|
||||
bgClass,
|
||||
cat,
|
||||
targetUrl,
|
||||
badgeText,
|
||||
sortOrder: sortOrder !== undefined ? Number(sortOrder) : undefined,
|
||||
status: status !== undefined ? Number(status) : undefined
|
||||
});
|
||||
|
||||
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.post('/api/admin/nav-categories/:id/status', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const catId = String(req.params.id);
|
||||
const { status } = req.body;
|
||||
if (status === undefined || (status !== 0 && status !== 1)) {
|
||||
return res.status(400).json({ code: 40000, message: '状态参数必须为 0 或 1' });
|
||||
}
|
||||
|
||||
const updated = await repo.updateNavCategoryStatus(catId, Number(status));
|
||||
if (!updated) {
|
||||
return res.status(404).json({ code: 40400, message: '品类导航不存在' });
|
||||
}
|
||||
|
||||
res.json({ code: 20000, data: updated, message: status === 1 ? '品类导航已上架' : '品类导航已下线隐藏' });
|
||||
} catch (err: any) {
|
||||
res.status(400).json({ code: 40000, message: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 管理后台: 删除品类导航
|
||||
app.delete('/api/admin/nav-categories/:id', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const catId = String(req.params.id);
|
||||
const ok = await repo.deleteNavCategory(catId);
|
||||
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 });
|
||||
}
|
||||
});
|
||||
|
||||
// 创建新订单 (落盘 MySQL)
|
||||
app.post('/api/orders', async (req: Request, res: Response) => {
|
||||
try {
|
||||
|
||||
在新工单中引用
屏蔽一个用户