feat(admin): complete post management, finance csv export, and wechat message template config
这个提交包含在:
@@ -2194,20 +2194,34 @@ export class MysqlRepository {
|
||||
|
||||
|
||||
// 友圈动态相关
|
||||
async getPosts(category?: string): Promise<any[]> {
|
||||
async getPosts(category?: string, keyword?: string, status?: string): Promise<any[]> {
|
||||
let sql = `
|
||||
SELECT
|
||||
id, user_id as userId, author, avatar, tag, tag_type as tagType,
|
||||
location, distance, content, topics, images, action_text as actionText,
|
||||
likes, comments, views, category, created_at as createdAt
|
||||
likes, comments, views, category, is_top as isTop, status, created_at as createdAt
|
||||
FROM posts
|
||||
`;
|
||||
const params: any[] = [];
|
||||
const where: string[] = [];
|
||||
|
||||
if (category && category !== 'all') {
|
||||
sql += ' WHERE category = ?';
|
||||
where.push('category = ?');
|
||||
params.push(category);
|
||||
}
|
||||
sql += ' ORDER BY created_at DESC';
|
||||
if (keyword) {
|
||||
where.push('(content LIKE ? OR author LIKE ? OR location LIKE ?)');
|
||||
params.push(`%${keyword}%`, `%${keyword}%`, `%${keyword}%`);
|
||||
}
|
||||
if (status && status !== 'all') {
|
||||
where.push('status = ?');
|
||||
params.push(status);
|
||||
}
|
||||
|
||||
if (where.length > 0) {
|
||||
sql += ' WHERE ' + where.join(' AND ');
|
||||
}
|
||||
sql += ' ORDER BY is_top DESC, created_at DESC';
|
||||
|
||||
const [rows]: any = await pool.query(sql, params);
|
||||
return rows.map((r: any) => {
|
||||
@@ -2222,12 +2236,45 @@ export class MysqlRepository {
|
||||
|
||||
return {
|
||||
...r,
|
||||
isTop: Boolean(r.isTop),
|
||||
status: r.status || '正常',
|
||||
topics: topicsArr,
|
||||
images: imagesArr,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// 管理端切换置顶
|
||||
async togglePostTop(postId: string, isTop: boolean): Promise<boolean> {
|
||||
const [result]: any = await pool.query(`
|
||||
UPDATE posts SET is_top = ? WHERE id = ?
|
||||
`, [isTop ? 1 : 0, postId]);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
|
||||
// 管理端切换状态 (正常 / 隐藏)
|
||||
async updatePostStatus(postId: string, status: string): Promise<boolean> {
|
||||
const [result]: any = await pool.query(`
|
||||
UPDATE posts SET status = ? WHERE id = ?
|
||||
`, [status, postId]);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
|
||||
// 管理端彻底删除动态及下属评论
|
||||
async adminDeletePost(postId: string): Promise<boolean> {
|
||||
try {
|
||||
await pool.query('DELETE FROM post_comments WHERE post_id = ?', [postId]);
|
||||
} catch (_) {}
|
||||
const [result]: any = await pool.query('DELETE FROM posts WHERE id = ?', [postId]);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
|
||||
// 管理端删除特定违规评论
|
||||
async adminDeletePostComment(commentId: string): Promise<boolean> {
|
||||
const [result]: any = await pool.query('DELETE FROM post_comments WHERE id = ?', [commentId]);
|
||||
return result.affectedRows > 0;
|
||||
}
|
||||
|
||||
async createPost(data: {
|
||||
userId?: number;
|
||||
author?: string;
|
||||
|
||||
在新工单中引用
屏蔽一个用户