Compare commits

..

1 Commits

BIN
.gitignore vendored

Binary file not shown.

@ -1,69 +1 @@
# 大模型增强的文物资源知识管理系统
## 项目简介
本项目是一个结合了现代 Web 技术与人工智能大模型的文物资源知识管理平台。系统旨在为博物馆、文物研究机构及广大文物爱好者提供一个集文物数字化管理、知识图谱可视化、智能问答助手及多模态资源展示于一体的综合性解决方案。
通过本系统,用户可以浏览精美的文物数字资源,探索文物背后的历史关联(知识图谱),并利用集成的大模型 AI 助手进行深入的文化知识交互。
## 核心功能
* **文物资源管理**支持文物基础信息、多模态资源图片、3D模型的录入、查询与展示。
* **知识图谱可视化**:基于 ECharts 构建文物实体间的关联网络,直观展示“同时代”、“同类型”或“相关事件”等知识联系。
* **AI 智能助手**:集成大语言模型,提供智能化的文物知识问答与导览服务。
* **多角色权限体系**:完善的 RBAC基于角色的访问控制系统区分普通用户、专家用户与管理员保障数据安全与审核流程。
* **审核流程**:用户提交的文物信息或建模资源需经过专家或管理员审核后方可发布。
## 系统架构
本项目采用前后端分离的架构设计:
* **前端**`src/vue`
* 基于 **Vue 3** + **Vite** 构建。
* 使用 **Element Plus** 组件库构建现代化 UI。
* 集成 **ECharts** 实现复杂的数据可视化。
* **后端**`src/ArtifactLLM_banker`
* 基于 **Spring Boot** 的微服务模块化架构。
* **artifact-system**:用户、角色、权限管理模块。
* **artifact-relic**:文物核心业务、审核流程及多模态资源管理。
* **artifact-knowledge**:知识图谱构建与查询服务。
* **artifact-ai**:大模型接口对接与智能服务。
* **artifact-common**:公共工具类、常量及通用配置。
## 目录结构
```text
root/
├── src/
│ ├── ArtifactLLM_banker/ # 后端工程根目录 (Maven多模块)
│ └── vue/ # 前端工程根目录 (Vue 3)
├── doc/ # 项目文档 (需求、设计、周报等)
└── README.md # 项目总说明文档
```
## 快速开始
### 1. 环境准备
* **JDK**: 1.8+ (开发使用 JDK 21)
* **Node.js**: 16+
* **MySQL**: 5.7+
* **Redis**: (可选,取决于缓存配置)
* **Neo4j**
### 2. 后端启动
1. 进入后端目录:`cd src/ArtifactLLM_banker`
2. 导入数据库脚本:在 MySQL 中执行 `src/ArtifactLLM_banker/sql/script_new.sql` 及其他 SQL 文件初始化数据库。
3. 修改配置:检查各模块 `src/main/resources/application.properties` (application.yml) 中的数据库连接信息。
4. 启动项目:运行 `ArtifactWebApplication` 主启动类。
### 3. 前端启动
1. 进入前端目录:`cd src/vue`
2. 安装依赖:`npm install`
3. 构建:`npm run build`
4. 启动开发服务器:`npm run dev`
5. 访问地址:`http://localhost:3005` (或控制台输出的其他端口)
## 文档导航
* [前端详细文档](src/vue/README.md)
* [后端详细文档](src/ArtifactLLM_banker/README.md)
# 2班_老师指定的组队_大模型增强的文物资源知识管理系统

@ -1,36 +0,0 @@
# 个人周总结-第11周
## 姓名和起止时间
**姓  名:** 袁明霜涛
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-01
**结束时间:** 2025-12-08
## 本周任务完成情况
| 序号 | 总结内容 | 完成情况 | 情况说明 |
|----|--------|---------------|----------------------------------------------|
| 1 | 学习后端知识 | 完成 | 周内持续学习了SpringBoot开发的相关知识 |
| 2 | 后端持续开发 | 部分完成 | 根据先前编写的需求文档以及此前完成的代码进行进一步了开发,本周完成两个模块,优化两个模块 |
| 3 | 学习代码测试 | 完成学习,进行部分单元测试 | 学习了代码测试相关流程与方法,对此前交付的功能编写了相应的测试类,进行了后端单元测试 |
## 小结
1. **学习收获:** 通过网络资源系统学习了SpringBoot开发知识为后续项目开发奠定了技术基础
2. **能力掌握:** 掌握了代码测试的基本流程和方法,提升了代码质量保障能力
3. **工作成果:** 按计划完成了两个新模块的后端开发工作,对现有模块进行了优化,提升了系统性能
4. **后续计划:** 继续深入学习SpringBoot内容加强与前端团队的协作确保项目整体进度
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,87 +0,0 @@
# 小组会议纪要-第12周
## 会议记录概要
**团队名称:** 2班-老师指定的组队
**指导老师:** 彭鹏
**主 持 人:** 袁明霜涛
**记录人员:** 袁明霜涛
**会议主题:** 阿尔法版本开发进展、集成问题与演示准备
**会议地点:** 天马二食堂二楼
**会议时间:** 2025-12-08 16:30-16:50
**纪录时间:** 2025年12月08日 18:00
**参与人员:** 李梦源、符晋康、哈俊元、袁明霜涛
---
## 会议内容
### 1. 代码提交规范与注意事项
不提交IDE配置文件如 .idea、.vscode和构建生成文件如 node_modules、dist。 提交时只选择已修改的代码文件,避免提交无关文件。
### 2. 文档撰写与更新
**过程文档:**(如计划、总结说明)需及时更新,尤其是上周内容;
**正式文档:**(如需求规格说明书、设计文档)需根据开发进展持续修订;
**新建文档:** 用户手册、测试报告等文档需配合开发进度同步编写。
### 3. 阿尔法版本开发进展与集成问题
**集成:** 前后端目前尚未完全集成,存在接口不一致、配置环境差异等问题。
**设计:** 后端数据库设计存在不足,需根据实际代码补充表结构。
**计划:** AI问答功能原计划调用API目前考虑先在前端实现后续再迁移至后端。
### 4. 演示准备与分工
明日向老师演示时,前后端将分开演示:
**前端:** 展示界面与交互;
**后端:** 通过单元测试类展示功能逻辑。
演示内容不包括完整集成系统,重点展示已完成模块。
### 5. 运维与部署安排
计划使用华为云服务器进行部署需提前配置运行环境JDK、Spring Boot、MySQL等。部署前需确保代码在本地可正常运行避免环境差异导致问题。
### 6. 后续任务安排
**集成:** 继续完善前后端接口对接,争取在阿尔法版本完成基本集成。
**设计:** 补充数据库设计修正已知bug。
---
## 问题总结
### 已解决问题:
1. 明确了代码提交规范,避免提交无效文件。
2. 确定了演示方式为前后端分离展示。
3. 确定AI功能先在前端实现后续再集成至后端。
### 待解决问题:
1. 前后端集成困难,接口不一致,环境配置复杂。
2. 数据库设计不完善,需根据代码调整。
3. 部分功能如知识图谱、AI问答实现难度大需进一步研究。
4. 部署环境配置尚未统一,需整理配置文档。
---
## 小组协作情况总结
1. 小组成员积极讨论,针对集成问题提出多种解决方案。
2. 前后端分工明确,但集成协调仍需加强。
3. 文档撰写任务分配清晰,进度基本符合预期。
---
## 备注
1. 下周重点任务为前后端集成与阿尔法版本初步验收。
2. 需统一开发环境配置,为运维环境部署进行准备。
3. 明日在指导老师处演示后,根据老师反馈调整开发计划。
---
## 【注】
1. 本文档为"老师指定的组队"小组软件过程会议记录记录人员必须在会议后一个工作日之内如实填写并汇报给PM、Lead及相关人员。
2. 文档内容已经标上编号,记录人员如有增加或者减少编号的需要,在保证文档格式正确的前提下修改。
3. 本文档内容在填写完毕之后,在已有的文件名称后面加上"(会议记录-第几周)",如"meeting-minutes-03",如果一周有多次会议,命名为"meeting-minutes-03-01"。

@ -1,40 +0,0 @@
# 小组周计划-第12周
## 团队名称和起止时间
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-08
**结束时间:** 2025-12-15
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|----|-------------|----------|---------------------------------------------------|
| 1 | 阿尔法版本持续迭代开发 | 全体成员 | 持续推进阿尔法版本的迭代开发工作。 |
| 2 | 前后端接口对接与联调 | 全体成员 | 后端完成模块开发后为前端提供接口文档,前端根据已完善的接口文档,完成前后端基础接口联调 |
| 3 | AI问答功能前端实现 | 哈俊元、李梦源 | 将AI问答功能暂时集成到前端通过调用API实现基础问答交互 |
| 4 | 数据库设计补充与调整 | 符晋康、袁明霜涛 | 根据实际开发情况,补充数据库表结构,修正已有前后端设计问题 |
| 5 | 阿尔法版本演示准备 | 全体成员 | 2025-12-09 14:00 准备前后端分离演示材料:前端展示界面,后端展示单元测试与功能逻辑 |
| 6 | 迭代开发计划调整 | 全体成员 | 根据指导老师对已完成模块演示的反馈,调整迭代开发计划,补充相关前后端设计 |
| 7 | 正式文档更新 | 全体成员 | 更新迭代开发计划、需求规格说明书等文档,同步最新开发进展 |
## 小结
1. **集成测试:** 本周核心任务是初步进行前后端集成,需集中精力解决接口对接与数据通信问题。
2. **文档同步:** 开发进度需及时反映在文档中,尤其是需求规格说明书与迭代开发计划。
3. **演示准备:** 阿尔法版本演示虽为分离展示,但需确保前后端功能完整、逻辑清晰。
4. **环境统一:** 开发与部署环境配置需标准化,避免因环境差异导致集成失败。
5. **沟通协作:** 前后端人员需保持高频沟通,及时解决集成过程中的技术问题。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. PM综合本小组成员工作情况提交小组周计划、周总结报告按时上传至代码托管平台。

@ -1,39 +0,0 @@
# 小组周总结-第12周
## 团队名称和起止时间
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-08
**结束时间:** 2025-12-15
## 本周任务完成情况
| 序号 | 总结内容 | 是否完成 | 情况说明 |
|----|-------------|------|----------------------------------------------------|
| 1 | 阿尔法版本持续迭代开发 | 部分完成 | 持续推进了阿尔法版本的迭代开发工作。 |
| 2 | 前后端接口对接与联调 | 部分完成 | 后端完成阿尔法版本模块开发,为前端提供了接口文档,前端根据已完善的接口文档,进行了前后端基础接口联调 |
| 3 | AI问答功能前端实现 | 未完成 | 当前AI问答功能在后端基础实现未进行真实大模型api调用 |
| 4 | 数据库设计补充与调整 | 完成 | 根据实际开发情况,补充了数据库表结构,修正了已有前后端设计问题 |
| 5 | 阿尔法版本演示准备 | 完成 | 2025-12-09 14:00 准备前后端分离演示材料:前端展示界面,后端展示单元测试与功能逻辑 |
| 6 | 迭代开发计划调整 | 未完成 | 根据指导老师对已完成模块演示的反馈,调整迭代开发计划,补充相关前后端设计 |
| 7 | 正式文档更新 | 部分完成 | 更新迭代开发计划、需求规格说明书等文档,同步最新开发进展 |
## 小结
1. **集成测试:** 本周核心任务是初步进行前后端集成,初步实现接口对接,当前面临数据通信问题。
2. **文档同步:** 开发进度需及时反映在了文档中,尤其是需求规格说明书与迭代开发计划。
3. **环境统一:** 开发与部署环境配置需标准化,避免因环境差异导致集成失败。
4. **沟通协作:** 前后端人员保持高频沟通,及时解决了集成过程中的一些技术问题。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. PM综合本小组成员工作情况提交小组周计划、周总结报告按时上传至代码托管平台。

@ -1,34 +0,0 @@
# 个人周总结-第12周
## 姓名和起止时间
**姓  名:** 符晋康
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-08
**结束时间:** 2025-12-15
## 本周任务完成情况
| 序号 | 总结内容 | | 情况说明 |
|----|-----------|-----|---------------------------|
| 1 | 实现后端接口的实现 | 完成 | 按照α计划和开发进度完成了α版本的接口实现 |
| 2 | 持续学习后端知识 | 完成 | 根据开发需要继续学习了gstore图数据库相关知识 |
| 3 | 集成测试 | 未完成 | 前后端依然没有集成成功 |
## 小结
1. **持续学习:** 根据后续开发的需要 持续学习必需的后端知识;
2. **代码测试:** 小组代码整合后重新测试接口功能。
3. **补充设计:** 学习gstore图数据库相关知识 为后续数据库优化做准备。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,25 +0,0 @@
# 个人周总结-第12周
## 个人信息和起止时间
**姓名:** 哈俊元
**开始时间:** 2025-11-17
**结束时间:** 2025-11-23
## 本周任务完成情况
| 序号 | 总结内容 | 是否完成 | 情况说明 |
|------|----------|----------|----------|
| 1 | 文物管理系统前端界面优化 | 完成 | 对文物详情页进行了UI优化提升了用户体验 |
| 2 | 知识图谱展示功能完善 | 完成 | 实现了文物关联关系的可视化展示功能 |
| 3 | AI问答模块测试 | 完成 | 对AI助手的问答功能进行了全面测试并修复了部分bug |
| 4 | 数据库查询优化 | 完成 | 优化了文物信息检索的SQL查询语句提高了查询效率 |
| 5 | 用户权限管理功能完善 | 完成 | 实现了更细粒度的用户权限控制机制 |
## 小结
1. **技术提升:** 本周通过对前端界面和后端查询的优化加深了对Vue和Spring Boot框架的理解。
2. **团队协作:** 与团队成员密切合作,解决了知识图谱展示中的技术难题。
3. **项目进展:** 项目核心功能已经基本实现,下一步重点是系统稳定性和性能优化。
---

