7 Commits

Author SHA1 Message Date
Chuck1sn
96de9a215f 更新 README.md 2026-03-20 10:19:30 +08:00
Chuck1sn
59631cea3d 更新用户管理页面中的推广横幅文本,修改为“AI 时代的 Java 测试驱动开发” 2025-08-12 10:52:50 +08:00
Chuck1sn
9425c2c88d 更新group.png图片文件 2025-07-29 16:27:33 +08:00
Chuck1sn
38556f3417 remove comment 2025-07-25 06:33:11 +08:00
Chuck1sn
f0a237fdf3 更新group.png图片文件 2025-07-24 11:03:25 +08:00
Chuck1sn
13d240342c 优化Assistant.vue组件中的Modal初始化,调整useAiChat.ts中的消息处理逻辑,简化package.json中的workerDirectory格式。 2025-07-17 21:36:38 +08:00
Chuck1sn
8e20f561a4 remove md 2025-07-17 17:01:41 +08:00
8 changed files with 17 additions and 161 deletions

View File

@@ -30,31 +30,27 @@
- [🍑 更多](#-更多) - [🍑 更多](#-更多)
- [🍒 部分技术选型](#-部分技术选型) - [🍒 部分技术选型](#-部分技术选型)
- [🔮 防失联,关注各大社区账号](#-防失联关注各大社区账号) - [🔮 防失联,关注各大社区账号](#-防失联关注各大社区账号)
- [💌 微信打赏](#-微信打赏)
## 🥝 产品社群 ## 🥝 产品社群
**加 QQ 群或微信群立送以下装备,瞬间秒杀全服!!**
1. 一键部署脚本(包含数据库 Redis 消息队列等所有中间件!) 1. 一键部署脚本(包含数据库 Redis 消息队列等所有中间件!)
2. 永久免费的 Https 证书 2. 永久免费的 Https 证书
3. 永久免费的分布式对象存储 3. 永久免费的分布式对象存储
4. 永久免费的 AI 模型 4. 永久免费的 AI 模型
5. 永久免费的 Node、Docker、Maven 国内镜像仓库 5. 永久免费的 Node、Docker、Maven 国内镜像仓库
![group](assets/group.png)
[![点击按钮加入 QQ群](https://img.shields.io/badge/-white?style=social&logo=QQ&label=或点击按钮加入QQ群)](https://qm.qq.com/q/9mvVC57jPO) [![点击按钮加入 QQ群](https://img.shields.io/badge/-white?style=social&logo=QQ&label=或点击按钮加入QQ群)](https://qm.qq.com/q/9mvVC57jPO)
- QQ群638254979(目前人较多) - QQ群638254979
- 微信Chuck9996(若微信群已过期可以加我 vx)
## 🍅 相关课程 ## 🍅 相关课程
已上线: 已上线:
- [国内首个无幻觉式 AI 编程指南](https://www.bilibili.com/cheese/play/ep1615343) - [AI 时代的 Java 测试驱动开发](https://www.bilibili.com/cheese/play/ep1615343)
敬请期待:(加群获取) 敬请期待:(加群获取)
@@ -209,9 +205,3 @@
[![Github](https://img.shields.io/badge/-white?style=social&logo=github&label=github)](https://github.com/ccmjga) [![Github](https://img.shields.io/badge/-white?style=social&logo=github&label=github)](https://github.com/ccmjga)
[![QQ](https://img.shields.io/badge/-white?style=social&logo=QQ&label=QQ群)](https://qm.qq.com/q/9mvVC57jPO) [![QQ](https://img.shields.io/badge/-white?style=social&logo=QQ&label=QQ群)](https://qm.qq.com/q/9mvVC57jPO)
## 💌 微信打赏
知路管理后台的发展离不开您的支持;再次对所有支持本项目的人们致以诚挚的谢意~
![pay](/assets/pay.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 538 KiB

After

Width:  |  Height:  |  Size: 580 KiB

View File

@@ -6,40 +6,10 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/**
* 跳过AOP日志记录注解
*
* <p>在方法上添加此注解该方法将不会被AOP日志切面拦截和记录。
*
* <p>使用场景:
*
* <ul>
* <li>敏感操作方法,不希望记录日志
* <li>高频调用方法,避免产生过多日志
* <li>内部工具方法,不需要业务日志记录
* </ul>
*
* <p>使用示例:
*
* <pre>{@code
* @SkipAopLog
* public void sensitiveMethod() {
* // 此方法不会被AOP日志记录
* }
* }</pre>
*
* @author AOP Log System
* @since 1.0
*/
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
public @interface SkipAopLog { public @interface SkipAopLog {
/**
* 跳过日志记录的原因说明(可选)
*
* @return 跳过原因
*/
String reason() default ""; String reason() default "";
} }

View File

@@ -1,103 +0,0 @@
# LoggingAspect generateCurlCommand 方法单元测试
## 测试概述
本测试文件 `LoggingAspectCurlGenerationTest.java` 专门针对 `LoggingAspect` 类中的 `generateCurlCommand` 方法进行全面的单元测试,验证该方法在各种场景下生成 curl 命令的正确性。
## 测试架构
测试采用 **嵌套测试类** 的结构,按功能模块组织:
### 1. GET 请求测试 (`GetRequestTests`)
- ✅ 基本 GET 请求 - 无查询参数
- ✅ GET 请求 - 包含查询参数
- ✅ GET 请求 - HTTPS 协议
- ✅ GET 请求 - 自定义端口
### 2. POST 请求测试 (`PostRequestTests`)
- ✅ POST 请求 - JSON 请求体
- ✅ POST 请求 - 空 JSON 请求体
- ✅ POST 请求 - 包含单引号的 JSON
### 3. PUT 和 PATCH 请求测试 (`PutAndPatchRequestTests`)
- ✅ PUT 请求 - JSON 请求体
- ✅ PATCH 请求 - JSON 请求体
### 4. 表单数据请求测试 (`FormDataRequestTests`)
- ✅ POST 请求 - 表单数据
- ✅ POST 请求 - 多值表单参数
- ✅ POST 请求 - 空表单数据
### 5. 请求头处理测试 (`HeaderProcessingTests`)
- ✅ 包含常规请求头
- ✅ 跳过特定请求头
- ✅ 验证跳过的请求头不会出现在 curl 命令中
### 6. 异常情况测试 (`ExceptionHandlingTests`)
- ✅ 读取请求体时发生 IOException
- ✅ 请求参数为 null
- ✅ 请求方法为 null
- ✅ 服务器信息为 null
### 7. 边界用例测试 (`BoundaryTests`)
- ✅ 最小化 GET 请求
- ✅ 复杂查询参数 - 包含特殊字符
- ✅ DELETE 请求 - 不应包含请求体
- ✅ HTTPS 请求 - 标准端口 443
- ✅ JSON 请求体为 null
## 测试覆盖的功能点
### 核心功能验证
1. **HTTP 方法处理**: GET, POST, PUT, PATCH, DELETE
2. **URL 构建**: 协议、主机名、端口、路径、查询参数
3. **请求头处理**: 包含/排除特定请求头
4. **请求体处理**: JSON、表单数据、空请求体
5. **异常处理**: 各种异常情况的优雅处理
### 特殊场景验证
1. **端口处理**: 标准端口省略,非标准端口包含
2. **字符转义**: JSON 中的单引号转义
3. **空值处理**: null 值的安全处理
4. **多值参数**: 表单中同名参数的多个值
## 测试技术特点
### 使用的测试技术
- **JUnit 5**: 现代化的测试框架
- **Mockito**: Mock 对象和行为验证
- **AssertJ**: 流畅的断言 API
- **嵌套测试**: 清晰的测试组织结构
### Mock 策略
- Mock `HttpServletRequest` 对象模拟各种 HTTP 请求场景
- Mock 依赖服务避免外部依赖
- 精确控制测试数据和行为
### 断言策略
- 验证生成的 curl 命令包含预期内容
- 验证不应包含的内容确实被排除
- 验证异常情况的错误消息
## 运行测试
```bash
# 运行所有 generateCurlCommand 相关测试
./gradlew test --tests "com.zl.mjga.unit.LoggingAspectCurlGenerationTest"
# 运行特定测试类别
./gradlew test --tests "com.zl.mjga.unit.LoggingAspectCurlGenerationTest\$GetRequestTests"
```
## 测试价值
这套测试确保了 `generateCurlCommand` 方法在各种复杂场景下都能正确工作,为 AOP 日志功能的 curl 命令生成提供了可靠的质量保证。通过全面的测试覆盖,可以:
1. **防止回归**: 代码修改时及时发现问题
2. **文档作用**: 测试用例本身就是最好的使用文档
3. **重构支持**: 安全地进行代码重构
4. **质量保证**: 确保功能在各种边界条件下正常工作
## 测试结果
所有 **24 个测试用例** 均通过,覆盖了 `generateCurlCommand` 方法的所有主要功能和边界情况。

View File

@@ -59,8 +59,6 @@
"vue-tsc": "^2.2.8" "vue-tsc": "^2.2.8"
}, },
"msw": { "msw": {
"workerDirectory": [ "workerDirectory": ["public"]
"public"
]
} }
} }

View File

@@ -443,10 +443,7 @@ onMounted(async () => {
const $userDeleteModalElement: HTMLElement | null = const $userDeleteModalElement: HTMLElement | null =
document.querySelector("#user-delete-modal"); document.querySelector("#user-delete-modal");
if ($userDeleteModalElement) { if ($userDeleteModalElement) {
userDeleteModal.value = new Modal( userDeleteModal.value = new Modal($userDeleteModalElement, {});
$userDeleteModalElement,
{}
);
} }
const $departmentDeleteModalElement: HTMLElement | null = const $departmentDeleteModalElement: HTMLElement | null =
document.querySelector("#department-delete-modal"); document.querySelector("#department-delete-modal");

View File

@@ -111,19 +111,23 @@ export const useAiChat = () => {
const searchAction = async (message: string) => { const searchAction = async (message: string) => {
isLoading.value = true; isLoading.value = true;
try { try {
const { data } = await client.POST("/ai/action/search", {
body: message,
});
messages.value.push({ messages.value.push({
content: data?.action content: "",
? "搜索到功能,请您执行。"
: "未搜索到指定功能,请告诉我更加准确的信息。",
type: "action", type: "action",
isUser: false, isUser: false,
username: "知路智能体", username: "知路智能体",
command: data?.action, command: undefined,
}); });
return data; const { data } = await client.POST("/ai/action/search", {
body: message,
});
messages.value[messages.value.length - 1].content = data?.action
? "搜索到功能,请您执行。"
: "未搜索到指定功能,请告诉我更加准确的信息。";
messages.value[messages.value.length - 1].command = data?.action;
} catch (error) {
messages.value.pop();
throw error;
} finally { } finally {
isLoading.value = false; isLoading.value = false;
} }

View File

@@ -2,7 +2,7 @@
<div class="px-2 sm:px-4 pt-6 sm:rounded-lg"> <div class="px-2 sm:px-4 pt-6 sm:rounded-lg">
<div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-4"> <div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-4">
<PromotionBanner href="https://www.bilibili.com/cheese/play/ss198449120" imageSrc="/ai-tdd.png" <PromotionBanner href="https://www.bilibili.com/cheese/play/ss198449120" imageSrc="/ai-tdd.png"
imageAlt="ai-tdd-tutorial" label="官方教程" text="无幻觉式 AI 编程方法论" /> imageAlt="ai-tdd-tutorial" label="官方教程" text="AI 时代的 Java 测试驱动开发" />
<PromotionBanner href="https://www.mjga.cc" imageSrc="/mjga.png" imageAlt="后端脚手架" label="后端脚手架" <PromotionBanner href="https://www.mjga.cc" imageSrc="/mjga.png" imageAlt="后端脚手架" label="后端脚手架"
text="国内唯一可选配组件和元信息的脚手架" /> text="国内唯一可选配组件和元信息的脚手架" />
</div> </div>