diff --git a/doc/process/weekly/week-04/members/lmy-weekly-plan-04.md b/doc/process/weekly/week-04/members/lmy-weekly-plan-04.md index b9180643..122d27c5 100644 --- a/doc/process/weekly/week-04/members/lmy-weekly-plan-04.md +++ b/doc/process/weekly/week-04/members/lmy-weekly-plan-04.md @@ -4,8 +4,8 @@ **姓  名:** 李梦源 **团队名称:** 2班-老师指定的组队 -**开始时间:** 2023-10-13 -**结束时间:** 2023-10-20 +**开始时间:** 2025-10-13 +**结束时间:** 2025-10-20 ## 本周任务计划安排 diff --git a/doc/process/weekly/week-04/members/lmy-weekly-summary-04.md b/doc/process/weekly/week-04/members/lmy-weekly-summary-04.md index 9ca93be9..ae5397f6 100644 --- a/doc/process/weekly/week-04/members/lmy-weekly-summary-04.md +++ b/doc/process/weekly/week-04/members/lmy-weekly-summary-04.md @@ -7,9 +7,9 @@ **团队名称:** 2班-老师指定的组队 -**开始时间:** 2023-10-13 +**开始时间:** 2025-10-13 -**结束时间:** 2023-10-20 +**结束时间:** 2025-10-20 ## 本周任务完成情况 diff --git a/doc/process/weekly/week-05/members/fjk-weekly-summary-05.md b/doc/process/weekly/week-05/members/fjk-weekly-summary-05.md index 4b783e3c..a3c50e9b 100644 --- a/doc/process/weekly/week-05/members/fjk-weekly-summary-05.md +++ b/doc/process/weekly/week-05/members/fjk-weekly-summary-05.md @@ -11,14 +11,13 @@ **结束时间:** 2025-10-27 -## 本周任务计划安排 +## 本周任务完成情况 | 序号 | 总结内容 | 是否完成 | 情况说明 | |----|----------|------|-------------------------------------------------------| -| 1 | 配置项目开发环境 | 完成 | 配置前端Vue,后端SpringBoot的相关开发环境 | -| 2 | 学习后端知识 | 完成 | 周内持续学习SpringBoot开发的相关知识 | +| 1 | 配置项目开发环境 | 完成 | 作为后端人员,配置后端SpringBoot的相关开发环境 | +| 2 | 学习后端知识 | 完成 | 学习SpringBoot框架controller,service,mapper方面基础知识 | | 3 | 确定分工 | 完成 | 2025-10-20 开会细分确定团队分工,统一开发工具 | -| 4 | 完成项目原型 | 完成 | 组员通过学习借鉴优秀的原型界面设计模板,利用墨刀平台协作,按照与老师沟通的需求设计Web端系统原型Demo | ## 小结 diff --git a/doc/process/weekly/week-05/members/lmy-weekly-summary-05.md b/doc/process/weekly/week-05/members/lmy-weekly-summary-05.md index 1421e0f5..3098165d 100644 --- a/doc/process/weekly/week-05/members/lmy-weekly-summary-05.md +++ b/doc/process/weekly/week-05/members/lmy-weekly-summary-05.md @@ -16,11 +16,11 @@ | 序号 | 计划内容| 是否完成 | 情况说明 | | ----| ------ | ------| ------- | -| 1 |持续学习前端知识 | 完成 | 持续学习前端vue相关知识,不断提升项目技能 | -| 2 |持续学习界面原型开发知识 | 完成 | 持续学习墨刀的使用,熟练掌握墨刀开发技巧 | -| 3 | 确定分工 | 完成 | 2025-10-20 开会细分确定团队分工,统一开发工具 | -| 4 | 确定需求 | 完成 | 2025-10-25通过视频会议用原型法与彭鹏老师不断的沟通确定需求 | -| 5 | 设计项目原型界面 | 完成 | 通过学习借鉴优秀的原型界面设计模板,借助墨刀工具,按照与老师沟通的需求设计Web端系统原型界面 | +| 1 |持续学习前端知识 | 完成 | 本周完成了Vue基础语法和组件生命周期的学习,掌握了数据绑定和事件处理的核心概念 | +| 2 |持续学习界面原型开发知识 | 完成 | 深入学习了墨刀的高级功能,包括动态效果实现 | +| 3 | 确定分工 | 完成 | 2025-10-20召开团队会议,明确了我负责前端界面设计和原型开发,前端统一了使用Vue 3的技术栈 | +| 4 | 确定需求 | 完成 | 2025-10-25与彭鹏老师进行了的视频会议,通过交互式原型演示明确了系统的核心功能和用户流程,记录了关键需求变更 | +| 5 | 设计项目原型界面 | 完成 | 结合老师反馈和团队讨论,设计了系统原型,实现了基础交互逻辑 | ## 小结 diff --git a/doc/process/weekly/week-06/members/fjk-weekly-summary-06.md b/doc/process/weekly/week-06/members/fjk-weekly-summary-06.md index 17293e8c..a52c54ca 100644 --- a/doc/process/weekly/week-06/members/fjk-weekly-summary-06.md +++ b/doc/process/weekly/week-06/members/fjk-weekly-summary-06.md @@ -1,4 +1,4 @@ -# 个人周计划-第6周 +# 个人周总结-第6周 ## 姓名和起止时间 @@ -11,7 +11,7 @@ **结束时间:** 2025-11-03 -## 本周任务计划安排 +## 本周任务完成情况 | 序号 | 总结内容 | 是否完成 | 情况说明 | |----|---------------|------|-------------------------------| diff --git a/doc/process/weekly/week-06/members/lmy-weekly-sunmmary-06.md b/doc/process/weekly/week-06/members/lmy-weekly-sunmmary-06.md index d681ff57..73879e48 100644 --- a/doc/process/weekly/week-06/members/lmy-weekly-sunmmary-06.md +++ b/doc/process/weekly/week-06/members/lmy-weekly-sunmmary-06.md @@ -1,4 +1,4 @@ -# 个人周计划-第6周 +# 个人周总结-第6周 ## 姓名和起止时间 @@ -15,9 +15,9 @@ | 序号 | 计划内容| 是否完成 | 情况说明 | | ----| ------ | ------| ------- | -| 1 |持续学习前端知识 | 完成 | 持续学习前端vue相关知识,不断提升项目技能 ,不断分析往届学生作品,汲取开发经验 | -| 2 | 确定分工 | 完成 | 2023-10-27 开会细分确定团队分工,明确周任务 | -| 3 | 用例文档撰写 | 完成 | 学习并完成系统用例文档的撰写,并为需求文档其他部分做准备 | +| 1 |持续学习前端知识 | 完成 | 本周深入学习了Vue组件化开发和状态管理,通过分析往届优秀项目,总结了前端开发的最佳实践 | +| 2 | 确定分工 | 完成 | 2025-10-27召开小组会议,明确了各成员的具体职责,我主要负责前端界面开发和原型设计 | +| 3 | 用例文档撰写 | 完成 | 与团队成员协作完成了系统用例文档的撰写,详细描述了用户交互流程和功能需求 | | 4 | 改进项目原型界面 | 完成 | 根据指导老师的建议,借助墨刀工具,不断改进Web端系统原型界面 | diff --git a/doc/process/weekly/week-07/members/fjk-weekly-summary-07.md b/doc/process/weekly/week-07/members/fjk-weekly-summary-07.md index f7f601f1..44d4775f 100644 --- a/doc/process/weekly/week-07/members/fjk-weekly-summary-07.md +++ b/doc/process/weekly/week-07/members/fjk-weekly-summary-07.md @@ -10,16 +10,14 @@ **结束时间:** 2025-11-10 -## 本周任务计划安排 - -| 序号 | 总结内容 | 是否完成 | 情况说明 | -|----|-------------|------|--------------------------------------------------| -| 1 | 学习后端知识 | 完成 | 周内持续学习SpringBoot开发的相关知识 | -| 2 | 确定分工 | 完成 | 2025-11-03,开会细分确定团队分工,明确周任务 | -| 3 | 完善原型界面与用例文档 | 完成 | 2025-11-07 前,完善原型界面,学习并完成系统用例文档的撰写,并为需求文档其他部分做准备 | -| 4 | 撰写项目前景和范围文档 | 完成 | 2025-11-07前,学习并撰写项目前景和范围文档 | -| 5 | 开始数据库设计 | 完成 | 2025-11-05前,学习并开始数据库设计,制作数据库表,绘制ER图 | -| 6 | 撰写需求规格说明书 | 完成 | 2025-11-07前,学习并撰写需求规格说明书第一稿 | +## 本周任务完成情况 + +| 序号 | 总结内容 | 是否完成 | 情况说明 | +|----|-----------|------|-------------------------------------------------------------------| +| 1 | 学习后端知识 | 完成 | 学习springboot框架的demo项目构建 | +| 2 | 完成各种文档 | 完成 | 2025-11-07 前,完善原型界面,学习并完成系统用例文档以及项目前景和范围文档的撰写,并为需求文档其他部分做准备 | +| 3 | 开始数据库设计 | 完成 | 2025-11-05前,学习并开始数据库设计,制作数据库表,绘制ER图 | +| 4 | 撰写需求规格说明书 | 完成 | 2025-11-07前,学习并撰写需求规格说明书第一稿 | ## 小结 diff --git a/doc/process/weekly/week-07/members/lmy-weekly-summary-07.md b/doc/process/weekly/week-07/members/lmy-weekly-summary-07.md index 0eec8093..d0960413 100644 --- a/doc/process/weekly/week-07/members/lmy-weekly-summary-07.md +++ b/doc/process/weekly/week-07/members/lmy-weekly-summary-07.md @@ -14,15 +14,15 @@ | 序号 | 计划内容 | 完成情况 | 情况说明 | |----|-------------|-----|--------------------------------------------------| -| 1 | 学习前端知识 | 完成 | 周内持续学习vue开发的相关知识 | -| 2 | 确定分工 | 完成 | 2025-11-03,开会细分确定团队分工,明确周任务 | -| 3 | 完善原型界面与用例文档 | 完成 | 2025-11-07前 ,完善了原型界面,学习并完成了系统用例文档的撰写,并为需求文档其他部分做准备 | -| 4 | 撰写需求规格说明书 | 完成 | 2025-11-07,学习并撰写了需求规格说明书第一稿 | +| 1 | 学习前端知识 | 完成 | 本周深入学习了Vue 3的Composition API,完成了组件通信和状态管理的实践练习,反复练习了setup语法的核心用法 | +| 2 | 确定分工 | 完成 | 2025-11-03召开团队会议,细化了各成员在需求分析和前端开发阶段的具体职责,制定了详细的任务时间表和交付标准 | +| 3 | 完善原型界面与用例文档 | 完成 | 2025-11-07前完成了原型界面的优化,并为需求文档其他部分做准备 | +| 4 | 撰写需求规格说明书 | 完成 | 2025-11-07与团队协作完成了需求规格说明书第一稿,详细描述了系统功能、非功能需求和数据模型,为后续开发提供了完整的技术指导 | ## 小结 -1. **学习需求:** 希望能有对于原型设计以及vue开发的教学; -2. **知识储备:** 提前学习后续需要使用的知识,为后续的前端开发做准备; +1. **专业成长:** 通过本周的学习和实践,在Vue 3新特性应用方面有了更深入的理解; +2. **项目成果:** 成功完成了原型界面优化和用例文档撰写; 3. **技术预研:** 根据需求了解后续进行开发可能遇到的相关技术难点 4. **撰写需求规格说明书** 学习并参与撰写需求规格说明书 diff --git a/doc/process/weekly/week-08/members/fjk-weekly-summary-08.md b/doc/process/weekly/week-08/members/fjk-weekly-summary-08.md index 77f36e67..dc72c35d 100644 --- a/doc/process/weekly/week-08/members/fjk-weekly-summary-08.md +++ b/doc/process/weekly/week-08/members/fjk-weekly-summary-08.md @@ -10,15 +10,14 @@ **结束时间:** 2025-11-17 -## 本周任务计划安排 - -| 序号 | 总结内容 | 是否完成 | 情况说明 | -|----|---------|------|----------------------------------------------------| -| 1 | 学习后端知识 | 完成 | 周内持续学习SpringBoot开发的相关知识 | -| 2 | 完善数据库设计 | 完成 | 2025-11-16 22:00之前,完善数据库设计,确认数据库表与ER图 | -| 3 | 数据库设计文档 | 完成 | 2025-11-16 22:00之前,完成数据库设计文档的编写,为后续开发提供准确的数据库实现依据。 | -| 4 | 确认迭代计划 | 完成 | 2025-11-11 14:30,与指导老师确认迭代开发计划 | -| 5 | 学习uml设计 | 完成 | 学习编写系统总的用例图,编写该迭代的主要业务功能的活动图、顺序图和类图 | +## 本周任务完成情况 + +| 序号 | 总结内容 | 是否完成 | 情况说明 | +|----|-------|------|----------------------------------------------------| +| 1 | 学习后端知识 | 完成 | 学习mybatis框架的使用 | +| 2 | 数据库设计 | 完成 |完善数据库设计,确认数据库表与ER图,并完成数据库设计文档的编写,为后续开发提供准确的数据库实现依据。 | +| 3 | 确认迭代计划 | 完成 | 2025-11-11 14:30,与指导老师确认迭代开发计划 | +| 4 | 学习uml设计 | 完成 | 学习编写系统总的用例图,编写该迭代的主要业务功能的活动图、顺序图和类图 | ## 小结 diff --git a/doc/process/weekly/week-08/members/lmy-weekly-summary-08.md b/doc/process/weekly/week-08/members/lmy-weekly-summary-08.md index 06ac7545..e21eb16d 100644 --- a/doc/process/weekly/week-08/members/lmy-weekly-summary-08.md +++ b/doc/process/weekly/week-08/members/lmy-weekly-summary-08.md @@ -15,16 +15,16 @@ | 序号 | 计划内容 | 是否完成 | 情况说明 | |----|---------|------|----------------------------------------------------| -| 1 | 学习前端知识 | 完成 | 周内持续学习vue开发的相关知识 | -| 2 | uml设计文档 | 完成 | 2025-11-14学习uml相关知识并完成uml设计文档 | -| 3 | 确认迭代计划 | 完成 | 2025-11-11 14:30,与指导老师确认迭代开发计划 | -| 4 | 完成迭代开发计划第一稿 | 完成 | 2025-11-16根据老师的要求完成开发计划第一稿 | +| 1 | 学习前端知识 | 完成 | 本周系统学习了Vue 3的Composition API、组件通信和路由管理,对前端开发有了更深入的理解。 | +| 2 | uml设计文档 | 完成 | 2025-11-14学习UML核心概念,完成了系统活动图和顺序图的初步设计, | +| 3 | 确认迭代计划 | 完成 | 2025-11-11 14:30与指导老师确认迭代开发计划 | +| 4 | 完成迭代开发计划第一稿 | 完成 | 2025-11-16根据老师的要求完成开发计划第一稿 | ## 小结 -1. **学习需求:** 希望能有对于uml以及vue开发的教学; +1. **技能提升:** 本周通过系统学习,在Vue开发和UML建模方面有了提升,为后续开发奠定了理论基础。 2. **知识储备:** 提前学习后续需要使用的知识,为后续的前端开发做准备; 3. **撰写uml设计文档:** 学习并撰写uml设计文档。 diff --git a/doc/process/weekly/week-09/members/fjk-weekly-summary-09.md b/doc/process/weekly/week-09/members/fjk-weekly-summary-09.md index 89982bc9..6869adea 100644 --- a/doc/process/weekly/week-09/members/fjk-weekly-summary-09.md +++ b/doc/process/weekly/week-09/members/fjk-weekly-summary-09.md @@ -10,15 +10,14 @@ **结束时间:** 2025-11-24 -## 本周任务计划安排 - -| 序号 | 总结内容 | 是否完成 | 情况说明 | -|----|------------|------|-------------------------------------| -| 1 | 学习后端知识 | 完成 | 周内持续学习SpringBoot开发的相关知识 | -| 2 | 确定项目后端代码结构 | 完成 | 根据先前编写的需求文档以及老师给出的参考确定后续开发的代码的结构 | -| 3 | 工程创建 | 完成 | 创建后端项目工程,根据配置的相关环境导入相应依赖 | -| 4 | 确认迭代计划第二稿 | 完成 | 根据反馈意见修改迭代开发计划 | -| 5 | 学习uml设计 | 完成 | 学习编写系统总的用例图,编写该迭代的主要业务功能的活动图、顺序图和类图 | +## 本周任务完成情况 + +| 序号 | 总结内容 | 是否完成 | 情况说明 | +|----|-----------|------|------------------------------------------------------------| +| 1 | 学习后端知识 | 完成 | 学习mybatisPlus框架的使用 | +| 2 | 项目后端代码构建 | 完成 | 根据先前编写的需求文档以及老师给出的参考确定后续开发的代码的结构,并创建后端项目工程,根据配置的相关环境导入相应依赖 | +| 3 | 确认迭代计划第二稿 | 完成 | 根据反馈意见修改迭代开发计划 | +| 4 | 学习uml设计 | 完成 | 学习编写用例图,完善该迭代的主要业务功能的活动图、顺序图和类图 | ## 小结 diff --git a/doc/process/weekly/week-09/members/lmy-weekly-summary-09.md b/doc/process/weekly/week-09/members/lmy-weekly-summary-09.md index e3de1ace..36840a1e 100644 --- a/doc/process/weekly/week-09/members/lmy-weekly-summary-09.md +++ b/doc/process/weekly/week-09/members/lmy-weekly-summary-09.md @@ -1,4 +1,4 @@ -# 个人周计划-第9周 +# 个人周总结-第9周 ## 姓名和起止时间 @@ -14,11 +14,11 @@ | 序号 | 计划内容 | 是否完成 | 情况说明 | |----|---------|------|----------------------------------------------------| -| 1 | 学习前端知识 | 完成 | 周内持续学习vue开发的相关知识,不断从学长的代码获取开发经验 | +| 1 | 学习前端知识 | 完成 | 深入学习了Vue 3的响应式原理和生命周期,分析了学长提供的代码案例,学习了组件复用和状态管理的最佳实践 | | 2 | 确定分工 | 完成 | 2025-11-17开会细分确定团队分工,明确周任务 | -| 2 | 完善uml设计文档 | 完成 | 学习uml相关知识并完善uml设计文档活动图顺序图的部分 | -| 3 | 确认迭代计划第二稿 | 完成 | 根据指导老师的意见完成迭代开发计划第二稿 | -| 4 | 前端开发 | 完成 | 根据进度安排开始项目的编码,根据原型进行前端的编码 | +| 3 | 完善uml设计文档 | 完成 | 学习uml相关知识并完善uml设计文档活动图顺序图的部分 | +| 4 | 确认迭代计划第二稿 | 完成 | 根据指导老师的意见完成迭代开发计划第二稿 | +| 5 | 前端开发 | 完成 | 根据进度安排开始项目的编码,根据原型进行前端的编码 | ## 小结 diff --git a/doc/process/weekly/week-10/group/weekly-summary-10.md b/doc/process/weekly/week-10/group/weekly-summary-10.md new file mode 100644 index 00000000..f57a7312 --- /dev/null +++ b/doc/process/weekly/week-10/group/weekly-summary-10.md @@ -0,0 +1,35 @@ +# 小组周总结-第10周 + +## 团队名称和起止时间 + +**团队名称:** 2班-老师指定的组队 + +**开始时间:** 2025-11-24 + +**结束时间:** 2025-12-01 + +## 本周任务完成情况 + +| 序号 | 总结内容 | 是否完成 | 情况说明 | +|----|------------|------|--------------------------------------------------| +| 1 | 项目编码实施 | 部分完成 | 前端功能开发基本完成,后端功能实现部分完成 | +| 2 | 前后端联调测试 | 未完成 | 由于后端功能尚未完全实现,前后端联调测试未能如期进行 | +| 3 | 系统测试用例设计 | 未完成 | 测试用例设计工作尚未开展 | +| 4 | 项目文档更新完善 | 部分完成 | 根据实际开发进度更新了部分文档,包括UML图等 | +| 5 | 代码审查与优化 | 部分完成 | 对已完成的前端代码进行了优化,后端代码正在进行中 | + +## 小结 + +1. **前端进展顺利:** 前端功能开发按计划完成,成功实现了文物信息展示页面及相关功能; +2. **后端仍在进行:** 后端开发虽有所进展,但尚未完成全部核心功能,影响了整体进度; +3. **协同有待加强:** 前后端开发进度不匹配,需要加强团队内部沟通与协调; +4. **后续重点明确:** 下一步需要加快推进后端开发进度,尽快完成前后端联调测试。 + +--- + +## 【注】 + +1. 在小结一栏中写出希望得到如何的帮助,如讲座等; +2. 请将个人计划和总结提前发给负责人; +3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交; +4. PM综合本小组成员工作情况提交小组周计划、周总结报告,按时上传至代码托管平台。 \ No newline at end of file diff --git a/doc/process/weekly/week-10/members/fjk-weekly-summary-10.md b/doc/process/weekly/week-10/members/fjk-weekly-summary-10.md new file mode 100644 index 00000000..2af1a356 --- /dev/null +++ b/doc/process/weekly/week-10/members/fjk-weekly-summary-10.md @@ -0,0 +1,34 @@ +# 个人周总结-第10周 + +## 姓名和起止时间 + +**姓  名:** 符晋康 + +**团队名称:** 2班-老师指定的组队 + +**开始时间:** 2025-11-24 + +**结束时间:** 2025-12-01 + +## 本周任务完成情况 + +| 序号 | 总结内容 | 是否完成 | 情况说明 | +|----|------------|------|-------------------------------------| +| 1 | 学习后端开发相关知识 | 完成 | 学习postman知识 能够简单测试接口 | +| 2 | 项目部分功能实现 | 完成 | 根据先前编写的需求文档,进行项目的后端开发,完成了部分核心功能 | +| 3 | 学习uml设计 | 完成 | 学习编写系统总的用例图,编写该迭代的主要业务功能的活动图、顺序图和类图 | + +## 小结 + +1. **学习需求:** 希望能有对于原型设计以及SpringBoot开发的教学; +2. **功能实现:** 利用学到的开发知识完成了部分核心功能的实现; +3. **uml设计:** 学习uml设计,为后续的uml设计做准备。 + +--- + +## 【注】 + +1. 在小结一栏中写出希望得到如何的帮助,如讲座等; +2. 请将个人计划和总结提前发给负责人; +3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交; +4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台; \ No newline at end of file diff --git a/doc/process/weekly/week-10/members/hjy-weekly-summary-10.md b/doc/process/weekly/week-10/members/hjy-weekly-summary-10.md new file mode 100644 index 00000000..c29b9633 --- /dev/null +++ b/doc/process/weekly/week-10/members/hjy-weekly-summary-10.md @@ -0,0 +1,37 @@ +# 个人周总结-第10周 + +## 姓名和起止时间 + +**姓  名:** 哈俊元 + +**团队名称:** 2班-老师指定的组队 + +**开始时间:** 2025-11-24 + +**结束时间:** 2025-12-01 + +## 本周任务完成情况 + +| 序号 | 总结内容 | 是否完成 | 情况说明 | +|------|----------|--------|----------| +| 1 | 前端功能开发 | 完成 | 成功完善了前端页面功能,实现了文物信息展示页面 | +| 2 | 前后端联调 | 未完成 | 由于后端功能尚未完全实现,未能进行前后端联调 | +| 3 | 代码优化 | 完成 | 对现有代码结构进行了优化,提高了代码可读性和可维护性 | +| 4 | 文档更新 | 完成 | 根据最新开发进度更新了相关技术文档 | +| 5 | 团队协作 | 完成 | 积极参与团队会议,汇报开发进度,讨论解决方案 | + +## 小结 + +1. **技能提升:** 通过项目实践进一步掌握了Vue3开发技巧和工程化实践; +2. **成果显著:** 成功完成了前端功能开发和代码优化任务; +3. **协同合作:** 积极参与团队协作,但由于后端进度原因,联调工作未能如期完成; +4. **质量保证:** 注重代码质量和可维护性,编写了清晰的注释和文档。 + +--- + +## 【注】 + +1. 在小结一栏中写出希望得到如何的帮助,如讲座等; +2. 请将个人计划和总结提前发给负责人; +3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交; +4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台; \ No newline at end of file diff --git a/doc/process/weekly/week-10/members/lmy-weekly-summary-10.md b/doc/process/weekly/week-10/members/lmy-weekly-summary-10.md new file mode 100644 index 00000000..fd38042d --- /dev/null +++ b/doc/process/weekly/week-10/members/lmy-weekly-summary-10.md @@ -0,0 +1,34 @@ +# 个人周总结-第10周 + +## 姓名和起止时间 + +**姓  名:** 李梦源 + +**团队名称:** 2班-老师指定的组队 + +**开始时间:** 2025-11-24 + +**结束时间:** 2025-12-01 + +## 本周任务完成情况 + +| 序号 | 计划内容 | 是否完成 | 情况说明 | +|----|-----------|------|-------------------| +| 1 | 学习前端知识 | 完成 | 本周深入学习了Vue 3的Pinia状态管理和Axios网络请求,学习了表单验证和动画效果实现。 | +| 2 | 前端持续开发 | 完成 | 成功合作完成了前端α版本的界面开发,实现了核心功能模块,界面符合设计原型要求,交互流畅。 | +| 3 | 学习uml设计 | 完成 | 完成了系统总的用例图、活动图、顺序图和类图设计,UML文档更加完整和规范。 | + +## 小结 + +1. **知识储备:** 提前学习后续需要使用的知识,为后续的前端开发做准备 +2. **项目推进:** 前端α版本界面开发顺利完成。 +3. **uml设计:** 学习uml设计,为后续的uml设计修改做准备。 + +--- + +## 【注】 + +1. 在小结一栏中写出希望得到如何的帮助,如讲座等; +2. 请将个人计划和总结提前发给负责人; +3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交; +4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台; \ No newline at end of file diff --git a/doc/process/weekly/week-10/members/ymst-weekly-summary-10.md b/doc/process/weekly/week-10/members/ymst-weekly-summary-10.md new file mode 100644 index 00000000..a72e2f52 --- /dev/null +++ b/doc/process/weekly/week-10/members/ymst-weekly-summary-10.md @@ -0,0 +1,33 @@ +# 个人周总结-第10周 + +## 姓名和起止时间 + +**姓  名:** 袁明霜涛 + +**团队名称:** 2班-老师指定的组队 + +**开始时间:** 2025-11-24 + +**结束时间:** 2025-12-01 + +## 本周任务计划安排 + +| 序号 | 总结内容 | 完成情况 | 情况说明 | +|----|---------|------|--------------------------------------------------------------| +| 1 | 学习后端知识 | 完成 | 周内持续学习SpringBoot开发的相关知识,在开发过程中补充缺失的知识 | +| 2 | 后端持续开发 | 完成 | 根据先前编写的需求文档以及老师给出的参考确定后续开发的代码的结构,本周完成两个模块的内容,并将相应模块的接口设计与前端同步 | +| 3 | 学习uml设计 | 完成 | 学习编写系统总的用例图,编写该迭代的主要业务功能的活动图、顺序图和类图 | + +## 小结 + +1. **学习来源:** 参考网络上javaweb相关SpringBoot开发的教学; +2. **开发进度:** 完成了两个模块的后端代码,并与前端同步接口设计。 + +--- + +## 【注】 + +1. 在小结一栏中写出希望得到如何的帮助,如讲座等; +2. 请将个人计划和总结提前发给负责人; +3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交; +4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台; \ No newline at end of file diff --git a/doc/process/weekly/week-11/group/meeting-minutes-11.md b/doc/process/weekly/week-11/group/meeting-minutes-11.md new file mode 100644 index 00000000..788042e4 --- /dev/null +++ b/doc/process/weekly/week-11/group/meeting-minutes-11.md @@ -0,0 +1,80 @@ +# 小组会议纪要-第11周 + +## 会议记录概要 + +**团队名称:** 2班-老师指定的组队 + +**指导老师:** 彭鹏 + +**主 持 人:** 李梦源 + +**记录人员:** 李梦源 + +**会议主题:** 本周计划与分工 + +**会议地点:** 线上会议 + +**会议时间:** 2025-12-1 16:30-16:50 + +**纪录时间:** 2025年12月1日 19:00 + +**参与人员:** 李梦源、符晋康、哈俊元、袁明霜涛 + +--- +## 会议内容 + +### 1.阿尔法版本迭代开发 +本周任务为持续推进阿尔法版本的迭代开发,并需提交相应的UML图。 + +### 2.确认开发进度 +目前后端部分模块仍在开发中,需加快进度以确保整体项目按时推进。 + +### 3.本周任务安排 +本周主要任务为完成阿尔法版本的开发,所有UML图需于本周五晚上十点前完成提交。 + +### 4.后续会议安排 +需要自行联系指导老师,就第二次迭代开发计划的具体调整进行确认。 + +--- + +## 问题总结 + +### 已解决问题: + +1. 完成了项目前后端基础框架搭建,以及前端界面、后端部分核心功能模块的编码工作 +2. 完善了接口文档并与实际编码保持一致 +3. 完成了用例图、活动图、顺序图和类图在uml设计文档中的初稿。 + +### 待解决问题: + +1. 需要根据老师反馈完善第二次迭代开发计划的部分内容。 +2. 后端需要加快进度完成阿尔法版本剩余模块的开发 +3. 前后端需要根据接口文档进行协作开发。 +4. 按时提交UML-活动图-顺序图-类图.pdf + +--- + +## 小组协作情况总结 + +1. **协作情况:** 小组成员积极参与,全员到会,对项目需求和功能模块有较深入的理解,协作氛围良好。 + +--- + +## 一周纪律情况总结 + +1. **纪律情况:** 小组成员按时参加会议,积极参与讨论,无迟到早退现象。 + +--- + +## 备注 + +1. 本周重点任务是阿尔法版本的开发工作 +2. 需要尽快完善uml图的设计 + +--- + +## 【注】 + +1. 本文档为"老师指定的组队"小组软件过程会议记录,记录人员必须在会议后一个工作日之内如实填写,并汇报给PM、Lead及相关人员。 +2. 文档内容已经标上编号,记录人员如有增加或者减少编号的需要,在保证文档格式正确的前提下修改。 +3. 本文档内容在填写完毕之后,在已有的文件名称后面加上"(会议记录-第几周)",如"meeting-minutes-03",如果一周有多次会议,命名为"meeting-minutes-03-01"。 \ No newline at end of file diff --git a/doc/process/weekly/week-11/group/weekly-plan-11.md b/doc/process/weekly/week-11/group/weekly-plan-11.md new file mode 100644 index 00000000..4081e681 --- /dev/null +++ b/doc/process/weekly/week-11/group/weekly-plan-11.md @@ -0,0 +1,38 @@ +# 小组周计划-第11周 + +## 团队名称和起止时间 + +**团队名称:** 2班-老师指定的组队 + +**开始时间:** 2025-12-01 + +**结束时间:** 2025-12-07 + +## 本周任务计划安排 + + +| 序号 | 计划内容 | 执行人 | 情况说明 | +|----|------------------------|----------|---------------------------------------------------| +| 1 | 阿尔法版本迭代开发 | 全体成员 | 持续推进阿尔法版本的迭代开发工作。 | +| 2 | 继续模块开发 | 符晋康、袁明霜涛 | 加快完成阿尔法版本中仍在开发的后端模块。 | +| 3 | UML图设计与提交 | 哈俊元、李梦源 | 完善并提交UML活动图、顺序图、类图,于本周五22:00前完成。 | +| 4 | 联系指导老师确认计划的调整 | 全体成员 | 根据老师反馈,对第二次迭代开发计划的内容进行修改与完善。 | +| 5 | 前后端协作联调 | 全体成员 | 根据已完善的接口文档,进行前后端协作开发与联合调试。 | +| 6 | 项目文档更新 | 全体成员 | 根据最新的开发进展,更新迭代开发计划及相关的UML设计文档,并完善前十一周存在问题的文档。 | + +## 小结 + +1. **核心交付**:本周首要目标是完成阿尔法版本的开发核心内容,并准时提交全套UML设计图。 +2. **持续推进** 本周重点是持续推进项目编码工作,确保按照既定计划完成各项功能实现。 +3. **协同与沟通**:加强前后端基于接口文档的协作,并主动与指导老师沟通,确保计划调整得到及时确认。 + + + +--- + +## 【注】 + +1. 在小结一栏中写出希望得到如何的帮助,如讲座等; +2. 请将个人计划和总结提前发给负责人; +3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交; +4. PM综合本小组成员工作情况提交小组周计划、周总结报告,按时上传至代码托管平台。 \ No newline at end of file diff --git a/doc/process/weekly/week-11/members/fjk-weekly-plan-11.md b/doc/process/weekly/week-11/members/fjk-weekly-plan-11.md new file mode 100644 index 00000000..10be7f7f --- /dev/null +++ b/doc/process/weekly/week-11/members/fjk-weekly-plan-11.md @@ -0,0 +1,34 @@ +# 个人周计划-第11周 + +## 姓名和起止时间 + +**姓  名:** 符晋康 + +**团队名称:** 2班-老师指定的组队 + +**开始时间:** 2025-12-01 + +**结束时间:** 2025-12-07 + +## 本周任务计划安排 + +| 序号 | 计划内容 | 执行人 | 情况说明 | +|----|--------|------|--------------------------| +| 1 | 学习后端知识 | 个人 | 周内持续学习SpringBoot开发的相关知识 | +| 2 | 后端持续开发 | 个人 | 根据目前的项目代码,继续完成核心功能的开发和完善 | +| 3 | 学习ES搜索 | 个人 | 学习ES搜索,为后续的模糊搜索功能做准备 | + +## 小结 + +1. **学习需求:** 希望能有对于原型设计以及SpringBoot开发的教学; +2. **知识储备:** 提前学习后续需要使用的知识,为后续的后端开发做准备; +3. **ES学习:** 学习ES搜索,为后续的模糊搜索功能做准备; + +--- + +## 【注】 + +1. 在小结一栏中写出希望得到如何的帮助,如讲座等; +2. 请将个人计划和总结提前发给负责人; +3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交; +4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台; \ No newline at end of file diff --git a/doc/process/weekly/week-11/members/hjy-weekly-plan-11.md b/doc/process/weekly/week-11/members/hjy-weekly-plan-11.md new file mode 100644 index 00000000..f2bf6d2e --- /dev/null +++ b/doc/process/weekly/week-11/members/hjy-weekly-plan-11.md @@ -0,0 +1,37 @@ +# 个人周计划-第11周 + +## 姓名和起止时间 + +**姓  名:** 哈俊元 + +**团队名称:** 2班-老师指定的组队 + +**开始时间:** 2025-12-01 + +**结束时间:** 2025-12-08 + +## 本周任务计划安排 + +| 序号 | 计划内容 | 协作人 | 情况说明 | +|------|----------|--------|----------| +| 1 | 前端代码优化 | 个人 | 继续优化前端代码结构和性能,提高用户体验 | +| 2 | 前后端联调准备 | 个人 | 等待后端开发完成,准备进行前后端联调 | +| 3 | Bug修复 | 个人 | 根据测试结果修复前端可能存在的问题 | +| 4 | 文档完善 | 个人 | 更新和完善相关技术文档 | +| 5 | 团队协作 | 全体成员 | 参与团队会议,协调联调工作安排 | + +## 小结 + +1. **持续优化:** 通过不断优化前端代码提升系统性能和用户体验; +2. **联调准备:** 积极准备前后端联调工作,确保接口对接顺利; +3. **团队协作:** 密切关注后端开发进度,及时进行沟通协调; +4. **质量保证:** 注重代码质量和系统稳定性,做好充分的测试准备。 + +--- + +## 【注】 + +1. 在小结一栏中写出希望得到如何的帮助,如讲座等; +2. 请将个人计划和总结提前发给负责人; +3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交; +4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台; \ No newline at end of file diff --git a/doc/process/weekly/week-11/members/lmy-weekly-plan-11.md b/doc/process/weekly/week-11/members/lmy-weekly-plan-11.md new file mode 100644 index 00000000..86262d63 --- /dev/null +++ b/doc/process/weekly/week-11/members/lmy-weekly-plan-11.md @@ -0,0 +1,35 @@ +# 个人周计划-第11周 + +## 姓名和起止时间 + +**姓  名:** 李梦源 + +**团队名称:** 2班-老师指定的组队 + +**开始时间:** 2025-12-01 + +**结束时间:** 2025-12-07 + +## 本周任务计划安排 + +| 序号 | 计划内容 | 执行人 | 情况说明 | +|----|--------|------|--------------------------| +| 1 | 学习前端知识 | 个人 | 周内持续学习vue开发的相关知识 | +| 2 | 前端持续开发 | 个人 | 根据接口文档,继续完成前端接口部分的编码 | +| 3 | 前端代码优化 | 个人 | 优化已经完成的代码,提升代码质量 | +| 4 | 前后端联调准备 | 个人 | 学习相关知识,为前后端联调做准备 | + +## 小结 + +1. **学习需求:** 希望能有对于vue开发的教学; +2. **知识储备:** 提前学习后续需要使用的知识,为后续的前端开发做准备; +3. **代码优化** 优化前端代码,提升代码质量,增强代码可靠性; + +--- + +## 【注】 + +1. 在小结一栏中写出希望得到如何的帮助,如讲座等; +2. 请将个人计划和总结提前发给负责人; +3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交; +4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台; \ No newline at end of file diff --git a/doc/process/weekly/week-11/members/ymst-weekly-plan-11.md b/doc/process/weekly/week-11/members/ymst-weekly-plan-11.md new file mode 100644 index 00000000..7dabc001 --- /dev/null +++ b/doc/process/weekly/week-11/members/ymst-weekly-plan-11.md @@ -0,0 +1,34 @@ +# 个人周计划-第11周 + +## 姓名和起止时间 + +**姓  名:** 袁明霜涛 + +**团队名称:** 2班-老师指定的组队 + +**开始时间:** 2025-12-01 + +**结束时间:** 2025-12-08 + +## 本周任务计划安排 + +| 序号 | 计划内容 | 执行人 | 情况说明 | +|----|--------|------|-------------------------------| +| 1 | 学习后端知识 | 个人 | 周内持续学习SpringBoot开发的相关知识 | +| 2 | 后端持续开发 | 个人 | 根据先前编写的需求文档以及此前完成的代码进行进一步开发 | +| 3 | 学习代码测试 | 个人 | 学习代码测试相关流程与方法,测试此前交付的功能能否正确相应 | + +## 小结 + +1. **学习需求:** 希望能有对于图数据库以及SpringBoot开发的教学; +2. **知识储备:** 提前学习后续需要使用的知识,为后续的后端开发做准备; +3. **代码测试:** 学习代码测试相关的流程与方法,审查相应功能。 + +--- + +## 【注】 + +1. 在小结一栏中写出希望得到如何的帮助,如讲座等; +2. 请将个人计划和总结提前发给负责人; +3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交; +4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台; \ No newline at end of file diff --git a/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/constant/SystemConstant.java b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/constant/SystemConstant.java new file mode 100644 index 00000000..03cc88e5 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/constant/SystemConstant.java @@ -0,0 +1,41 @@ + +package cn.edu.hnu.artifactcommon.constant; + +/** + * 系统通用常量 + */ +public class SystemConstant { + /** + * 用户角色常量 + */ + public static final String ROLE_GUEST = "guest"; + public static final String ROLE_USER = "user"; + public static final String ROLE_ADVANCED = "advanced"; + public static final String ROLE_ADMIN = "admin"; + + /** + * 用户状态常量 + */ + public static final Integer STATUS_NORMAL = 0; // 正常 + public static final Integer STATUS_DISABLED = 1; // 禁用 + + /** + * JWT相关常量 + */ + public static final String JWT_HEADER = "Authorization"; + public static final String JWT_PREFIX = "Bearer "; + public static final String JWT_SECRET = "artifact-system-secret-key"; + public static final Long JWT_EXPIRATION = 7 * 24 * 60 * 60 * 1000L; // 7天 + + /** + * Redis缓存相关常量 + */ + public static final String REDIS_KEY_PREFIX = "artifact:"; + public static final String REDIS_KEY_CAPTCHA = "captcha:"; + public static final String REDIS_KEY_USER = "user:"; + public static final String REDIS_KEY_TOKEN = "token:"; + + private SystemConstant() { + // 私有构造方法,防止实例化 + } +} diff --git a/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/context/UserContext.java b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/context/UserContext.java new file mode 100644 index 00000000..402abf30 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/context/UserContext.java @@ -0,0 +1,34 @@ + +package cn.edu.hnu.artifactcommon.context; + +/** + * 用户上下文 + */ +public class UserContext { + + /** + * 使用ThreadLocal存储当前线程的用户信息 + */ + private static final ThreadLocal USER_THREAD_LOCAL = new ThreadLocal<>(); + + /** + * 设置当前线程的用户名 + */ + public static void setCurrentUsername(String username) { + USER_THREAD_LOCAL.set(username); + } + + /** + * 获取当前线程的用户名 + */ + public static String getCurrentUsername() { + return USER_THREAD_LOCAL.get(); + } + + /** + * 清除当前线程的用户信息 + */ + public static void clear() { + USER_THREAD_LOCAL.remove(); + } +} diff --git a/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/exception/BusinessException.java b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/exception/BusinessException.java new file mode 100644 index 00000000..2ae0c9fd --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/exception/BusinessException.java @@ -0,0 +1,55 @@ + +package cn.edu.hnu.artifactcommon.exception; + +/** + * 业务异常类 + */ +public class BusinessException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** + * 错误码 + */ + private Integer code; + + /** + * 错误消息 + */ + private String message; + + public BusinessException(String message) { + super(message); + this.message = message; + this.code = 500; + } + + public BusinessException(Integer code, String message) { + super(message); + this.code = code; + this.message = message; + } + + public BusinessException(String message, Throwable e) { + super(message, e); + this.message = message; + this.code = 500; + } + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + @Override + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/pojo/dto/UserDTO.java b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/pojo/dto/UserDTO.java new file mode 100644 index 00000000..db37ae8f --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/pojo/dto/UserDTO.java @@ -0,0 +1,35 @@ + +package cn.edu.hnu.artifactcommon.pojo.dto; + +import lombok.Data; + +/** + * 用户数据传输对象 + */ +@Data +public class UserDTO { + /** + * 用户名 + */ + private String username; + + /** + * 密码 + */ + private String password; + + /** + * 邮箱 + */ + private String email; + + /** + * 验证码 + */ + private String captcha; + + /** + * 验证码UUID + */ + private String captchaUuid; +} diff --git a/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/pojo/vo/LoginVO.java b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/pojo/vo/LoginVO.java new file mode 100644 index 00000000..44869fc0 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/pojo/vo/LoginVO.java @@ -0,0 +1,20 @@ + +package cn.edu.hnu.artifactcommon.pojo.vo; + +import lombok.Data; + +/** + * 登录响应视图对象 + */ +@Data +public class LoginVO { + /** + * JWT令牌 + */ + private String token; + + /** + * 用户信息 + */ + private UserVO user; +} diff --git a/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/pojo/vo/UserVO.java b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/pojo/vo/UserVO.java new file mode 100644 index 00000000..db170c0a --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/pojo/vo/UserVO.java @@ -0,0 +1,47 @@ + +package cn.edu.hnu.artifactcommon.pojo.vo; + +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 用户视图对象 + */ +@Data +public class UserVO { + /** + * 用户ID + */ + private Long id; + + /** + * 用户名 + */ + private String username; + + /** + * 邮箱 + */ + private String email; + + /** + * 角色 + */ + private String role; + + /** + * 状态:0-正常,1-禁用 + */ + private Integer status; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 最后登录时间 + */ + private LocalDateTime lastLoginTime; +} diff --git a/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/result/Result.java b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/result/Result.java new file mode 100644 index 00000000..71cc264d --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/result/Result.java @@ -0,0 +1,100 @@ + +package cn.edu.hnu.artifactcommon.result; + +import lombok.Data; + +/** + * 统一响应结果封装类 + */ +@Data +public class Result { + /** + * 状态码 + */ + private Integer code; + + /** + * 消息 + */ + private String message; + + /** + * 数据 + */ + private T data; + + /** + * 时间戳 + */ + private Long timestamp; + + private Result() { + this.timestamp = System.currentTimeMillis(); + } + + /** + * 成功响应 + */ + public static Result success() { + Result result = new Result<>(); + result.setCode(200); + result.setMessage("操作成功"); + return result; + } + + /** + * 成功响应(带消息) + */ + public static Result success(String message) { + Result result = success(); + result.setMessage(message); + return result; + } + + /** + * 成功响应(带数据) + */ + public static Result success(T data) { + Result result = success(); + result.setData(data); + return result; + } + + /** + * 成功响应(带消息和数据) + */ + public static Result success(String message, T data) { + Result result = success(message); + result.setData(data); + return result; + } + + /** + * 失败响应 + */ + public static Result error() { + Result result = new Result<>(); + result.setCode(500); + result.setMessage("操作失败"); + return result; + } + + /** + * 失败响应(带消息) + */ + public static Result error(String message) { + Result result = error(); + result.setMessage(message); + return result; + } + + /** + * 失败响应(带状态码和消息) + */ + public static Result error(Integer code, String message) { + Result result = new Result<>(); + result.setCode(code); + result.setMessage(message); + return result; + } +} diff --git a/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/utils/CaptchaUtil.java b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/utils/CaptchaUtil.java new file mode 100644 index 00000000..49323c48 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/utils/CaptchaUtil.java @@ -0,0 +1,175 @@ + +package cn.edu.hnu.artifactcommon.utils; + +import cn.edu.hnu.artifactcommon.constant.SystemConstant; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import org.springframework.stereotype.Component; + +import jakarta.annotation.Resource; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Base64; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +/** + * 验证码工具类 + */ +@Component +public class CaptchaUtil { + + @Resource + private RedisUtil redisUtil; + + /** + * 验证码字符集 + */ + private static final String CAPTCHA_CHARS = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; + + /** + * 验证码长度 + */ + private static final int CAPTCHA_LENGTH = 4; + + /** + * 验证码过期时间(分钟) + */ + private static final int CAPTCHA_EXPIRE_MINUTES = 5; + + /** + * 生成验证码 + * @param uuid 验证码唯一标识 + * @return Base64编码的验证码图片 + * @throws IOException IO异常 + */ + public String generateCaptcha(String uuid) throws IOException { + // 生成随机验证码 + String captcha = generateRandomCaptcha(); + + // 将验证码存储到Redis,设置过期时间 + String redisKey = SystemConstant.REDIS_KEY_CAPTCHA + uuid; + redisUtil.set(redisKey, captcha, CAPTCHA_EXPIRE_MINUTES, TimeUnit.MINUTES); + + // 生成验证码图片 + BufferedImage image = createCaptchaImage(captcha); + + // 将图片转换为Base64字符串 + return imageToBase64(image); + } + + /** + * 验证验证码 + * @param uuid 验证码唯一标识 + * @param captcha 用户输入的验证码 + * @return 验证结果 + */ + public boolean validateCaptcha(String uuid, String captcha) { + if (StringUtils.isEmpty(uuid) || StringUtils.isEmpty(captcha)) { + return false; + } + + String redisKey = SystemConstant.REDIS_KEY_CAPTCHA + uuid; + String storedCaptcha = redisUtil.get(redisKey).toString(); + + if (storedCaptcha == null) { + return false; + } + + // 验证成功后删除验证码 + redisUtil.del(redisKey); + + // 不区分大小写比较 + return storedCaptcha.equalsIgnoreCase(captcha); + } + + /** + * 生成随机验证码字符串 + * @return 验证码字符串 + */ + private String generateRandomCaptcha() { + Random random = new Random(); + StringBuilder captcha = new StringBuilder(); + + for (int i = 0; i < CAPTCHA_LENGTH; i++) { + captcha.append(CAPTCHA_CHARS.charAt(random.nextInt(CAPTCHA_CHARS.length()))); + } + + return captcha.toString(); + } + + /** + * 创建验证码图片 + * @param captcha 验证码字符串 + * @return 验证码图片 + */ + private BufferedImage createCaptchaImage(String captcha) { + int width = 120; + int height = 40; + + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics graphics = image.getGraphics(); + + // 设置背景色 + graphics.setColor(Color.WHITE); + graphics.fillRect(0, 0, width, height); + + // 设置字体 + graphics.setFont(new Font("Arial", Font.BOLD, 20)); + + // 绘制验证码 + Random random = new Random(); + for (int i = 0; i < captcha.length(); i++) { + // 设置随机颜色 + graphics.setColor(new Color( + random.nextInt(110), + random.nextInt(110), + random.nextInt(110) + )); + + // 绘制字符 + graphics.drawString( + String.valueOf(captcha.charAt(i)), + 20 * i + 10, + 25 + ); + } + + // 绘制干扰线 + for (int i = 0; i < 8; i++) { + graphics.setColor(new Color( + random.nextInt(256), + random.nextInt(256), + random.nextInt(256) + )); + + int x1 = random.nextInt(width); + int y1 = random.nextInt(height); + int x2 = random.nextInt(width); + int y2 = random.nextInt(height); + + graphics.drawLine(x1, y1, x2, y2); + } + + graphics.dispose(); + + return image; + } + + /** + * 将图片转换为Base64字符串 + * @param image 图片 + * @return Base64字符串 + * @throws IOException IO异常 + */ + private String imageToBase64(BufferedImage image) throws IOException { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + javax.imageio.ImageIO.write(image, "png", outputStream); + + byte[] imageBytes = outputStream.toByteArray(); + + return "data:image/png;base64," + Base64.getEncoder().encodeToString(imageBytes); + } +} diff --git a/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/utils/EncryptUtil.java b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/utils/EncryptUtil.java new file mode 100644 index 00000000..c44958f2 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/utils/EncryptUtil.java @@ -0,0 +1,88 @@ + +package cn.edu.hnu.artifactcommon.utils; + +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.util.DigestUtils; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.UUID; + +/** + * 加密工具类 + */ +public class EncryptUtil { + + /** + * MD5加密 + * @param text 明文 + * @return 密文 + */ + public static String md5(String text) { + return DigestUtils.md5DigestAsHex(text.getBytes()); + } + + /** + * MD5加盐加密 + * @param text 明文 + * @param salt 盐 + * @return 密文 + */ + public static String md5(String text, String salt) { + return md5(text + salt); + } + + /** + * 生成随机盐 + * @return 盐 + */ + public static String generateSalt() { + return UUID.randomUUID().toString().replace("-", ""); + } + + /** + * BCrypt加密 + * @param password 明文密码 + * @return 密文 + */ + public static String bcrypt(String password) { + BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); + return encoder.encode(password); + } + + /** + * BCrypt密码验证 + * @param password 明文密码 + * @param encodedPassword 密文密码 + * @return 是否匹配 + */ + public static boolean bcryptMatch(String password, String encodedPassword) { + BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); + return encoder.matches(password, encodedPassword); + } + + /** + * SHA256加密 + * @param text 明文 + * @return 密文 + */ + public static String sha256(String text) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] hash = digest.digest(text.getBytes()); + StringBuilder hexString = new StringBuilder(); + + for (byte b : hash) { + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + + return hexString.toString(); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("SHA-256加密失败", e); + } + } +} diff --git a/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/utils/JwtUtil.java b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/utils/JwtUtil.java new file mode 100644 index 00000000..c026286c --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/utils/JwtUtil.java @@ -0,0 +1,100 @@ + +package cn.edu.hnu.artifactcommon.utils; + +import cn.edu.hnu.artifactcommon.constant.SystemConstant; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import org.springframework.stereotype.Component; + +import java.security.Key; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +/** + * JWT工具类 + */ +@Component +public class JwtUtil { + + /** + * 获取签名密钥 + */ + private Key getSigningKey() { + return Keys.hmacShaKeyFor(SystemConstant.JWT_SECRET.getBytes()); + } + + /** + * 从token中获取用户名 + */ + public String getUsernameFromToken(String token) { + return getClaimFromToken(token, Claims::getSubject); + } + + /** + * 从token中获取过期时间 + */ + public Date getExpirationDateFromToken(String token) { + return getClaimFromToken(token, Claims::getExpiration); + } + + /** + * 从token中获取指定声明 + */ + public T getClaimFromToken(String token, Function claimsResolver) { + final Claims claims = getAllClaimsFromToken(token); + return claimsResolver.apply(claims); + } + + /** + * 从token中获取所有声明 + */ + private Claims getAllClaimsFromToken(String token) { + return Jwts.parserBuilder() + .setSigningKey(getSigningKey()) + .build() + .parseClaimsJws(token) + .getBody(); + } + + /** + * 检查token是否过期 + */ + private Boolean isTokenExpired(String token) { + final Date expiration = getExpirationDateFromToken(token); + return expiration.before(new Date()); + } + + /** + * 生成token + */ + public String generateToken(String username, String role) { + Map claims = new HashMap<>(); + claims.put("role", role); + return doGenerateToken(claims, username); + } + + /** + * 生成token的具体实现 + */ + private String doGenerateToken(Map claims, String subject) { + return Jwts.builder() + .setClaims(claims) + .setSubject(subject) + .setIssuedAt(new Date(System.currentTimeMillis())) + .setExpiration(new Date(System.currentTimeMillis() + SystemConstant.JWT_EXPIRATION)) + .signWith(getSigningKey(), SignatureAlgorithm.HS256) + .compact(); + } + + /** + * 验证token + */ + public Boolean validateToken(String token, String username) { + final String tokenUsername = getUsernameFromToken(token); + return (tokenUsername.equals(username) && !isTokenExpired(token)); + } +} diff --git a/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/utils/RedisUtil.java b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/utils/RedisUtil.java new file mode 100644 index 00000000..9668bcc4 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-common/src/main/java/cn/edu/hnu/artifactcommon/utils/RedisUtil.java @@ -0,0 +1,157 @@ + +package cn.edu.hnu.artifactcommon.utils; + +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import jakarta.annotation.Resource; +import java.util.Collection; +import java.util.concurrent.TimeUnit; + +/** + * Redis工具类 + */ +@Component +public class RedisUtil { + + @Resource + private RedisTemplate redisTemplate; + + /** + * 验证码过期时间(分钟) + */ + private static final int CAPTCHA_EXPIRE_MINUTES = 5; + + /** + * 指定缓存失效时间 + * @param key 键 + * @param time 时间(秒) + */ + public boolean expire(String key, long time) { + try { + if (time > 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 根据key 获取过期时间 + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 判断key是否存在 + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + return redisTemplate.hasKey(key); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除缓存 + * @param key 可以传一个值 或多个 + */ + @SuppressWarnings("unchecked") + public void del(String... key) { + if (key != null && key.length > 0) { + if (key.length == 1) { + redisTemplate.delete(key[0]); + } else { + redisTemplate.delete((Collection) CollectionUtils.arrayToList(key)); + } + } + } + + /** + * 普通缓存获取 + * @param key 键 + * @return 值 + */ + public Object get(String key) { + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + /** + * 普通缓存放入 + * + * @param redisKey + * @param key 键 + * @param captchaExpireMinutes + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String redisKey, String key, int captchaExpireMinutes, Object value) { + try { + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 普通缓存放入并设置时间 + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + // 修改这里,调整参数顺序 + set(key, value, CAPTCHA_EXPIRE_MINUTES * 60L); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + + + + /** + * 递增 + * @param key 键 + * @param delta 要增加几(大于0) + */ + public long incr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递增因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, delta); + } + + /** + * 递减 + * @param key 键 + * @param delta 要减少几(小于0) + */ + public long decr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递减因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, -delta); + } +} diff --git a/src/ArtifactLLM_banker/artifact-system/pom.xml b/src/ArtifactLLM_banker/artifact-system/pom.xml index e32b60da..446018a2 100644 --- a/src/ArtifactLLM_banker/artifact-system/pom.xml +++ b/src/ArtifactLLM_banker/artifact-system/pom.xml @@ -37,8 +37,14 @@ org.springframework.boot spring-boot-starter + + cn.edu.hnu + artifact-common + 0.0.1-SNAPSHOT + compile + - + diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/controller/PermissionController.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/controller/PermissionController.java new file mode 100644 index 00000000..1317d9c0 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/controller/PermissionController.java @@ -0,0 +1,107 @@ + +package cn.edu.hnu.artifactsystem.controller; + +import cn.edu.hnu.artifactsystem.entity.Permission; +import cn.edu.hnu.artifactsystem.service.IPermissionService; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.web.bind.annotation.*; + +import jakarta.annotation.Resource; +import java.util.List; + +/** + * 权限控制器 + */ +@RestController +@RequestMapping("/api/permissions") +public class PermissionController { + + @Resource + private IPermissionService permissionService; + + /** + * 分页查询权限列表 + */ + @GetMapping + public Page getPermissionPage( + @RequestParam(defaultValue = "1") int current, + @RequestParam(defaultValue = "10") int size, + @RequestParam(required = false) String name, + @RequestParam(required = false) Integer type, + @RequestParam(required = false) Integer status) { + return permissionService.getPermissionPage(current, size, name, type, status); + } + + /** + * 根据ID获取权限 + */ + @GetMapping("/{id}") + public Permission getPermissionById(@PathVariable Long id) { + return permissionService.getPermissionById(id); + } + + /** + * 获取所有权限 + */ + @GetMapping("/all") + public List getAllPermissions() { + return permissionService.getAllPermissions(); + } + + /** + * 获取树形结构权限列表 + */ + @GetMapping("/tree") + public List getPermissionTree() { + return permissionService.getPermissionTree(); + } + + /** + * 添加权限 + */ + @PostMapping + public Permission addPermission(@RequestBody Permission permission) { + return permissionService.addPermission(permission); + } + + /** + * 更新权限 + */ + @PutMapping("/{id}") + public boolean updatePermission(@PathVariable Long id, @RequestBody Permission permission) { + permission.setId(id); + return permissionService.updatePermission(permission); + } + + /** + * 删除权限 + */ + @DeleteMapping("/{id}") + public boolean deletePermission(@PathVariable Long id) { + return permissionService.deletePermission(id); + } + + /** + * 批量删除权限 + */ + @DeleteMapping("/batch") + public boolean batchDeletePermissions(@RequestBody List ids) { + return permissionService.batchDeletePermissions(ids); + } + + /** + * 根据用户ID获取权限列表 + */ + @GetMapping("/user/{userId}") + public List getPermissionsByUserId(@PathVariable Long userId) { + return permissionService.getPermissionsByUserId(userId); + } + + /** + * 根据角色ID获取权限列表 + */ + @GetMapping("/role/{roleId}") + public List getPermissionsByRoleId(@PathVariable Long roleId) { + return permissionService.getPermissionsByRoleId(roleId); + } +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/controller/RoleController.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/controller/RoleController.java new file mode 100644 index 00000000..663c680b --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/controller/RoleController.java @@ -0,0 +1,114 @@ + +package cn.edu.hnu.artifactsystem.controller; + +import cn.edu.hnu.artifactsystem.entity.Role; +import cn.edu.hnu.artifactsystem.service.IRoleService; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.web.bind.annotation.*; + +import jakarta.annotation.Resource; +import java.util.List; + +/** + * 角色控制器 + */ +@RestController +@RequestMapping("/api/roles") +public class RoleController { + + @Resource + private IRoleService roleService; + + /** + * 分页查询角色列表 + */ + @GetMapping + public Page getRolePage( + @RequestParam(defaultValue = "1") int current, + @RequestParam(defaultValue = "10") int size, + @RequestParam(required = false) String name, + @RequestParam(required = false) Integer status) { + return roleService.getRolePage(current, size, name, status); + } + + /** + * 根据ID获取角色 + */ + @GetMapping("/{id}") + public Role getRoleById(@PathVariable Long id) { + return roleService.getRoleById(id); + } + + /** + * 获取所有角色 + */ + @GetMapping("/all") + public List getAllRoles() { + return roleService.getAllRoles(); + } + + /** + * 添加角色 + */ + @PostMapping + public Role addRole(@RequestBody Role role) { + return roleService.addRole(role); + } + + /** + * 更新角色 + */ + @PutMapping("/{id}") + public boolean updateRole(@PathVariable Long id, @RequestBody Role role) { + role.setId(id); + return roleService.updateRole(role); + } + + /** + * 删除角色 + */ + @DeleteMapping("/{id}") + public boolean deleteRole(@PathVariable Long id) { + return roleService.deleteRole(id); + } + + /** + * 批量删除角色 + */ + @DeleteMapping("/batch") + public boolean batchDeleteRoles(@RequestBody List ids) { + return roleService.batchDeleteRoles(ids); + } + + /** + * 根据用户ID获取角色列表 + */ + @GetMapping("/user/{userId}") + public List getRolesByUserId(@PathVariable Long userId) { + return roleService.getRolesByUserId(userId); + } + + /** + * 为用户分配角色 + */ + @PostMapping("/user/{userId}") + public boolean assignRolesToUser(@PathVariable Long userId, @RequestBody List roleIds) { + return roleService.assignRolesToUser(userId, roleIds); + } + + /** + * 根据角色ID获取权限ID列表 + */ + @GetMapping("/{roleId}/permissions") + public List getPermissionIdsByRoleId(@PathVariable Long roleId) { + return roleService.getPermissionIdsByRoleId(roleId); + } + + /** + * 为角色分配权限 + */ + @PostMapping("/{roleId}/permissions") + public boolean assignPermissionsToRole(@PathVariable Long roleId, @RequestBody List permissionIds) { + return roleService.assignPermissionsToRole(roleId, permissionIds); + } +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/controller/UserController.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/controller/UserController.java new file mode 100644 index 00000000..b25b0ac7 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/controller/UserController.java @@ -0,0 +1,89 @@ + +package cn.edu.hnu.artifactsystem.controller; + +import cn.edu.hnu.artifactcommon.pojo.dto.UserDTO; +import cn.edu.hnu.artifactcommon.pojo.vo.LoginVO; +import cn.edu.hnu.artifactcommon.pojo.vo.UserVO; +import cn.edu.hnu.artifactcommon.utils.CaptchaUtil; +import cn.edu.hnu.artifactsystem.service.IUserService; +import org.springframework.web.bind.annotation.*; + +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * 用户控制器 + */ +@RestController +@RequestMapping("/api/user") +public class UserController { + + @Resource + private IUserService userService; + + @Resource + private CaptchaUtil captchaUtil; + + /** + * 用户注册 + */ + @PostMapping("/register") + public UserVO register(@RequestBody UserDTO userDTO) { + return userService.register(userDTO); + } + + /** + * 用户登录 + */ + @PostMapping("/login") + public LoginVO login(@RequestBody UserDTO userDTO) { + return userService.login(userDTO); + } + + /** + * 获取验证码 + */ + @GetMapping("/captcha") + public Map getCaptcha() throws IOException { + // 生成UUID作为验证码标识 + String uuid = UUID.randomUUID().toString(); + + // 生成验证码图片 + String captchaImage = captchaUtil.generateCaptcha(uuid); + + // 返回验证码图片和UUID + Map result = new HashMap<>(); + result.put("uuid", uuid); + result.put("image", captchaImage); + + return result; + } + + /** + * 获取当前用户信息 + */ + @GetMapping("/info") + public UserVO getCurrentUser(HttpServletRequest request) { + // 从请求属性中获取用户名 + String username = (String) request.getAttribute("username"); + + if (username == null || username.isEmpty()) { + throw new RuntimeException("未登录或令牌已过期"); + } + + return userService.getUserByUsername(username); + } + + /** + * 用户登出 + */ + @PostMapping("/logout") + public String logout() { + // 实际应用中可以在这里处理令牌黑名单等逻辑 + return "登出成功"; + } +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/controller/UserManagementController.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/controller/UserManagementController.java new file mode 100644 index 00000000..1c2184ab --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/controller/UserManagementController.java @@ -0,0 +1,96 @@ + +package cn.edu.hnu.artifactsystem.controller; + +import cn.edu.hnu.artifactsystem.entity.User; +import cn.edu.hnu.artifactsystem.service.IUserService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.web.bind.annotation.*; + +import jakarta.annotation.Resource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 用户管理控制器 + */ +@RestController +@RequestMapping("/api/users") +public class UserManagementController { + + @Resource + private IUserService userService; + + /** + * 分页查询用户列表 + */ + @GetMapping + public Map getUserPage( + @RequestParam(defaultValue = "1") int current, + @RequestParam(defaultValue = "10") int size, + @RequestParam(required = false) String username) { + + Page page = new Page<>(current, size); + QueryWrapper queryWrapper = new QueryWrapper<>(); + + if (username != null && !username.isEmpty()) { + queryWrapper.like("username", username); + } + + queryWrapper.orderByDesc("create_time"); + Page userPage = userService.page(page, queryWrapper); + + Map result = new HashMap<>(); + result.put("items", userPage.getRecords()); + result.put("total", userPage.getTotal()); + + return result; + } + + /** + * 根据ID获取用户 + */ + @GetMapping("/{id}") + public User getUserById(@PathVariable Long id) { + return userService.getById(id); + } + + /** + * 更新用户 + */ + @PutMapping("/{id}") + public boolean updateUser(@PathVariable Long id, @RequestBody User user) { + user.setId(id); + return userService.updateById(user); + } + + /** + * 删除用户 + */ + @DeleteMapping("/{id}") + public boolean deleteUser(@PathVariable Long id) { + return userService.removeById(id); + } + + /** + * 批量删除用户 + */ + @DeleteMapping("/batch") + public boolean batchDeleteUsers(@RequestBody List ids) { + return userService.removeByIds(ids); + } + + /** + * 切换用户状态 + */ + @PutMapping("/{id}/status") + public boolean toggleUserStatus(@PathVariable Long id, @RequestParam Integer status) { + User user = userService.getById(id); + if (user != null) { + user.setStatus(status); + return userService.updateById(user); + } + return false; + } +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/Permission.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/Permission.java new file mode 100644 index 00000000..ddd093ad --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/Permission.java @@ -0,0 +1,83 @@ + +package cn.edu.hnu.artifactsystem.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 权限实体类 + */ +@Data +@TableName("sys_permission") +public class Permission { + /** + * 权限ID + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 权限名称 + */ + private String name; + + /** + * 权限代码 + */ + private String code; + + /** + * 权限类型:1-菜单,2-按钮,3-接口 + */ + private Integer type; + + /** + * 父权限ID + */ + private Long parentId; + + /** + * 路径 + */ + private String path; + + /** + * 组件路径 + */ + private String component; + + /** + * 权限图标 + */ + private String icon; + + /** + * 排序 + */ + private Integer sortOrder; + + /** + * 状态:0-正常,1-禁用 + */ + private Integer status; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 子权限列表(非数据库字段) + */ + private List children; +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/Role.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/Role.java new file mode 100644 index 00000000..a3be6589 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/Role.java @@ -0,0 +1,57 @@ + +package cn.edu.hnu.artifactsystem.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 角色实体类 + */ +@Data +@TableName("sys_role") +public class Role { + /** + * 角色ID + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 角色名称 + */ + private String name; + + /** + * 角色代码 + */ + private String code; + + /** + * 角色描述 + */ + private String description; + + /** + * 排序 + */ + private Integer sortOrder; + + /** + * 状态:0-正常,1-禁用 + */ + private Integer status; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/RolePermission.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/RolePermission.java new file mode 100644 index 00000000..4c1d24ea --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/RolePermission.java @@ -0,0 +1,29 @@ + +package cn.edu.hnu.artifactsystem.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 角色权限关联实体类 + */ +@Data +@TableName("sys_role_permission") +public class RolePermission { + /** + * 角色ID + */ + private Long roleId; + + /** + * 权限ID + */ + private Long permissionId; + + /** + * 创建时间 + */ + private LocalDateTime createTime; +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/User.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/User.java new file mode 100644 index 00000000..d45e6bf6 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/User.java @@ -0,0 +1,57 @@ + +package cn.edu.hnu.artifactsystem.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 用户实体类 + */ +@Data +@TableName("sys_user") +public class User { + /** + * 用户ID + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 用户名 + */ + private String username; + + /** + * 密码 + */ + private String password; + + /** + * 邮箱 + */ + private String email; + + /** + * 角色 + */ + private String role; + + /** + * 状态:0-正常,1-禁用 + */ + private Integer status; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 最后登录时间 + */ + private LocalDateTime lastLoginTime; +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/UserRole.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/UserRole.java new file mode 100644 index 00000000..c2bf72c0 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/entity/UserRole.java @@ -0,0 +1,29 @@ + +package cn.edu.hnu.artifactsystem.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 用户角色关联实体类 + */ +@Data +@TableName("sys_user_role") +public class UserRole { + /** + * 用户ID + */ + private Long userId; + + /** + * 角色ID + */ + private Long roleId; + + /** + * 创建时间 + */ + private LocalDateTime createTime; +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/PermissionMapper.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/PermissionMapper.java new file mode 100644 index 00000000..4a3230b7 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/PermissionMapper.java @@ -0,0 +1,15 @@ + +package cn.edu.hnu.artifactsystem.mapper; + +import cn.edu.hnu.artifactsystem.entity.Permission; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 权限映射器接口 + */ +@Mapper +public interface PermissionMapper extends BaseMapper { + // 继承BaseMapper后,基本的CRUD操作已由MyBatis-Plus提供 + // 如需自定义SQL,可在此添加方法并使用@Select、@Insert等注解 +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/RoleMapper.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/RoleMapper.java new file mode 100644 index 00000000..f316063c --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/RoleMapper.java @@ -0,0 +1,15 @@ + +package cn.edu.hnu.artifactsystem.mapper; + +import cn.edu.hnu.artifactsystem.entity.Role; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 角色映射器接口 + */ +@Mapper +public interface RoleMapper extends BaseMapper { + // 继承BaseMapper后,基本的CRUD操作已由MyBatis-Plus提供 + // 如需自定义SQL,可在此添加方法并使用@Select、@Insert等注解 +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/RolePermissionMapper.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/RolePermissionMapper.java new file mode 100644 index 00000000..c09e57e5 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/RolePermissionMapper.java @@ -0,0 +1,29 @@ + +package cn.edu.hnu.artifactsystem.mapper; + +import cn.edu.hnu.artifactsystem.entity.RolePermission; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + * 角色权限映射器接口 + */ +@Mapper +public interface RolePermissionMapper extends BaseMapper { + + /** + * 根据角色ID查询权限ID列表 + */ + @Select("SELECT permission_id FROM sys_role_permission WHERE role_id = #{roleId}") + List selectPermissionIdsByRoleId(@Param("roleId") Long roleId); + + /** + * 根据权限ID查询角色ID列表 + */ + @Select("SELECT role_id FROM sys_role_permission WHERE permission_id = #{permissionId}") + List selectRoleIdsByPermissionId(@Param("permissionId") Long permissionId); +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/UserMapper.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/UserMapper.java new file mode 100644 index 00000000..e5bd5668 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/UserMapper.java @@ -0,0 +1,15 @@ + +package cn.edu.hnu.artifactsystem.mapper; + +import cn.edu.hnu.artifactsystem.entity.User; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 用户映射器接口 + */ +@Mapper +public interface UserMapper extends BaseMapper { + // 继承BaseMapper后,基本的CRUD操作已由MyBatis-Plus提供 + // 如需自定义SQL,可在此添加方法并使用@Select、@Insert等注解 +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/UserRoleMapper.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/UserRoleMapper.java new file mode 100644 index 00000000..c9c5fc48 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/mapper/UserRoleMapper.java @@ -0,0 +1,29 @@ + +package cn.edu.hnu.artifactsystem.mapper; + +import cn.edu.hnu.artifactsystem.entity.UserRole; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + * 用户角色映射器接口 + */ +@Mapper +public interface UserRoleMapper extends BaseMapper { + + /** + * 根据用户ID查询角色ID列表 + */ + @Select("SELECT role_id FROM sys_user_role WHERE user_id = #{userId}") + List selectRoleIdsByUserId(@Param("userId") Long userId); + + /** + * 根据角色ID查询用户ID列表 + */ + @Select("SELECT user_id FROM sys_user_role WHERE role_id = #{roleId}") + List selectUserIdsByRoleId(@Param("roleId") Long roleId); +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/IPermissionService.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/IPermissionService.java new file mode 100644 index 00000000..bd6c674d --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/IPermissionService.java @@ -0,0 +1,64 @@ + +package cn.edu.hnu.artifactsystem.service; + +import cn.edu.hnu.artifactsystem.entity.Permission; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 权限服务接口 + */ +public interface IPermissionService extends IService { + + /** + * 分页查询权限列表 + */ + Page getPermissionPage(int current, int size, String name, Integer type, Integer status); + + /** + * 根据ID获取权限 + */ + Permission getPermissionById(Long id); + + /** + * 添加权限 + */ + Permission addPermission(Permission permission); + + /** + * 更新权限 + */ + boolean updatePermission(Permission permission); + + /** + * 删除权限 + */ + boolean deletePermission(Long id); + + /** + * 批量删除权限 + */ + boolean batchDeletePermissions(List ids); + + /** + * 获取所有权限 + */ + List getAllPermissions(); + + /** + * 获取树形结构权限列表 + */ + List getPermissionTree(); + + /** + * 根据用户ID获取权限列表 + */ + List getPermissionsByUserId(Long userId); + + /** + * 根据角色ID获取权限列表 + */ + List getPermissionsByRoleId(Long roleId); +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/IRoleService.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/IRoleService.java new file mode 100644 index 00000000..311e67ef --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/IRoleService.java @@ -0,0 +1,69 @@ + +package cn.edu.hnu.artifactsystem.service; + +import cn.edu.hnu.artifactsystem.entity.Role; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + * 角色服务接口 + */ +public interface IRoleService extends IService { + + /** + * 分页查询角色列表 + */ + Page getRolePage(int current, int size, String name, Integer status); + + /** + * 根据ID获取角色 + */ + Role getRoleById(Long id); + + /** + * 添加角色 + */ + Role addRole(Role role); + + /** + * 更新角色 + */ + boolean updateRole(Role role); + + /** + * 删除角色 + */ + boolean deleteRole(Long id); + + /** + * 批量删除角色 + */ + boolean batchDeleteRoles(List ids); + + /** + * 获取所有角色 + */ + List getAllRoles(); + + /** + * 根据用户ID获取角色列表 + */ + List getRolesByUserId(Long userId); + + /** + * 为用户分配角色 + */ + boolean assignRolesToUser(Long userId, List roleIds); + + /** + * 根据角色ID获取权限ID列表 + */ + List getPermissionIdsByRoleId(Long roleId); + + /** + * 为角色分配权限 + */ + boolean assignPermissionsToRole(Long roleId, List permissionIds); +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/IUserService.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/IUserService.java new file mode 100644 index 00000000..2ddca8e2 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/IUserService.java @@ -0,0 +1,44 @@ + +package cn.edu.hnu.artifactsystem.service; + +import cn.edu.hnu.artifactsystem.entity.User; +import cn.edu.hnu.artifactcommon.pojo.dto.UserDTO; +import cn.edu.hnu.artifactcommon.pojo.vo.LoginVO; +import cn.edu.hnu.artifactcommon.pojo.vo.UserVO; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * 用户服务接口 + */ +public interface IUserService extends IService { + + /** + * 用户注册 + */ + UserVO register(UserDTO userDTO); + + /** + * 用户登录 + */ + LoginVO login(UserDTO userDTO); + + /** + * 根据用户名查询用户 + */ + User findByUsername(String username); + + /** + * 根据ID获取用户VO + */ + UserVO getUserById(Long id); + + /** + * 检查用户名是否存在 + */ + boolean checkUsernameExists(String username); + + /** + * 根据用户名获取用户VO + */ + UserVO getUserByUsername(String username); +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/impl/PermissionServiceImpl.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/impl/PermissionServiceImpl.java new file mode 100644 index 00000000..8e544610 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/impl/PermissionServiceImpl.java @@ -0,0 +1,179 @@ + +package cn.edu.hnu.artifactsystem.service.impl; + +import cn.edu.hnu.artifactsystem.entity.Permission; +import cn.edu.hnu.artifactsystem.entity.RolePermission; +import cn.edu.hnu.artifactsystem.entity.UserRole; +import cn.edu.hnu.artifactsystem.mapper.PermissionMapper; +import cn.edu.hnu.artifactsystem.mapper.RolePermissionMapper; +import cn.edu.hnu.artifactsystem.mapper.UserRoleMapper; +import cn.edu.hnu.artifactsystem.service.IPermissionService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import jakarta.annotation.Resource; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 权限服务实现类 + */ +@Service +public class PermissionServiceImpl extends ServiceImpl implements IPermissionService { + + @Resource + private PermissionMapper permissionMapper; + + @Resource + private UserRoleMapper userRoleMapper; + + @Resource + private RolePermissionMapper rolePermissionMapper; + + @Override + public Page getPermissionPage(int current, int size, String name, Integer type, Integer status) { + Page page = new Page<>(current, size); + QueryWrapper queryWrapper = new QueryWrapper<>(); + + if (name != null && !name.isEmpty()) { + queryWrapper.like("name", name); + } + + if (type != null) { + queryWrapper.eq("type", type); + } + + if (status != null) { + queryWrapper.eq("status", status); + } + + queryWrapper.orderByAsc("sort_order"); + return permissionMapper.selectPage(page, queryWrapper); + } + + @Override + public Permission getPermissionById(Long id) { + return permissionMapper.selectById(id); + } + + @Override + public Permission addPermission(Permission permission) { + permission.setCreateTime(LocalDateTime.now()); + permissionMapper.insert(permission); + return permission; + } + + @Override + public boolean updatePermission(Permission permission) { + permission.setUpdateTime(LocalDateTime.now()); + return permissionMapper.updateById(permission) > 0; + } + + @Override + public boolean deletePermission(Long id) { + // 删除权限前,先检查是否有角色使用该权限 + List roleIds = rolePermissionMapper.selectRoleIdsByPermissionId(id); + if (roleIds != null && !roleIds.isEmpty()) { + throw new RuntimeException("该权限已被角色使用,无法删除"); + } + + // 删除权限 + return permissionMapper.deleteById(id) > 0; + } + + @Override + public boolean batchDeletePermissions(List ids) { + if (ids == null || ids.isEmpty()) { + return false; + } + + for (Long id : ids) { + deletePermission(id); + } + return true; + } + + @Override + public List getAllPermissions() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("status", 0); // 只查询正常状态的权限 + queryWrapper.orderByAsc("sort_order"); + return permissionMapper.selectList(queryWrapper); + } + + @Override + public List getPermissionTree() { + List allPermissions = getAllPermissions(); + + // 构建父子关系 + Map permissionMap = new HashMap<>(); + for (Permission permission : allPermissions) { + permissionMap.put(permission.getId(), permission); + } + + List rootPermissions = new ArrayList<>(); + for (Permission permission : allPermissions) { + if (permission.getParentId() == null || permission.getParentId() == 0) { + rootPermissions.add(permission); + } else { + Permission parent = permissionMap.get(permission.getParentId()); + if (parent != null) { + if (parent.getChildren() == null) { + parent.setChildren(new ArrayList<>()); + } + parent.getChildren().add(permission); + } + } + } + + return rootPermissions; + } + + @Override + public List getPermissionsByUserId(Long userId) { + // 先获取用户的所有角色ID + List roleIds = userRoleMapper.selectRoleIdsByUserId(userId); + + if (roleIds == null || roleIds.isEmpty()) { + return new ArrayList<>(); + } + + // 再获取这些角色的所有权限ID + List permissionIds = new ArrayList<>(); + for (Long roleId : roleIds) { + List ids = rolePermissionMapper.selectPermissionIdsByRoleId(roleId); + if (ids != null) { + permissionIds.addAll(ids); + } + } + + // 去重 + permissionIds = permissionIds.stream().distinct().collect(Collectors.toList()); + + // 最后根据权限ID获取权限信息 + if (permissionIds.isEmpty()) { + return new ArrayList<>(); + } + + return permissionMapper.selectBatchIds(permissionIds); + } + + @Override + public List getPermissionsByRoleId(Long roleId) { + // 先获取角色的所有权限ID + List permissionIds = rolePermissionMapper.selectPermissionIdsByRoleId(roleId); + + if (permissionIds == null || permissionIds.isEmpty()) { + return new ArrayList<>(); + } + + // 根据权限ID获取权限信息 + return permissionMapper.selectBatchIds(permissionIds); + } +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/impl/RoleServiceImpl.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/impl/RoleServiceImpl.java new file mode 100644 index 00000000..a0174b32 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/impl/RoleServiceImpl.java @@ -0,0 +1,169 @@ + +package cn.edu.hnu.artifactsystem.service.impl; + +import cn.edu.hnu.artifactsystem.entity.Role; +import cn.edu.hnu.artifactsystem.entity.RolePermission; +import cn.edu.hnu.artifactsystem.entity.UserRole; +import cn.edu.hnu.artifactsystem.mapper.RoleMapper; +import cn.edu.hnu.artifactsystem.mapper.RolePermissionMapper; +import cn.edu.hnu.artifactsystem.mapper.UserRoleMapper; +import cn.edu.hnu.artifactsystem.service.IRoleService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import jakarta.annotation.Resource; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +/** + * 角色服务实现类 + */ +@Service +public class RoleServiceImpl extends ServiceImpl implements IRoleService { + + @Resource + private RoleMapper roleMapper; + + @Resource + private UserRoleMapper userRoleMapper; + + @Resource + private RolePermissionMapper rolePermissionMapper; + + @Override + public Page getRolePage(int current, int size, String name, Integer status) { + Page page = new Page<>(current, size); + QueryWrapper queryWrapper = new QueryWrapper<>(); + + if (name != null && !name.isEmpty()) { + queryWrapper.like("name", name); + } + + if (status != null) { + queryWrapper.eq("status", status); + } + + queryWrapper.orderByAsc("sort_order"); + return roleMapper.selectPage(page, queryWrapper); + } + + @Override + public Role getRoleById(Long id) { + return roleMapper.selectById(id); + } + + @Override + public Role addRole(Role role) { + role.setCreateTime(LocalDateTime.now()); + roleMapper.insert(role); + return role; + } + + @Override + public boolean updateRole(Role role) { + role.setUpdateTime(LocalDateTime.now()); + return roleMapper.updateById(role) > 0; + } + + @Override + public boolean deleteRole(Long id) { + // 删除角色前,先删除角色与用户的关联关系 + QueryWrapper userRoleWrapper = new QueryWrapper<>(); + userRoleWrapper.eq("role_id", id); + userRoleMapper.delete(userRoleWrapper); + + // 删除角色前,先删除角色与权限的关联关系 + QueryWrapper rolePermissionWrapper = new QueryWrapper<>(); + rolePermissionWrapper.eq("role_id", id); + rolePermissionMapper.delete(rolePermissionWrapper); + + // 删除角色 + return roleMapper.deleteById(id) > 0; + } + + @Override + public boolean batchDeleteRoles(List ids) { + if (ids == null || ids.isEmpty()) { + return false; + } + + for (Long id : ids) { + deleteRole(id); + } + return true; + } + + @Override + public List getAllRoles() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("status", 0); // 只查询正常状态的角色 + queryWrapper.orderByAsc("sort_order"); + return roleMapper.selectList(queryWrapper); + } + + @Override + public List getRolesByUserId(Long userId) { + // 先查询用户拥有的角色ID + List roleIds = userRoleMapper.selectRoleIdsByUserId(userId); + + if (roleIds == null || roleIds.isEmpty()) { + return new ArrayList<>(); + } + + // 再根据角色ID查询角色信息 + return roleMapper.selectBatchIds(roleIds); + } + + @Override + @Transactional + public boolean assignRolesToUser(Long userId, List roleIds) { + // 先删除用户原有的角色关系 + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("user_id", userId); + userRoleMapper.delete(wrapper); + + // 添加新的角色关系 + if (roleIds != null && !roleIds.isEmpty()) { + for (Long roleId : roleIds) { + UserRole userRole = new UserRole(); + userRole.setUserId(userId); + userRole.setRoleId(roleId); + userRole.setCreateTime(LocalDateTime.now()); + userRoleMapper.insert(userRole); + } + } + + return true; + } + + @Override + public List getPermissionIdsByRoleId(Long roleId) { + return rolePermissionMapper.selectPermissionIdsByRoleId(roleId); + } + + @Override + @Transactional + public boolean assignPermissionsToRole(Long roleId, List permissionIds) { + // 先删除角色原有的权限关系 + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("role_id", roleId); + rolePermissionMapper.delete(wrapper); + + // 添加新的权限关系 + if (permissionIds != null && !permissionIds.isEmpty()) { + for (Long permissionId : permissionIds) { + RolePermission rolePermission = new RolePermission(); + rolePermission.setRoleId(roleId); + rolePermission.setPermissionId(permissionId); + rolePermission.setCreateTime(LocalDateTime.now()); + rolePermissionMapper.insert(rolePermission); + } + } + + return true; + } +} diff --git a/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/impl/UserServiceImpl.java b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/impl/UserServiceImpl.java new file mode 100644 index 00000000..a950a337 --- /dev/null +++ b/src/ArtifactLLM_banker/artifact-system/src/main/java/cn/edu/hnu/artifactsystem/service/impl/UserServiceImpl.java @@ -0,0 +1,143 @@ + +package cn.edu.hnu.artifactsystem.service.impl; + +import cn.edu.hnu.artifactcommon.constant.SystemConstant; +import cn.edu.hnu.artifactcommon.pojo.dto.UserDTO; +import cn.edu.hnu.artifactcommon.pojo.vo.LoginVO; +import cn.edu.hnu.artifactcommon.pojo.vo.UserVO; +import cn.edu.hnu.artifactcommon.utils.CaptchaUtil; +import cn.edu.hnu.artifactcommon.utils.EncryptUtil; +import cn.edu.hnu.artifactcommon.utils.JwtUtil; +import cn.edu.hnu.artifactsystem.entity.User; +import cn.edu.hnu.artifactsystem.mapper.UserMapper; +import cn.edu.hnu.artifactsystem.service.IUserService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import jakarta.annotation.Resource; +import java.time.LocalDateTime; + +/** + * 用户服务实现类 + */ +@Service +public class UserServiceImpl extends ServiceImpl implements IUserService { + + @Resource + private UserMapper userMapper; + + @Resource + private JwtUtil jwtUtil; + + @Resource + private CaptchaUtil captchaUtil; + + @Override + public UserVO register(UserDTO userDTO) { + // 验证验证码 + if (!captchaUtil.validateCaptcha(userDTO.getCaptchaUuid(), userDTO.getCaptcha())) { + throw new RuntimeException("验证码错误"); + } + + // 检查用户名是否已存在 + if (checkUsernameExists(userDTO.getUsername())) { + throw new RuntimeException("用户名已存在"); + } + + // 创建用户实体 + User user = new User(); + user.setUsername(userDTO.getUsername()); + user.setPassword(encryptPassword(userDTO.getPassword())); + user.setEmail(userDTO.getEmail()); + user.setRole(SystemConstant.ROLE_USER); // 默认角色为普通用户 + user.setStatus(SystemConstant.STATUS_NORMAL); // 默认状态为正常 + user.setCreateTime(LocalDateTime.now()); + + // 保存用户 + userMapper.insert(user); + + // 转换为VO并返回 + return convertToVO(user); + } + + @Override + public LoginVO login(UserDTO userDTO) { + // 验证验证码 + if (!captchaUtil.validateCaptcha(userDTO.getCaptchaUuid(), userDTO.getCaptcha())) { + throw new RuntimeException("验证码错误"); + } + + // 根据用户名查询用户 + User user = findByUsername(userDTO.getUsername()); + if (user == null) { + throw new RuntimeException("用户不存在"); + } + + // 验证密码 + if (!user.getPassword().equals(encryptPassword(userDTO.getPassword()))) { + throw new RuntimeException("密码错误"); + } + + // 检查用户状态 + if (!SystemConstant.STATUS_NORMAL.equals(user.getStatus())) { + throw new RuntimeException("账户已被禁用"); + } + + // 更新最后登录时间 + user.setLastLoginTime(LocalDateTime.now()); + userMapper.updateById(user); + + // 生成JWT令牌 + String token = jwtUtil.generateToken(user.getUsername(), user.getRole()); + + // 构建登录响应 + LoginVO loginVO = new LoginVO(); + loginVO.setToken(token); + loginVO.setUser(convertToVO(user)); + + return loginVO; + } + + @Override + public User findByUsername(String username) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("username", username); + return userMapper.selectOne(queryWrapper); + } + + @Override + public UserVO getUserById(Long id) { + User user = userMapper.selectById(id); + return user != null ? convertToVO(user) : null; + } + + @Override + public boolean checkUsernameExists(String username) { + return findByUsername(username) != null; + } + + @Override + public UserVO getUserByUsername(String username) { + User user = findByUsername(username); + return user != null ? convertToVO(user) : null; + } + + /** + * 密码加密 + */ + private String encryptPassword(String password) { + return EncryptUtil.md5(password); + } + + /** + * 实体转VO + */ + private UserVO convertToVO(User user) { + UserVO userVO = new UserVO(); + BeanUtils.copyProperties(user, userVO); + // 不返回密码 + return userVO; + } +} diff --git a/src/ArtifactLLM_banker/artifact-web/pom.xml b/src/ArtifactLLM_banker/artifact-web/pom.xml index 0081428f..8fa7f33f 100644 --- a/src/ArtifactLLM_banker/artifact-web/pom.xml +++ b/src/ArtifactLLM_banker/artifact-web/pom.xml @@ -38,6 +38,32 @@ spring-boot-starter + + + cn.edu.hnu + artifact-system + 0.0.1-SNAPSHOT + + + + + cn.edu.hnu + artifact-ai + 0.0.1-SNAPSHOT + + + + cn.edu.hnu + artifact-knowledge + 0.0.1-SNAPSHOT + + + + cn.edu.hnu + artifact-relic + 0.0.1-SNAPSHOT + + diff --git a/src/ArtifactLLM_banker/pom.xml b/src/ArtifactLLM_banker/pom.xml index 0d31fdcb..07e74ce5 100644 --- a/src/ArtifactLLM_banker/pom.xml +++ b/src/ArtifactLLM_banker/pom.xml @@ -43,6 +43,7 @@ org.springframework.boot spring-boot-starter-web + org.mybatis.spring.boot mybatis-spring-boot-starter @@ -54,18 +55,69 @@ mysql-connector-j runtime + org.springframework.boot spring-boot-starter-test test + org.mybatis.spring.boot mybatis-spring-boot-starter-test 3.0.5 test - + + + org.projectlombok + lombok + 1.18.34 + provided + + + + com.baomidou + mybatis-plus-boot-starter + 3.5.3.1 + + + + jakarta.annotation + jakarta.annotation-api + 2.1.1 + + + + org.springframework.boot + spring-boot-starter-security + + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + diff --git a/src/ArtifactLLM_banker/sql/create_database_part1.sql b/src/ArtifactLLM_banker/sql/create_database_part1.sql new file mode 100644 index 00000000..3e1a564a --- /dev/null +++ b/src/ArtifactLLM_banker/sql/create_database_part1.sql @@ -0,0 +1,120 @@ +-- 创建数据库 +CREATE DATABASE IF NOT EXISTS artifact_llm CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- 使用数据库 +USE artifact_llm; + +/*==============================================================*/ +/* DBMS name: MySQL 8.0 */ +/* Created on: 2024/XX/XX 10:00:00 */ +/*==============================================================*/ + +-- 删除所有表(按依赖关系逆序) +DROP TABLE IF EXISTS audit_trails; +DROP TABLE IF EXISTS user_management_logs; +DROP TABLE IF EXISTS content_review_logs; +DROP TABLE IF EXISTS model_review_records; +DROP TABLE IF EXISTS feedback; +DROP TABLE IF EXISTS user_favorites; +DROP TABLE IF EXISTS search_history; +DROP TABLE IF EXISTS messages; +DROP TABLE IF EXISTS kg_update_requests; +DROP TABLE IF EXISTS modeling_versions; +DROP TABLE IF EXISTS modeling_projects; +DROP TABLE IF EXISTS user_defined_relations; +DROP TABLE IF EXISTS user_defined_entities; +DROP TABLE IF EXISTS ai_research_reports; +DROP TABLE IF EXISTS ai_messages; +DROP TABLE IF EXISTS entity_relations; +DROP TABLE IF EXISTS relic_multi_mode; +DROP TABLE IF EXISTS cultural_relics; +DROP TABLE IF EXISTS login_operation_log; +DROP TABLE IF EXISTS users; + +/*==============================================================*/ +/* Table: users */ +/*==============================================================*/ +CREATE TABLE users +( + id INT NOT NULL AUTO_INCREMENT, + username VARCHAR(50) NOT NULL, + password VARCHAR(255) NOT NULL, + email VARCHAR(100), + real_name VARCHAR(50), + phone VARCHAR(20), + user_type VARCHAR(20) NOT NULL DEFAULT 'normal', + status VARCHAR(10) NOT NULL DEFAULT 'active', + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + last_login DATETIME, + PRIMARY KEY (id), + UNIQUE KEY uk_username (username), + UNIQUE KEY uk_email (email) +); + +/*==============================================================*/ +/* Table: login_operation_log */ +/*==============================================================*/ +CREATE TABLE login_operation_log +( + id INT NOT NULL AUTO_INCREMENT, + user_id INT NOT NULL, + operation_type VARCHAR(50) NOT NULL, + operation_detail TEXT, + ip_address VARCHAR(45), + user_agent TEXT, + operation_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + status VARCHAR(10) NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (user_id) REFERENCES users (id) +); + +/*==============================================================*/ +/* Table: cultural_relics */ +/*==============================================================*/ +CREATE TABLE cultural_relics +( + id INT NOT NULL AUTO_INCREMENT, + relic_code VARCHAR(50) NOT NULL, + name VARCHAR(200) NOT NULL, + era VARCHAR(100), + material VARCHAR(100), + size VARCHAR(100), + discovery_site VARCHAR(200), + current_location VARCHAR(200), + description TEXT, + cultural_level VARCHAR(50), + preservation_status VARCHAR(50), + created_by INT NOT NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_by INT NOT NULL, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id), + UNIQUE KEY uk_relic_code (relic_code), + FOREIGN KEY (created_by) REFERENCES users (id), + FOREIGN KEY (updated_by) REFERENCES users (id) +); + +/*==============================================================*/ +/* Table: relic_multi_mode */ +/*==============================================================*/ +CREATE TABLE relic_multi_mode +( + id INT NOT NULL AUTO_INCREMENT, + relic_id INT NOT NULL, + resource_type VARCHAR(20) NOT NULL, + resource_name VARCHAR(200) NOT NULL, + resource_path VARCHAR(500) NOT NULL, + file_size BIGINT, + file_format VARCHAR(20), + description TEXT, + upload_by INT NOT NULL, + upload_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + is_approved TINYINT NOT NULL DEFAULT 0, + approved_by INT, + approved_time DATETIME, + PRIMARY KEY (id), + FOREIGN KEY (relic_id) REFERENCES cultural_relics (id), + FOREIGN KEY (upload_by) REFERENCES users (id), + FOREIGN KEY (approved_by) REFERENCES users (id) +); diff --git a/src/ArtifactLLM_banker/sql/create_database_part2.sql b/src/ArtifactLLM_banker/sql/create_database_part2.sql new file mode 100644 index 00000000..a1776645 --- /dev/null +++ b/src/ArtifactLLM_banker/sql/create_database_part2.sql @@ -0,0 +1,98 @@ +/*==============================================================*/ +/* Table: entity_relations */ +/*==============================================================*/ +CREATE TABLE entity_relations +( + id INT NOT NULL AUTO_INCREMENT, + source_entity_id INT NOT NULL, + target_entity_id INT NOT NULL, + relation_type VARCHAR(50) NOT NULL, + relation_name VARCHAR(100) NOT NULL, + description TEXT, + confidence DECIMAL(3,2), + created_by INT NOT NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_by INT NOT NULL, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id), + FOREIGN KEY (source_entity_id) REFERENCES cultural_relics (id), + FOREIGN KEY (target_entity_id) REFERENCES cultural_relics (id), + FOREIGN KEY (created_by) REFERENCES users (id), + FOREIGN KEY (updated_by) REFERENCES users (id) +); + +/*==============================================================*/ +/* Table: ai_messages */ +/*==============================================================*/ +CREATE TABLE ai_messages +( + id INT NOT NULL AUTO_INCREMENT, + user_id INT NOT NULL, + session_id VARCHAR(100) NOT NULL, + message_type VARCHAR(10) NOT NULL, + message_content TEXT NOT NULL, + ai_response TEXT, + response_time INT, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + is_satisfied TINYINT, + PRIMARY KEY (id), + FOREIGN KEY (user_id) REFERENCES users (id) +); + +/*==============================================================*/ +/* Table: ai_research_reports */ +/*==============================================================*/ +CREATE TABLE ai_research_reports +( + id INT NOT NULL AUTO_INCREMENT, + report_title VARCHAR(200) NOT NULL, + report_type VARCHAR(50) NOT NULL, + report_content TEXT NOT NULL, + generated_by INT NOT NULL, + generated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + data_source TEXT, + keywords VARCHAR(500), + download_count INT NOT NULL DEFAULT 0, + is_public TINYINT NOT NULL DEFAULT 0, + PRIMARY KEY (id), + FOREIGN KEY (generated_by) REFERENCES users (id) +); + +/*==============================================================*/ +/* Table: user_defined_entities */ +/*==============================================================*/ +CREATE TABLE user_defined_entities +( + id INT NOT NULL AUTO_INCREMENT, + entity_name VARCHAR(200) NOT NULL, + entity_type VARCHAR(50) NOT NULL, + description TEXT, + properties JSON, + created_by INT NOT NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_by INT NOT NULL, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + status VARCHAR(10) NOT NULL DEFAULT 'pending', + PRIMARY KEY (id), + FOREIGN KEY (created_by) REFERENCES users (id), + FOREIGN KEY (updated_by) REFERENCES users (id) +); + +/*==============================================================*/ +/* Table: user_defined_relations */ +/*==============================================================*/ +CREATE TABLE user_defined_relations +( + id INT NOT NULL AUTO_INCREMENT, + source_entity_id INT NOT NULL, + target_entity_id INT NOT NULL, + relation_name VARCHAR(100) NOT NULL, + relation_description TEXT, + created_by INT NOT NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + status VARCHAR(10) NOT NULL DEFAULT 'pending', + PRIMARY KEY (id), + FOREIGN KEY (source_entity_id) REFERENCES user_defined_entities (id), + FOREIGN KEY (target_entity_id) REFERENCES user_defined_entities (id), + FOREIGN KEY (created_by) REFERENCES users (id) +); diff --git a/src/ArtifactLLM_banker/sql/create_database_part3.sql b/src/ArtifactLLM_banker/sql/create_database_part3.sql new file mode 100644 index 00000000..0d8dd91d --- /dev/null +++ b/src/ArtifactLLM_banker/sql/create_database_part3.sql @@ -0,0 +1,57 @@ +/*==============================================================*/ +/* Table: modeling_projects */ +/*==============================================================*/ +CREATE TABLE modeling_projects +( + id INT NOT NULL AUTO_INCREMENT, + project_name VARCHAR(200) NOT NULL, + project_description TEXT, + created_by INT NOT NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + status VARCHAR(20) NOT NULL DEFAULT 'drafting', + is_collaborative TINYINT NOT NULL DEFAULT 0, + collaborators JSON, + PRIMARY KEY (id), + FOREIGN KEY (created_by) REFERENCES users (id) +); + +/*==============================================================*/ +/* Table: modeling_versions */ +/*==============================================================*/ +CREATE TABLE modeling_versions +( + id INT NOT NULL AUTO_INCREMENT, + project_id INT NOT NULL, + version_number VARCHAR(20) NOT NULL, + version_description TEXT, + model_data JSON NOT NULL, + created_by INT NOT NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + is_current TINYINT NOT NULL DEFAULT 1, + PRIMARY KEY (id), + FOREIGN KEY (project_id) REFERENCES modeling_projects (id), + FOREIGN KEY (created_by) REFERENCES users (id) +); + +/*==============================================================*/ +/* Table: kg_update_requests */ +/*==============================================================*/ +CREATE TABLE kg_update_requests +( + id INT NOT NULL AUTO_INCREMENT, + request_type VARCHAR(20) NOT NULL, + target_type VARCHAR(20) NOT NULL, + target_id INT, + request_data JSON, + request_reason TEXT, + requested_by INT NOT NULL, + requested_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + status VARCHAR(20) NOT NULL DEFAULT 'pending', + processed_by INT, + processed_at DATETIME, + process_comment TEXT, + PRIMARY KEY (id), + FOREIGN KEY (requested_by) REFERENCES users (id), + FOREIGN KEY (processed_by) REFERENCES users (id) +); diff --git a/src/ArtifactLLM_banker/sql/create_database_part4.sql b/src/ArtifactLLM_banker/sql/create_database_part4.sql new file mode 100644 index 00000000..3add75d5 --- /dev/null +++ b/src/ArtifactLLM_banker/sql/create_database_part4.sql @@ -0,0 +1,50 @@ +/*==============================================================*/ +/* Table: messages */ +/*==============================================================*/ +CREATE TABLE messages +( + id INT NOT NULL AUTO_INCREMENT, + sender_id INT NOT NULL, + receiver_id INT NOT NULL, + message_type VARCHAR(20) NOT NULL, + message_title VARCHAR(200), + message_content TEXT NOT NULL, + sent_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + is_read TINYINT NOT NULL DEFAULT 0, + read_at DATETIME, + PRIMARY KEY (id), + FOREIGN KEY (sender_id) REFERENCES users (id), + FOREIGN KEY (receiver_id) REFERENCES users (id) +); + +/*==============================================================*/ +/* Table: search_history */ +/*==============================================================*/ +CREATE TABLE search_history +( + id INT NOT NULL AUTO_INCREMENT, + user_id INT NOT NULL, + search_keywords VARCHAR(500) NOT NULL, + search_filters JSON, + search_results INT, + search_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + search_duration INT, + PRIMARY KEY (id), + FOREIGN KEY (user_id) REFERENCES users (id) +); + +/*==============================================================*/ +/* Table: user_favorites */ +/*==============================================================*/ +CREATE TABLE user_favorites +( + id INT NOT NULL AUTO_INCREMENT, + user_id INT NOT NULL, + favorite_type VARCHAR(20) NOT NULL, + favorite_target_id INT NOT NULL, + favorite_title VARCHAR(200) NOT NULL, + favorite_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + tags VARCHAR(500), + PRIMARY KEY (id), + FOREIGN KEY (user_id) REFERENCES users (id) +); diff --git a/src/ArtifactLLM_banker/sql/create_database_part5.sql b/src/ArtifactLLM_banker/sql/create_database_part5.sql new file mode 100644 index 00000000..18b7cf9c --- /dev/null +++ b/src/ArtifactLLM_banker/sql/create_database_part5.sql @@ -0,0 +1,54 @@ +/*==============================================================*/ +/* Table: feedback */ +/*==============================================================*/ +CREATE TABLE feedback +( + id INT NOT NULL AUTO_INCREMENT, + user_id INT NOT NULL, + feedback_type VARCHAR(20) NOT NULL, + feedback_title VARCHAR(200) NOT NULL, + feedback_content TEXT NOT NULL, + contact_info VARCHAR(100), + submitted_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + status VARCHAR(20) NOT NULL DEFAULT 'pending', + processed_by INT, + processed_at DATETIME, + process_result TEXT, + PRIMARY KEY (id), + FOREIGN KEY (user_id) REFERENCES users (id), + FOREIGN KEY (processed_by) REFERENCES users (id) +); + +/*==============================================================*/ +/* Table: model_review_records */ +/*==============================================================*/ +CREATE TABLE model_review_records +( + id INT NOT NULL AUTO_INCREMENT, + project_id INT NOT NULL, + reviewer_id INT NOT NULL, + review_result VARCHAR(20) NOT NULL, + review_comment TEXT, + reviewed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + revision_required TINYINT NOT NULL DEFAULT 0, + revision_deadline DATETIME, + PRIMARY KEY (id), + FOREIGN KEY (project_id) REFERENCES modeling_projects (id), + FOREIGN KEY (reviewer_id) REFERENCES users (id) +); + +/*==============================================================*/ +/* Table: content_review_logs */ +/*==============================================================*/ +CREATE TABLE content_review_logs +( + id INT NOT NULL AUTO_INCREMENT, + content_type VARCHAR(20) NOT NULL, + content_id INT NOT NULL, + reviewer_id INT NOT NULL, + review_result VARCHAR(20) NOT NULL, + review_comment TEXT, + reviewed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id), + FOREIGN KEY (reviewer_id) REFERENCES users (id) +); diff --git a/src/ArtifactLLM_banker/sql/create_database_part6.sql b/src/ArtifactLLM_banker/sql/create_database_part6.sql new file mode 100644 index 00000000..2a5d0efd --- /dev/null +++ b/src/ArtifactLLM_banker/sql/create_database_part6.sql @@ -0,0 +1,54 @@ +/*==============================================================*/ +/* Table: user_management_logs */ +/*==============================================================*/ +CREATE TABLE user_management_logs +( + id INT NOT NULL AUTO_INCREMENT, + admin_id INT NOT NULL, + target_user_id INT NOT NULL, + operation_type VARCHAR(20) NOT NULL, + operation_detail TEXT, + operation_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + ip_address VARCHAR(45), + PRIMARY KEY (id), + FOREIGN KEY (admin_id) REFERENCES users (id), + FOREIGN KEY (target_user_id) REFERENCES users (id) +); + +/*==============================================================*/ +/* Table: audit_trails */ +/*==============================================================*/ +CREATE TABLE audit_trails +( + id INT NOT NULL AUTO_INCREMENT, + user_id INT NOT NULL, + event_type VARCHAR(50) NOT NULL, + event_description TEXT, + event_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + ip_address VARCHAR(45), + user_agent TEXT, + resource_accessed VARCHAR(500), + operation_result VARCHAR(20) NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (user_id) REFERENCES users (id) +); + +-- 创建索引以提高查询性能 +CREATE INDEX idx_users_user_type ON users(user_type); +CREATE INDEX idx_users_status ON users(status); +CREATE INDEX idx_login_operation_log_user_id ON login_operation_log(user_id); +CREATE INDEX idx_login_operation_log_operation_time ON login_operation_log(operation_time); +CREATE INDEX idx_cultural_relics_relic_code ON cultural_relics(relic_code); +CREATE INDEX idx_cultural_relics_era ON cultural_relics(era); +CREATE INDEX idx_relic_multi_mode_relic_id ON relic_multi_mode(relic_id); +CREATE INDEX idx_relic_multi_mode_resource_type ON relic_multi_mode(resource_type); +CREATE INDEX idx_entity_relations_source_target ON entity_relations(source_entity_id, target_entity_id); +CREATE INDEX idx_ai_messages_user_id ON ai_messages(user_id); +CREATE INDEX idx_ai_messages_session_id ON ai_messages(session_id); +CREATE INDEX idx_ai_research_reports_generated_by ON ai_research_reports(generated_by); +CREATE INDEX idx_ai_research_reports_is_public ON ai_research_reports(is_public); +CREATE INDEX idx_user_favorites_user_id ON user_favorites(user_id); +CREATE INDEX idx_search_history_user_id ON search_history(user_id); +CREATE INDEX idx_search_history_search_time ON search_history(search_time); +CREATE INDEX idx_audit_trails_user_id ON audit_trails(user_id); +CREATE INDEX idx_audit_trails_event_time ON audit_trails(event_time);