From da4ebc41f9d2c7806b380dfbe06855f501af3c17 Mon Sep 17 00:00:00 2001 From: hewh Date: Sun, 13 Jul 2025 22:09:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E5=91=BD=E4=BB=A4=E7=95=8C?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + .vscode/settings.json | 3 + README.md | 126 +++++-- pkm.bat | 23 ++ pom.xml | 29 +- run.bat | 27 +- src/main/java/com/example/App.java | 18 +- .../java/com/example/cli/CommandParser.java | 357 ++++++++++++++++++ .../java/com/example/model/ExportFormat.java | 7 + 9 files changed, 552 insertions(+), 40 deletions(-) create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 pkm.bat create mode 100644 src/main/java/com/example/cli/CommandParser.java create mode 100644 src/main/java/com/example/model/ExportFormat.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..45255b6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.class +target/* \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c5f3f6b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/README.md b/README.md index e247f75..fc00b7a 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,144 @@ -# Java Maven Hello World 项目 +# 个人知识管理系统 - 命令行版本 (PKM CLI) -这是一个简单的Java Maven项目,用于演示如何创建和运行一个基本的Java应用程序。 +这是一个基于Java的个人知识管理系统,提供完整的命令行界面来管理你的笔记和知识库。 ## 项目结构 ``` PKM/ -├── pom.xml # Maven配置文件 +├── pom.xml # Maven配置文件 ├── src/ │ ├── main/ │ │ └── java/ │ │ └── com/ │ │ └── example/ -│ │ └── App.java # 主应用程序类 +│ │ ├── App.java # 主应用程序入口 +│ │ ├── cli/ +│ │ │ └── CommandParser.java # 命令解析器 +│ │ └── model/ +│ │ └── ExportFormat.java # 导出格式枚举 │ └── test/ │ └── java/ │ └── com/ │ └── example/ -│ └── AppTest.java # 测试类 -└── README.md # 项目说明文件 +│ └── AppTest.java # 测试类 +├── target/classes/ # 编译输出目录 +├── pkm.bat # PKM快捷启动脚本 +├── run.bat # 运行脚本 +├── clean.bat # 清理脚本 +└── README.md # 项目说明文件 ``` +## 功能特性 + +### 核心命令 +- `new` - 创建新笔记 +- `list` - 列出所有笔记(支持标签过滤) +- `view` - 查看笔记详情 +- `edit` - 编辑笔记内容 +- `delete` - 删除笔记 + +### 标签管理 +- `tag` - 为笔记添加标签 +- `untag` - 从笔记移除标签 + +### 搜索功能 +- `search` - 按关键词搜索笔记 + +### 导出功能 +- `export` - 导出单个笔记 +- `export-all` - 导出所有笔记 +- 支持格式:TXT、JSON + +### 其他 +- `help` - 显示帮助信息 +- `exit/quit` - 退出程序 + ## 如何运行 ### 前提条件 - 安装Java 17或更高版本 -- 安装Maven 3.6或更高版本 +- 确保Java在系统PATH中 -### 编译项目 +### 快速启动 +使用PKM快捷脚本(推荐): ```bash -mvn compile +# 交互模式 +pkm.bat + +# 命令模式 +pkm.bat help +pkm.bat new "我的笔记" "笔记内容" +pkm.bat list --tag java ``` -### 运行应用程序 +### 手动编译运行 ```bash -mvn exec:java +# 编译项目 +javac -cp src\main\java -d target\classes src\main\java\com\example\*.java src\main\java\com\example\cli\*.java src\main\java\com\example\model\*.java + +# 运行程序 +java -cp target\classes com.example.App [命令] ``` -### 运行测试 +### 使用run.bat脚本 ```bash -mvn test +# 自动编译并运行 +run.bat ``` -### 打包项目 +## 使用示例 + +### 交互模式 ```bash -mvn package +> pkm.bat +欢迎使用个人知识管理系统 (CLI版) +输入 help 查看可用命令 + +pkm> new "Java学习笔记" "今天学习了面向对象编程..." +创建笔记: Java学习笔记 +内容: 今天学习了面向对象编程... + +pkm> list +列出所有笔记: +[1] Java笔记 (2023-10-01) [编程, 学习] +[2] 设计模式笔记 (2023-10-05) [编程, 架构] + +pkm> exit +感谢使用个人知识管理系统! ``` -### 清理项目 +### 命令模式 ```bash -mvn clean -``` +# 创建笔记 +pkm.bat new "Python学习" "学习Python基础语法" -## 输出结果 -运行程序后,控制台将显示: -``` -Hello World! -欢迎使用Java Maven项目! +# 列出笔记 +pkm.bat list + +# 按标签过滤 +pkm.bat list --tag programming + +# 搜索笔记 +pkm.bat search "设计模式" + +# 导出笔记 +pkm.bat export 123e4567 txt my-note.txt + +# 查看帮助 +pkm.bat help ``` +## 开发状态 + +当前版本实现了完整的命令行界面和命令解析功能。后续开发计划: + +- [ ] 笔记存储和管理 +- [ ] 标签系统 +- [ ] 搜索功能 +- [ ] 导出功能 +- [ ] 配置管理 + ## 技术栈 - Java 17 - Maven 3.x diff --git a/pkm.bat b/pkm.bat new file mode 100644 index 0000000..8cb6d21 --- /dev/null +++ b/pkm.bat @@ -0,0 +1,23 @@ +@echo off +REM PKM - Personal Knowledge Management System +REM 个人知识管理系统快捷启动脚本 + +REM 切换到脚本所在目录 +cd /d "%~dp0" + +REM 检查是否需要编译 +if not exist target\classes\com\example\App.class ( + echo 首次运行,正在编译项目... + mkdir target\classes 2>nul + javac -cp src\main\java -d target\classes src\main\java\com\example\*.java src\main\java\com\example\cli\*.java src\main\java\com\example\model\*.java + if %errorlevel% neq 0 ( + echo 编译失败! + pause + exit /b 1 + ) + echo 编译成功! + echo. +) + +REM 运行程序,传递所有参数 +java -cp target\classes com.example.App %* diff --git a/pom.xml b/pom.xml index 16ff89d..d61f009 100644 --- a/pom.xml +++ b/pom.xml @@ -6,17 +6,18 @@ 4.0.0 com.example - hello-world + pkm-cli 1.0-SNAPSHOT jar - hello-world - A simple Hello World Java Maven project + pkm-cli + Personal Knowledge Management System - CLI Version 17 17 UTF-8 + com.example.App @@ -56,6 +57,28 @@ com.example.App + + + + org.apache.maven.plugins + maven-shade-plugin + 3.4.1 + + + package + + shade + + + + + com.example.App + + + + + + diff --git a/run.bat b/run.bat index 147860f..d609856 100644 --- a/run.bat +++ b/run.bat @@ -1,18 +1,25 @@ @echo off +REM Personal Knowledge Management System - CLI Version +REM 个人知识管理系统 - 命令行版本 + +REM 检查是否需要编译 +if not exist target\classes\com\example\App.class ( + echo 首次运行,正在编译项目... + call :compile +) + +REM 运行程序,传递所有参数 +java -cp target\classes com.example.App %* +goto :eof + +:compile echo 正在编译Java项目... -javac -cp src\main\java -d target\classes src\main\java\com\example\App.java +mkdir target\classes 2>nul +javac -cp src\main\java -d target\classes src\main\java\com\example\*.java src\main\java\com\example\cli\*.java src\main\java\com\example\model\*.java if %errorlevel% neq 0 ( echo 编译失败! pause exit /b 1 ) echo 编译成功! - -echo. -echo 正在运行应用程序... -echo ======================== -java -cp target\classes com.example.App -echo ======================== -echo. -echo 程序运行完成! -pause +goto :eof diff --git a/src/main/java/com/example/App.java b/src/main/java/com/example/App.java index f754855..c11ae43 100644 --- a/src/main/java/com/example/App.java +++ b/src/main/java/com/example/App.java @@ -1,13 +1,23 @@ package com.example; +import com.example.cli.CommandParser; + /** - * Hello World Application + * Personal Knowledge Management System - CLI Version * - * 这是一个简单的Java应用程序,用于输出"Hello World"到控制台 + * 个人知识管理系统命令行版本 */ public class App { public static void main(String[] args) { - System.out.println("Hello World!"); - System.out.println("欢迎使用Java Maven项目!"); + CommandParser parser = new CommandParser(); + + try { + parser.parseArgs(args); + } catch (Exception e) { + System.err.println("程序执行出错: " + e.getMessage()); + e.printStackTrace(); + } finally { + parser.close(); + } } } diff --git a/src/main/java/com/example/cli/CommandParser.java b/src/main/java/com/example/cli/CommandParser.java new file mode 100644 index 0000000..9e9156b --- /dev/null +++ b/src/main/java/com/example/cli/CommandParser.java @@ -0,0 +1,357 @@ +package com.example.cli; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; + +public class CommandParser { + private Scanner scanner; + private boolean isRunning; + + public CommandParser() { + this.scanner = new Scanner(System.in); + this.isRunning = true; + } + + /** + * 解析命令行参数 + */ + public void parseArgs(String[] args) { + if (args.length == 0) { + // 进入交互模式 + startInteractiveMode(); + } else { + // 执行单个命令 + executeCommand(String.join(" ", args)); + } + } + + /** + * 启动交互式命令行模式 + */ + private void startInteractiveMode() { + System.out.println("欢迎使用个人知识管理系统 (CLI版)"); + System.out.println("输入 help 查看可用命令\n"); + + while (isRunning) { + System.out.print("pkm> "); + String input = scanner.nextLine().trim(); + + if (!input.isEmpty()) { + executeCommand(input); + } + } + } + + /** + * 执行命令 + */ + private void executeCommand(String commandLine) { + String[] parts = parseCommandLine(commandLine); + if (parts.length == 0) return; + + String command = parts[0].toLowerCase(); + String[] args = Arrays.copyOfRange(parts, 1, parts.length); + + switch (command) { + case "new": + handleNewCommand(args); + break; + case "list": + handleListCommand(args); + break; + case "view": + handleViewCommand(args); + break; + case "edit": + handleEditCommand(args); + break; + case "delete": + handleDeleteCommand(args); + break; + case "tag": + handleTagCommand(args); + break; + case "untag": + handleUntagCommand(args); + break; + case "search": + handleSearchCommand(args); + break; + case "export": + handleExportCommand(args); + break; + case "export-all": + handleExportAllCommand(args); + break; + case "help": + handleHelpCommand(); + break; + case "exit": + case "quit": + handleExitCommand(); + break; + default: + System.out.println("未知命令: " + command); + System.out.println("输入 help 查看可用命令"); + } + } + + /** + * 解析命令行,支持引号包围的参数 + */ + private String[] parseCommandLine(String commandLine) { + return commandLine.split("\\s+(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)"); + } + + /** + * 处理 new 命令 + */ + private void handleNewCommand(String[] args) { + if (args.length < 2) { + System.out.println("用法: new <标题> <内容>"); + System.out.println("示例: new \"Java笔记\" \"面向对象编程的三大特性...\""); + return; + } + + String title = args[0].replaceAll("^\"|\"$", ""); + String content = args[1].replaceAll("^\"|\"$", ""); + + System.out.println("创建笔记: " + title); + System.out.println("内容: " + content); + // TODO: 调用 NoteController.createNote() + } + + /** + * 处理 list 命令 + */ + private void handleListCommand(String[] args) { + Map options = parseOptions(args); + + if (options.containsKey("tag")) { + String tag = options.get("tag"); + System.out.println("列出标签为 '" + tag + "' 的笔记:"); + } else { + System.out.println("列出所有笔记:"); + } + + // TODO: 调用 NoteController.listNotes() + // 示例输出格式 + System.out.println("[1] Java笔记 (2023-10-01) [编程, 学习]"); + System.out.println("[2] 设计模式笔记 (2023-10-05) [编程, 架构]"); + } + + /** + * 处理 view 命令 + */ + private void handleViewCommand(String[] args) { + if (args.length < 1) { + System.out.println("用法: view <笔记ID>"); + System.out.println("示例: view 123e4567"); + return; + } + + String noteId = args[0]; + System.out.println("查看笔记: " + noteId); + // TODO: 调用 NoteController.viewNote() + } + + /** + * 处理 edit 命令 + */ + private void handleEditCommand(String[] args) { + if (args.length < 2) { + System.out.println("用法: edit <笔记ID> <新内容>"); + System.out.println("示例: edit 123e4567 \"更新的内容\""); + return; + } + + String noteId = args[0]; + String newContent = args[1].replaceAll("^\"|\"$", ""); + + System.out.println("编辑笔记: " + noteId); + System.out.println("新内容: " + newContent); + // TODO: 调用 NoteController.editNote() + } + + /** + * 处理 delete 命令 + */ + private void handleDeleteCommand(String[] args) { + if (args.length < 1) { + System.out.println("用法: delete <笔记ID>"); + System.out.println("示例: delete 123e4567"); + return; + } + + String noteId = args[0]; + System.out.println("删除笔记: " + noteId); + // TODO: 调用 NoteController.deleteNote() + } + + /** + * 处理 tag 命令 + */ + private void handleTagCommand(String[] args) { + if (args.length < 2) { + System.out.println("用法: tag <笔记ID> <标签>"); + System.out.println("示例: tag 123e4567 programming"); + return; + } + + String noteId = args[0]; + String tag = args[1]; + + System.out.println("为笔记 " + noteId + " 添加标签: " + tag); + // TODO: 调用 TagController.addTag() + } + + /** + * 处理 untag 命令 + */ + private void handleUntagCommand(String[] args) { + if (args.length < 2) { + System.out.println("用法: untag <笔记ID> <标签>"); + System.out.println("示例: untag 123e4567 old"); + return; + } + + String noteId = args[0]; + String tag = args[1]; + + System.out.println("从笔记 " + noteId + " 移除标签: " + tag); + // TODO: 调用 TagController.removeTag() + } + + /** + * 处理 search 命令 + */ + private void handleSearchCommand(String[] args) { + if (args.length < 1) { + System.out.println("用法: search <关键词>"); + System.out.println("示例: search \"设计模式\""); + return; + } + + String keyword = String.join(" ", args).replaceAll("^\"|\"$", ""); + System.out.println("搜索关键词: " + keyword); + // TODO: 调用 SearchService.searchByKeyword() + } + + /** + * 处理 export 命令 + */ + private void handleExportCommand(String[] args) { + if (args.length < 3) { + System.out.println("用法: export <笔记ID> <格式> <路径>"); + System.out.println("示例: export 123e4567 txt output.txt"); + System.out.println("支持格式: txt, json"); + return; + } + + String noteId = args[0]; + String format = args[1].toLowerCase(); + String filePath = args[2]; + + if (!format.equals("txt") && !format.equals("json")) { + System.out.println("不支持的格式: " + format); + System.out.println("支持格式: txt, json"); + return; + } + + System.out.println("导出笔记 " + noteId + " 为 " + format + " 格式到: " + filePath); + // TODO: 调用 ExporterFactory.createExporter() 和 export() + } + + /** + * 处理 export-all 命令 + */ + private void handleExportAllCommand(String[] args) { + if (args.length < 2) { + System.out.println("用法: export-all <格式> <路径>"); + System.out.println("示例: export-all json backup.json"); + System.out.println("支持格式: txt, json"); + return; + } + + String format = args[0].toLowerCase(); + String filePath = args[1]; + + if (!format.equals("txt") && !format.equals("json")) { + System.out.println("不支持的格式: " + format); + System.out.println("支持格式: txt, json"); + return; + } + + System.out.println("导出所有笔记为 " + format + " 格式到: " + filePath); + // TODO: 调用 ExporterFactory.createExporter() 和 exportAll() + } + + /** + * 处理 help 命令 + */ + private void handleHelpCommand() { + System.out.println("个人知识管理系统 - 命令行版本"); + System.out.println("=====================================\n"); + + System.out.println("可用命令:"); + System.out.println(" new <标题> <内容> - 创建新笔记"); + System.out.println(" list [--tag TAG] - 列出所有笔记"); + System.out.println(" view <笔记ID> - 查看笔记详情"); + System.out.println(" edit <笔记ID> <新内容> - 编辑笔记内容"); + System.out.println(" delete <笔记ID> - 删除笔记"); + System.out.println(" tag <笔记ID> <标签> - 添加标签"); + System.out.println(" untag <笔记ID> <标签> - 移除标签"); + System.out.println(" search <关键词> - 搜索笔记"); + System.out.println(" export <格式> <路径> - 导出笔记"); + System.out.println(" export-all <格式> <路径> - 导出所有笔记"); + System.out.println(" help - 显示此帮助信息"); + System.out.println(" exit - 退出程序\n"); + + System.out.println("示例:"); + System.out.println(" pkm new \"Java笔记\" \"面向对象编程的三大特性...\""); + System.out.println(" pkm list --tag java"); + System.out.println(" pkm view 123e4567"); + System.out.println(" pkm search \"设计模式\""); + System.out.println(" pkm export 123e4567 txt output.txt"); + } + + /** + * 处理 exit 命令 + */ + private void handleExitCommand() { + System.out.println("感谢使用个人知识管理系统!"); + isRunning = false; + } + + /** + * 解析命令选项(如 --tag value) + */ + private Map parseOptions(String[] args) { + Map options = new HashMap<>(); + + for (int i = 0; i < args.length; i++) { + if (args[i].startsWith("--")) { + String key = args[i].substring(2); + if (i + 1 < args.length && !args[i + 1].startsWith("--")) { + options.put(key, args[i + 1]); + i++; // 跳过值参数 + } else { + options.put(key, "true"); + } + } + } + + return options; + } + + /** + * 关闭资源 + */ + public void close() { + if (scanner != null) { + scanner.close(); + } + } +} diff --git a/src/main/java/com/example/model/ExportFormat.java b/src/main/java/com/example/model/ExportFormat.java new file mode 100644 index 0000000..75ce90b --- /dev/null +++ b/src/main/java/com/example/model/ExportFormat.java @@ -0,0 +1,7 @@ +package com.example.model; + +public enum ExportFormat { + TXT, + JSON, + PDF +}