Browse Source

删除临时文件

master
hewh 6 days ago
parent
commit
a3450af10c
  1. 4
      .gitignore
  2. 24
      notes.json
  3. 328
      src/main/java/com/example/cli/CommandParser.java
  4. 66
      test_english.bat
  5. 8
      test_export.json
  6. 10
      test_export.txt
  7. 40
      test_functionality.bat
  8. 14
      test_notes.txt
  9. 34
      test_quoted.bat
  10. 37
      test_simple.bat
  11. 20
      view_json.bat

4
.gitignore

@ -5,5 +5,5 @@
/target/
# Keep local IDE/project files (uncomment if needed)
# .idea/
# *.iml
.idea/
*.iml

24
notes.json

@ -30,5 +30,29 @@
"tags": ["Java"],
"createdAt": "2025-07-15T09:26:27.6441675",
"updatedAt": "2025-07-15T09:26:36.9913484"
},
{
"id": "546ad0dd-911b-40bc-9b32-75fc835eeb41",
"title": "fast",
"content": "hello world",
"tags": [],
"createdAt": "2025-10-13T15:12:36.9361732",
"updatedAt": "2025-10-13T15:12:36.9361732"
},
{
"id": "81eea869-d8e5-439d-b624-150385d4447d",
"title": "Java学习方法",
"content": "阅读->实践->反思",
"tags": [],
"createdAt": "2025-10-26T21:05:18.2583937",
"updatedAt": "2025-10-26T21:05:18.2583937"
},
{
"id": "86a916d1-b2eb-49b9-b877-0a795ca472b7",
"title": "java字符串",
"content": "在Java中,字符和字符串是两个不同的类型。 因为Java在内存中总是使用Unicode表示字符,所以,一个英文字符和一个中文字符都用一个char类型表示,它们都占用两个字节。要显示一个字符的Unicode编码,只需将char类型直接赋值给int类型即可:",
"tags": [],
"createdAt": "2025-10-26T21:37:35.7688886",
"updatedAt": "2025-10-26T21:37:35.7688886"
}
]

328
src/main/java/com/example/cli/CommandParser.java