@ -1,42 +0,0 @@
# 个人周总结-第12周
## 姓名和起止时间
**姓  名:** 李梦源
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-08
**结束时间:** 2025-12-15
## 本周任务完成情况
| 序号 | 计划内容 | 是否完成 | 情况说明 |
|------|---------------------|------------|--------------------|
| 1 | 整理项目材料,准备验收 | 完成 | 汇总文档与演示内容,顺利通过阶段性验收 |
| 2 | 优化前端功能模块 | 完成 | 进一步提升了代码质量与交互体验 |
| 3 | 配合后端完成接口联调 | 部分完成 | 对接数据部分接口,确保前后端通信稳定、数据准确 |
| 4 | 系统测试与问题修复 | 完成 | 针对测试过程中出现的几个问题进行排查、修复与性能调优 |
## 小结
1. **学习需求:** 学习了有关数据库和前后端对接的一部分知识;
2. **前端功能优化**:持续改进前端模块,增强用户体验与界面交互流畅度;
3. **测试修复与质量保障**:开展系统测试,及时修复发现问题,优化整体性能;
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,38 +0,0 @@
# 个人周计划-第12周
## 姓名和起止时间
**姓  名:** 袁明霜涛
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-08
**结束时间:** 2025-12-15
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|----|------------|-----|-------------------------------------------------|
| 1 | 学习后端知识 | 个人 | 周内持续学习SpringBoot开发的相关知识 |
| 2 | 后端持续开发 | 个人 | 根据先前编写的需求文档以及此前完成的代码进行进一步开发 |
| 3 | 学习代码测试 | 个人 | 学习代码测试相关流程与方法,测试此前交付的功能能否正确相应,进一步学习集成测试方法 |
| 4 | 数据库设计补充与调整 | 个人 | 根据实际开发情况,补充数据库表结构,修正已有数据库设计问题 |
| 5 | 阿尔法版本演示准备 | 个人 | 2025-12-09 14:00 准备后端演示:后端展示单元测试与功能逻辑,编写单元测试测试类 |
## 小结
1. **学习需求:** 希望能有对于图数据库以及SpringBoot开发的教学
2. **知识储备:** 提前学习后续需要使用的知识,为后续的后端开发做准备;
3. **代码测试:** 学习代码测试相关的流程与方法,审查相应功能。
4. **补充设计:** 补充数据库表结构,修正已有数据库设计问题。
5. **演示准备:** 准备后端演示:后端展示单元测试与功能逻辑。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,37 +0,0 @@
# 个人周总结-第12周
## 姓名和起止时间
**姓  名:** 袁明霜涛
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-08
**结束时间:** 2025-12-15
## 本周任务完成情况
| 序号 | 总结内容 | | 情况说明 |
|----|------------|-----|------------------------------------------------------|
| 1 | 学习后端知识 | 完成 | 周内持续学习了SpringBoot开发的相关知识 |
| 2 | 后端持续开发 | 完成 | 根据先前编写的需求文档以及此前完成的代码进行进一步开发,完成了阿尔法版本个人任务 |
| 3 | 学习代码测试 | 未完成 | 学习了代码测试相关流程与方法,测试此前交付的功能能否正确相应,进一步学习集成测试方法,当前有待进一步测试 |
| 4 | 数据库设计补充与调整 | 完成 | 根据实际开发情况,补充了数据库表结构,修正了已有数据库设计问题 |
| 5 | 阿尔法版本演示准备 | 完成 | 2025-12-09 14:00 准备后端演示:后端展示单元测试与功能逻辑,编写单元测试测试类 |
## 小结
1. **学习需求:** 希望能有对于图数据库以及SpringBoot开发的教学
2. **知识储备:** 提前学习后续需要使用的知识,为后续的后端开发做准备;
3. **代码测试:** 学习了代码测试相关的流程与方法,初步审查了相应功能。
4. **补充设计:** 补充了数据库表结构,修正了已有数据库设计问题。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,78 +0,0 @@
# 小组会议纪要-第13周
## 会议记录概要
**团队名称:** 2班-老师指定的组队
**指导老师:** 彭鹏
**主 持 人:** 符晋康
**记录人员:** 符晋康
**会议主题:** 阿尔法版本开发进展、集成问题与演示准备
**会议地点:** 线上会议
**会议时间:** 2025-12-15 16:30-16:50
**纪录时间:** 2025年12月15日 18:00
**参与人员:** 李梦源、符晋康、哈俊元、袁明霜涛
---
## 会议内容
### 1. gstore图数据库配置
说明gstore图数据库的配置步骤为之后β版本开发优化数据库做准备
### 2. 部分文档更新
**迭代开发计划第三稿:** 根据开发进度和实际情况更新迭代开发计划;
**需求规格说明书:** 根据实际开发情况进行修改,提交最终稿;
### 3. α版本开发集成测试
**集成:** 前后端依然没有完成集成测试,加快进度完成前后端联调。
### 4. 小班课演示开发进度
准备周三小班课α版本演示:
**功能展示:** 展示目前实现开发的功能;
**代码分析:** 根据老师要求将前后端代码模块进行分析与改进。
### 5. 后续任务安排
**集成测试:** 实现前后端集成测试 保证后端已完成接口正常使用。
**图数据库:** 后续学习gstore图数据库 优化数据库设计。
---
## 问题总结
### 已解决问题:
1. 根据开发进度实现后端数据库设计的初步确定。
2. 实现了项目前后端项目的同时启动。
### 待解决问题:
1. 前后端集成测试未实现。
2. 学习gstore图数据库配置。
3. 部分难度较高的功能实现需要学习新知识。
---
## 小组协作情况总结
1. 小组成员积极讨论,针对集成问题提出多种解决方案。
2. 前后端分工明确,但集成协调仍需加强。
3. 文档撰写任务分配清晰,进度基本符合预期。
---
## 备注
1. 这周重点任务为前后端集成测试与α版本演示。
2. 验收后续准备优化数据库设计 准备β版本的开发。
3. 对现有代码进行结构分析并改进。
---
## 【注】
1. 本文档为"老师指定的组队"小组软件过程会议记录记录人员必须在会议后一个工作日之内如实填写并汇报给PM、Lead及相关人员。
2. 文档内容已经标上编号,记录人员如有增加或者减少编号的需要,在保证文档格式正确的前提下修改。
3. 本文档内容在填写完毕之后,在已有的文件名称后面加上"(会议记录-第几周)",如"meeting-minutes-03",如果一周有多次会议,命名为"meeting-minutes-03-01"。

@ -1,38 +0,0 @@
# 小组周计划-第13周
## 团队名称和起止时间
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-15
**结束时间:** 2025-12-22
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|----|----------|----------|-------------------------------|
| 1 | α版本开发完成 | 全体成员 | 完成α版本所有功能的实现与测试。 |
| 2 | 前后端集成测试 | 全体成员 | 前端根据后端提供的api文档进行接口联调 |
| 3 | 数据库设计优化 | 符晋康、袁明霜涛 | 待α版本验收后 学习gstore图数据库 进行数据库的优化 |
| 4 | α版本验收 | 全体成员 | 小班课进行α版本演示 并分析修改代码结构 |
| 5 | 迭代开发文档修改 | 全体成员 | 根据实际开发情况修正α迭代开发文档 |
| 6 | 需求规格文档修改 | 全体成员 | 根据开发情况和需求更改完成需求规格文档最终稿的确定 |
## 小结
1. **α版本开发完成:** 在小班验收前完全实现α版本的开发实现。
2. **数据库优化:** 学习gstore图数据库相关知识 后续准备数据库优化。
3. **开发演示:** 小班课演示α版本开发情况 并分析修改代码结构。
4. **文档修改:** 修改迭代开发文档以及需求规格文档
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. PM综合本小组成员工作情况提交小组周计划、周总结报告按时上传至代码托管平台。

@ -1,37 +0,0 @@
# 小组周总结-第13周
## 团队名称和起止时间
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-15
**结束时间:** 2025-12-22
## 本周任务完成情况
| 序号 | 总结内容 | 是否完成 | 情况说明 |
|----|-------------|------|---------------------------------|
| 1 | α版本开发完成 | 完成 | 完成α版本所有功能的实现与测试 |
| 2 | 前后端集成测试 | 完成 | 前后端接口可以正常集成测试各个接口 |
| 3 | 数据库设计优化 | 未完成 | 需继续学习gstore图数据库相关知识 再优化数据库设计 |
| 4 | α版本验收 | 完成 | 小班课进行了α版本演示 并根据老师要求分析了代码结构并进行优化 |
| 5 | 迭代开发文档修改 | 完成 | 根据实际开发情况修正α迭代开发文档 |
| 6 | 需求规格文档修改 | 完成 | 根据开发情况和需求更改完成需求规格文档最终稿的确定 |
## 小结
1. **α版本开发完成:** 在小班验收前完全实现α版本的开发实现。
2. **数据库优化:** 学习gstore图数据库相关知识 后续准备数据库优化。
3. **开发演示:** 小班课演示α版本开发情况 并分析修改代码结构。
4. **文档修改:** 修改迭代开发文档以及需求规格文档
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. PM综合本小组成员工作情况提交小组周计划、周总结报告按时上传至代码托管平台。

@ -1,35 +0,0 @@
# 个人周计划-第13周
## 姓名和起止时间
**姓  名:** 符晋康
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-15
**结束时间:** 2025-12-23
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|----|--------------|---|---------------------------------------|
| 1 | α版本开发完全实现 | 个人 | 本周完全实现α版本开发 |
| 2 | α版本演示及代码结构修改 | 个人 | 本周小班课演示α版本开发进度 并根据老师要求分析并修改代码结构 |
| 3 | 学习gstore图数据库知识 | 个人 | 学习gstore图数据库相关知识为后续开发做准备 |
## 小结
1. **学习需求:** 希望能有对于gstore图数据库的教学
2. **知识储备:** 周内持续学习gstore图数据库相关知识为后续开发做准备
3. **代码测试:** 学习代码集成测试知识 保证前后端接口联调正常。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,35 +0,0 @@
# 个人周总结-第13周
## 姓名和起止时间
**姓  名:** 符晋康
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-15
**结束时间:** 2025-12-23
## 本周任务完成情况
| 序号 | 总结内容 | 是否完成 | 情况说明 |
|----|----------------|------|---------------------------------|
| 1 | α版本开发完全实现 | 完成 | 本周实现了α版本开发 实现了大部分功能 |
| 2 | α版本演示及代码结构修改 | 完成 | 本周小班课演示α版本开发进度 并根据老师要求分析并修改代码结构 |
| 3 | 学习gstore图数据库知识 | 完成 | 持续学习gstore图数据库相关知识为后续优化数据库做准备 |
## 小结
1. **学习进度:** 学习了图数据库以及SpringBoot开发的相关知识
2. **知识储备:** 决定使用neo4j作为图数据库的框架,提前学习后续需要使用neo4j图数据库相关知识为后续的后端开发做准备
3. **代码测试:** 通过代码测试相关的流程与方法的学习与使用审查了相应功能确认了目前存在的bug以及需要补充的设计。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,38 +0,0 @@
# 个人周计划-第13周
## 姓名和起止时间
**姓  名:** 哈俊元
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-15
**结束时间:** 2025-12-22
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|------|----------|--------|----------|
| 1 | 完成α版本开发 | 个人 | 全面完成α版本前端所有功能的实现与优化 |
| 2 | 前后端集成测试 | 个人 | 与后端完成所有接口的联调,确保数据传输准确无误 |
| 3 | α版本演示准备 | 个人 | 准备周三小班课的α版本演示材料,包括功能展示和代码说明 |
| 4 | 代码结构优化 | 个人 | 根据老师指导和团队讨论结果,优化前端代码结构 |
| 5 | 学习gstore图数据库 | 个人 | 学习gstore图数据库相关知识为后续开发做准备 |
## 小结
1. **版本交付:** 本周核心任务是完成α版本的所有开发工作,确保功能完整性和稳定性;
2. **集成测试:** 重点解决前后端集成过程中的问题,确保系统整体运行流畅;
3. **演示准备:** 认真准备α版本演示,清晰展示项目成果和技术创新点;
4. **技术学习:** 积极学习gstore图数据库知识为后续β版本开发做好技术储备
5. **代码质量:** 注重代码结构优化,提高代码可读性和可维护性。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,33 +0,0 @@
# 个人周总结-第13周
## 个人信息和起止时间
**姓名:** 哈俊元
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-15
**结束时间:** 2025-12-22
## 本周任务完成情况
| 序号 | 总结内容 | 是否完成 | 情况说明 |
|------|----------|----------|----------|
| 1 | 完成α版本开发 | 完成 | 全面完成了α版本前端所有功能的实现与优化包括文物浏览、智能检索、AI助手等多个核心模块 |
| 2 | 前后端集成测试 | 完成 | 与后端完成了主要接口的联调,确保了数据传输的准确性 |
| 3 | α版本演示准备 | 完成 | 准备了周三小班课的α版本演示材料,整理了功能展示流程 |
| 4 | 代码结构优化 | 完成 | 根据团队讨论结果,优化了前端代码结构,提高了代码可维护性 |
| 5 | 学习gstore图数据库 | 完成 | 初步学习了gstore图数据库相关知识为后续开发奠定了基础 |
## 小结
1. **技术提升:** 本周通过α版本的开发和优化工作深入掌握了Vue3和Element Plus的使用技巧特别是在组件通信、状态管理和用户体验优化方面有了显著进步。
2. **团队协作:** 在前后端集成过程中,与后端开发人员密切配合,解决了多个接口对接问题,增强了跨职能协作能力。
3. **项目进展:** α版本的核心功能已全部实现并完成测试,达到了预期的交付标准。项目即将进入β版本的开发阶段。
4. **问题解决:** 在开发过程中遇到了一些技术难点,如搜索历史记录功能的实现、复杂表单的布局优化等,通过查阅文档和团队讨论都得到了有效解决。
---

