--- name: create-routes description: 创建路由例子模板代码 --- # 创建路由例子模板代码 app是自定义@kevisual/router的一个APP 1. 一般来说,修改path,和对应的schema表,就可以快速创建对应的增删改查接口。 2. 根据需要,每一个功能需要添加对应的描述 3. 根据需要,对应schema表的字段进行修改代码 示例: ```ts import { desc, eq, count, or, like, and } from 'drizzle-orm'; import { schema, app, db } from '@/app.ts'; import { z } from 'zod'; app .route({ path: 'prompts', key: 'list', middleware: ['auth'], description: '获取提示词列表', metadata: { args: { page: z.number().optional().default(1).describe('页码'), pageSize: z.number().optional().default(20).describe('每页数量'), search: z.string().optional().describe('搜索关键词'), sort: z.enum(['ASC', 'DESC']).optional().default('DESC').describe('排序方式'), }, }, }) .define(async (ctx) => { const tokenUser = ctx.state.tokenUser; const uid = tokenUser.id; const { page = 1, pageSize = 20, search, sort = 'DESC' } = ctx.query || {}; const offset = (page - 1) * pageSize; const orderByField = sort === 'ASC' ? schema.prompts.updatedAt : desc(schema.prompts.updatedAt); let whereCondition = eq(schema.prompts.uid, uid); if (search) { whereCondition = and(eq(schema.prompts.uid, uid), or(like(schema.prompts.title, `%${search}%`), like(schema.prompts.summary, `%${search}%`))); } const [list, totalCount] = await Promise.all([ db.select().from(schema.prompts).where(whereCondition).limit(pageSize).offset(offset).orderBy(orderByField), db.select({ count: count() }).from(schema.prompts).where(whereCondition), ]); ctx.body = { list, pagination: { page, current: page, pageSize, total: totalCount[0]?.count || 0, }, }; return ctx; }) .addTo(app); app .route({ path: 'prompts', key: 'create', middleware: ['auth'], description: '创建提示词', metadata: { args: { data: z .object({ title: z.string().describe('提示词标题'), description: z.string().optional().describe('描述'), summary: z.string().optional().describe('摘要'), tags: z.array(z.string()).optional().describe('标签'), link: z.string().optional().describe('链接'), data: z.record(z.string(), z.any()).optional().describe('数据对象'), parents: z.array(z.string()).optional().describe('父级ID数组'), }) .describe('提示词对象'), }, }, }) .define(async (ctx) => { const tokenUser = ctx.state.tokenUser; const { title, description, summary, tags, link, data, parents } = ctx.query.data || {}; if (!title) { ctx.throw(400, 'title 参数缺失'); } const newPrompt = await db .insert(schema.prompts) .values({ title, description, summary, tags, link, data, parents, uid: tokenUser.id, }) .returning(); ctx.body = newPrompt; }) .addTo(app); app .route({ path: 'prompts', key: 'update', middleware: ['auth'], description: '更新提示词', metadata: { args: { data: z .object({ id: z.string().optional().describe('提示词ID, 不填表示创建'), title: z.string().describe('提示词标题'), description: z.string().optional().describe('描述'), summary: z.string().optional().describe('摘要'), tags: z.array(z.string()).optional().describe('标签'), link: z.string().optional().describe('链接'), data: z.record(z.string(), z.any()).optional().describe('数据对象'), parents: z.array(z.string()).optional().describe('父级ID数组'), }) .describe('提示词对象'), }, }, }) .define(async (ctx) => { const { id, uid, updatedAt, ...rest } = ctx.query.data || {}; const tokenUser = ctx.state.tokenUser; let prompt; if (!id) { ctx.throw(400, 'id 参数缺失'); } const existing = await db.select().from(schema.prompts).where(eq(schema.prompts.id, id)).limit(1); if (existing.length === 0) { ctx.throw(404, '没有找到对应的提示词'); } if (existing[0].uid !== tokenUser.id) { ctx.throw(403, '没有权限更新该提示词'); } prompt = await db .update(schema.prompts) .set({ ...rest, }) .where(eq(schema.prompts.id, id)) .returning(); ctx.body = prompt; }) .addTo(app); app .route({ path: 'prompts', key: 'delete', middleware: ['auth'], description: '删除提示词, 参数: id 提示词ID', metadata: { args: { id: z.string().describe('提示词ID'), }, }, }) .define(async (ctx) => { const tokenUser = ctx.state.tokenUser; const { id } = ctx.query || {}; if (!id) { ctx.throw(400, 'id 参数缺失'); } const existing = await db.select().from(schema.prompts).where(eq(schema.prompts.id, id)).limit(1); if (existing.length === 0) { ctx.throw(404, '没有找到对应的提示词'); } if (existing[0].uid !== tokenUser.id) { ctx.throw(403, '没有权限删除该提示词'); } await db.delete(schema.prompts).where(eq(schema.prompts.id, id)); ctx.body = { success: true }; }) .addTo(app); app .route({ path: 'prompts', key: 'get', middleware: ['auth'], description: '获取单个提示词, 参数: id 提示词ID', metadata: { args: { id: z.string().describe('提示词ID'), }, }, }) .define(async (ctx) => { const tokenUser = ctx.state.tokenUser; const { id } = ctx.query || {}; if (!id) { ctx.throw(400, 'id 参数缺失'); } const existing = await db.select().from(schema.prompts).where(eq(schema.prompts.id, id)).limit(1); if (existing.length === 0) { ctx.throw(404, '没有找到对应的提示词'); } if (existing[0].uid !== tokenUser.id) { ctx.throw(403, '没有权限查看该提示词'); } ctx.body = existing[0]; }) .addTo(app); ```