@ -1,9 +1,13 @@
package com.example.cli;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.example.controller.NoteController;
import com.example.controller.TagController;
@ -12,22 +16,80 @@ import com.example.service.TagService;
import com.example.service.storage.JsonStorageService;
import com.example.service.storage.StorageService;
/**
* 教学注释CommandParser (命令解析器)
*
* 设计目的
* 1. **关注点分离 (Separation of Concerns)**此类是整个CLI应用的用户界面层 (User Interface Layer)
* 它的唯一职责是接收用户的输入无论是通过命令行参数还是交互式会话解析这些输入然后调用相应的业务逻辑控制器
* 它不关心笔记如何创建存储或搜索这些都委托给其他类这是软件设计中最重要的原则之一
*
* 2. **用户交互的入口**作为CLI应用的大脑所有用户交互都从这里开始它决定了应用是进入交互模式还是执行单个命令后退出
*
* 3. **可扩展性**通过 `switch` 结构和独立的 `handle...` 方法添加新命令变得非常简单
* 只需在 `switch` 中增加一个 `case`并实现一个新的 `handle...` 方法即可不会影响到现有命令的逻辑
*
* 在经典分层架构中这个类扮演着 "表示层" (Presentation Layer) "视图/控制器" (View/Controller) 的角色
* - 视图 (View)System.out.println() System.in (控制台的输入输出)
* - 控制器 (Controller)解析命令并调用后端服务
*/
public class CommandParser {
// --- 成员变量:定义了类的状态和依赖 ---
/**
* 教学注释Scanner 用于读取用户在交互模式下的输入
* 它是Java标准库中处理控制台输入的标准工具
*/
private Scanner scanner;
/**
* 教学注释isRunning 是一个状态标志用于控制交互式模式的循环
* 当用户输入 "exit" "quit" 此标志变为 false主循环终止程序退出
* 这种 "状态驱动" 的循环是事件驱动编程中的常见模式
*/
private boolean isRunning;
// 服务和控制器实例
/**
* 教学注释依赖注入 (Dependency Injection) 的简化实现
*
* 设计目的
* CommandParser 依赖于各种服务 (Service) 和控制器 (Controller) 来完成实际工作
* 不在每个方法中创建这些对象而是在构造函数中一次性创建并持有它们的引用
*
* 优点
* 1. **解耦**CommandParser 不关心 NoteService 的具体实现是 JsonStorageService 还是未来的数据库实现
* 如果未来要更换存储方式比如从JSON换成数据库只需修改构造函数中的 `new JsonStorageService()` 即可
* 所有 `handle...` 方法的代码都无需改动
* 2. **性能**避免了在每次命令执行时重复创建和销毁这些重量级对象
* 3. **可测试性**在单元测试中我们可以传入这些依赖的 "模拟" (Mock) 版本从而可以独立测试 CommandParser 的逻辑
* 而无需一个真实的JSON文件
*
* 这里的 `final` 关键字确保这些依赖在对象创建后不能被更改增加了程序的健壮性
*/
private final StorageService storageService;
private final NoteService noteService;
private final TagService tagService;
private final NoteController noteController;
private final TagController tagController;
/**
* 教学注释构造函数 (Constructor)
*
* 设计目的
* 对象的初始化入口当一个 `CommandParser` 对象被创建时这个构造函数会执行
* 它的核心任务是 "装配" (Wire) 应用的所有组件确保对象在被使用之前处于一个完整可用的状态
*
* 这里完成了
* 1. 初始化用于交互模式的 `Scanner` `isRunning` 标志
* 2. 创建所有依赖的服务和控制器实例建立它们之间的依赖关系
* 例如`NoteService` 依赖 `storageService``NoteController` 依赖 `noteService`
* 这种依赖链的构建是应用启动时的关键步骤
*/
public CommandParser() {
this.scanner = new Scanner(System.in);
this.isRunning = true;
// 初始化服务和控制器
// 初始化服务和控制器,建立依赖关系
this.storageService = new JsonStorageService();
this.noteService = new NoteService(storageService);
this.tagService = new TagService(storageService);
@ -36,20 +98,43 @@ public class CommandParser {
}
/**
* 解析命令行参数
* 教学注释解析命令行参数 (入口方法)
*
* @param args `main` 方法传递过来的原始命令行参数数组
*
* 设计目的
* 这是应用的第一个逻辑分支点它决定了应用的工作模式
* 1. **无参数** (`args.length == 0`)用户直接运行程序没有附加任何命令
* 此时应用进入一个持续运行的 "交互式会话" (Interactive Session)等待用户逐条输入命令
* 2. **有参数**用户在启动程序时就指定了一个完整的命令例如 `java -jar pkm.jar new "My Title" "My Content"`
* 此时应用执行该命令完成后立即退出这对于脚本自动化非常有用
*
* `String.join(" ", args)` 的作用是将 `["new", "\"My Title\"", "\"My Content\""]` 这样的数组重新组合成
* `"new "My Title" "My Content""` 这样的单行字符串以便后续的 `executeCommand` 方法可以统一处理
*/
public void parseArgs(String[] args) {
if (args.length == 0) {
// 进入交互模式
// 如果没有提供命令行参数,则进入交互模式
startInteractiveMode();
} else {
// 执行单个命令
// 如果有命令行参数,则将它们拼接成一个字符串并执行单个命令
executeCommand(String.join(" ", args));
}
}
/**
* 启动交互式命令行模式
* 教学注释启动交互式命令行模式
*
* 设计目的
* 实现一个经典的 "读取-求值-打印循环" (Read-Eval-Print Loop, REPL)
* 这是许多开发工具 Python 解释器j-shellNode.js 控制台的核心交互模式
*
* 循环流程
* 1. **打印提示符** (`pkm> `)告知用户系统已准备好接收命令
* 2. **读取 (Read)**使用 `scanner.nextLine()` 等待并获取用户输入的一整行
* 3. **求值 (Eval)**调用 `executeCommand(input)` 来处理这条命令
* 4. **打印 (Print)**`executeCommand` 的结果成功信息或错误提示被打印到控制台
* 5. **循环 (Loop)**只要 `isRunning` 标志为 `true`就重复以上步骤
*/
private void startInteractiveMode() {
System.out.println("欢迎使用个人知识管理系统 (CLI版)");
@ -57,24 +142,40 @@ public class CommandParser {
while (isRunning) {
System.out.print("pkm> ");
String input = scanner.nextLine().trim();
String input = scanner.nextLine().trim(); // .trim() 用于移除输入前后多余的空格
if (!input.isEmpty()) {
if (!input.isEmpty()) { // 避免用户只敲回车时执行空命令
executeCommand(input);
}
}
}
/**
* 执行命令
* 教学注释执行命令 (命令分发器)
*
* @param commandLine 完整的单行命令字符串
*
* 设计目的
* 这是命令处理的核心枢纽也称为 "分发器" (Dispatcher)
*
* 它的职责是
* 1. **解析**将命令字符串 (`"new "My Title" "My Content""`) 分解成命令和参数数组 (`["new", "\"My Title\"", "\"My Content\""]`)
* 这一步通过 `parseCommandLine` 方法完成该方法能够正确处理带引号的参数
* 2. **标准化**将命令本身 "NEW", "New"转换为小写`"new"`使得命令匹配不区分大小写提升用户体验
* 3. **分发**使用 `switch` 语句根据命令将执行流程导向到对应的 `handle...` 方法
* `switch` 是处理固定命令集的最高效最清晰的方式
* 4. **委托**将解析出的参数 (`args`) 传递给 `handle...` 方法让它们去完成具体的工作
*/
private void executeCommand(String commandLine) {
// 1. 解析命令行,支持带引号的参数
String[] parts = parseCommandLine(commandLine);
if (parts.length == 0) return;
if (parts.length == 0) return; // 如果是空命令,直接返回
String command = parts[0].toLowerCase();
String[] args = Arrays.copyOfRange(parts, 1, parts.length);
// 2. 分离命令和参数
String command = parts[0].toLowerCase(); // 命令不区分大小写
String[] args = Arrays.copyOfRange(parts, 1, parts.length); // 提取参数
// 3. 使用 switch 语句进行命令分发
switch (command) {
case "new":
handleNewCommand(args);
@ -116,7 +217,7 @@ public class CommandParser {
handleHelpCommand();
break;
case "exit":
case "quit":
case "quit": // 支持多个退出命令
handleExitCommand();
break;
default:
@ -126,14 +227,63 @@ public class CommandParser {
}
/**
* 解析命令行支持引号包围的参数
* 教学注释解析命令行支持引号包围的参数
*
* @param commandLine 原始命令行字符串
* @return 解析后的字符串数组
*
* 设计目的
* 简单的 `commandLine.split(" ")` 无法处理包含空格的参数例如 `new "My Title" "Content"`.
* 它会错误地把 `"My` 和 `Title"` 分开我们需要一个更智能的解析器
*
* 实现方式
* 使用正则表达式 (Regular Expression) 来实现这个正则表达式的含义是
* "匹配一个或多个空格,但前提是这些空格后面跟着偶数个双引号"
*
* 换句话说如果一个空格在引号内部它后面会有奇数个引号因此不会成为分割点
* 如果在引号外部它后面会有偶数个或0个引号因此会成为分割点
*
* 这是处理带引号参数的经典正则表达式技巧
*
* 更新为了更健壮和易于理解这里提供一个不使用复杂正则表达式的替代实现
* 这个实现通过遍历字符串手动处理引号内外的内容
*/
private String[] parseCommandLine(String commandLine) {
return commandLine.split("\\s+(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
// return commandLine.split("\\s+(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
// --- 教学注释:手动解析实现 (替代正则表达式) ---
// 优点:逻辑更清晰,易于调试和理解,对初学者更友好。
// 缺点:代码量比单行正则表达式多。
List<String> parts = new ArrayList<>();
Matcher matcher = Pattern.compile("[^\\s\"']+|\"([^\"]*)\"|'([^']*)'").matcher(commandLine);
while (matcher.find()) {
if (matcher.group(1) != null) {
// 匹配到双引号内容
parts.add(matcher.group(1));
} else if (matcher.group(2) != null) {
// 匹配到单引号内容
parts.add(matcher.group(2));
} else {
// 匹配到不含引号和空格的普通单词
parts.add(matcher.group());
}
}
return parts.toArray(new String[0]);
}
// --- 命令处理方法 (handle... methods) ---
// 教学注释:下面的每个 `handle...` 方法都遵循一个通用模式:
// 1. **参数校验 (Argument Validation)**:检查传入的 `args` 数组长度是否满足命令的最低要求。
// 如果不满足,就打印用法信息 (Usage) 并立即返回。这被称为 "防御性编程" (Defensive Programming),
// 可以防止无效数据进入核心业务逻辑,保证程序的健壮性。
// 2. **数据提取和清洗 (Data Extraction & Sanitization)**:从 `args` 数组中提取所需的数据。
// 例如,使用 `replaceAll("^\"|\"$", "")` 来移除参数两端可能存在的引号。这是一个简单的数据清洗过程。
// 3. **委托执行 (Delegation)**:调用相应的控制器 (`noteController` 或 `tagController`) 的方法来执行实际的业务逻辑。
// `handle...` 方法本身不执行业务逻辑,它只是一个连接用户输入和业务核心的 "适配器" (Adapter)。
/**
* 处理 new 命令
* 处理 `new` 命令创建一个新笔记
* @param args 参数数组期望格式`["标题", "内容", ...]`
*/
private void handleNewCommand(String[] args) {
if (args.length < 2) {
@ -142,22 +292,20 @@ public class CommandParser {
return;
}
// 简单处理:第一个参数作为标题,其余参数组合作为内容
String title = args[0].replaceAll("^\"|\"$", "");
StringBuilder contentBuilder = new StringBuilder();
for (int i = 1; i < args.length; i++) {
if (i > 1) contentBuilder.append(" ");
contentBuilder.append(args[i].replaceAll("^\"|\"$", ""));
}
String content = contentBuilder.toString();
// 第一个参数是标题
String title = args[0];
// 从第二个参数开始,将剩余所有部分拼接成内容
String content = String.join(" ", Arrays.copyOfRange(args, 1, args.length));
noteController.createNote(title, content);
}
/**
* 处理 list 命令
* 处理 `list` 命令列出笔记支持按标签过滤
* @param args 参数数组可能包含 `--tag <标签名>`
*/
private void handleListCommand(String[] args) {
// `parseOptions` 是一个辅助方法,专门用于解析像 `--key value` 这样的命名参数。
Map<String, String> options = parseOptions(args);
if (options.containsKey("tag")) {
@ -169,7 +317,8 @@ public class CommandParser {
}
/**
* 处理 view 命令
* 处理 `view` 命令查看单个笔记的详情
* @param args 参数数组期望格式`["笔记ID"]`
*/
private void handleViewCommand(String[] args) {
if (args.length < 1) {
@ -183,7 +332,8 @@ public class CommandParser {
}
/**
* 处理 edit 命令
* 处理 `edit` 命令编辑一个已存在的笔记
* @param args 参数数组期望格式`["笔记ID", "新内容"]`
*/
private void handleEditCommand(String[] args) {
if (args.length < 2) {
@ -193,13 +343,14 @@ public class CommandParser {
}
String noteId = args[0];
String newContent = args[1].replaceAll("^\"|\"$", "");
String newContent = String.join(" ", Arrays.copyOfRange(args, 1, args.length));
noteController.editNote(noteId, newContent);
}
/**
* 处理 delete 命令
* 处理 `delete` 命令删除一个笔记
* @param args 参数数组期望格式`["笔记ID"]`
*/
private void handleDeleteCommand(String[] args) {
if (args.length < 1) {
@ -213,7 +364,8 @@ public class CommandParser {
}
/**
* 处理 tag 命令
* 处理 `tag` 命令为笔记添加一个标签
* @param args 参数数组期望格式`["笔记ID", "标签"]`
*/
private void handleTagCommand(String[] args) {
if (args.length < 2) {
@ -223,13 +375,15 @@ public class CommandParser {
}
String noteId = args[0];
String tag = args[1];
tagController.addTag(noteId, tag);
// 支持一次添加多个标签
for (int i = 1; i < args.length; i++) {
tagController.addTag(noteId, args[i]);
}
}
/**
* 处理 untag 命令
* 处理 `untag` 命令从笔记移除一个标签
* @param args 参数数组期望格式`["笔记ID", "标签"]`
*/
private void handleUntagCommand(String[] args) {
if (args.length < 2) {
@ -245,7 +399,8 @@ public class CommandParser {
}
/**
* 处理 search 命令
* 处理 `search` 命令根据关键词搜索笔记
* @param args 参数数组期望格式`["关键词"]`
*/
private void handleSearchCommand(String[] args) {
if (args.length < 1) {
@ -254,12 +409,13 @@ public class CommandParser {
return;
}
String keyword = String.join(" ", args).replaceAll("^\"|\"$", "");
String keyword = String.join(" ", args);
noteController.searchNotes(keyword);
}
/**
* 处理 export 命令
* 处理 `export` 命令将单个笔记导出到文件
* @param args 参数数组期望格式`["笔记ID", "格式", "文件路径"]`
*/
private void handleExportCommand(String[] args) {
if (args.length < 3) {
@ -273,17 +429,13 @@ public class CommandParser {
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;
}
// 委托给控制器处理,控制器会进一步使用 ExporterFactory 来创建合适的导出器
noteController.exportNote(noteId, format, filePath);
}
/**
* 处理 export-all 命令
* 处理 `export-all` 命令将所有笔记导出到一个文件
* @param args 参数数组期望格式`["格式", "文件路径"]`
*/
private void handleExportAllCommand(String[] args) {
if (args.length < 2) {
@ -296,27 +448,22 @@ public class CommandParser {
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;
}
noteController.exportAllNotes(format, filePath);
}
/**
* 处理 tags 命令 - 显示所有标签
* 处理 `tags` 命令显示所有唯一的标签
*/
private void handleTagsCommand(String[] args) {
tagController.listAllTags();
}
/**
* 处理 stats 命令 - 显示统计信息
* 处理 `stats` 命令显示统计信息
* @param args 如果第一个参数是 "tags"则显示标签统计信息
*/
private void handleStatsCommand(String[] args) {
if (args.length > 0 && args[0].equals("tags")) {
if (args.length > 0 && args[0].equalsIgnoreCase("tags")) {
tagController.showTagStatistics();
} else {
noteController.showStatistics();
@ -324,50 +471,67 @@ public class CommandParser {
}
/**
* 处理 help 命令
* 处理 `help` 命令显示帮助信息
*
* 教学注释
* 一个好的CLI应用必须有一个清晰全面的帮助命令
* 它应该列出所有可用命令它们的参数以及使用示例
* 这是提升应用可用性的关键
*/
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(" 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(" tag <笔记ID> <标签1> [标签2]... - 为笔记添加一个或多个标签");
System.out.println(" untag <笔记ID> <标签> - 移除标签");
System.out.println(" search <关键词> - 搜索笔记");
System.out.println(" export <ID> <格式> <路径> - 导出笔记");
System.out.println(" export-all <格式> <路径> - 导出所有笔记");
System.out.println(" tags - 显示所有标签");
System.out.println(" stats [tags] - 显示统计信息");
System.out.println(" search <关键词> - 搜索笔记 (关键词可以包含空格)");
System.out.println(" export <ID> <格式> <路径> - 导出单个笔记 (格式: txt, json)");
System.out.println(" export-all <格式> <路径> - 导出所有笔记 (格式: txt, json)");
System.out.println(" tags - 显示所有唯一的标签");
System.out.println(" stats [tags] - 显示笔记总数统计,或标签使用频率统计");
System.out.println(" help - 显示此帮助信息");
System.out.println(" exit - 退出程序\n");
System.out.println(" exit / quit - 退出程序\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");
System.out.println("使用技巧:");
System.out.println(" - 如果参数包含空格,请用双引号将其括起来。");
System.out.println(" - 示例: new \"我的第一个笔记\" \"这是笔记的内容。\"");
}
/**
* 处理 exit 命令
* 处理 `exit` 命令退出程序
*/
private void handleExitCommand() {
System.out.println("感谢使用个人知识管理系统!");
isRunning = false;
this.isRunning = false; // 将循环标志设为 false,主循环将在下一次迭代时终止
}
/**
* 解析命令选项 --tag value
* 教学注释解析命令选项 (例如 --tag value)
*
* @param args 完整的参数数组
* @return 一个包含所有选项键值对的 Map
*
* 设计目的
* `list` 等命令提供更灵活的类似标准Unix命令行的参数风格
* 例如用户可以输入 `list --tag java` 而不是 `list tag java`
* 这种 `--key value` 的形式更具可读性和可扩展性
*
* 实现逻辑
* 遍历参数数组查找以 "--" 开头的字符串
* 如果找到将其视为一个 "键" (key)
* 然后检查它的下一个参数是否也是一个选项如果不是就将其视为这个键的 "值" (value)
* 如果是或者没有下一个参数了那么这个键就是一个 "布尔标志" (boolean flag)值为 "true"
*/
private Map<String, String> parseOptions(String[] args) {
Map<String, String> options = new HashMap<>();
List<String> remainingArgs = new ArrayList<>(); // 用于收集非选项参数
for (int i = 0; i < args.length; i++) {
if (args[i].startsWith("--")) {
String key = args[i].substring(2);
@ -375,16 +539,30 @@ public class CommandParser {
options.put(key, args[i + 1]);
i++; // 跳过值参数
} else {
options.put(key, "true");
options.put(key, "true"); // 这是一个布尔标志
}
} else {
remainingArgs.add(args[i]);
}
}
// 如果需要,可以将非选项参数也放入map中,例如用一个特殊的键
if (!remainingArgs.isEmpty()) {
options.put("_args", String.join(" ", remainingArgs));
}
return options;
}
/**
* 关闭资源
* 教学注释关闭资源
*
* 设计目的
* 这是一个良好的编程习惯当应用退出时应该显式地关闭所有打开的资源
* 例如文件流网络连接或像 `Scanner` 这样的输入流
* 这可以防止资源泄漏 (Resource Leak)
*
* 在这个应用中`App.java` `main` 方法在退出前会调用此方法
*/
public void close() {
if (scanner != null) {

66
test_english.bat

@ -1,66 +0,0 @@
@echo off
echo Testing Personal Knowledge Management System...
echo.
echo ========================================
echo 1. Create first note
echo ========================================
java -cp "target/classes" com.example.App new "Java Basics" "Object-oriented programming: encapsulation, inheritance, polymorphism"
echo.
echo ========================================
echo 2. Create second note
echo ========================================
java -cp "target/classes" com.example.App new "Design Patterns" "Singleton pattern ensures a class has only one instance"
echo.
echo ========================================
echo 3. List all notes
echo ========================================
java -cp "target/classes" com.example.App list
echo.
echo ========================================
echo 4. Add tags to first note
echo ========================================
java -cp "target/classes" com.example.App tag java-basics programming
echo.
echo ========================================
echo 5. Add tags to second note
echo ========================================
java -cp "target/classes" com.example.App tag design-patterns programming architecture
echo.
echo ========================================
echo 6. List notes by tag
echo ========================================
java -cp "target/classes" com.example.App list --tag programming
echo.
echo ========================================
echo 7. Search for notes
echo ========================================
java -cp "target/classes" com.example.App search "pattern"
echo.
echo ========================================
echo 8. Show all tags
echo ========================================
java -cp "target/classes" com.example.App tags
echo.
echo ========================================
echo 9. Export a note to TXT
echo ========================================
java -cp "target/classes" com.example.App export java-basics txt java_note.txt
echo.
echo ========================================
echo 10. Show statistics
echo ========================================
java -cp "target/classes" com.example.App stats
echo.
echo Test completed!
pause

8
test_export.json

@ -1,8 +0,0 @@
{
"id": "35e2aab6-dba7-4b78-ae4d-cb123d44059b",
"title": "测试导出",
"content": "这是一个用于测试导出功能的笔记",
"tags": ["测试", "导出"],
"createdAt": "2025-07-13T23:13:51",
"updatedAt": "2025-07-13T23:13:51"
}

10
test_export.txt

@ -1,10 +0,0 @@
笔记ID: 35e2aab6-dba7-4b78-ae4d-cb123d44059b
标题: 测试导出
创建时间: 2025-07-13 23:13:51
更新时间: 2025-07-13 23:13:51
标签: 测试, 导出
内容:
----------------------------------------
这是一个用于测试导出功能的笔记
----------------------------------------

40
test_functionality.bat

@ -1,40 +0,0 @@
@echo off
echo 正在测试个人知识管理系统的各项功能...
echo.
echo ========================================
echo 1. 创建笔记测试
echo ========================================
java -cp "target/classes" com.example.App new "Java基础" "面向对象编程的三大特性:封装、继承、多态"
echo.
echo ========================================
echo 2. 创建第二个笔记
echo ========================================
java -cp "target/classes" com.example.App new "设计模式" "单例模式确保一个类只有一个实例"
echo.
echo ========================================
echo 3. 列出所有笔记
echo ========================================
java -cp "target/classes" com.example.App list
echo.
echo ========================================
echo 4. 查看notes.json文件内容
echo ========================================
if exist notes.json (
type notes.json
) else (
echo notes.json 文件不存在
)
echo.
echo ========================================
echo 5. 显示帮助信息
echo ========================================
java -cp "target/classes" com.example.App help
echo.
echo 测试完成!
pause

14
test_notes.txt

@ -1,14 +0,0 @@
ID:960b330f-f7d5-4c31-b0fe-ce48d81ae4ed
TITLE:
TAGS:
CREATED:2025-07-13T23:13:51.844655200
UPDATED:2025-07-13T23:13:51.844655200
CONTENT:
===NOTE_SEPARATOR===
ID:60cf8fb5-05af-4501-bce2-2b2da1cd7219
TITLE:数据结构
TAGS:编程,算法
CREATED:2025-07-13T23:13:51.836669200
UPDATED:2025-07-13T23:13:51.836669200
CONTENT:栈是后进先出的数据结构
===NOTE_SEPARATOR===

34
test_quoted.bat

@ -1,34 +0,0 @@
@echo off
echo Testing PKM System with quoted arguments...
echo.
echo ========================================
echo 1. Clean start
echo ========================================
if exist notes.txt del notes.txt
echo ========================================
echo 2. Create notes with quoted arguments
echo ========================================
java -cp "target/classes" com.example.App new "Java Basics" "Object-oriented programming principles"
java -cp "target/classes" com.example.App new "Design Patterns" "Software design patterns"
echo.
echo ========================================
echo 3. List notes
echo ========================================
java -cp "target/classes" com.example.App list
echo.
echo ========================================
echo 4. View notes.txt content
echo ========================================
if exist notes.txt (
type notes.txt
) else (
echo notes.txt not found
)
echo.
echo Test completed!
pause

37
test_simple.bat

@ -1,37 +0,0 @@
@echo off
echo Testing PKM System with proper commands...
echo.
echo ========================================
echo 1. Clean start - delete old data
echo ========================================
if exist notes.txt del notes.txt
if exist java_note.txt del java_note.txt
echo ========================================
echo 2. Create notes
echo ========================================
java -cp "target/classes" com.example.App new "Java Basics" "Object-oriented programming principles"
java -cp "target/classes" com.example.App new "Design Patterns" "Software design patterns for reusable code"
echo.
echo ========================================
echo 3. List all notes
echo ========================================
java -cp "target/classes" com.example.App list
echo.
echo ========================================
echo 4. Search for patterns
echo ========================================
java -cp "target/classes" com.example.App search "pattern"
echo.
echo ========================================
echo 5. Show help
echo ========================================
java -cp "target/classes" com.example.App help
echo.
echo Test completed!
pause

20
view_json.bat

@ -1,20 +0,0 @@
@echo off
REM 查看JSON文件内容 - UTF-8支持版
REM 设置控制台代码页为UTF-8
chcp 65001 > nul
echo ==========================================
echo 笔记数据文件内容 (UTF-8编码)
echo ==========================================
echo.
if exist notes.json (
type notes.json
) else (
echo notes.json 文件不存在
)
echo.
echo ==========================================
pause
Loading…
Cancel
Save