@ -1,37 +0,0 @@
# 个人周计划-第13周
## 姓名和起止时间
**姓  名:** 李梦源
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-15
**结束时间:** 2025-12-23
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|----|------------|---|-----------------------------------------|
| 1 | 准备迭代开发计划第三版 | 个人 | 与小组成员合作撰写第三版迭代开发计划 |
| 2 | 系统测试与问题修复 | 个人 | 针对测试过程中出现的几个问题进行排查、修复与性能调优 |
| 3 | 学习前端知识 | 个人 | 持续学习vue相关的内容为后续β版本的开发做准备 |
| 4 | α版本演示准备 | 个人 | 准备α版本演示,根据课程老师提出的要求进行审查 |
## 小结
1. **学习需求:** 希望能有对于vue开发和测试的教学
2. **前端功能优化**:持续改进前端模块,增强用户体验与界面交互流畅度;
3. **测试修复与质量保障**:开展系统测试,及时修复发现问题,优化整体性能;
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,37 +0,0 @@
# 个人周总结-第13周
## 姓名和起止时间
**姓  名:** 李梦源
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-15
**结束时间:** 2025-12-23
## 本周完成情况
| 序号 | 计划内容 | 是否完成 | 情况说明 |
|----|------------|---|-----------------------------------------|
| 1 | 准备迭代开发计划第三版 | 完成 | 与小组成员合作撰写第三版迭代开发计划 |
| 2 | 系统测试与问题修复 | 完成 | 针对测试过程中出现的几个问题进行排查、修复与性能调优 |
| 3 | 学习前端知识 | 完成 | 持续学习vue相关的内容为后续β版本的开发做准备 |
| 4 | α版本演示准备 | 完成 | 完成α版本演示,并根据课程老师提出的要求进行整理修改 |
## 小结
1. **α版本演示**:完成了α版本演示,并根据课程老师提出的要求进行整理修改
2. **前端功能优化**:持续改进前端模块,增强用户体验与界面交互流畅度;
3. **测试修复与质量保障**:开展系统测试,及时修复发现问题,优化整体性能;
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,36 +0,0 @@
# 个人周计划-第13周
## 姓名和起止时间
**姓  名:** 袁明霜涛
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-15
**结束时间:** 2025-12-23
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|----|------------|---|-----------------------------------------|
| 1 | 学习后端知识 | 个人 | 周内持续学习SpringBoot开发的相关知识 |
| 2 | 后端代码测试 | 个人 | 学习代码测试相关流程与方法,测试此前交付的功能能否正确相应,进一步进行集成测试 |
| 3 | 学习gstore图数据库知识 | 个人 | 学习gstore图数据库的配置与使用为β版本的知识图谱构建做准备 |
| 4 | 阿尔法版本演示准备 | 个人 | 2025-12-17 准备阿尔法版本演示,根据课程老师提出的要求进行审查 |
## 小结
1. **学习需求:** 希望能有对于图数据库以及SpringBoot开发的教学
2. **知识储备:** 提前学习后续需要使用gstore图数据库相关知识为后续的后端开发做准备
3. **代码测试:** 学习代码测试相关的流程与方法,审查相应功能。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,36 +0,0 @@
# 个人周总结-第13周
## 姓名和起止时间
**姓  名:** 袁明霜涛
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-15
**结束时间:** 2025-12-23
## 本周任务完成情况
| 序号 | 总结内容 | 是否完成 | 情况说明 |
|----|----------------|------|--------------------------------------------------------|
| 1 | 学习后端知识 | 完成 | 周内持续学习了SpringBoot开发的相关知识 |
| 2 | 后端代码测试 | 完成 | 学习了代码测试相关流程与方法,测试此前交付的功能能否正确相应,进一步进行集成测试 |
| 3 | 学习gstore图数据库知识 | 完成 | 学习了图数据库的配置与使用为β版本的知识图谱构建做准备经过与指导老师进行讨论决定使用neo4j图数据库 |
| 4 | 阿尔法版本演示准备 | 完成 | 2025-12-17 准备了阿尔法版本演示,根据课程老师提出的要求进行审查 |
## 小结
1. **学习进度:** 学习了图数据库以及SpringBoot开发的相关知识
2. **知识储备:** 决定使用neo4j作为图数据库的框架,提前学习后续需要使用neo4j图数据库相关知识为后续的后端开发做准备
3. **代码测试:** 通过代码测试相关的流程与方法的学习与使用审查了相应功能确认了目前存在的bug以及需要补充的设计。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,103 +0,0 @@
# 小组会议纪要-第14周
## 会议记录概要
**团队名称:** 2班-老师指定的组队
**指导老师:** 彭鹏
**主 持 人:** 符晋康
**记录人员:** 符晋康
**会议主题:** Beta版本开发任务分配与进度规划
**会议地点:** 线上会议
**会议时间:** 2025-12-22 16:30-17:00
**纪录时间:** 2025年12月22日 17:30
**参与人员:** 李梦源、符晋康、哈俊元、袁明霜涛
---
## 会议内容
### 1. Beta版本开发任务分配
根据上周Alpha版本验收反馈及项目整体规划明确Beta版本开发任务分配
- 前端团队重点完善界面优化和功能实现
- 后端团队重点完成接口开发和数据库优化
- 全员协同进行系统集成测试
### 2. 需要修改的问题讨论
**前端界面问题:**
- 登录界面验证码自动刷新功能异常问题,由前端团队本周内修复
- 文物浏览界面文物图片对齐和大小不一致问题,需要调整样式
- AI助手输入框自动下拉功能优化
- 用户管理界面状态更新显示异常问题需要修复
**后端功能问题:**
- 筛选功能需从数据库动态获取选项,而非前端模拟
- 模糊搜索功能需要后端支持实现
- 批量导入功能扩展支持多种文件格式
- 提交审核后图片禁用功能需要修复
### 3. 新功能开发任务
**功能新增与完善:**
- 添加用户反馈渠道至普通用户界面
- 实现文物图片超链接功能(点击查看大图)
- 添加搜索记录功能用户使用AI聊天时能查看历史记录
- 完善知识图谱的关系型数据库与图数据库结合设计
### 4. 开发与测试安排
- 本周主要进行Beta版本的编码、测试
- 前后端协作完成功能开发:前端先完善页面界面,后端补充接口功能和方法
- 前端独立运行测试界面,后端配合接口调试
- 进行系统部署准备工作容器化如Docker + 云环境),配置数据库和网络连接
### 5. 文档工作安排
- 加快文档迭代计划修改和补充包括Beta版本功能描述、数据库设计等
- 文档需内部审核,确保准确性和完整性
- 为15周最终版本完成和文档提交做准备
### 6. 大模型与提示词优化
- 优化大模型使用时的提示词策略
- 完善提示词工程提高AI助手回答质量
---
## 问题总结
### 已解决问题:
1. Alpha版本验收完成明确了改进方向
2. Beta版本开发任务已分配明确
3. 团队成员分工进一步细化
### 待解决问题:
1. 前后端集成测试中可能遇到的接口匹配问题
2. 图数据库与关系型数据库结合设计的技术难点
3. 多模态设计中3D部分的技术实现问题
4. 代码分支整理和合并问题
---
## 小组协作情况总结
1. 小组成员对Beta版本开发目标认识统一积极性高
2. 前后端分工明确,协作机制逐步完善
3. 文档工作与开发工作并行推进,协调较好
---
## 备注
1. 本周重点任务为Beta版本功能开发与测试。
2. 需重点关注前后端接口联调和系统集成测试。
3. 为15周最终版本发布做好充分准备。
---
## 【注】
1. 本文档为"老师指定的组队"小组软件过程会议记录记录人员必须在会议后一个工作日之内如实填写并汇报给PM、Lead及相关人员。
2. 文档内容已经标上编号,记录人员如有增加或者减少编号的需要,在保证文档格式正确的前提下修改。
3. 本文档内容在填写完毕之后,在已有的文件名称后面加上"(会议记录-第几周)",如"meeting-minutes-03",如果一周有多次会议,命名为"meeting-minutes-03-01"。

@ -1,39 +0,0 @@
# 小组周计划-第14周
## 团队名称和起止时间
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-22
**结束时间:** 2025-12-29
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|------|----------------------------|----------------|--------------------------------------------------------------------------|
| 1 | Beta版本功能开发 | 全体成员 | 完成Beta版本核心功能的开发与实现 |
| 2 | 前端界面优化 | 前端团队 | 修复已知界面问题,优化用户体验 |
| 3 | 后端接口完善 | 后端团队 | 补充和完善各模块接口功能,确保接口稳定性 |
| 4 | 前后端集成测试 | 全体成员 | 进行系统集成测试,解决接口联调问题 |
| 5 | 数据库优化 | 符晋康、袁明霜涛 | 结合图数据库优化数据存储结构 |
| 6 | 文档迭代更新 | 全体成员 | 根据开发进度更新相关文档 |
| 7 | 系统部署准备 | 全体成员 | 准备Docker容器化部署方案 |
|
## 小结
1. **Beta版本开发** 本周核心任务是完成Beta版本的功能开发和测试确保各模块功能完善。
2. **问题修复:** 重点修复Alpha版本验收中发现的各项问题提升系统稳定性和用户体验。
3. **集成测试:** 加强前后端协同,完成系统集成测试,确保各模块无缝衔接。
4. **文档完善:** 根据开发进度及时更新相关文档,为最终版本提交做好准备。
5. **部署准备:** 完成系统部署方案设计,为下周正式部署做好准备。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. PM综合本小组成员工作情况提交小组周计划、周总结报告按时上传至代码托管平台。

@ -1,45 +0,0 @@
# 小组周总结-第14周
## 团队名称和起止时间
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-22
**结束时间:** 2025-12-29
## 本周任务完成情况
| 序号 | 完成内容 | 执行人 | 完成情况 |
|------|----------------------------|----------------|--------------------------------------------------------------------------|
| 1 | Beta版本功能开发 | 全体成员 | 完成Beta版本核心功能的开发与实现前端界面优化基本完成 |
| 2 | 前端界面优化 | 前端团队 | 修复已知界面问题,优化用户体验,登录验证码、图片对齐等问题已解决 |
| 3 | 后端接口完善 | 后端团队 | 补充和完善各模块接口功能,接口稳定性得到提升 |
| 4 | 前后端集成测试 | 全体成员 | 完成大部分接口联调,前后端基本连接成功,数据传输正常 |
| 5 | 数据库优化 | 符晋康、袁明霜涛 | 结合图数据库优化数据存储结构,推进关系型数据库与图数据库结合设计 |
| 6 | 文档迭代更新 | 全体成员 | 根据开发进度更新相关文档 |
| 7 | 系统部署准备 | 全体成员 | 开始准备Docker容器化部署方案 |
## 小结
1. **Beta版本开发** 本周按计划完成了Beta版本的主要功能开发前端界面优化基本完成后端接口功能得到完善系统整体功能趋于完善。
2. **问题修复:** 成功修复了Alpha版本验收中发现的大部分问题包括前端界面的验证码刷新、图片对齐等系统稳定性和用户体验得到显著提升。
3. **集成测试:** 前后端协同工作取得显著进展,大部分接口已完成联调,数据传输正常,系统各模块基本实现无缝衔接。
4. **文档完善:** 根据开发进度及时更新了相关文档,为最终版本提交做好准备。
5. **部署准备:** 开始进行系统部署方案设计,为下周正式部署做准备。
## 待解决问题
1. **智能检索的模糊搜索功能:** 搜索引擎的模糊搜索功能尚未完全解决,需要进一步优化算法和数据库查询逻辑。
2. **批量导入功能:** 批量导入功能在处理某些文件格式时仍存在问题,需要进一步完善支持多种文件格式的处理逻辑。
3. **部分接口细节:** 仍有少量接口需要进一步优化和完善,确保系统稳定性。
4. **图数据库集成:** 关系型数据库与图数据库结合的部分功能仍需完善。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. PM综合本小组成员工作情况提交小组周计划、周总结报告按时上传至代码托管平台。

