Files
browser-helper/src/routes/xhs/xhs-user-list.ts

170 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { desc, eq, count, or, like } from 'drizzle-orm';
import { schema, app, db } from '@/app.ts'
import z from 'zod';
const xhsUser = schema.xhsUser;
app.route({
path: 'xhs-users',
key: 'list',
middleware: ['auth'],
description: `获取小红书用户列表, 参数说明:
page: 页码默认1
pageSize: 每页数量默认20
search: 搜索关键词,模糊匹配昵称、用户名和描述
sort: 排序方式ASC或DESC默认DESC按更新时间降序
`,
metadata: {
tags: ['小红书', '用户'],
args: {
page: z.number().int().positive().optional().describe('页码默认为1'),
pageSize: z.number().int().positive().optional().describe('每页数量默认为20'),
search: z.string().optional().describe('搜索关键词,支持在昵称、用户名和描述中搜索'),
sort: z.enum(['ASC', 'DESC']).optional().describe('排序方式默认为DESC')
}
}
}).define(async (ctx) => {
const { page = 1, pageSize = 20, search, sort = 'DESC' } = ctx.query || {};
const offset = (page - 1) * pageSize;
const orderByField = sort === 'ASC' ? xhsUser.updatedAt : desc(xhsUser.updatedAt);
let whereCondition = undefined;
if (search) {
whereCondition = or(
like(xhsUser.nickname, `%${search}%`),
like(xhsUser.username, `%${search}%`),
like(xhsUser.description, `%${search}%`)
);
}
const [list, totalCount] = await Promise.all([
db.select()
.from(xhsUser)
.where(whereCondition)
.limit(pageSize)
.offset(offset)
.orderBy(orderByField),
db.select({ count: count() })
.from(xhsUser)
.where(whereCondition)
]);
ctx.body = {
list,
pagination: {
page,
current: page,
pageSize,
total: totalCount[0]?.count || 0,
},
};
return ctx;
}).addTo(app);
const userUpdate = `创建或更新一个小红书用户, 参数定义:
nickname: 用户昵称, 必填
username: 用户名, 选填
avatar: 用户头像, 选填
description: 用户描述, 选填
tags: 标签数组, 选填
data: 用户数据, 对象, 选填
`;
app.route({
path: 'xhs-users',
key: 'update',
middleware: ['auth'],
description: userUpdate,
metadata: {
tags: ['小红书', '用户'],
}
}).define(async (ctx) => {
const { id, createdAt, updatedAt, ...rest } = ctx.query.data || {};
let user;
if (!id) {
user = await db.insert(xhsUser).values({
id: rest.id || `user_${Date.now()}`,
nickname: rest.nickname || '',
username: rest.username || '',
avatar: rest.avatar || '',
description: rest.description || '',
summary: rest.summary || '',
tags: rest.tags ? JSON.stringify(rest.tags) : null,
link: rest.link || '',
data: rest.data ? JSON.stringify(rest.data) : null,
syncStatus: 1,
syncAt: Date.now(),
createdAt: Date.now(),
updatedAt: Date.now(),
}).returning();
} else {
const existing = await db.select().from(xhsUser).where(eq(xhsUser.id, id)).limit(1);
if (existing.length === 0) {
ctx.throw(404, '没有找到对应的用户');
}
user = await db.update(xhsUser).set({
nickname: rest.nickname,
username: rest.username,
avatar: rest.avatar,
description: rest.description,
summary: rest.summary,
tags: rest.tags ? JSON.stringify(rest.tags) : undefined,
link: rest.link,
data: rest.data ? JSON.stringify(rest.data) : undefined,
updatedAt: Date.now(),
}).where(eq(xhsUser.id, id)).returning();
}
ctx.body = user;
}).addTo(app);
app.route({
path: 'xhs-users',
key: 'delete',
middleware: ['auth'],
description: '删除小红书用户, 参数: data.id 用户ID',
metadata: {
tags: ['小红书', '用户'],
args: {
data: z.object({
id: z.string().describe('用户ID')
}).describe('请求数据对象包含用户ID')
}
}
}).define(async (ctx) => {
const { id } = ctx.query.data || {};
if (!id) {
ctx.throw(400, 'id 参数缺失');
}
const existing = await db.select().from(xhsUser).where(eq(xhsUser.id, id)).limit(1);
if (existing.length === 0) {
ctx.throw(404, '没有找到对应的用户');
}
await db.delete(xhsUser).where(eq(xhsUser.id, id));
ctx.body = { success: true };
}).addTo(app);
app.route({
path: 'xhs-users',
key: 'get',
middleware: ['auth'],
description: '获取单个小红书用户, 参数: data.id 用户ID',
metadata: {
tags: ['小红书', '用户'],
args: {
data: z.object({
id: z.string().describe('用户ID')
}).describe('请求数据对象包含用户ID')
}
}
}).define(async (ctx) => {
const { id } = ctx.query.data || {};
if (!id) {
ctx.throw(400, 'id 参数缺失');
}
const existing = await db.select().from(xhsUser).where(eq(xhsUser.id, id)).limit(1);
if (existing.length === 0) {
ctx.throw(404, '没有找到对应的用户');
}
ctx.body = existing[0];
}).addTo(app);