Todo-CLI 交互式待办工具 v1.0.0-ts-精简学习版本v0.1 // 极简交互式Todo待办工具 | 核心功能增删改查本地JSON持久化 // 运行 bun src/todocli.ts 输入 exit 退出 import fs from fs/promises; import path from path; import readline from readline; // 持久化文件路径 const TASK_FILE path.resolve(__dirname, ./tasks.json); // 核心类型 type Task { id: number; title: string; priority: low | medium | high; status: active | done; }; type TaskStore { list: Task[]; nextId: number; }; // ---------------------- 文件读写核心工具 ---------------------- // 加载任务文件不存在返回空模板 async function loadTasks(): PromiseTaskStore { try { const raw await fs.readFile(TASK_FILE, utf8); return JSON.parse(raw) as TaskStore; } catch { return { list: [], nextId: 1 }; } } // 保存任务到本地json全量覆盖写入 async function saveTasks(store: TaskStore) { await fs.writeFile(TASK_FILE, JSON.stringify(store, null, 2), utf8); } // 错误打印工具 function errLog(msg: string) { console.log(\x1b[31m❌ ${msg}\x1b[0m); } // 成功打印封装统一绿色输出 function sucLog(msg: string) { console.log(\x1b[32m✅ ${msg}\x1b[0m); } // ---------------------- 完整CRUD业务命令 ---------------------- const cmdMap: Recordstring, (args: string[]) Promisevoid { // 【增】add 标题 --priorityhigh --done创建即完成 add: async (args) { const priorityArg args.find(item item.startsWith(--priority)); const priority priorityArg ? (priorityArg.split()[1] as Task[priority]) : medium; // 判断是否创建直接完成 const createDone args.includes(--done); // 过滤配置参数提取任务标题 const title args.filter(i !i.startsWith(--)).join( ).trim(); if (!title) return errLog(必须输入任务标题); const store await loadTasks(); const newTask: Task { id: store.nextId, title, priority, status: createDone ? done : active }; store.list.push(newTask); store.nextId 1; await saveTasks(store); const statusText createDone ? 已完成 : 待完成; sucLog(创建任务 #${newTask.id}【${statusText}】${title}); }, // 【查】list / list --statusactive/done list: async (args) { const statusArg args.find(item item.startsWith(--status)); const filterStatus statusArg ? statusArg.split()[1] : all; const store await loadTasks(); let showList store.list; if (filterStatus ! all) showList store.list.filter(t t.status filterStatus); console.log(\x1b[32m 任务列表\x1b[0m); if (showList.length 0) return console.log( 暂无任务); showList.forEach(t { const stat t.status active ? 待完成 : 已完成; console.log( ID:${t.id} | ${t.title} | 优先级:${t.priority} | ${stat}); }); }, // 【改】标记完成 done id done: async (args) { const id Number(args[0]); if (isNaN(id) || id 0) return errLog(请输入合法数字ID); const store await loadTasks(); const target store.list.find(t t.id id); if (!target) return errLog(不存在ID${id}的任务); target.status done; await saveTasks(store); sucLog(任务#${id}已标记完成); }, // 【改】update 1 --title新标题 --prioritylow update: async (args) { const id Number(args[0]); if (isNaN(id) || id 0) return errLog(第一个参数必须是任务ID); const titleArg args.find(i i.startsWith(--title)); const prioArg args.find(i i.startsWith(--priority)); const store await loadTasks(); const target store.list.find(t t.id id); if (!target) return errLog(不存在ID${id}的任务); // 按需更新字段 if (titleArg) target.title titleArg.split()[1]; if (prioArg) target.priority prioArg.split()[1] as Task[priority]; await saveTasks(store); sucLog(任务#${id}修改成功); }, // 【删】删除单条任务 delete id delete: async (args) { const id Number(args[0]); if (isNaN(id) || id 0) return errLog(请输入合法数字ID); const store await loadTasks(); const oldLen store.list.length; store.list store.list.filter(t t.id ! id); if (store.list.length oldLen) return errLog(不存在ID${id}的任务); await saveTasks(store); sucLog(任务#${id}已删除); }, // 批量清理已完成任务 clear clear: async () { const store await loadTasks(); const before store.list.length; store.list store.list.filter(t t.status ! done); const del before - store.list.length; await saveTasks(store); sucLog(清理完成移除${del}条已完成任务); } }; // ---------------------- 交互主循环 ---------------------- // 启动交互式命令行主程序负责终端输入输出、命令循环监听 async function startCli() { // 创建readline交互实例用于读取终端键盘输入与打印输出 const rl readline.createInterface({ input: process.stdin, // 标准输入流接收用户键盘输入 output: process.stdout, // 标准输出流向控制台打印文字 prompt: \x1b[32mtodo \x1b[0m // 自定义输入提示符\x1b[32m设置绿色字体\x1b[0m重置字体颜色 }); console.clear(); console.log( Todo极简工具【增删改查】); console.log(可用命令); console.log(add 任务名 --prioritylow/medium/high --done 创建任务--done直接完成); console.log(list --statusactive/done 查看任务); console.log(done ID 标记任务完成); console.log(update ID --title新标题 --priorityhigh 修改任务); console.log(delete ID 删除单条任务); console.log(clear 清空全部已完成任务); console.log(exit 退出程序\n); // 在控制台输出自定义提示符 todo 等待用户输入命令 rl.prompt(); // 监听用户按下回车的输入事件input 为用户输入的整行文本 rl.on(line, async (input) { // 去除输入文本首尾多余空格 const line input.trim(); // 判断输入为exit执行退出逻辑 if (line exit) { sucLog(退出程序数据已保存); // 关闭readline交互实例 rl.close(); // 终止当前事件回调后续代码执行 return; } // 用户仅输入空格/直接回车无有效内容重新弹出输入提示符 if (!line) { rl.prompt(); return; } // 以任意空白符空格、Tab分割整行输入拆分为命令参数数组 const parts line.split(/\s/); // 数组第一个元素为主命令add/list/update等 const cmd parts[0]; // 截取数组剩余所有元素作为命令的参数列表 const args parts.slice(1); // 判断输入的命令不存在 if (!cmdMap[cmd]) { errLog(未知命令${cmd}); } else { // 执行对应命令的异步处理函数捕获命令内部异常并打印错误 await cmdMap[cmd](args).catch(e errLog((e as Error).message)); } // 打印空行分隔两次命令输出优化控制台阅读体验 console.log(); // 执行完一条命令后再次弹出提示符等待下一次输入形成循环交互 rl.prompt(); }); // 监听readline关闭事件彻底结束Node/Bun进程0代表正常退出码 rl.on(close, () process.exit(0)); } // 启动程序捕获全局致命异常 startCli().catch(e errLog(全局异常${(e as Error).message}));0.1

