// 需要在 index.ts 旁边创建一个 data.json,内容是 [],空数组,注意使用 utf-8 编码 import { definePlugin } from 'kivibot' import todo from './todo.json' export default definePlugin({ name: 'todo', version: '1.0.0', setup(ctx) { const store = ctx.createVanilla({ todo: todo as Record }) store.subscribe(async () => { const { todo } = store.snapshot() const filePath = ctx.path.join(__dirname, './todo.json') ctx.fs.writeFileSync(filePath, JSON.stringify(todo)) }) ctx.handle('message', async (e) => { const text = ctx.getText(e) if (!text) return if (text.match(/^todo\s+help$/)) { return await e.reply( ctx .dedent( ` 〓 待办插件帮助 〓 todo - 查看所有待办 todo add - 添加 todo done <id> - 标记完成 todo undo <id> - 还原标记 todo delete <id> - 删除 todo clear - 清空 `, ) .trim(), ) } if (text.match(/^todo$/i)) { // biome-ignore lint/suspicious/noAssignInExpressions: <explanation> const userTodo = (store.mutate.todo[e.sender.user_id] ??= []) if (userTodo.length <= 12) { const todoListStr = userTodo .map((item) => `- [${item.status === 'done' ? 'x' : ' '}] [${item.id}] ${item.title}`) .join('\n') return await e.reply(`〓 待办事项 〓\n${todoListStr ? todoListStr : '[事情都干完啦~]'}`) } const msgs = await ctx.bot.makeForwardMsg( userTodo.slice(0, 99).map((item) => ({ nickname: e.sender.nickname, user_id: e.sender.user_id, message: `- [${item.status === 'done' ? 'x' : ''}] [${item.id}] ${item.title}`, })), ) await e.reply(msgs) } if (text.match(/^todo\s+clear$/)) { // biome-ignore lint/suspicious/noAssignInExpressions: <explanation> const userTodo = (store.mutate.todo[e.sender.user_id] ??= []) userTodo.length = 0 return await e.reply('已清空待办事项') } if (text.match(/^todo\s+done/)) { // biome-ignore lint/suspicious/noAssignInExpressions: <explanation> const userTodo = (store.mutate.todo[e.sender.user_id] ??= []) const id = text.replace(/^todo\s+done/, () => '').trim() if (!id) return await e.reply('请提供待办事项 ID', true) const item = userTodo.find((item) => item.id.toLowerCase() === id.toLowerCase()) if (!item) return await e.reply('未找到待办事项', true) item.status = 'done' item.updatedAt = Date.now() return await e.reply(`已标记待办事项 【${item.title}】 为完成`) } if (text.match(/^todo\s+undo/)) { // biome-ignore lint/suspicious/noAssignInExpressions: <explanation> const userTodo = (store.mutate.todo[e.sender.user_id] ??= []) const id = text.replace(/^todo\s+undo/, () => '').trim() if (!id) return await e.reply('请提供待办事项 ID', true) const item = userTodo.find((item) => item.id.toLowerCase() === id.toLowerCase()) if (!item) return await e.reply('未找到待办事项', true) item.status = 'todo' item.updatedAt = Date.now() return await e.reply(`已标记待办事项 【${item.title}】 为未完成`) } if (text.match(/^todo\s+delete/)) { // biome-ignore lint/suspicious/noAssignInExpressions: <explanation> const userTodo = (store.mutate.todo[e.sender.user_id] ??= []) const id = text.replace(/^todo\s+delete/, () => '').trim() if (!id) return await e.reply('请提供待办事项 ID', true) const idx = userTodo.findIndex((item) => item.id.toLowerCase() === id.toLowerCase()) if (idx === -1) return await e.reply('未找到待办事项', true) const item = userTodo.splice(idx, 1) return await e.reply(`已删除待办事项 【${item[0].title}】`) } if (text.match(/^todo\s+add/)) { // biome-ignore lint/suspicious/noAssignInExpressions: <explanation> const userTodo = (store.mutate.todo[e.sender.user_id] ??= []) const title = text.replace(/^todo\s+add/, () => '').trim() if (!title) return await e.reply('请提供待办事项的标题', true) userTodo.push({ id: uuid(), title, status: 'todo', createdAt: Date.now(), updatedAt: Date.now(), }) return await e.reply(`已添加待办事项:${title}`) } }) }, }) function uuid() { return Math.random().toString(16).slice(2, 6).toUpperCase() } interface TodoItem { id: string title: string status: 'todo' | 'done' createdAt: number updatedAt: number }