Files
code-center/.opencode/skills/create-routes/SKILL.md

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