@ -1,36 +0,0 @@
# 个人周计划-第14周
## 姓名和起止时间
**姓  名:** 符晋康
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-22
**结束时间:** 2025-12-29
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|----|-------------|---|------------------------------|
| 1 | 学习后端知识 | 个人 | 周内持续学习SpringBoot开发的相关知识 |
| 2 | 后端代码完善 | 个人 | 根据α开发进展和β版本的开发需求 进一步完善后端代码 |
| 3 | docker容器化部署 | 个人 | 学习docker容器化部署相关知识 为后续部署项目做准备 |
| 4 | 云服务器部署 | 个人 | 学习云服务器部署相关知识 为后续部署项目做准备 |
## 小结
1. **学习需求:** 希望能有对于图数据库以及SpringBoot开发的教学
2. **项目部署:** 学习docker容器化部署及云服务器部署相关知识 为后续部署项目做准备;
3. **文档更新:** 将正式文档更新到正确的版本,完善先前遗漏的内容,修改错误的内容。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,35 +0,0 @@
# 个人周计划-第14周
## 姓名和起止时间
**姓  名:** 符晋康
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-22
**结束时间:** 2025-12-29
## 本周任务完成情况
| 序号 | 总结内容 | 是否完成 | 情况说明 |
|----|-----------|------|----------------------------------------|
| 1 | 学习后端知识 | 完成 | 周内持续学习SpringBoot开发的相关知识 |
| 2 | 后端代码完善 | 完成 | 根据β版本开发需求 进一步完善了后端代码 |
| 3 | docker容器化部署 | 未完成 | 学习docker容器化部署相关知识 未实现docker容器化部署 需持续学习 |
| 4 | 云服务器部署 | 未完成 | 学习云服务器部署相关知识 未实现云服务器部署 需持续学习 |
## 小结
1. **学习成果:** 进一步学习了SpringBoot开发
2. **容器化部署:** 学习了docker容器化部署和云服务器部署相关知识 需持续学习;
3. **文档更新:** 将正式文档部分更新到正确的版本,完善先前遗漏的内容,修改错误的内容。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,39 +0,0 @@
# 个人周计划-第14周
## 姓名和起止时间
**姓  名:** 哈俊元
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-22
**结束时间:** 2025-12-29
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|------|----------|--------|----------|
| 1 | Beta版本前端功能开发 | 个人 | 完成文物浏览界面优化、AI助手界面改进等前端功能开发 |
| 2 | 修复已知前端问题 | 个人 | 修复登录验证码刷新异常、图片对齐等问题 |
| 3 | 实现新功能界面 | 个人 | 实现反馈渠道、搜索记录等新功能的界面设计与开发 |
| 4 | 前后端接口联调 | 个人 | 与后端配合完成接口调试,确保数据传输准确无误 |
| 5 | 代码重构与优化 | 个人 | 优化前端代码结构,提高代码质量和可维护性 |
## 小结
1. **功能完善:** 本周重点是完成Beta版本前端功能开发确保界面美观、功能完善
2. **问题修复:** 及时修复已知的前端问题,提升用户体验;
3. **新功能实现:** 按照需求完成新功能的界面开发,确保与整体风格一致;
4. **接口联调:** 密切配合后端开发人员,确保前后端数据交互正常;
5. **代码质量:** 注重代码重构和优化,提高代码的可读性和可维护性;
6. **技术提升:** 通过实际开发工作,不断提升前端技术水平和解决问题的能力。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,39 +0,0 @@
# 个人周总结-第14周
## 姓名和起止时间
**姓  名:** 哈俊元
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-22
**结束时间:** 2025-12-29
## 本周任务完成情况
| 序号 | 完成内容 | 执行人 | 完成情况 |
|------|----------|--------|----------|
| 1 | Beta版本前端功能开发 | 个人 | 完成文物浏览界面优化、AI助手界面改进等前端功能开发 |
| 2 | 修复已知前端问题 | 个人 | 修复登录验证码刷新异常、图片对齐等问题 |
| 3 | 实现新功能界面 | 个人 | 实现反馈渠道、搜索记录等新功能的界面设计与开发 |
| 4 | 前后端接口联调 | 个人 | 与后端配合完成接口调试,确保数据传输准确无误 |
| 5 | 代码重构与优化 | 个人 | 优化前端代码结构,提高代码质量和可维护性 |
## 小结
1. **功能完善:** 本周按计划完成了Beta版本前端功能开发优化了文物浏览界面改进了AI助手界面确保界面美观、功能完善
2. **问题修复:** 成功修复了登录验证码刷新异常、文物图片对齐等问题,显著提升了用户体验;
3. **新功能实现:** 按需求完成了反馈渠道、搜索记录等新功能的界面开发,确保与整体风格一致;
4. **接口联调:** 与后端团队密切配合,完成了大部分前后端接口联调,确保数据交互正常;
5. **代码质量:** 对部分前端代码进行了重构和优化,提高了代码的可读性和可维护性;
6. **技术提升:** 通过实际开发工作,在前端技术应用和问题解决能力方面得到了提升。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,43 +0,0 @@
# 个人周计划-第14周
## 姓名和起止时间
**姓  名:** 李梦源
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-22
**结束时间:** 2025-12-29
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|----------|---------------------|----------------|--------------------|
| 1 | β版本前端功能开发 | 个人 | 完成文物浏览界面优化、AI助手界面改进等前端功能细化调整 |
| 2 | 问题修复 | 个人 |针对测试过程中出现的几个问题进行排查、修复与性能调优 |
| 3 | 学习前端知识 | 个人 | 持续学习前端以及数据库基础相关的知识,增强对代码的理解与修改能力 |
| 4 | 前端优化 | 个人 | 持续改进前端模块,增强用户体验与界面交互流畅度;|
## 小结
1. **细节优化:** 本周重点聚焦β版本前端功能微调,细化界面布局与交互细节,保障界面美观度与使用流畅性;
2. **问题排查:** 精准排查并修复前端细节问题,进一步提升用户使用体验;
3. **功能适配:** 按需求完成功能界面的微调与适配工作,确保与项目整体风格统一协调;
4. **联调配合:** 紧密配合后端团队推进接口联调,针对性优化适配细节,保障数据交互稳定准确;
5. **代码规整:** 注重代码细节优化与规整,提升代码可读性与可维护性,为后续迭代奠定基础;
6. **能力提升:** 在细节优化与问题排查过程中,深化对前端适配与交互的理解,提升精准解决问题的能力。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,43 +0,0 @@
# 个人周总结-第14周
## 姓名和起止时间
**姓  名:** 李梦源
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-22
**结束时间:** 2025-12-29
## 本周任务完成情况
| 序号 | 计划内容 | 是否完成 | 情况说明 |
|----------|---------------------|----------------|--------------------|
| 1 | β版本前端功能开发 | 完成 | 完成智能搜索、AI助手界面等前端功能细化调整 |
| 2 | 问题修复 | 完成 |针对测试过程中出现的几个问题进行排查、修复与性能调优 |
| 3 | 学习前端知识 | 完成 | 持续学习前端以及数据库基础相关的知识,增强对代码的理解与修改能力 |
| 4 | 前端优化 | 完成 | 持续改进前端模块,增强用户体验与界面交互流畅度;|
## 小结
1. **细节优化:** 本周重点聚焦β版本前端功能微调,细化界面布局与交互细节,保障界面美观度与使用流畅性;
2. **代码规整:** 注重代码细节优化与规整,提升代码可读性与可维护性,为后续迭代奠定基础;
3. **功能适配:** 按需求完成功能界面的微调与适配工作,确保与项目整体风格统一协调;
4. **联调配合:** 紧密配合后端团队推进接口联调,针对性优化适配细节,保障数据交互稳定准确;
5. **问题排查:** 精准排查并修复多个前端细节如表、按钮对齐等问题,进一步提升用户使用体验;
6. **能力提升:** 在细节优化与问题排查过程中,深化对前端适配与交互的理解,提升精准解决问题的能力。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,36 +0,0 @@
# 个人周计划-第14周
## 姓名和起止时间
**姓  名:** 袁明霜涛
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-22
**结束时间:** 2025-12-29
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|----|-----------|---|--------------------------------------|
| 1 | 学习后端知识 | 个人 | 周内持续学习SpringBoot开发的相关知识 |
| 2 | 后端代码完善 | 个人 | 根据先前的α版本验收以及指导老师处的反馈,完善目前后端代码,实现相关功能 |
| 3 | neo4j图数据库 | 个人 | 学习neo4j图数据库的配置与使用完成β版本的知识图谱构建 |
| 4 | 文档修改与完善 | 个人 | 完善先前完成的正式文档,更新到正确的版本,并初步编写后续的文档。 |
## 小结
1. **学习需求:** 希望能有对于图数据库以及SpringBoot开发的教学
2. **知识图谱:** 学习neo4j图数据库相关知识为后续的后端开发做准备
3. **文档更新:** 将正式文档更新到正确的版本,完善先前遗漏的内容,修改错误的内容。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,36 +0,0 @@
# 个人周计划-第14周
## 姓名和起止时间
**姓  名:** 袁明霜涛
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-22
**结束时间:** 2025-12-29
## 本周任务完成情况
| 序号 | 总结内容 | 是否完成 | 情况说明 |
|----|-----------|------|--------------------------------------|
| 1 | 学习后端知识 | 完成 | 周内持续学习SpringBoot开发的相关知识 |
| 2 | 后端代码完善 | 部分完成 | 根据先前的α版本验收以及指导老师处的反馈,完善目前后端代码,实现相关功能 |
| 3 | neo4j图数据库 | 部分完成 | 学习neo4j图数据库的配置与使用完成β版本的知识图谱构建 |
| 4 | 文档修改与完善 | 部分完成 | 完善先前完成的正式文档,更新到正确的版本,并初步编写后续的文档。 |
## 小结
1. **学习成果:** 进一步学习了neo4j图数据库以及SpringBoot开发
2. **知识图谱:** 学习了neo4j图数据库相关知识为后续的知识图谱构建做准备
3. **文档更新:** 将正式文档部分更新到正确的版本,完善先前遗漏的内容,修改错误的内容。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,89 +0,0 @@
# 小组会议纪要-第15周
## 会议记录概要
**团队名称:** 2班-老师指定的组队
**指导老师:** 彭鹏
**主 持 人:** 袁明霜涛
**记录人员:** 李梦源
**会议主题:** 项目开发进度与问题
**会议地点:** 线上会议
**会议时间:** 2025-12-29 16:30-17:00
**纪录时间:** 2025年12月29日 17:30
**参与人员:** 李梦源、符晋康、哈俊元、袁明霜涛
---
## 会议内容
### 1.系统功能与界面讨论
- 讨论了登录和注册功能,确认注册已完成,登录界面需要调整。
- 确认年代和地址字段是固定的,材质类型是动态从数据库获取的。
- 讨论了新增实体类型的实现方式,建议通过下拉栏展示已有实体类,方便用户操作。
- 讨论了画布的功能,建议将建模和实体分开处理,以更符合用户实际行为。
### 2.数据库与导入功能
- 确认当前数据库中的数据多为模拟数据,需要进一步处理以导入真实数据。
- 讨论了导入功能的问题包括从CSV文件导入数据到关系型数据库和图数据库的复杂性。
- 提到需要实现模糊搜索功能可能需要引入分词技术如EF以提高搜索准确性。
### 3.AI增强功能
- 讨论了通过RAG技术调用大模型API将本地知识库与AI结合以提供更可靠的答案。
- 探讨了利用AI API增强数据库搜索功能的可能性但目前实现难度较大。
### 4.文档与用户手册
- 确认当前文档需要根据实际开发进度进行大幅修改,以反映最新功能设计。
- 提到用户手册可以开始编写,但需等待功能完全定型后再补充图表等内容。
### 5.部署与后续计划
- 讨论了云端部署的可能性,包括使用华为云等平台,并提到需要容器化部署。
- 总结了当前开发进度,重点包括模糊搜索、数据库整合和容器化部署等任务。
- 提到后续将优先完成功能开发,再考虑部署和其他高级功能。
---
## 问题总结
### 已解决问题:
1. 明确了改进方向
2. 开发任务已分配明确
3. 团队成员分工进一步细化
### 待解决问题:
1. 处理并解决导入数据时遇到的问题,确保数据能正确导入数据库
2. 检查并修复数据库和模糊搜索问题以确保项目顺利进行
3. 解决文物浏览界面无法添加图片的问题
4. 准备用户手册与测试报告
5. 修改并部署已确定的开发功能
---
## 小组协作情况总结
1. 小组成员对开发目标认识统一,积极性高
2. 前后端分工明确,协作机制逐步完善
3. 文档工作与开发工作并行推进,协调较好
---
## 备注
1. 本周重点任务为系统功能开发与测试。
2. 当前文档需要根据实际开发进度进行大幅修改,以反映最新功能设计。
3. 为最终版本发布做好充分准备。
---
## 【注】
1. 本文档为"老师指定的组队"小组软件过程会议记录记录人员必须在会议后一个工作日之内如实填写并汇报给PM、Lead及相关人员。
2. 文档内容已经标上编号,记录人员如有增加或者减少编号的需要,在保证文档格式正确的前提下修改。
3. 本文档内容在填写完毕之后,在已有的文件名称后面加上"(会议记录-第几周)",如"meeting-minutes-03",如果一周有多次会议,命名为"meeting-minutes-03-01"。

