218 lines
6.3 KiB
Markdown
218 lines
6.3 KiB
Markdown
---
|
||
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);
|
||
```
|