RelicVoyage(博物寻迹)是一个面向中国历史文物与博物馆信息的前后端分离项目。系统提供文物浏览、博物馆查询、收藏、评论互动、个人资料管理,以及面向管理员的内容维护和数据看板功能;同时集成了 AI 问答和高德地图能力,用于辅助检索和博物馆路线展示。
当前项目更适合作为本地开发、课程设计或功能演示项目。生产环境部署前需要补充正式的身份认证、密码加密、密钥管理、上传限制和反向代理配置。
- 用户注册、登录和退出。
- 浏览和筛选文物,查看文物详情及关联博物馆。
- 浏览博物馆列表,按关键词或城市筛选,查看博物馆详情。
- 收藏/取消收藏文物,查看个人收藏列表。
- 对文物发表评论、点赞,以及查看管理员回复。
- 编辑个人资料和密码。
- 查看个人数据看板。
- 使用页面右下角的 AI 助手,咨询系统内置说明、文物、博物馆和统计信息。
- 查看管理端数据看板。
- 新增、编辑、删除文物。
- 新增、编辑、删除博物馆。
- 上传文物和博物馆图片。
- 查看用户列表,新增/编辑用户,启用或停用用户,删除用户。
- 查看全部评论并回复评论。
| 部分 | 技术 |
|---|---|
| 前端 | Vue 3、Vue Router 4、Vite 6、Element Plus、ECharts |
| 后端 | Java 17、Spring Boot 3.3.5、Spring Web、Spring JDBC |
| 数据访问 | MyBatis Spring Boot Starter 3.0.4、MySQL Connector/J 8.4.0 |
| 缓存 | Redis |
| AI | 兼容 OpenAI Chat Completions 协议的模型服务,默认配置为阿里云百炼 qwen-plus |
| 地图 | 高德地图 JavaScript API 2.0 |
| 数据库 | MySQL 8.x,字符集使用 utf8mb4 |
RelicVoyage/
├── backend/ # Spring Boot 后端
│ ├── pom.xml # Maven 依赖和构建配置
│ └── src/
│ ├── main/java/com/example/
│ │ ├── controller/ # REST 接口
│ │ ├── service/ # 业务接口及实现
│ │ ├── mapper/ # MyBatis Mapper 接口
│ │ ├── dto/ # 数据传输对象
│ │ ├── config/ # Spring、Redis、AI 配置
│ │ ├── common/ # 统一返回体和异常处理
│ │ └── utils/ # Redis、数据库、请求身份辅助类
│ ├── main/resources/
│ │ ├── application.yml # 默认后端配置
│ │ ├── application-local.yml # 本地 AI/地图相关配置
│ │ └── mapper/ # MyBatis XML 映射文件
│ └── test/ # 后端测试
├── frontend/ # Vue 前端
│ ├── package.json
│ ├── vite.config.js # 5173 端口和 /api 代理
│ └── src/
│ ├── api/ # 前端接口封装
│ ├── components/ # 通用组件
│ ├── pages/ # 页面组件
│ ├── router/ # 路由和角色跳转控制
│ ├── utils/ # 会话、地图、图表等工具
│ └── styles.css # 全局样式
├── media/ # 前端静态媒体目录
│ ├── relics/ # 文物图片
│ └── museums/ # 博物馆图片
├── relic_voyage.sql # 数据库结构和演示数据
└── README.md
开始前请安装并确认以下工具可用:
- JDK 17 或更高版本,且
JAVA_HOME已正确配置。 - Maven 3.8+。也可以使用 IDE 内置 Maven。
- Node.js 18+,建议使用随 Node.js 一起安装的 npm。
- MySQL 8.x。
- Redis 6.x 或更高版本。
检查版本:
java -version
mvn -version
node -v
npm -v
mysql --version
redis-server --version项目需要先启动 MySQL 和 Redis,再分别启动后端和前端。建议在两个终端窗口中运行后端和前端。
先创建数据库:
CREATE DATABASE relic_voyage
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;然后导入仓库中的结构和演示数据:
mysql -u root -p relic_voyage < relic_voyage.sqlWindows PowerShell 也可以执行同一条命令;输入密码时使用 MySQL 用户密码。SQL 文件包含表结构、索引、外键和演示数据,重复导入会先删除同名表,请不要在重要数据库上直接执行。
数据库连接默认配置在 backend/src/main/resources/application.yml:
spring:
datasource:
url: jdbc:mysql://localhost:3306/relic_voyage
username: root
password: 123456如果本机 MySQL 用户名、密码或端口不同,请先修改该配置。
确保 Redis 正在监听默认地址 localhost:6379。如果 Redis 配置不同,请修改 application.yml 中的配置:
spring:
data:
redis:
host: localhost
port: 6379
timeout: 2000msRedis 主要用于缓存文物、博物馆、评论和看板数据。后端启动时需要能够连接 Redis;缓存不可用时,相关接口可能无法正常工作。
进入后端目录并启动 Spring Boot:
cd backend
mvn spring-boot:run后端默认地址:http://localhost:8080
也可以先打包再启动:
cd backend
mvn clean package
java -jar target/backend-1.0-SNAPSHOT.jar打开另一个终端:
cd frontend
npm install
npm run dev前端默认地址:http://localhost:5173
前端 Vite 配置会把 /api 请求代理到 http://localhost:8080,因此本地开发时前端不需要单独配置 API 地址。浏览器访问:
http://localhost:5173
后端通过以下配置读取 AI 服务参数:
app.ai.api-keyapp.ai.base-urlapp.ai.model
默认模型为 qwen-plus,默认兼容接口地址为阿里云百炼兼容 OpenAI 协议的地址。推荐在本地配置文件中使用环境变量,不要把真实密钥提交到 Git:
app:
ai:
api-key: ${QWEN_API_KEY:}
base-url: ${QWEN_BASE_URL:https://dashscope.aliyuncs.com/compatible-mode/v1}
model: ${QWEN_MODEL:qwen-plus}PowerShell 示例:
$env:QWEN_API_KEY = "替换为你自己的密钥"
$env:QWEN_BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1"
$env:QWEN_MODEL = "qwen-plus"如果没有配置模型密钥,AI 助手仍可返回系统内置说明和部分数据库统计类回答,但无法调用外部模型完成普通自然语言问答。前端 AI 请求超时时间为 25 秒。
前端地图加载逻辑位于 frontend/src/utils/amap.js。地图功能依赖高德地图 JavaScript API Key 和安全密钥,并且需要浏览器能够访问高德地图资源。正式环境应将 Key 放在环境变量或构建时注入的配置中,并限制 Key 的域名白名单。
relic_voyage.sql 中包含用于本地演示的账号,密码均为 SQL 文件中的明文演示密码 123456:
| 类型 | 账号 | 状态 |
|---|---|---|
| 管理员 | admin01 |
正常 |
| 管理员 | admin02 |
正常 |
| 管理员 | admin03 |
正常 |
| 管理员 | admin04 |
正常 |
| 普通用户 | 沈亚 |
正常 |
| 普通用户 | 谷叶 |
正常 |
| 普通用户 | 王五 |
已停用,用于演示账号状态管理 |
登录入口:
- 普通用户:
http://localhost:5173/#/login - 管理员:
http://localhost:5173/#/login?role=admin
前端使用 sessionStorage 保存当前会话,并在请求头中发送:
X-User-Id
X-User-Role
后端通过这两个请求头完成当前版本的接口权限校验。该机制适用于演示,不等同于生产环境的安全认证方案。
| 路径 | 页面 | 角色 |
|---|---|---|
/ |
用户首页和数据概览 | 普通用户 |
/login |
登录 | 未登录 |
/register |
注册 | 未登录 |
/artifacts |
文物列表和筛选 | 普通用户 |
/artifacts/:id |
文物详情、收藏和评论 | 普通用户 |
/museums |
博物馆列表和筛选 | 普通用户 |
/museums/:id |
博物馆详情和地图 | 普通用户 |
/profile |
个人资料 | 普通用户 |
/profile/favorites |
我的收藏 | 普通用户 |
/admin |
管理员首页和数据看板 | 管理员 |
/admin/artifacts |
文物管理 | 管理员 |
/admin/museums |
博物馆管理 | 管理员 |
/admin/comments |
评论查看和回复 | 管理员 |
/admin/users |
用户管理 | 管理员 |
路由使用 Vue Router 的 Hash History,因此部署为静态文件时不要求服务器额外配置 HTML5 History 回退规则。
所有接口默认以 http://localhost:8080 为根地址。成功响应通常为以下格式:
{
"code": 200,
"message": "success",
"data": {}
}失败响应会使用非 200 的业务状态码,并在 message 中返回错误原因。
| 方法 | 路径 | 说明 | 权限 |
|---|---|---|---|
| POST | /api/auth/login |
登录,表单参数 username、password、role |
公开 |
| POST | /api/auth/register |
注册,表单参数包含用户名、密码及个人资料 | 公开 |
| GET | /api/profile?id={id} |
查询个人资料 | 当前用户本人 |
| POST | /api/profile/update |
更新资料或密码,表单参数包含 id |
当前用户本人 |
| 方法 | 路径 | 说明 | 权限 |
|---|---|---|---|
| GET | /api/artifacts/search |
文物筛选列表 | 登录用户 |
| GET | /api/artifacts/{id} |
文物详情 | 登录用户 |
| GET | /api/artifacts/all |
获取全部文物 | 登录用户 |
| POST | /api/artifacts/save |
新增或编辑文物 | 管理员 |
| DELETE | /api/artifacts/delete?id={id} |
删除文物 | 管理员 |
| GET | /api/museums/search |
博物馆列表,支持 keyword、city |
登录用户 |
| GET | /api/museums/{id} |
博物馆详情 | 登录用户 |
| POST | /api/museums/save |
新增或编辑博物馆 | 管理员 |
| DELETE | /api/museums/delete?id={id} |
删除博物馆 | 管理员 |
| POST | /api/uploads/image |
上传图片,Multipart 参数 file、category |
管理员 |
category 仅支持 relics 和 museums。上传文件会保存到根目录 media/relics 或 media/museums,接口返回的图片路径可直接保存到文物或博物馆记录中。
| 方法 | 路径 | 说明 | 权限 |
|---|---|---|---|
| GET | /api/favorites/list?userId={id} |
查询用户收藏 | 当前用户本人 |
| POST | /api/favorites/add |
添加收藏,表单参数 userId、artifactId |
当前用户本人 |
| POST | /api/favorites/remove |
取消收藏,表单参数 userId、artifactId |
当前用户本人 |
| GET | /api/comments/artifact?artifactId={id}&userId={id} |
查询文物评论 | 登录用户 |
| POST | /api/comments/add |
发表评论,表单参数 artifactId、userId、content |
当前用户本人 |
| POST | /api/comments/like |
点赞/取消点赞,表单参数 commentId、userId |
当前用户本人 |
| GET | /api/comments/all |
查询全部评论 | 管理员 |
| POST | /api/comments/reply |
回复评论,表单参数 commentId、content |
管理员 |
| GET | /api/dashboard/user?userId={id} |
用户看板 | 当前用户本人 |
| GET | /api/dashboard/admin |
管理员看板 | 管理员 |
| POST | /api/ai/chat |
AI 问答,JSON 参数 message、role、route、history |
登录用户 |
| 方法 | 路径 | 说明 | 权限 |
|---|---|---|---|
| GET | /api/admin/users/search |
查询用户列表 | 管理员 |
| POST | /api/admin/users/save |
新增或编辑用户 | 管理员 |
| POST | /api/admin/users/toggle?id={id} |
启用/停用用户 | 管理员 |
| DELETE | /api/admin/users/delete?id={id} |
删除用户 | 管理员 |
构建前端生产包:
cd frontend
npm run build本地预览前端生产包:
cd frontend
npm run preview编译并运行后端测试:
cd backend
mvn test部分后端测试会访问数据库并写入测试数据。运行前请确保 MySQL、Redis 已启动,并且数据库连接配置正确。
确认后端是否运行在 http://localhost:8080,并检查 frontend/vite.config.js 中的代理目标。修改代理后需要重启 Vite 开发服务器。
检查以下项目:
- MySQL 服务是否启动。
- 数据库
relic_voyage是否已创建并导入 SQL。 application.yml中的用户名、密码、端口和数据库名是否正确。- MySQL 用户是否允许本机连接,字符集是否支持
utf8mb4。
确认 Redis 运行在 localhost:6379,或把 application.yml 中的 Redis 地址改成实际配置。Redis 使用的是无密码连接;如果本机启用了密码,需要补充 Spring Data Redis 的密码配置。
确认图片位于根目录 media/relics 或 media/museums,数据库中的 image_url 使用类似 /relics/example.jpg 的路径。前端开发服务器通过 Vite 的 publicDir 将根目录 media 作为静态资源目录。
没有配置有效模型密钥时,系统只能处理内置说明和部分统计问题。配置密钥后重启后端,并确认服务器可以访问 AI 服务的 base-url。
检查登录时是否选择管理员角色。前端会根据 sessionStorage 中的 role 判断身份;后端还会校验请求头中的 X-User-Id 和 X-User-Role。
- 不要将真实 AI API Key、数据库密码或高德地图密钥提交到公共仓库。
- 当前数据库示例中的密码是明文,且后端登录逻辑按明文比对;正式环境必须改用强哈希密码,例如 BCrypt 或 Argon2。
- 当前会话身份主要依赖前端
sessionStorage和自定义请求头,不能抵御伪造请求;正式环境应使用服务端会话或签名 Token,并在服务端统一鉴权。 - 上传接口虽然限制了图片扩展名,但生产环境仍应增加 MIME 校验、文件大小限制、图片内容检测、访问权限和存储隔离。
- 建议将本地配置拆分为未提交的配置文件或环境变量,并为已暴露过的密钥执行轮换。
- SQL 文件包含演示数据和可登录账号,仅用于本地开发,不应直接用于生产数据库。
本仓库当前未提供单独的开源许可证文件。media 目录中的图片和文物/博物馆资料应在公开部署前确认版权、授权范围和来源标注要求。