@ -1,34 +0,0 @@
# 小组周计划-第15周
## 团队名称和起止时间
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-29
**结束时间:** 2025-01-05
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|------|----------------------------|----------------|-------------------|
| 1 | 前端界面优化 | 前端团队 | 建模板块实现通过侧边栏动态展示已有实体类 ai板块合理化修改等 |
| 2 | 功能完善 | 后端团队 | 导入功能实现从关系型及图数据库的稳定导入流程等 |
| 3 | 数据库整合与优化 | 后端团队 | 整合关系型与图数据库结构,优化数据存储与查询性能 |
| 4 | 项目文档迭代 | 全体成员 | 根据最新功能设计更新系统文档,启动用户手册、测试文档初稿编写,在周五晚上按时提交 |
| 5 | 容器化部署方案准备 | 全体成员 | 设计并验证Docker容器化部署方案调研华为云等云端部署环境 |
## 小结
1. **功能界面优化**本周将重点优化用户交互界面特别是实体管理与AI助手使其更符合用户实际操作逻辑。
2. **问题修复与文档**:修复当前系统中存在的问题,根据最新功能设计更新系统文档,并启动用户手册和测试报告的撰写工作。
3. **技术预研与部署准备**:完成容器化部署方案的设计,为后续正式部署做好准备。
4. **团队协作**:各团队需紧密配合,确保前后端接口联调顺畅,推动项目按计划进入下一阶段。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. PM综合本小组成员工作情况提交小组周计划、周总结报告按时上传至代码托管平台。

@ -1,34 +0,0 @@
# 小组周总结-第15周
## 团队名称和起止时间
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-29
**结束时间:** 2025-01-05
## 本周任务完成情况
| 序号 | 计划内容 | 是否完成 | 情况说明 |
|------|----------------------------|----------------|-------------------|
| 1 | 前端界面优化 | 完成 | 建模板块实现通过侧边栏动态展示已有实体类、侧边栏展开折叠以及缩放ai板块合理化修改等 |
| 2 | 功能完善 | 完成 | 导入功能实现从关系型及图数据库的稳定导入流程等 |
| 3 | 数据库整合与优化 | 完成 | 整合关系型与图数据库结构,优化数据存储与查询性能 |
| 4 | 项目文档迭代 | 完成 | 根据最新功能设计更新系统文档,启动用户手册、测试文档初稿编写,在周五晚上按时提交 |
| 5 | 容器化部署方案准备 | 完成 | 设计部署方案,调研华为云等云端部署环境 |
## 小结
1. **功能界面优化**:本周重点在于优化用户交互界面,特别是数据建模与搜索,使其更符合用户实际操作逻辑。
2. **问题修复与文档**:修复当前系统中存在的问题,根据最新功能设计更新系统文档,并启动用户手册和测试报告的撰写工作。
3. **技术预研与部署准备**:完成了部署方案的设计,为后续正式部署做好准备。
4. **团队协作**:各团队需紧密配合,确保前后端接口联调顺畅,推动项目按计划进入下一阶段。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. PM综合本小组成员工作情况提交小组周计划、周总结报告按时上传至代码托管平台。

@ -1,36 +0,0 @@
# 个人周计划-第15周
## 姓名和起止时间
**姓  名:** 符晋康
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-29
**结束时间:** 2025-01-05
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|----|--------|---|----------------------|
| 1 | 学习后端知识 | 个人 | 周内持续学习SpringBoot开发的相关知识 |
| 2 | 后端代码完善 | 个人 | 根据开发进度和项目需求,完善目前后端代码 |
| 3 | 学习软件测试 | 个人 | 学习软件测试相关知识 为团队项目进行相关测试 |
| 4 | 云服务器部署 | 个人 | 学习云服务器部署相关知识,初步对项目进行部署 |
## 小结
1. **学习需求:** 希望能有对于图数据库以及SpringBoot开发的教学
2. **软件测试:** 学习软件测试相关知识 为团队项目进行整合测试;
3. **服务器部署:** 根据所学习的华为云服务器部署相关知识,初步对项目进行部署。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,37 +0,0 @@
# 个人周总结-第15周
## 姓名和起止时间
**姓  名:** 符晋康
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-29
**结束时间:** 2025-01-05
## 本周任务完成情况
| 序号 | 总结内容 | 是否完成 | 情况说明 |
|----|-----------|------|-----------------------------|
| 1 | 学习后端知识 | 完成 | 周内持续学习SpringBoot开发的相关知识 |
| 2 | 后端代码完善 | 完成 | 根据开发进度和项目需求,完善目前后端代码 |
| 3 | 学习软件测试 | 完成 | 学习软件测试相关知识 为团队项目进行相关测试 |
| 4 | 云服务器部署 | 完成 | 学习云服务器部署相关知识,成功将项目部署到华为云服务器 |
## 小结
1. **持续学习:** 持续学习SpringBoot开发
2. **软件测试:** 学习软件测试相关知识 为团队项目进行整合测试;
3. **服务器部署:** 根据所学习的华为云服务器部署相关知识,成功将项目部署到华为云服务器。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,39 +0,0 @@
# 个人周计划-第15周
## 姓名和起止时间
**姓  名:** 哈俊元
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-29
**结束时间:** 2026-01-05
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|------|----------|--------|----------|
| 1 | Beta版本前端功能完善 | 个人 | 完善文物详情展示页面,优化知识图谱可视化界面 |
| 2 | AI助手功能优化 | 个人 | 改进AI助手交互体验优化对话界面和响应逻辑 |
| 3 | 模型管理界面开发 | 个人 | 完成模型审核、批处理等管理功能的前端界面开发 |
| 4 | 前后端接口对接 | 个人 | 与后端团队协作,完成新增功能的接口对接和调试 |
| 5 | 代码重构与性能优化 | 个人 | 优化前端代码结构,提升页面加载速度和用户体验 |
## 小结
1. **功能完善:** 本周重点是完善Beta版本的前端功能特别是AI助手和知识图谱相关功能
2. **性能优化:** 优化现有代码性能,提升页面响应速度,改善用户体验;
3. **新功能开发:** 按照需求完成模型管理功能的界面开发,确保与整体风格一致;
4. **接口联调:** 继续配合后端开发人员,确保前后端数据交互稳定可靠;
5. **代码质量:** 进一步优化代码结构,提高可维护性和可扩展性;
6. **问题修复:** 解决上周遗留的问题,持续改进系统稳定性。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,38 +0,0 @@
# 个人周总结-第15周
## 姓名和起止时间
**姓  名:** 哈俊元
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-29
**结束时间:** 2026-01-05
## 本周任务完成情况
| 序号 | 总结内容 | 是否完成 | 情况说明 |
|----|-----------|---|-------------------------------------|
| 1 | Beta版本前端功能完善 | 完成 | 成功完善了文物详情展示页面,优化了知识图谱可视化界面,提升了用户交互体验 |
| 2 | AI助手功能优化 | 完成 | 改进了AI助手交互体验优化了对话界面和响应逻辑使其更符合用户操作习惯 |
| 3 | 模型管理界面开发 | 完成 | 完成了模型审核、批处理等管理功能的前端界面开发,与整体设计风格保持一致 |
| 4 | 前后端接口对接 | 完成 | 与后端团队协作,完成新增功能的接口对接和调试,确保数据交互稳定 |
| 5 | 代码重构与性能优化 | 完成 | 优化了前端代码结构,提升了页面加载速度和用户体验,提高了代码可维护性 |
## 小结
1. **功能完善:** 本周按照计划成功完成了Beta版本的前端功能完善特别是AI助手和知识图谱相关功能使系统更加符合用户实际操作逻辑
2. **性能优化:** 通过代码重构优化了现有代码性能,提升了页面响应速度,改善了用户体验;
3. **团队协作:** 与后端开发人员紧密配合,确保前后端数据交互稳定可靠,推动了项目按计划进入下一阶段;
4. **问题修复:** 解决了上周遗留的问题持续改进系统稳定性修复了部分UI显示问题
5. **文档更新:** 根据最新功能设计参与更新了系统文档,为用户手册的编写提供了相关功能说明。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,36 +0,0 @@
# 个人周计划-第15周
## 姓名和起止时间
**姓  名:** 李梦源
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-29
**结束时间:** 2025-01-05
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|----|-----------|---|-------------------------------------|
| 1 | 学习前端知识 | 个人 | 周内持续学习vue开发的相关知识 |
| 2 | 前端代码完善 | 个人 | 持续改进前端模块,增强用户体验与界面交互流畅度|
| 3 | 相关界面优化 | 个人 | 完成实体管理、AI助手界面等前端功能细化调整 |
| 4 | 文档修改撰写 | 个人 | 完成对前面的文档的修改,开始对用户手册的撰写工作 |
## 小结
1. **学习需求:** 希望能有对于vue开发的教学
2. **前端功能优化**:持续改进前端模块,增强用户体验与界面交互流畅度;
3. **测试修复与质量保障**:开展系统测试,及时修复发现问题,优化整体性能;
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,36 +0,0 @@
# 个人周总结-第15周
## 姓名和起止时间
**姓  名:** 李梦源
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-29
**结束时间:** 2025-01-05
## 本周任务完成情况
| 序号 | 计划内容 | 是否完成 | 情况说明 |
|----|-----------|---|-------------------------------------|
| 1 | 学习前端知识 | 完成 | 周内持续学习了vue开发的相关知识 |
| 2 | 前端代码完善 | 完成 | 持续改进前端模块,增强用户体验与界面交互流畅度,如建模板块搜索板块|
| 3 | 相关界面优化 | 完成 | 完成实体管理、AI助手界面等前端功能细化调整 |
| 4 | 文档修改撰写 | 完成 | 完成对前面的文档的修改如uml设计文档开始对用户手册的撰写工作 |
## 小结
1. **周内学习** 周内持续学习了vue开发的相关知识
2. **前端功能优化**:持续改进前端模块,修复代码中的漏洞,增强用户体验与界面交互流畅度;
3. **测试修复与质量保障**:开展系统测试,及时修复发现问题,优化整体性能;
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,36 +0,0 @@
# 个人周计划-第15周
## 姓名和起止时间
**姓  名:** 袁明霜涛
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-29
**结束时间:** 2025-01-05
## 本周任务计划安排
| 序号 | 计划内容 | 执行人 | 情况说明 |
|----|-----------|---|-------------------------------------|
| 1 | 学习后端知识 | 个人 | 周内持续学习SpringBoot开发的相关知识 |
| 2 | 后端代码完善 | 个人 | 根据此前的完成进度以及指导老师处的反馈,完善目前后端代码,实现相关功能 |
| 3 | neo4j图数据库 | 个人 | 学习neo4j图数据库的配置与使用完成β版本的知识图谱构建 |
| 4 | 华为云部署 | 个人 | 根据所学习的华为云服务器部署相关知识,初步对项目进行部署 |
## 小结
1. **学习需求:** 希望能有对于图数据库以及SpringBoot开发的教学
2. **知识图谱:** 学习neo4j图数据库相关知识为后续的后端开发做准备
3. **服务器部署:** 根据所学习的华为云服务器部署相关知识,初步对项目进行部署。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -1,36 +0,0 @@
# 个人周总结-第15周
## 姓名和起止时间
**姓  名:** 袁明霜涛
**团队名称:** 2班-老师指定的组队
**开始时间:** 2025-12-29
**结束时间:** 2025-01-05
## 本周任务完成情况
| 序号 | 总结内容 | 是否完成 | 情况说明 |
|----|-----------|------|-------------------------------------|
| 1 | 学习后端知识 | 完成 | 周内持续学习SpringBoot开发的相关知识 |
| 2 | 后端代码完善 | 完成 | 根据此前的完成进度以及指导老师处的反馈,完善目前后端代码,实现相关功能 |
| 3 | neo4j图数据库 | 完成 | 学习neo4j图数据库的配置与使用完成β版本的知识图谱构建 |
| 4 | 华为云部署 | 未完成 | 根据所学习的华为云服务器部署相关知识,初步对项目进行部署 |
## 小结
1. **学习需求:** 希望能有对于图数据库以及SpringBoot开发的教学
2. **知识图谱:** 学习neo4j图数据库相关知识为后续的后端开发做准备
3. **服务器部署:** 根据所学习的华为云服务器部署相关知识,初步对项目进行部署。
---
## 【注】
1. 在小结一栏中写出希望得到如何的帮助,如讲座等;
2. 请将个人计划和总结提前发给负责人;
3. 周任务总结与计划是项目小组评分考核的重要依据,将直接记入平时成绩,请各位同学按要求认真填写并按时提交;
4. 所有组员都需提交个人周计划、周总结文档,按时上传至代码托管平台;

@ -0,0 +1,6 @@
http://1.95.82.181/#/login
用户15730786372密码Xk123456
【腾讯文档】2025-软件工程导论-团队项目初选
https://docs.qq.com/sheet/DWmd5Q0ZoWHZWWE5E?tab=gnqs53

6
package-lock.json generated

@ -1,6 +0,0 @@
{
"name": "ArtifactLLM",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}

@ -0,0 +1,3 @@
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip

