Skip to content

todo cli.js

文件信息

  • 📄 原文件:01_todo_cli.js
  • 🔤 语言:javascript

Todo 命令行应用 一个简单的命令行 Todo 应用,演示 Node.js 开发。 用法: node 01_todo_cli.js add "任务内容" node 01_todo_cli.js list node 01_todo_cli.js done <id> node 01_todo_cli.js remove <id> node 01_todo_cli.js clear

完整代码

javascript
/**
 * ============================================================
 *                Todo 命令行应用
 * ============================================================
 * 一个简单的命令行 Todo 应用,演示 Node.js 开发。
 *
 * 用法:
 *   node 01_todo_cli.js add "任务内容"
 *   node 01_todo_cli.js list
 *   node 01_todo_cli.js done <id>
 *   node 01_todo_cli.js remove <id>
 *   node 01_todo_cli.js clear
 * ============================================================
 */

const fs = require("fs");
const path = require("path");
const readline = require("readline");

// 数据文件路径
const DATA_FILE = path.join(__dirname, "todos.json");

// ============================================================
//                    数据管理
// ============================================================

/**
 * 加载 Todo 列表
 */
function loadTodos() {
    try {
        if (fs.existsSync(DATA_FILE)) {
            const data = fs.readFileSync(DATA_FILE, "utf8");
            return JSON.parse(data);
        }
    } catch (error) {
        console.error("加载数据失败:", error.message);
    }
    return [];
}

/**
 * 保存 Todo 列表
 */
function saveTodos(todos) {
    try {
        fs.writeFileSync(DATA_FILE, JSON.stringify(todos, null, 2));
    } catch (error) {
        console.error("保存数据失败:", error.message);
    }
}

/**
 * 生成唯一 ID
 */
function generateId(todos) {
    if (todos.length === 0) return 1;
    return Math.max(...todos.map(t => t.id)) + 1;
}

// ============================================================
//                    命令处理
// ============================================================

/**
 * 添加任务
 */
function addTodo(content) {
    if (!content || content.trim().length === 0) {
        console.log("❌ 任务内容不能为空");
        return;
    }

    const todos = loadTodos();
    const newTodo = {
        id: generateId(todos),
        content: content.trim(),
        completed: false,
        createdAt: new Date().toISOString()
    };

    todos.push(newTodo);
    saveTodos(todos);

    console.log(`✅ 已添加任务 [${newTodo.id}]: ${newTodo.content}`);
}

/**
 * 列出任务
 */
function listTodos() {
    const todos = loadTodos();

    if (todos.length === 0) {
        console.log("📋 暂无任务");
        return;
    }

    console.log("\n" + "=".repeat(50));
    console.log("📋 Todo 列表");
    console.log("=".repeat(50));

    const pending = todos.filter(t => !t.completed);
    const completed = todos.filter(t => t.completed);

    if (pending.length > 0) {
        console.log("\n【待办】");
        pending.forEach(todo => {
            console.log(`  [${todo.id}] ○ ${todo.content}`);
        });
    }

    if (completed.length > 0) {
        console.log("\n【已完成】");
        completed.forEach(todo => {
            console.log(`  [${todo.id}] ● ${todo.content}`);
        });
    }

    console.log("\n" + "-".repeat(50));
    console.log(`总计: ${todos.length} 项 | 待办: ${pending.length} | 已完成: ${completed.length}`);
    console.log();
}

/**
 * 完成任务
 */
function completeTodo(id) {
    const todos = loadTodos();
    const todo = todos.find(t => t.id === parseInt(id));

    if (!todo) {
        console.log(`❌ 未找到任务 ID: ${id}`);
        return;
    }

    if (todo.completed) {
        console.log(`⚠️ 任务已经完成: ${todo.content}`);
        return;
    }

    todo.completed = true;
    todo.completedAt = new Date().toISOString();
    saveTodos(todos);

    console.log(`✅ 已完成任务 [${todo.id}]: ${todo.content}`);
}

/**
 * 删除任务
 */
function removeTodo(id) {
    const todos = loadTodos();
    const index = todos.findIndex(t => t.id === parseInt(id));

    if (index === -1) {
        console.log(`❌ 未找到任务 ID: ${id}`);
        return;
    }

    const removed = todos.splice(index, 1)[0];
    saveTodos(todos);

    console.log(`🗑️ 已删除任务 [${removed.id}]: ${removed.content}`);
}

/**
 * 清空所有任务
 */
function clearTodos() {
    saveTodos([]);
    console.log("🗑️ 已清空所有任务");
}

/**
 * 显示帮助
 */
function showHelp() {
    console.log(`
📝 Todo CLI - 命令行任务管理工具

用法:
  node 01_todo_cli.js <命令> [参数]

命令:
  add <内容>     添加新任务
  list           列出所有任务
  done <id>      标记任务完成
  remove <id>    删除任务
  clear          清空所有任务
  help           显示帮助

示例:
  node 01_todo_cli.js add "学习 Node.js"
  node 01_todo_cli.js list
  node 01_todo_cli.js done 1
  node 01_todo_cli.js remove 1
`);
}

// ============================================================
//                    交互模式
// ============================================================

/**
 * 交互模式
 */
function interactiveMode() {
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });

    console.log("\n📝 Todo CLI 交互模式");
    console.log("输入 help 查看命令,exit 退出\n");

    const prompt = () => {
        rl.question("todo> ", (input) => {
            const parts = input.trim().split(" ");
            const command = parts[0].toLowerCase();
            const args = parts.slice(1).join(" ");

            switch (command) {
                case "add":
                    addTodo(args);
                    break;
                case "list":
                case "ls":
                    listTodos();
                    break;
                case "done":
                case "complete":
                    completeTodo(args);
                    break;
                case "remove":
                case "rm":
                case "delete":
                    removeTodo(args);
                    break;
                case "clear":
                    clearTodos();
                    break;
                case "help":
                    showHelp();
                    break;
                case "exit":
                case "quit":
                case "q":
                    console.log("再见!👋");
                    rl.close();
                    return;
                case "":
                    break;
                default:
                    console.log(`未知命令: ${command},输入 help 查看帮助`);
            }

            prompt();
        });
    };

    prompt();
}

// ============================================================
//                    主程序
// ============================================================

function main() {
    const args = process.argv.slice(2);

    if (args.length === 0) {
        // 无参数时进入交互模式
        interactiveMode();
        return;
    }

    const command = args[0].toLowerCase();
    const param = args.slice(1).join(" ");

    switch (command) {
        case "add":
            addTodo(param);
            break;
        case "list":
        case "ls":
            listTodos();
            break;
        case "done":
        case "complete":
            completeTodo(param);
            break;
        case "remove":
        case "rm":
        case "delete":
            removeTodo(param);
            break;
        case "clear":
            clearTodos();
            break;
        case "help":
        case "--help":
        case "-h":
            showHelp();
            break;
        default:
            console.log(`未知命令: ${command}`);
            showHelp();
    }
}

main();

💬 讨论

使用 GitHub 账号登录后即可参与讨论

基于 MIT 许可发布