相关新闻

最新新闻

Java入门指南:从基础语法到核心概念

Java入门指南:从基础语法到核心概念

1. Java学习两个月后的认知梳理学习Java两个月后,我逐渐从最初的迷茫状态过渡到对这门语言有了相对清晰的认识。Java作为一门面向对象的编程语言,其"一次编写,到处运行"的特性确实令人印象深刻。通过这段时间的学习,我理…

2026/7/19 11:16:57
2019电商技术面试核心考点与实战解析

2019电商技术面试核心考点与实战解析

1. 2019年电商行业面试全景观察2019年的电商行业正处于从移动互联网向新零售转型的关键节点。那一年我作为某头部电商平台的面试官,累计参与了87场技术岗面试,从初级开发到架构师岗位都有涉猎。现在回看当年的面试情况,很多考察点至今仍具有参…

2026/7/19 11:16:57
AM275x Mailbox中断配置实战:状态清除与使能寄存器详解

AM275x Mailbox中断配置实战:状态清除与使能寄存器详解

1. 项目概述与核心价值在嵌入式多核系统开发中,处理器核(Core)之间的高效、可靠通信是项目成败的关键。无论是DSP与ARM核之间的数据交换,还是不同任务域之间的状态同步,传统的共享内存轮询方式不仅效率低下&#xff0c…

2026/7/19 11:16:57
TI DSP eQEP模块深度解析:从正交编码器信号到精准位置与速度反馈

TI DSP eQEP模块深度解析:从正交编码器信号到精准位置与速度反馈

1. 从信号到位置:eQEP模块的核心价值与设计哲学在电机控制、机器人关节驱动或者任何需要精确位置反馈的工业场景里,我们工程师最头疼的问题之一,就是如何让控制器“看见”并“理解”电机的实时位置和速度。这就像给一个盲人装上眼睛&#xff…

2026/7/19 11:16:57
国外优质编程学习资源推荐与高效学习策略

国外优质编程学习资源推荐与高效学习策略

1. 为什么需要关注国外程序员学习资源?作为一名从业十年的全栈开发者,我深刻体会到技术视野的局限性对职业发展的制约。国内技术社区虽然活跃,但在某些前沿领域和深度内容上仍存在明显的信息差。国外优质学习平台往往能提供更系统化的知识体系…

2026/7/19 11:16:57
Unity万人同屏GPU加速方案:从渲染到逻辑的全链路优化实践

Unity万人同屏GPU加速方案:从渲染到逻辑的全链路优化实践

1. 项目概述:从“万人同屏”到“全能方案”的进化最近在社区里看到不少朋友在讨论大规模角色同屏渲染和交互的难题,尤其是在做MMO、SLG或者大世界探索类游戏时,一旦场景里的单位数量上千,帧率就开始“跳水”。传统的GameObject A…

2026/7/19 11:11:57

月新闻