@ -1,121 +0,0 @@
# 文物资源知识管理系统后端
这是“ArtifactLLM”大模型增强的文物资源知识管理系统的后端多模块工程基于 Spring Boot 3 与 Java 21 构建提供文物浏览、智能检索、知识图谱、AI 助手、用户与权限管理、模型管理等核心服务能力。
## 项目概述
后端采用 Maven 多模块结构按领域拆分为系统管理、文物建模、知识图谱、AI 服务等模块。主应用通常由 artifact-web 模块启动,其他服务模块可按需独立运行(注意端口与资源占用)。
## 技术栈
- Java 21
- Spring Boot 3
- Spring Web
- Spring Security + 自定义 JWT 拦截器
- MyBatis-Plus
- MySQL
- Redis
- Neo4j
- Spring Mail
- Maven
## 项目结构
```
ArtifactLLM_banker/
├── artifact-web/ # 主应用启动模块(入口、聚合接口、全局配置)
│ └── src/main/
│ ├── java/cn/edu/hnu/artifactweb/ArtifactWebApplication.java
│ └── resources/application.yml
├── artifact-system/ # 系统管理(用户、角色、权限、反馈等)
│ └── src/main/
│ ├── java/cn/edu/hnu/artifactsystem/{controller,service,mapper,config,interceptor}
│ └── resources/application.yml
├── artifact-relic/ # 文物建模与审核
│ └── src/main/
│ ├── java/cn/edu/hnu/artifactrelic/{controller,service,mapper,config,utils}
│ └── resources/application.yml
├── artifact-knowledge/ # 知识图谱服务Neo4j
│ └── src/main/
│ ├── java/cn/edu/hnu/artifactknowledge/{controller,service,connector}
│ └── resources/application.yml
├── artifact-ai/ # AI 服务(智能问答、会话)
│ └── src/main/
│ ├── java/cn/edu/hnu/artifactai/{controller,service,mapper,config}
│ └── resources/application.properties
├── artifact-common/ # 通用模块统一返回、上下文、JWT 等)
│ └── src/main/java/cn/edu/hnu/artifactcommon/{result,utils,context}
└── pom.xml # Maven 父 POM依赖与版本管理
```
## 开发环境搭建
1. 安装 JDK 21 与 Maven推荐 Maven 3.9+
2. 准备依赖服务:
- MySQL创建数据库并配置连接
- Redis本地或远程实例
- Neo4j本地或远程图数据库
3. 根据实际环境修改各模块的配置文件数据库地址、账号密码、Redis、Neo4j、邮件、AI 密钥等):
- artifact-web: `src/main/resources/application.yml`
- artifact-system: `src/main/resources/application.yml`
- artifact-relic: `src/main/resources/application.yml`
- artifact-knowledge: `src/main/resources/application.yml`
- artifact-ai: `src/main/resources/application.properties`
4. 在项目根目录执行依赖安装与编译:
```
mvn clean install
```
5. 启动主应用artifact-web
```
cd artifact-web
mvn spring-boot:run
```
## 构建部署
- 构建生产版本(以主应用为例):
```
mvn -pl artifact-web -am clean package
```
- 运行打包产物:
```
java -jar artifact-web/target/artifact-web-*.jar
```
- 也可按需在各模块内独立运行(注意端口避免冲突)。
## 端口与配置
- artifact-web默认 8080前端开发代理指向该端口
- artifact-relic默认 8080与主应用共端口避免同时独立运行
- artifact-knowledge默认 8083
- artifact-ai默认 8083
- 数据源与中间件:
- MySQL各模块独立配置
- Redis主要在 artifact-web 使用
- Neo4jartifact-web 与 artifact-knowledge 使用
## 功能模块
1. 系统管理(用户、角色、权限、反馈)
2. 文物建模与审核(建模实体创建、类型创建、批量导入、审核)
3. 智能检索与知识图谱Neo4j 关联查询、图谱可视化数据服务)
4. AI 助手(模型问答、消息交互)
5. 通用能力统一返回结构、JWT 工具、上下文封装)
## 安全与认证
- 使用 Spring Security 的无状态基础配置,关闭 CSRF
- 通过自定义拦截器实现:
- JWT 认证拦截器:保护 `/api/**`,放行登录、注册、验证码、图谱与文物公共接口
- 权限拦截器:基于注解驱动的细粒度权限校验
- JWT 采用 HS256 签名,包含用户角色与用户 ID 的声明
## 注意事项
- 开发联调:前端开发服务器默认代理到 `http://localhost:8080`
- 生产环境务必:
- 使用强密钥并通过环境变量或外部配置注入
- 不要在代码库中硬编码任何敏感信息数据库、Redis、Neo4j、邮件、AI 密钥等)
- 合理拆分与部署各模块,避免端口冲突与资源竞争
- 运行各模块前请确保依赖服务已启动MySQL、Redis、Neo4j

@ -0,0 +1,3 @@
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip

@ -35,24 +35,19 @@
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.edu.hnu</groupId>
<artifactId>artifact-common</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
</dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,13 @@
package cn.edu.hnu.artifactai;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ArtifactAiApplication {
public static void main(String[] args) {
SpringApplication.run(ArtifactAiApplication.class, args);
}
}

@ -1,113 +0,0 @@
package cn.edu.hnu.artifactai.client;
import cn.edu.hnu.artifactai.config.DeepSeekProperties;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class DeepSeekClient {
private final DeepSeekProperties deepSeekProperties;
private final OkHttpClient httpClient;
public DeepSeekClient(DeepSeekProperties deepSeekProperties) {
this.deepSeekProperties = deepSeekProperties;
this.httpClient = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(120, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build();
}
/**
* Simple chat completion
* @param prompt User input
* @return AI response content
*/
public String chat(String prompt) {
return chat(prompt, deepSeekProperties.getModel());
}
public String chat(String prompt, String model) {
JSONObject requestBody = new JSONObject();
requestBody.put("model", model);
JSONObject message = new JSONObject();
message.put("role", "user");
message.put("content", prompt);
requestBody.put("messages", Collections.singletonList(message));
requestBody.put("temperature", deepSeekProperties.getTemperature());
requestBody.put("max_tokens", deepSeekProperties.getMaxTokens());
requestBody.put("stream", false);
RequestBody body = RequestBody.create(
requestBody.toJSONString(),
MediaType.parse("application/json; charset=utf-8")
);
Request request = new Request.Builder()
.url(deepSeekProperties.getBaseUrl() + "/chat/completions")
.addHeader("Authorization", "Bearer " + deepSeekProperties.getApiKey())
.addHeader("Content-Type", "application/json")
.post(body)
.build();
try (Response response = httpClient.newCall(request).execute()) {
if (!response.isSuccessful()) {
String errorBody = response.body() != null ? response.body().string() : "Unknown error";
log.error("DeepSeek API error: code={}, body={}", response.code(), errorBody);
String userMessage = "AI 服务调用失败,请稍后重试";
try {
JSONObject errorJson = JSON.parseObject(errorBody);
JSONObject errorObj = errorJson.getJSONObject("error");
if (errorObj != null) {
String msg = errorObj.getString("message");
String code = errorObj.getString("code");
if (msg != null && msg.toLowerCase().contains("insufficient balance")) {
userMessage = "AI 服务调用失败";
} else if (msg != null && !msg.isEmpty()) {
userMessage = "AI 服务调用失败:" + msg;
} else if (code != null && !code.isEmpty()) {
userMessage = "AI 服务调用失败:" + code;
}
}
} catch (Exception ignored) {
}
throw new RuntimeException(userMessage);
}
if (response.body() == null) {
throw new RuntimeException("DeepSeek API returned empty body");
}
String responseStr = response.body().string();
JSONObject jsonResponse = JSON.parseObject(responseStr);
JSONArray choices = jsonResponse.getJSONArray("choices");
if (choices != null && !choices.isEmpty()) {
JSONObject choice = choices.getJSONObject(0);
JSONObject messageObj = choice.getJSONObject("message");
return messageObj.getString("content");
}
return null;
} catch (IOException e) {
log.error("DeepSeek network error", e);
throw new RuntimeException("DeepSeek network error: " + e.getMessage());
}
}
}

@ -1,35 +0,0 @@
package cn.edu.hnu.artifactai.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "ai.deepseek")
public class DeepSeekProperties {
/**
* API Key
*/
private String apiKey = "sk-6f015483467b42c899233139feacfe11";
/**
* Base URL (e.g., https://api.deepseek.com)
*/
private String baseUrl = "https://api.deepseek.com";
/**
* Model name (e.g., deepseek-chat)
*/
private String model = "deepseek-reasoner";
/**
* Max tokens
*/
private Integer maxTokens = 2048;
/**
* Temperature
*/
private Double temperature = 0.7;
}

@ -1,38 +0,0 @@
package cn.edu.hnu.artifactai.controller;
import cn.edu.hnu.artifactai.service.IAiChatService;
import cn.edu.hnu.artifactcommon.result.Result;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/ai")
public class AiController {
@Autowired
private IAiChatService aiChatService;
@PostMapping("/chat")
public Result<ChatResponse> chat(@RequestBody ChatRequest request) {
String response = aiChatService.chat(request.getPrompt(), request.getSessionId());
return Result.success(new ChatResponse(response, request.getSessionId()));
}
@Data
public static class ChatRequest {
private String prompt;
private String sessionId;
}
@Data
public static class ChatResponse {
private String content;
private String sessionId;
public ChatResponse(String content, String sessionId) {
this.content = content;
this.sessionId = sessionId;
}
}
}

@ -1,31 +0,0 @@
package cn.edu.hnu.artifactai.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@TableName("ai_chat_history")
public class AiChatHistory implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private String sessionId;
private Long userId;
private String userInput;
private String aiResponse;
private String model;
private LocalDateTime createTime;
}

@ -1,9 +0,0 @@
package cn.edu.hnu.artifactai.mapper;
import cn.edu.hnu.artifactai.entity.AiChatHistory;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface AiChatHistoryMapper extends BaseMapper<AiChatHistory> {
}

@ -1,15 +0,0 @@
package cn.edu.hnu.artifactai.service;
import cn.edu.hnu.artifactai.entity.AiChatHistory;
import com.baomidou.mybatisplus.extension.service.IService;
public interface IAiChatService extends IService<AiChatHistory> {
/**
* Chat with AI
* @param prompt User input
* @param sessionId Session ID (optional)
* @return AI response
*/
String chat(String prompt, String sessionId);
}

@ -1,58 +0,0 @@
package cn.edu.hnu.artifactai.service.impl;
import cn.edu.hnu.artifactai.client.DeepSeekClient;
import cn.edu.hnu.artifactai.config.DeepSeekProperties;
import cn.edu.hnu.artifactai.entity.AiChatHistory;
import cn.edu.hnu.artifactai.mapper.AiChatHistoryMapper;
import cn.edu.hnu.artifactai.service.IAiChatService;
import cn.edu.hnu.artifactcommon.context.UserContext;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.UUID;
@Service
public class AiChatServiceImpl extends ServiceImpl<AiChatHistoryMapper, AiChatHistory> implements IAiChatService {
@Autowired
private DeepSeekClient deepSeekClient;
@Autowired
private DeepSeekProperties deepSeekProperties;
@Override
public String chat(String prompt, String sessionId) {
// 1. Check/Generate Session ID
if (sessionId == null || sessionId.isEmpty()) {
sessionId = UUID.randomUUID().toString();
}
// 2. Call AI
// In a real app, you might want to fetch previous context for this session
// For now, we just do a single-turn chat with the model
String response = deepSeekClient.chat(prompt);
// 3. Save History
AiChatHistory history = new AiChatHistory();
history.setSessionId(sessionId);
history.setUserInput(prompt);
history.setAiResponse(response);
history.setModel(deepSeekProperties.getModel());
history.setCreateTime(LocalDateTime.now());
try {
Long userId = UserContext.getCurrentUserId();
if (userId != null) {
history.setUserId(userId);
}
} catch (Exception e) {
// Ignore if user context is not available
}
this.save(history);
return response;
}
}

@ -1,19 +1 @@
spring.application.name=artifact-ai
server.port=8083
# DeepSeek Configuration
ai.deepseek.api-key=sk-6f015483467b42c899233139feacfe11
ai.deepseek.base-url=https://api.deepseek.com
ai.deepseek.model=deepseek-reasoner
ai.deepseek.max-tokens=2048
ai.deepseek.temperature=0.7
# Database Configuration (Assuming shared or specific DB)
spring.datasource.url=jdbc:mysql://localhost:3306/artifactllm1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# MyBatis Plus
mybatis-plus.mapper-locations=classpath*:/mapper/**/*.xml
mybatis-plus.configuration.map-underscore-to-camel-case=true

@ -1,7 +1,9 @@
package cn.edu.hnu.artifactai;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ArtifactAiApplicationTests {
@Test

@ -0,0 +1,3 @@
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip

@ -37,28 +37,14 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 添加maven-compiler-plugin确保正确编译 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>21</source>
<target>21</target>
</configuration>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

@ -1,8 +0,0 @@
package cn.edu.hnu;
import org.springframework.boot.SpringBootConfiguration;
@SpringBootConfiguration
public class RootBootConfiguration {
}

@ -0,0 +1,13 @@
package cn.edu.hnu.artifactcommon;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ArtifactCommonApplication {
public static void main(String[] args) {
SpringApplication.run(ArtifactCommonApplication.class, args);
}
}

@ -0,0 +1,30 @@
package cn.edu.hnu.artifactcommon;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
private Boolean success;
private String errorMsg;
private Object data;
private Long total;
public static Result ok(){
return new Result(true, null, null, null);
}
public static Result ok(Object data){
return new Result(true, null, data, null);
}
public static Result ok(List<?> data, Long total){
return new Result(true, null, data, total);
}
public static Result fail(String errorMsg){
return new Result(false, errorMsg, null, null);
}
}

@ -24,7 +24,7 @@ public class SystemConstant {
*/
public static final String JWT_HEADER = "Authorization";
public static final String JWT_PREFIX = "Bearer ";
public static final String JWT_SECRET = "artifact-system-secret-key-2025-12-16-strong-secret";
public static final String JWT_SECRET = "artifact-system-secret-key";
public static final Long JWT_EXPIRATION = 7 * 24 * 60 * 60 * 1000L; // 7天
/**

@ -6,77 +6,23 @@ package cn.edu.hnu.artifactcommon.context;
*/
public class UserContext {
/**
*
*/
private static class UserInfo {
private String username;
private Long userId;
public UserInfo(String username, Long userId) {
this.username = username;
this.userId = userId;
}
public String getUsername() {
return username;
}
public Long getUserId() {
return userId;
}
}
/**
* 使ThreadLocal线
*/
private static final ThreadLocal<UserInfo> USER_THREAD_LOCAL = new ThreadLocal<>();
/**
* 线
*/
public static void setCurrentUser(String username, Long userId) {
USER_THREAD_LOCAL.set(new UserInfo(username, userId));
}
private static final ThreadLocal<String> USER_THREAD_LOCAL = new ThreadLocal<>();
/**
* 线
*/
public static void setCurrentUsername(String username) {
UserInfo userInfo = USER_THREAD_LOCAL.get();
if (userInfo != null) {
USER_THREAD_LOCAL.set(new UserInfo(username, userInfo.getUserId()));
} else {
USER_THREAD_LOCAL.set(new UserInfo(username, null));
}
}
/**
* 线ID
*/
public static void setCurrentUserId(Long userId) {
UserInfo userInfo = USER_THREAD_LOCAL.get();
if (userInfo != null) {
USER_THREAD_LOCAL.set(new UserInfo(userInfo.getUsername(), userId));
} else {
USER_THREAD_LOCAL.set(new UserInfo(null, userId));
}
USER_THREAD_LOCAL.set(username);
}
/**
* 线
*/
public static String getCurrentUsername() {
UserInfo userInfo = USER_THREAD_LOCAL.get();
return userInfo != null ? userInfo.getUsername() : null;
}
/**
* 线ID
*/
public static Long getCurrentUserId() {
UserInfo userInfo = USER_THREAD_LOCAL.get();
return userInfo != null ? userInfo.getUserId() : null;
return USER_THREAD_LOCAL.get();
}
/**

@ -32,19 +32,4 @@ public class UserDTO {
* UUID
*/
private String captchaUuid;
/**
*
*/
private String realName;
/**
*
*/
private String phone;
/**
*
*/
private String emailCode;
}

@ -44,14 +44,4 @@ public class UserVO {
*
*/
private LocalDateTime lastLoginTime;
/**
*
*/
private String realName;
/**
*
*/
private String phone;
}

@ -50,7 +50,7 @@ public class CaptchaUtil {
// 将验证码存储到Redis设置过期时间
String redisKey = SystemConstant.REDIS_KEY_CAPTCHA + uuid;
redisUtil.set(redisKey, captcha, CAPTCHA_EXPIRE_MINUTES * 60L);
redisUtil.set(redisKey, captcha, CAPTCHA_EXPIRE_MINUTES, TimeUnit.MINUTES);
// 生成验证码图片
BufferedImage image = createCaptchaImage(captcha);
@ -71,13 +71,11 @@ public class CaptchaUtil {
}
String redisKey = SystemConstant.REDIS_KEY_CAPTCHA + uuid;
Object storedCaptchaObj = redisUtil.get(redisKey);
if (storedCaptchaObj == null) {
String storedCaptcha = redisUtil.get(redisKey).toString();
if (storedCaptcha == null) {
return false;
}
String storedCaptcha = storedCaptchaObj.toString();
// 验证成功后删除验证码
redisUtil.del(redisKey);
@ -174,4 +172,4 @@ public class CaptchaUtil {
return "data:image/png;base64," + Base64.getEncoder().encodeToString(imageBytes);
}
}
}

@ -33,14 +33,6 @@ public class JwtUtil {
public String getUsernameFromToken(String token) {
return getClaimFromToken(token, Claims::getSubject);
}
/**
* tokenID
*/
public Long getUserIdFromToken(String token) {
Claims claims = getAllClaimsFromToken(token);
return claims.get("userId", Long.class);
}
/**
* token
@ -79,10 +71,9 @@ public class JwtUtil {
/**
* token
*/
public String generateToken(String username, String role, Long userId) {
public String generateToken(String username, String role) {
Map<String, Object> claims = new HashMap<>();
claims.put("role", role);
claims.put("userId", userId);
return doGenerateToken(claims, username);
}

@ -1,30 +0,0 @@
package cn.edu.hnu.artifactcommon.utils;
import cn.edu.hnu.artifactcommon.pojo.vo.UserVO;
import java.util.HashMap;
import java.util.Map;
/**
*
*
*/
public class UserConvertUtil {
/**
* UserVOMap
* @param user
* @return Map
*/
public static Map<String, Object> convertUserVOToMap(UserVO user) {
Map<String, Object> userInfo = new HashMap<>();
userInfo.put("id", user.getId());
userInfo.put("username", user.getUsername());
userInfo.put("email", user.getEmail());
userInfo.put("role", user.getRole());
userInfo.put("status", user.getStatus() != null ? user.getStatus() : 0);
userInfo.put("created_at", user.getCreateTime());
userInfo.put("last_login", user.getLastLoginTime());
return userInfo;
}
}

@ -1,7 +1,9 @@
package cn.edu.hnu.artifactcommon;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ArtifactCommonApplicationTests {
@Test

@ -0,0 +1,3 @@
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip

@ -35,22 +35,18 @@
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>cn.edu.hnu</groupId>
<artifactId>artifact-common</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,13 @@
package cn.edu.hnu.artifactknowledge;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ArtifactKnowledgeApplication {
public static void main(String[] args) {
SpringApplication.run(ArtifactKnowledgeApplication.class, args);
}
}

@ -1,36 +0,0 @@
package cn.edu.hnu.artifactknowledge.connector;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.neo4j.core.Neo4jClient;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@Component
public class Neo4jConnector {
@Autowired
private Neo4jClient neo4jClient;
public List<Map<String, Object>> query(String cypher) {
return query(cypher, Collections.emptyMap());
}
public List<Map<String, Object>> query(String cypher, Map<String, Object> params) {
if (params == null || params.isEmpty()) {
return (List<Map<String, Object>>) neo4jClient.query(cypher).fetch().all();
}
return (List<Map<String, Object>>) neo4jClient.query(cypher).bindAll(params).fetch().all();
}
public void execute(String cypher, Map<String, Object> params) {
if (params == null || params.isEmpty()) {
neo4jClient.query(cypher).run();
} else {
neo4jClient.query(cypher).bindAll(params).run();
}
}
}

@ -1,76 +0,0 @@
package cn.edu.hnu.artifactknowledge.connector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
@Component
public class Neo4jHttpConnector {
@Value("${neo4j.http.base-url:http://localhost:7474}")
private String baseUrl;
@Value("${neo4j.http.commit-path:/db/neo4j/tx/commit}")
private String commitPath;
@Value("${spring.neo4j.authentication.username}")
private String username;
@Value("${spring.neo4j.authentication.password}")
private String password;
private final RestTemplate restTemplate = new RestTemplate();
public List<Map<String, Object>> query(String cypher, Map<String, Object> params) {
String url = baseUrl + commitPath;
Map<String, Object> payload = new HashMap<>();
Map<String, Object> stmt = new HashMap<>();
stmt.put("statement", cypher);
stmt.put("parameters", params == null ? Map.of() : params);
payload.put("statements", List.of(stmt));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
String auth = username + ":" + password;
String encoded = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
headers.set("Authorization", "Basic " + encoded);
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(payload, headers);
Map<?, ?> resp = restTemplate.postForObject(url, entity, Map.class);
if (resp == null) {
return List.of();
}
List<?> results = (List<?>) resp.get("results");
if (results == null || results.isEmpty()) {
return List.of();
}
Map<?, ?> first = (Map<?, ?>) results.get(0);
List<?> columns = (List<?>) first.get("columns");
List<?> data = (List<?>) first.get("data");
List<Map<String, Object>> out = new ArrayList<>();
if (columns == null || data == null) {
return out;
}
for (Object d : data) {
Map<?, ?> rowObj = (Map<?, ?>) d;
List<?> row = (List<?>) rowObj.get("row");
Map<String, Object> m = new HashMap<>();
for (int i = 0; i < columns.size() && i < row.size(); i++) {
String col = String.valueOf(columns.get(i));
m.put(col, row.get(i));
}
out.add(m);
}
return out;
}
}

@ -1,63 +0,0 @@
package cn.edu.hnu.artifactknowledge.controller;
import cn.edu.hnu.artifactcommon.result.Result;
import cn.edu.hnu.artifactknowledge.dto.GraphQueryDTO;
import cn.edu.hnu.artifactknowledge.service.IKnowledgeGraphService;
import cn.edu.hnu.artifactknowledge.service.IKnowledgeGraphHttpService;
import cn.edu.hnu.artifactknowledge.vo.GraphVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping({"/knowledge/gstore", "/knowledge/neo4j", "/api/knowledge/neo4j"})
public class Neo4jController {
@Autowired
private IKnowledgeGraphService knowledgeGraphService;
@Autowired
private IKnowledgeGraphHttpService knowledgeGraphHttpService;
@PostMapping("/query")
public cn.edu.hnu.artifactcommon.result.Result<String> query(@RequestBody GraphQueryDTO queryDTO) {
String cypher = queryDTO.getCypher();
if (cypher == null || cypher.isBlank()) {
cypher = queryDTO.getSparql();
}
if (cypher == null || cypher.isBlank()) {
return cn.edu.hnu.artifactcommon.result.Result.error(400, "cypher 不能为空");
}
return cn.edu.hnu.artifactcommon.result.Result.success(knowledgeGraphService.query(cypher));
}
@GetMapping("/test")
public cn.edu.hnu.artifactcommon.result.Result<String> test() {
String cypher = "MATCH (n) RETURN n LIMIT 1";
return cn.edu.hnu.artifactcommon.result.Result.success(knowledgeGraphService.query(cypher));
}
@GetMapping("/graph")
public cn.edu.hnu.artifactcommon.result.Result<GraphVO> getGraph(@RequestParam String relicName) {
return cn.edu.hnu.artifactcommon.result.Result.success(knowledgeGraphService.getRelicGraph(relicName));
}
@GetMapping("/httpGraph")
public cn.edu.hnu.artifactcommon.result.Result<GraphVO> getHttpGraph(@RequestParam String relicName) {
return cn.edu.hnu.artifactcommon.result.Result.success(knowledgeGraphHttpService.getRelicGraph(relicName));
}
@PostMapping("/import")
public cn.edu.hnu.artifactcommon.result.Result<String> importArtifacts(@RequestParam String path) {
try {
knowledgeGraphService.importArtifacts(path);
return cn.edu.hnu.artifactcommon.result.Result.success("Import started/completed successfully.");
} catch (Exception e) {
return cn.edu.hnu.artifactcommon.result.Result.error(500, "Import failed: " + e.getMessage());
}
}
}

@ -1,10 +0,0 @@
package cn.edu.hnu.artifactknowledge.dto;
import lombok.Data;
@Data
public class GraphQueryDTO {
private String cypher;
private String sparql;
}

@ -1,8 +0,0 @@
package cn.edu.hnu.artifactknowledge.service;
import cn.edu.hnu.artifactknowledge.vo.GraphVO;
public interface IKnowledgeGraphHttpService {
GraphVO getRelicGraph(String relicName);
}

@ -1,12 +0,0 @@
package cn.edu.hnu.artifactknowledge.service;
import cn.edu.hnu.artifactknowledge.vo.GraphVO;
public interface IKnowledgeGraphService {
String query(String cypher);
GraphVO getRelicGraph(String relicName);
void importArtifacts(String directoryPath);
}

@ -1,99 +0,0 @@
package cn.edu.hnu.artifactknowledge.service.impl;
import cn.edu.hnu.artifactknowledge.connector.Neo4jHttpConnector;
import cn.edu.hnu.artifactknowledge.service.IKnowledgeGraphHttpService;
import cn.edu.hnu.artifactknowledge.vo.GraphLink;
import cn.edu.hnu.artifactknowledge.vo.GraphNode;
import cn.edu.hnu.artifactknowledge.vo.GraphVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class KnowledgeGraphHttpServiceImpl implements IKnowledgeGraphHttpService {
@Autowired
private Neo4jHttpConnector httpConnector;
@Override
public GraphVO getRelicGraph(String relicName) {
String cypher = ""
+ "MATCH (a:Artifact) "
+ "WHERE toString(coalesce(a.name,'')) = $relicName "
+ "MATCH (a)-[r]-(n) "
+ "WHERE type(r) <> 'HAS_IMAGE' "
+ "AND NOT (n:Artifact AND toString(coalesce(n.name,'')) <> $relicName) "
+ "RETURN elementId(a) AS nId, elementId(n) AS mId, labels(a) AS nLabels, labels(n) AS mLabels, "
+ "a AS nProps, n AS mProps, type(r) AS rType, elementId(a) AS rStart, elementId(n) AS rEnd "
+ "LIMIT 200";
List<Map<String, Object>> rows = httpConnector.query(cypher, Map.of("relicName", relicName));
Map<String, GraphNode> nodeMap = new HashMap<>();
List<GraphLink> links = new ArrayList<>();
Set<String> linkSet = new HashSet<>();
for (Map<String, Object> row : rows) {
String nId = String.valueOf(row.get("nId"));
String mId = String.valueOf(row.get("mId"));
Map<String, Object> nProps = castMap(row.get("nProps"));
Map<String, Object> mProps = castMap(row.get("mProps"));
String rType = String.valueOf(row.get("rType"));
String rStart = String.valueOf(row.get("rStart"));
String rEnd = String.valueOf(row.get("rEnd"));
GraphNode nNode = toGraphNode(nId, nProps, relicName);
GraphNode mNode = toGraphNode(mId, mProps, relicName);
nodeMap.putIfAbsent(nNode.getId(), nNode);
nodeMap.putIfAbsent(mNode.getId(), mNode);
String linkKey = rStart + "|" + rEnd + "|" + rType;
if (!linkSet.contains(linkKey)) {
GraphLink link = new GraphLink();
link.setSource(rStart);
link.setTarget(rEnd);
link.setValue(rType);
links.add(link);
linkSet.add(linkKey);
}
}
return new GraphVO(new ArrayList<>(nodeMap.values()), links);
}
private Map<String, Object> castMap(Object v) {
if (v instanceof Map) {
Map<?, ?> in = (Map<?, ?>) v;
Map<String, Object> out = new HashMap<>();
for (Map.Entry<?, ?> e : in.entrySet()) {
out.put(String.valueOf(e.getKey()), e.getValue());
}
return out;
}
return Map.of();
}
private GraphNode toGraphNode(String id, Map<String, Object> props, String relicName) {
String name = extractName(props);
boolean isMain = false;
if (relicName != null && !relicName.isBlank() && name != null) {
isMain = name.equals(relicName);
}
GraphNode node = new GraphNode();
node.setId(id);
node.setName(name);
node.setCategory(isMain ? 0 : 1);
node.setSymbolSize(isMain ? 80.0 : 60.0);
node.setValue(name);
return node;
}
private String extractName(Map<String, Object> props) {
for (String key : List.of("name", "relicName", "label", "title")) {
Object v = props.get(key);
if (v != null) {
return String.valueOf(v);
}
}
return null;
}
}

@ -1,304 +0,0 @@
package cn.edu.hnu.artifactknowledge.service.impl;
import cn.edu.hnu.artifactknowledge.connector.Neo4jConnector;
import cn.edu.hnu.artifactknowledge.service.IKnowledgeGraphService;
import cn.edu.hnu.artifactknowledge.vo.GraphLink;
import cn.edu.hnu.artifactknowledge.vo.GraphNode;
import cn.edu.hnu.artifactknowledge.vo.GraphVO;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.neo4j.driver.Value;
import org.neo4j.driver.types.Node;
import org.neo4j.driver.types.Relationship;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
@Slf4j
@Service
public class KnowledgeGraphServiceImpl implements IKnowledgeGraphService {
@Autowired
private Neo4jConnector neo4jConnector;
@Override
public void importArtifacts(String directoryPath) {
log.info("Starting artifact import from: {}", directoryPath);
try (Stream<Path> paths = Files.walk(Paths.get(directoryPath))) {
paths.filter(Files::isRegularFile)
.filter(p -> p.toString().endsWith(".json"))
.forEach(this::processJsonFile);
} catch (IOException e) {
log.error("Error reading files from directory: {}", directoryPath, e);
throw new RuntimeException("Import failed", e);
}
log.info("Import completed.");
}
private void processJsonFile(Path filePath) {
try {
String content = Files.readString(filePath);
JSONObject json = JSON.parseObject(content);
importArtifactData(json);
} catch (Exception e) {
log.error("Failed to process file: {}", filePath, e);
}
}
private void importArtifactData(JSONObject json) {
String uuid = json.getString("uuid");
JSONObject info = json.getJSONObject("artifact_info");
if (uuid == null || info == null) return;
String name = info.getString("文物名");
String relicNo = info.getString("文物号");
String category = info.getString("分类");
String era = info.getString("年代");
String detailUrl = json.getString("detail_url");
// 1. Merge Artifact Node
String createArtifactCypher = """
MERGE (a:Artifact {uuid: $uuid})
SET a.name = $name,
a.relicNo = $relicNo,
a.detailUrl = $detailUrl
""";
Map<String, Object> artifactParams = new HashMap<>();
artifactParams.put("uuid", uuid);
artifactParams.put("name", name);
artifactParams.put("relicNo", relicNo);
artifactParams.put("detailUrl", detailUrl);
neo4jConnector.execute(createArtifactCypher, artifactParams);
// 2. Merge Category Node and Relationship
if (category != null && !category.isBlank()) {
String categoryCypher = """
MATCH (a:Artifact {uuid: $uuid})
MERGE (c:Category {name: $category})
MERGE (a)-[:BELONGS_TO]->(c)
""";
neo4jConnector.execute(categoryCypher, Map.of("uuid", uuid, "category", category));
}
// 3. Merge Era Node and Relationship
if (era != null && !era.isBlank()) {
String eraCypher = """
MATCH (a:Artifact {uuid: $uuid})
MERGE (e:Era {name: $era})
MERGE (a)-[:FROM_ERA]->(e)
""";
neo4jConnector.execute(eraCypher, Map.of("uuid", uuid, "era", era));
}
// 4. Handle Colors
JSONArray colors = info.getJSONArray("颜色");
if (colors != null) {
for (int i = 0; i < colors.size(); i++) {
JSONObject color = colors.getJSONObject(i);
String code = color.getString("code");
String background = color.getString("background");
if (code != null) {
String colorCypher = """
MATCH (a:Artifact {uuid: $uuid})
MERGE (col:Color {code: $code})
SET col.background = $background
MERGE (a)-[:HAS_COLOR]->(col)
""";
neo4jConnector.execute(colorCypher, Map.of("uuid", uuid, "code", code, "background", background != null ? background : ""));
}
}
}
// 5. Handle Same Category Artifacts (Recommendations)
JSONArray sameCategory = json.getJSONArray("same_category_artifacts");
if (sameCategory != null) {
for (int i = 0; i < sameCategory.size(); i++) {
JSONObject other = sameCategory.getJSONObject(i);
String otherUuid = other.getString("uuid");
String otherName = other.getString("name");
if (otherUuid != null) {
String relationCypher = """
MATCH (a:Artifact {uuid: $uuid})
MERGE (o:Artifact {uuid: $otherUuid})
ON CREATE SET o.name = $otherName
MERGE (a)-[:RELATED_TO]->(o)
""";
neo4jConnector.execute(relationCypher, Map.of("uuid", uuid, "otherUuid", otherUuid, "otherName", otherName != null ? otherName : ""));
}
}
}
}
@Override
public String query(String cypher) {
List<Map<String, Object>> rows = neo4jConnector.query(cypher);
List<Map<String, Object>> normalized = new ArrayList<>(rows.size());
for (Map<String, Object> row : rows) {
Map<String, Object> out = new LinkedHashMap<>();
for (Map.Entry<String, Object> entry : row.entrySet()) {
out.put(entry.getKey(), normalizeValue(entry.getValue()));
}
normalized.add(out);
}
return JSONArray.toJSONString(normalized);
}
@Override
public GraphVO getRelicGraph(String relicName) {
String cypher = """
MATCH (a:Artifact)
WHERE toString(coalesce(a.name,'')) = $relicName
WITH collect(a)[0] AS a
OPTIONAL MATCH (a)-[r1:FROM_ERA]->(e:Era)
RETURN a AS n, r1 AS r, e AS m
UNION
MATCH (a:Artifact)
WHERE toString(coalesce(a.name,'')) = $relicName
WITH collect(a)[0] AS a
OPTIONAL MATCH (a)-[r2:BELONGS_TO]->(c:Category)
RETURN a AS n, r2 AS r, c AS m
""";
List<Map<String, Object>> rows = neo4jConnector.query(cypher, Map.of("relicName", relicName));
Map<String, GraphNode> nodeMap = new HashMap<>();
List<GraphLink> links = new ArrayList<>();
for (Map<String, Object> row : rows) {
Object nObj = row.get("n");
Object mObj = row.get("m");
Object rObj = row.get("r");
if (!(nObj instanceof Node) || !(mObj instanceof Node) || !(rObj instanceof Relationship)) {
continue;
}
Node n = (Node) nObj;
Node m = (Node) mObj;
Relationship r = (Relationship) rObj;
GraphNode nNode = toGraphNode(n, relicName);
GraphNode mNode = toGraphNode(m, relicName);
nodeMap.putIfAbsent(nNode.getId(), nNode);
nodeMap.putIfAbsent(mNode.getId(), mNode);
GraphLink link = new GraphLink();
link.setSource(nNode.getId());
link.setTarget(mNode.getId());
link.setValue(r.type());
links.add(link);
}
return new GraphVO(new ArrayList<>(nodeMap.values()), links);
}
private GraphNode toGraphNode(Node node, String relicName) {
String id = node.elementId();
String name = extractName(node);
boolean isMain = false;
if (relicName != null && !relicName.isBlank()) {
for (String key : List.of("name", "relicName", "label", "title")) {
if (node.containsKey(key) && node.get(key) != null) {
String v = String.valueOf(node.get(key).asObject());
if (v.equals(relicName)) {
isMain = true;
break;
}
}
}
}
GraphNode graphNode = new GraphNode();
graphNode.setId(id);
graphNode.setName(name);
graphNode.setCategory(isMain ? 0 : 1);
graphNode.setSymbolSize(isMain ? 20.0 : 10.0);
graphNode.setValue(name);
return graphNode;
}
private String extractName(Node node) {
for (String key : List.of("name", "label", "title")) {
if (node.containsKey(key) && node.get(key) != null) {
Value v = node.get(key);
if (!v.isNull()) {
return String.valueOf(v.asObject());
}
}
}
if (!node.labels().iterator().hasNext()) {
return node.elementId();
}
return node.labels().iterator().next() + ":" + node.elementId();
}
private Object normalizeValue(Object value) {
if (value == null) {
return null;
}
if (value instanceof Node) {
Node node = (Node) value;
Map<String, Object> out = new LinkedHashMap<>();
out.put("elementId", node.elementId());
List<String> labels = new ArrayList<>();
node.labels().forEach(labels::add);
out.put("labels", labels);
out.put("properties", node.asMap());
return out;
}
if (value instanceof Relationship) {
Relationship rel = (Relationship) value;
Map<String, Object> out = new LinkedHashMap<>();
out.put("elementId", rel.elementId());
out.put("type", rel.type());
out.put("startNodeId", rel.startNodeId());
out.put("endNodeId", rel.endNodeId());
out.put("properties", rel.asMap());
return out;
}
if (value instanceof Map) {
Map<?, ?> map = (Map<?, ?>) value;
Map<String, Object> out = new LinkedHashMap<>();
for (Map.Entry<?, ?> entry : map.entrySet()) {
out.put(String.valueOf(entry.getKey()), normalizeValue(entry.getValue()));
}
return out;
}
if (value instanceof Iterable) {
List<Object> out = new ArrayList<>();
for (Object v : (Iterable<?>) value) {
out.add(normalizeValue(v));
}
return out;
}
if (value instanceof Object[]) {
List<Object> out = new ArrayList<>();
for (Object v : (Object[]) value) {
out.add(normalizeValue(v));
}
return out;
}
if (value instanceof Value) {
Value v = (Value) value;
if (v.isNull()) {
return null;
}
return normalizeValue(v.asObject());
}
return value;
}
}

@ -1,14 +0,0 @@
package cn.edu.hnu.artifactknowledge.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class GraphLink {
private String source;
private String target;
private String value; // The relationship name
}

@ -1,16 +0,0 @@
package cn.edu.hnu.artifactknowledge.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class GraphNode {
private String id;
private String name;
private int category; // 0: main node, 1: property, 2: value (simplified)
private double symbolSize;
private String value;
}

@ -1,15 +0,0 @@
package cn.edu.hnu.artifactknowledge.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class GraphVO {
private List<GraphNode> nodes;
private List<GraphLink> links;
}

@ -1,15 +0,0 @@
server:
port: 8083
spring:
application:
name: artifact-knowledge
neo4j:
uri: bolt://localhost:7687
authentication:
username: neo4j
password: artifactllm
neo4j:
http:
base-url: http://localhost:7474
commit-path: /db/neo4j/tx/commit

@ -1,7 +1,9 @@
package cn.edu.hnu.artifactknowledge;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ArtifactKnowledgeApplicationTests {
@Test

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save