release: 提交版修改
This commit is contained in:
12
.idea/misc.xml
generated
Normal file
12
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="zulu-21" project-jdk-type="JavaSDK" />
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
63
.idea/workspace.xml
generated
Normal file
63
.idea/workspace.xml
generated
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="a18e42eb-749f-47ad-9d80-c0c33fa80d9c" name="更改" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/server/docs/init.sql" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/server/docs/sample_data.sql" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/server/src/main/resources/application.yml" beforeDir="false" afterPath="$PROJECT_DIR$/server/src/main/resources/application.yml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/server/target/classes/application.yml" beforeDir="false" afterPath="$PROJECT_DIR$/server/target/classes/application.yml" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo"><![CDATA[{
|
||||
"customColor": "",
|
||||
"associatedIndex": 1
|
||||
}]]></component>
|
||||
<component name="ProjectId" id="38CagDQueaecmzLh359o7LYgcfB" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"git-widget-placeholder": "main",
|
||||
"kotlin-language-version-configured": "true",
|
||||
"last_opened_file_path": "C:/Users/shiro/Desktop/campus-activity-system/server",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
<set>
|
||||
<option value="bundled-jdk-9f38398b9061-39b83d9b5494-intellij.indexing.shared.core-IU-241.19416.15" />
|
||||
<option value="bundled-js-predefined-1d06a55b98c1-0b3e54e931b4-JavaScript-IU-241.19416.15" />
|
||||
</set>
|
||||
</attachedChunks>
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="应用程序级" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="默认任务">
|
||||
<changelist id="a18e42eb-749f-47ad-9d80-c0c33fa80d9c" name="更改" comment="" />
|
||||
<created>1768306117632</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1768306117632</updated>
|
||||
<workItem from="1768306119876" duration="55000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
</project>
|
||||
6
server/.idea/appmap.xml
generated
Normal file
6
server/.idea/appmap.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="appmap-project">
|
||||
<option name="explainWithNavieOpened" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
3
server/.vscode/settings.json
vendored
Normal file
3
server/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx4G -Xms100m -Xlog:disable"
|
||||
}
|
||||
1119
server/docs/业务流程图.md
Normal file
1119
server/docs/业务流程图.md
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,823 +0,0 @@
|
||||
# 校园活动组织与报名系统 - 前端开发计划
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
### 1.1 项目背景
|
||||
本项目为校园活动组织与报名系统的前端部分,采用前后端分离架构,对接已完成的 Spring Boot 后端 API。
|
||||
|
||||
### 1.2 系统目标
|
||||
实现活动从 **发布 → 报名 → 签到 → 评价 → 统计分析** 的一体化管理前端界面。
|
||||
|
||||
### 1.3 用户角色
|
||||
| 角色 | 权限说明 |
|
||||
|------|----------|
|
||||
| 普通学生 | 浏览活动、报名/取消报名、签到、评价活动 |
|
||||
| 活动管理员 | 发布活动、管理报名、查看签到、统计分析、导出数据 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 技术选型
|
||||
|
||||
### 2.1 核心框架
|
||||
| 技术 | 版本 | 说明 |
|
||||
|------|------|------|
|
||||
| Vue.js | 3.4+ | 渐进式 JavaScript 框架 |
|
||||
| Vite | 5.x | 下一代前端构建工具 |
|
||||
| TypeScript | 5.x | JavaScript 超集,类型安全 |
|
||||
| Vue Router | 4.x | 官方路由管理 |
|
||||
| Pinia | 2.x | 官方状态管理 |
|
||||
|
||||
### 2.2 UI 组件库
|
||||
| 技术 | 说明 |
|
||||
|------|------|
|
||||
| Vant 4 | 轻量、可靠的移动端 Vue 组件库(小程序风格) |
|
||||
| @vant/use | Vant 组合式 API 工具库 |
|
||||
|
||||
### 2.3 工具库
|
||||
| 技术 | 说明 |
|
||||
|------|------|
|
||||
| Axios | HTTP 请求库 |
|
||||
| Day.js | 轻量日期处理库 |
|
||||
| vue-qrcode-reader | 二维码扫描组件 |
|
||||
| html2canvas | 截图/生成图片 |
|
||||
| @vueuse/core | Vue 组合式工具集 |
|
||||
|
||||
### 2.4 开发工具
|
||||
| 技术 | 说明 |
|
||||
|------|------|
|
||||
| ESLint | 代码规范检查 |
|
||||
| Prettier | 代码格式化 |
|
||||
| Husky | Git Hooks 工具 |
|
||||
| lint-staged | 暂存区代码检查 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 项目结构设计
|
||||
|
||||
```
|
||||
campus-activity-frontend/
|
||||
├── public/ # 静态资源
|
||||
│ └── favicon.ico
|
||||
├── src/
|
||||
│ ├── api/ # API 接口层
|
||||
│ │ ├── index.ts # Axios 实例配置
|
||||
│ │ ├── auth.ts # 认证相关 API
|
||||
│ │ ├── activity.ts # 活动相关 API
|
||||
│ │ ├── registration.ts # 报名相关 API
|
||||
│ │ ├── checkin.ts # 签到相关 API
|
||||
│ │ ├── review.ts # 评价相关 API
|
||||
│ │ └── statistics.ts # 统计相关 API
|
||||
│ │
|
||||
│ ├── assets/ # 静态资源
|
||||
│ │ ├── images/ # 图片资源
|
||||
│ │ └── styles/ # 全局样式
|
||||
│ │ ├── variables.scss # SCSS 变量
|
||||
│ │ ├── mixins.scss # SCSS 混入
|
||||
│ │ └── global.scss # 全局样式
|
||||
│ │
|
||||
│ ├── components/ # 公共组件
|
||||
│ │ ├── common/ # 通用组件
|
||||
│ │ │ ├── NavBar.vue # 导航栏
|
||||
│ │ │ ├── TabBar.vue # 底部标签栏
|
||||
│ │ │ ├── Empty.vue # 空状态
|
||||
│ │ │ ├── Loading.vue # 加载状态
|
||||
│ │ │ └── ErrorPage.vue # 错误页面
|
||||
│ │ │
|
||||
│ │ ├── activity/ # 活动相关组件
|
||||
│ │ │ ├── ActivityCard.vue # 活动卡片
|
||||
│ │ │ ├── ActivityList.vue # 活动列表
|
||||
│ │ │ ├── ActivityFilter.vue # 活动筛选
|
||||
│ │ │ └── CalendarView.vue # 日历视图
|
||||
│ │ │
|
||||
│ │ ├── registration/ # 报名相关组件
|
||||
│ │ │ ├── TicketCard.vue # 电子票卡片
|
||||
│ │ │ └── RegistrationList.vue # 报名列表
|
||||
│ │ │
|
||||
│ │ ├── review/ # 评价相关组件
|
||||
│ │ │ ├── ReviewCard.vue # 评价卡片
|
||||
│ │ │ ├── ReviewForm.vue # 评价表单
|
||||
│ │ │ └── RatingStars.vue # 评分星星
|
||||
│ │ │
|
||||
│ │ └── statistics/ # 统计相关组件
|
||||
│ │ ├── StatCard.vue # 统计卡片
|
||||
│ │ └── ChartView.vue # 图表视图
|
||||
│ │
|
||||
│ ├── composables/ # 组合式函数
|
||||
│ │ ├── useAuth.ts # 认证相关
|
||||
│ │ ├── useActivity.ts # 活动相关
|
||||
│ │ ├── useRegistration.ts # 报名相关
|
||||
│ │ ├── usePagination.ts # 分页相关
|
||||
│ │ └── useToast.ts # 提示消息
|
||||
│ │
|
||||
│ ├── layouts/ # 布局组件
|
||||
│ │ ├── DefaultLayout.vue # 默认布局
|
||||
│ │ ├── AdminLayout.vue # 管理员布局
|
||||
│ │ └── BlankLayout.vue # 空白布局
|
||||
│ │
|
||||
│ ├── router/ # 路由配置
|
||||
│ │ ├── index.ts # 路由入口
|
||||
│ │ ├── routes.ts # 路由定义
|
||||
│ │ └── guards.ts # 路由守卫
|
||||
│ │
|
||||
│ ├── stores/ # 状态管理
|
||||
│ │ ├── index.ts # Store 入口
|
||||
│ │ ├── user.ts # 用户状态
|
||||
│ │ ├── activity.ts # 活动状态
|
||||
│ │ └── app.ts # 应用状态
|
||||
│ │
|
||||
│ ├── types/ # TypeScript 类型定义
|
||||
│ │ ├── api.d.ts # API 响应类型
|
||||
│ │ ├── user.d.ts # 用户类型
|
||||
│ │ ├── activity.d.ts # 活动类型
|
||||
│ │ ├── registration.d.ts # 报名类型
|
||||
│ │ ├── checkin.d.ts # 签到类型
|
||||
│ │ ├── review.d.ts # 评价类型
|
||||
│ │ └── statistics.d.ts # 统计类型
|
||||
│ │
|
||||
│ ├── utils/ # 工具函数
|
||||
│ │ ├── request.ts # 请求封装
|
||||
│ │ ├── storage.ts # 本地存储
|
||||
│ │ ├── format.ts # 格式化工具
|
||||
│ │ ├── validate.ts # 校验工具
|
||||
│ │ └── constant.ts # 常量定义
|
||||
│ │
|
||||
│ ├── views/ # 页面视图
|
||||
│ │ ├── auth/ # 认证页面
|
||||
│ │ │ ├── Login.vue # 登录
|
||||
│ │ │ └── Register.vue # 注册
|
||||
│ │ │
|
||||
│ │ ├── home/ # 首页
|
||||
│ │ │ └── Index.vue # 首页
|
||||
│ │ │
|
||||
│ │ ├── activity/ # 活动页面
|
||||
│ │ │ ├── List.vue # 活动列表
|
||||
│ │ │ ├── Detail.vue # 活动详情
|
||||
│ │ │ ├── Calendar.vue # 日历视图
|
||||
│ │ │ └── Search.vue # 搜索页面
|
||||
│ │ │
|
||||
│ │ ├── registration/ # 报名页面
|
||||
│ │ │ ├── MyList.vue # 我的报名
|
||||
│ │ │ └── Ticket.vue # 电子票详情
|
||||
│ │ │
|
||||
│ │ ├── checkin/ # 签到页面
|
||||
│ │ │ └── Scan.vue # 扫码签到
|
||||
│ │ │
|
||||
│ │ ├── review/ # 评价页面
|
||||
│ │ │ ├── Write.vue # 写评价
|
||||
│ │ │ └── MyList.vue # 我的评价
|
||||
│ │ │
|
||||
│ │ ├── user/ # 用户页面
|
||||
│ │ │ ├── Profile.vue # 个人中心
|
||||
│ │ │ ├── Settings.vue # 设置
|
||||
│ │ │ └── ChangePassword.vue # 修改密码
|
||||
│ │ │
|
||||
│ │ └── admin/ # 管理员页面
|
||||
│ │ ├── Dashboard.vue # 数据面板
|
||||
│ │ ├── ActivityManage.vue # 活动管理
|
||||
│ │ ├── ActivityForm.vue # 活动表单(新增/编辑)
|
||||
│ │ ├── RegistrationManage.vue # 报名管理
|
||||
│ │ ├── CheckInManage.vue # 签到管理
|
||||
│ │ ├── QRCodeGenerate.vue # 生成签到码
|
||||
│ │ ├── ReviewManage.vue # 评价管理
|
||||
│ │ ├── Statistics.vue # 统计分析
|
||||
│ │ └── Export.vue # 数据导出
|
||||
│ │
|
||||
│ ├── App.vue # 根组件
|
||||
│ └── main.ts # 入口文件
|
||||
│
|
||||
├── .env # 环境变量
|
||||
├── .env.development # 开发环境变量
|
||||
├── .env.production # 生产环境变量
|
||||
├── .eslintrc.cjs # ESLint 配置
|
||||
├── .prettierrc # Prettier 配置
|
||||
├── index.html # HTML 入口
|
||||
├── package.json # 项目依赖
|
||||
├── tsconfig.json # TypeScript 配置
|
||||
├── vite.config.ts # Vite 配置
|
||||
└── README.md # 项目说明
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 页面设计规划
|
||||
|
||||
### 4.1 页面清单
|
||||
|
||||
#### 公共页面
|
||||
| 页面 | 路由 | 说明 |
|
||||
|------|------|------|
|
||||
| 登录 | /login | 用户登录 |
|
||||
| 注册 | /register | 用户注册 |
|
||||
|
||||
#### 学生端页面
|
||||
| 页面 | 路由 | 说明 |
|
||||
|------|------|------|
|
||||
| 首页 | / | 推荐活动、快捷入口 |
|
||||
| 活动列表 | /activities | 活动列表(筛选、搜索) |
|
||||
| 活动详情 | /activities/:id | 活动详细信息、报名入口 |
|
||||
| 日历视图 | /calendar | 按日历展示活动 |
|
||||
| 我的报名 | /my/registrations | 已报名活动列表 |
|
||||
| 电子票 | /ticket/:id | 电子票详情、二维码 |
|
||||
| 扫码签到 | /checkin/scan | 扫码签到页面 |
|
||||
| 写评价 | /review/:activityId | 活动评价表单 |
|
||||
| 我的评价 | /my/reviews | 我的评价列表 |
|
||||
| 个人中心 | /profile | 个人信息 |
|
||||
| 修改密码 | /change-password | 修改密码 |
|
||||
|
||||
#### 管理员页面
|
||||
| 页面 | 路由 | 说明 |
|
||||
|------|------|------|
|
||||
| 数据面板 | /admin/dashboard | 统计概览 |
|
||||
| 活动管理 | /admin/activities | 活动列表管理 |
|
||||
| 创建活动 | /admin/activities/create | 新建活动 |
|
||||
| 编辑活动 | /admin/activities/:id/edit | 编辑活动 |
|
||||
| 报名管理 | /admin/activities/:id/registrations | 活动报名列表 |
|
||||
| 签到管理 | /admin/activities/:id/checkin | 签到管理、生成二维码 |
|
||||
| 评价管理 | /admin/activities/:id/reviews | 活动评价列表 |
|
||||
| 统计分析 | /admin/statistics/:id | 活动数据统计 |
|
||||
| 数据导出 | /admin/export | 导出 Excel |
|
||||
|
||||
### 4.2 UI 风格设计(小程序风格)
|
||||
|
||||
#### 配色方案
|
||||
```scss
|
||||
// 主色调
|
||||
$primary-color: #07C160; // 微信绿
|
||||
$primary-light: #E8F8ED; // 浅绿背景
|
||||
|
||||
// 功能色
|
||||
$success-color: #07C160; // 成功
|
||||
$warning-color: #FFA500; // 警告
|
||||
$error-color: #EE0A24; // 错误
|
||||
$info-color: #1989FA; // 信息
|
||||
|
||||
// 中性色
|
||||
$text-primary: #323233; // 主要文字
|
||||
$text-secondary: #969799; // 次要文字
|
||||
$text-placeholder: #C8C9CC; // 占位文字
|
||||
$border-color: #EBEDF0; // 边框颜色
|
||||
$background-color: #F7F8FA; // 页面背景
|
||||
|
||||
// 活动状态色
|
||||
$status-pending: #909399; // 未开始
|
||||
$status-open: #07C160; // 报名中
|
||||
$status-ongoing: #1989FA; // 进行中
|
||||
$status-ended: #C8C9CC; // 已结束
|
||||
```
|
||||
|
||||
#### 设计原则
|
||||
1. **简洁清晰**: 界面简洁,信息层级分明
|
||||
2. **圆角卡片**: 使用圆角卡片承载内容,间距 12px
|
||||
3. **底部安全区**: 适配各种手机底部安全区域
|
||||
4. **下拉刷新**: 列表页支持下拉刷新
|
||||
5. **骨架屏**: 加载时显示骨架屏,优化体验
|
||||
6. **空状态**: 无数据时显示友好的空状态提示
|
||||
|
||||
---
|
||||
|
||||
## 5. 核心功能模块设计
|
||||
|
||||
### 5.1 认证模块
|
||||
|
||||
#### 登录页面
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ 校园活动 │
|
||||
│ │
|
||||
│ ┌─────────────────────┐ │
|
||||
│ │ 👤 请输入用户名 │ │
|
||||
│ └─────────────────────┘ │
|
||||
│ ┌─────────────────────┐ │
|
||||
│ │ 🔒 请输入密码 │ │
|
||||
│ └─────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────┐ │
|
||||
│ │ 登 录 │ │
|
||||
│ └─────────────────────┘ │
|
||||
│ │
|
||||
│ 还没有账号?去注册 │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Token 管理
|
||||
- Access Token 存储在 localStorage
|
||||
- Refresh Token 存储在 localStorage
|
||||
- Token 过期前自动刷新
|
||||
- 401 响应自动跳转登录页
|
||||
|
||||
### 5.2 活动模块
|
||||
|
||||
#### 活动列表页
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ 🔍 搜索活动 │
|
||||
├─────────────────────────────────┤
|
||||
│ [全部] [报名中] [进行中] [已结束]│
|
||||
├─────────────────────────────────┤
|
||||
│ ┌─────────────────────────────┐ │
|
||||
│ │ 🖼️ 封面图 │ │
|
||||
│ │ 校园篮球赛 │ │
|
||||
│ │ 📅 2025-06-01 09:00 │ │
|
||||
│ │ 📍 体育馆 │ │
|
||||
│ │ ⭐ 4.5 👥 45/100 │ │
|
||||
│ │ [报名中] │ │
|
||||
│ └─────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────┐ │
|
||||
│ │ ... │ │
|
||||
│ └─────────────────────────────┘ │
|
||||
├─────────────────────────────────┤
|
||||
│ 🏠 📅 ✉️ 👤 │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 活动详情页
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ ← 活动详情 │
|
||||
├─────────────────────────────────┤
|
||||
│ ┌─────────────────────────────┐ │
|
||||
│ │ 封面图片 │ │
|
||||
│ └─────────────────────────────┘ │
|
||||
│ │
|
||||
│ 校园篮球赛 │
|
||||
│ [体育] [报名中] │
|
||||
│ │
|
||||
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
||||
│ 📅 活动时间 │
|
||||
│ 2025-06-01 09:00-17:00 │
|
||||
│ │
|
||||
│ 📍 活动地点 │
|
||||
│ 体育馆A区 │
|
||||
│ │
|
||||
│ 👥 报名人数 │
|
||||
│ 45/100(剩余55个名额) │
|
||||
│ │
|
||||
│ ⏰ 报名截止 │
|
||||
│ 2025-05-30 23:59 │
|
||||
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
||||
│ │
|
||||
│ 活动详情 │
|
||||
│ 年度篮球比赛详细介绍... │
|
||||
│ │
|
||||
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
||||
│ 评价 (20条) ⭐ 4.5 │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ 张三 ⭐⭐⭐⭐⭐ │ │
|
||||
│ │ 活动组织得很好! │ │
|
||||
│ └─────────────────────────┘ │
|
||||
│ │
|
||||
├─────────────────────────────────┤
|
||||
│ ┌─────────────────────────────┐ │
|
||||
│ │ 立即报名 │ │
|
||||
│ └─────────────────────────────┘ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 5.3 报名模块
|
||||
|
||||
#### 我的报名列表
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ ← 我的报名 │
|
||||
├─────────────────────────────────┤
|
||||
│ [全部] [待签到] [已签到] [已取消]│
|
||||
├─────────────────────────────────┤
|
||||
│ ┌─────────────────────────────┐ │
|
||||
│ │ 🖼️ 校园篮球赛 │ │
|
||||
│ │ 📅 2025-06-01 09:00 │ │
|
||||
│ │ 📍 体育馆 │ │
|
||||
│ │ 票号: TK20250601001 │ │
|
||||
│ │ [待签到] [查看电子票] → │ │
|
||||
│ └─────────────────────────────┘ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 电子票页面
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ ← 电子票 │
|
||||
├─────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ ┌───────────┐ │ │
|
||||
│ │ │ QR码 │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ └───────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ 票号: TK20250601001 │ │
|
||||
│ │ ───────────────────── │ │
|
||||
│ │ 活动: 校园篮球赛 │ │
|
||||
│ │ 时间: 2025-06-01 09:00│ │
|
||||
│ │ 地点: 体育馆 │ │
|
||||
│ │ 姓名: 张三 │ │
|
||||
│ │ 学号: 2021001001 │ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ 下载电子票 │ │
|
||||
│ └─────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ 取消报名 │ │
|
||||
│ └─────────────────────────┘ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 5.4 签到模块
|
||||
|
||||
#### 扫码签到页面
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ ← 扫码签到 │
|
||||
├─────────────────────────────────┤
|
||||
│ │
|
||||
│ │
|
||||
│ ┌─────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ 相机取景框 │ │
|
||||
│ │ 扫描二维码 │ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────┘ │
|
||||
│ │
|
||||
│ 将二维码放入框内扫描 │
|
||||
│ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 5.5 评价模块
|
||||
|
||||
#### 写评价页面
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ ← 活动评价 │
|
||||
├─────────────────────────────────┤
|
||||
│ │
|
||||
│ 校园篮球赛 │
|
||||
│ │
|
||||
│ 评分 │
|
||||
│ ⭐ ⭐ ⭐ ⭐ ⭐ │
|
||||
│ │
|
||||
│ 评价内容 │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ 请输入您的评价... │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────┘ │
|
||||
│ │
|
||||
├─────────────────────────────────┤
|
||||
│ ┌─────────────────────────────┐ │
|
||||
│ │ 提交评价 │ │
|
||||
│ └─────────────────────────────┘ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 5.6 管理员模块
|
||||
|
||||
#### 数据面板
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ 数据面板 👤 │
|
||||
├─────────────────────────────────┤
|
||||
│ ┌───────┐ ┌───────┐ ┌───────┐ │
|
||||
│ │ 活动 │ │ 报名 │ │ 签到 │ │
|
||||
│ │ 50 │ │ 1200 │ │ 1050 │ │
|
||||
│ └───────┘ └───────┘ └───────┘ │
|
||||
│ │
|
||||
│ ┌───────┐ ┌───────┐ │
|
||||
│ │ 评价 │ │ 平均分 │ │
|
||||
│ │ 800 │ │ 4.3 │ │
|
||||
│ └───────┘ └───────┘ │
|
||||
│ │
|
||||
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
||||
│ 本月活动趋势 │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ 📊 图表 │ │
|
||||
│ └─────────────────────────┘ │
|
||||
│ │
|
||||
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
||||
│ 快捷操作 │
|
||||
│ [+创建活动] [📊统计] [📥导出] │
|
||||
├─────────────────────────────────┤
|
||||
│ 🏠 📋 📊 👤 │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 活动管理页面
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ 活动管理 [+] │
|
||||
├─────────────────────────────────┤
|
||||
│ 🔍 搜索活动 │
|
||||
│ [全部] [报名中] [进行中] [已结束]│
|
||||
├─────────────────────────────────┤
|
||||
│ ┌─────────────────────────────┐ │
|
||||
│ │ 校园篮球赛 │ │
|
||||
│ │ 📅 2025-06-01 │ │
|
||||
│ │ 👥 45/100 [报名中] │ │
|
||||
│ │ ────────────────────────── │ │
|
||||
│ │ [报名] [签到] [评价] [统计]│ │
|
||||
│ │ [编辑] [删除] │ │
|
||||
│ └─────────────────────────────┘ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. API 对接规划
|
||||
|
||||
### 6.1 请求封装
|
||||
```typescript
|
||||
// src/utils/request.ts
|
||||
import axios from 'axios'
|
||||
import type { AxiosInstance, AxiosRequestConfig } from 'axios'
|
||||
|
||||
const instance: AxiosInstance = axios.create({
|
||||
baseURL: import.meta.env.VITE_API_BASE_URL,
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
// 请求拦截器:添加 Token
|
||||
instance.interceptors.request.use(config => {
|
||||
const token = localStorage.getItem('accessToken')
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`
|
||||
}
|
||||
return config
|
||||
})
|
||||
|
||||
// 响应拦截器:处理错误
|
||||
instance.interceptors.response.use(
|
||||
response => response.data,
|
||||
error => {
|
||||
if (error.response?.status === 401) {
|
||||
// Token 过期,尝试刷新或跳转登录
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### 6.2 API 模块划分
|
||||
|
||||
| 模块 | 文件 | API 数量 | 说明 |
|
||||
|------|------|----------|------|
|
||||
| 认证 | api/auth.ts | 5 | 登录、注册、刷新 Token、获取用户信息、修改密码 |
|
||||
| 活动 | api/activity.ts | 7 | 活动 CRUD、列表、日历、冲突检测 |
|
||||
| 报名 | api/registration.ts | 5 | 报名、取消、我的报名、活动报名列表、电子票 |
|
||||
| 签到 | api/checkin.ts | 4 | 生成二维码、扫码签到、扫票签到、签到列表 |
|
||||
| 评价 | api/review.ts | 3 | 提交评价、活动评价列表、我的评价 |
|
||||
| 统计 | api/statistics.ts | 3 | 活动统计、总体统计、数据导出 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 状态管理设计
|
||||
|
||||
### 7.1 用户状态 (stores/user.ts)
|
||||
```typescript
|
||||
interface UserState {
|
||||
token: string | null
|
||||
refreshToken: string | null
|
||||
userInfo: UserInfo | null
|
||||
isLoggedIn: boolean
|
||||
}
|
||||
|
||||
// Actions
|
||||
- login(username, password)
|
||||
- logout()
|
||||
- refreshToken()
|
||||
- getUserInfo()
|
||||
- updateUserInfo()
|
||||
```
|
||||
|
||||
### 7.2 活动状态 (stores/activity.ts)
|
||||
```typescript
|
||||
interface ActivityState {
|
||||
activities: Activity[]
|
||||
currentActivity: Activity | null
|
||||
loading: boolean
|
||||
filters: ActivityFilters
|
||||
pagination: Pagination
|
||||
}
|
||||
|
||||
// Actions
|
||||
- fetchActivities(params)
|
||||
- fetchActivityDetail(id)
|
||||
- createActivity(data)
|
||||
- updateActivity(id, data)
|
||||
- deleteActivity(id)
|
||||
```
|
||||
|
||||
### 7.3 应用状态 (stores/app.ts)
|
||||
```typescript
|
||||
interface AppState {
|
||||
loading: boolean
|
||||
tabBarActive: string
|
||||
theme: 'light' | 'dark'
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 路由守卫设计
|
||||
|
||||
```typescript
|
||||
// 路由守卫逻辑
|
||||
router.beforeEach((to, from, next) => {
|
||||
const userStore = useUserStore()
|
||||
|
||||
// 白名单路由
|
||||
const whiteList = ['/login', '/register']
|
||||
|
||||
if (userStore.isLoggedIn) {
|
||||
if (to.path === '/login') {
|
||||
next('/')
|
||||
} else {
|
||||
// 检查权限
|
||||
if (to.meta.requiresAdmin && userStore.userInfo?.role !== 1) {
|
||||
next('/403')
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (whiteList.includes(to.path)) {
|
||||
next()
|
||||
} else {
|
||||
next(`/login?redirect=${to.path}`)
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 错误处理设计
|
||||
|
||||
### 9.1 全局错误处理
|
||||
- 网络错误:显示"网络异常,请稍后重试"
|
||||
- 401 错误:跳转登录页
|
||||
- 403 错误:显示"无权限访问"
|
||||
- 404 错误:显示"资源不存在"
|
||||
- 409 错误:显示业务冲突信息(如"已报名")
|
||||
- 500 错误:显示"服务器异常"
|
||||
|
||||
### 9.2 表单校验
|
||||
使用 Vant 内置的表单校验 + 自定义校验规则
|
||||
|
||||
---
|
||||
|
||||
## 10. 性能优化方案
|
||||
|
||||
### 10.1 代码分割
|
||||
- 路由懒加载
|
||||
- 组件按需导入
|
||||
- Vant 组件按需加载
|
||||
|
||||
### 10.2 资源优化
|
||||
- 图片懒加载
|
||||
- 列表虚拟滚动(大数据量)
|
||||
- 骨架屏优化首屏体验
|
||||
|
||||
### 10.3 缓存策略
|
||||
- 活动列表数据缓存
|
||||
- 用户信息缓存
|
||||
- API 请求去重
|
||||
|
||||
---
|
||||
|
||||
## 11. 移动端适配
|
||||
|
||||
### 11.1 Viewport 配置
|
||||
```html
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
```
|
||||
|
||||
### 11.2 PostCSS 配置
|
||||
```javascript
|
||||
// postcss.config.js
|
||||
module.exports = {
|
||||
plugins: {
|
||||
'postcss-pxtorem': {
|
||||
rootValue: 37.5, // Vant 官方推荐
|
||||
propList: ['*'],
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### 11.3 安全区适配
|
||||
```scss
|
||||
// 底部安全区
|
||||
.safe-area-bottom {
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. 部署方案
|
||||
|
||||
### 12.1 构建命令
|
||||
```bash
|
||||
# 开发
|
||||
npm run dev
|
||||
|
||||
# 构建
|
||||
npm run build
|
||||
|
||||
# 预览
|
||||
npm run preview
|
||||
```
|
||||
|
||||
### 12.2 环境变量
|
||||
```env
|
||||
# .env.development
|
||||
VITE_API_BASE_URL=http://localhost:8080/api/v1
|
||||
|
||||
# .env.production
|
||||
VITE_API_BASE_URL=/api/v1
|
||||
```
|
||||
|
||||
### 12.3 Nginx 配置示例
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name example.com;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# 前端路由
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# API 代理
|
||||
location /api {
|
||||
proxy_pass http://backend:8080;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 13. 项目初始化命令
|
||||
|
||||
```bash
|
||||
# 创建项目
|
||||
npm create vite@latest campus-activity-frontend -- --template vue-ts
|
||||
|
||||
# 进入目录
|
||||
cd campus-activity-frontend
|
||||
|
||||
# 安装依赖
|
||||
npm install
|
||||
|
||||
# 安装 UI 组件库
|
||||
npm install vant @vant/use
|
||||
|
||||
# 安装路由和状态管理
|
||||
npm install vue-router pinia
|
||||
|
||||
# 安装工具库
|
||||
npm install axios dayjs @vueuse/core
|
||||
|
||||
# 安装 SCSS
|
||||
npm install -D sass
|
||||
|
||||
# 安装 ESLint + Prettier
|
||||
npm install -D eslint prettier eslint-plugin-vue @typescript-eslint/eslint-plugin @typescript-eslint/parser
|
||||
|
||||
# 安装移动端适配
|
||||
npm install -D postcss-pxtorem amfe-flexible
|
||||
|
||||
# 安装二维码相关
|
||||
npm install vue-qrcode-reader qrcode
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 14. 总结
|
||||
|
||||
本前端开发计划基于后端 API 接口设计,采用 Vue 3 + TypeScript + Vant 4 技术栈,实现符合中国小程序风格的校园活动管理系统。
|
||||
|
||||
**核心特点**:
|
||||
1. 完整覆盖所有后端 API 接口
|
||||
2. 清晰的项目结构和模块划分
|
||||
3. 规范的 TypeScript 类型定义
|
||||
4. 小程序风格的 UI 设计
|
||||
5. 完善的错误处理机制
|
||||
6. 良好的移动端适配方案
|
||||
|
||||
**下一步**:
|
||||
- 制定详细的开发规范文档
|
||||
- 分解具体开发任务清单
|
||||
683
server/docs/答辩.md
Normal file
683
server/docs/答辩.md
Normal file
@@ -0,0 +1,683 @@
|
||||
# 校园活动组织与报名系统 - 答辩文档
|
||||
|
||||
## 一、整体框架结构
|
||||
|
||||
### 1.1 技术栈
|
||||
|
||||
- **后端框架**: Spring Boot 3.1.8
|
||||
- **数据库**: MySQL 8.0
|
||||
- **ORM框架**: MyBatis-Plus 3.5.5
|
||||
- **安全框架**: Spring Security + JWT
|
||||
- **API文档**: Knife4j (Swagger)
|
||||
- **工具库**: Hutool、Lombok
|
||||
- **其他**: ZXing(二维码生成)、iText(PDF生成)、EasyExcel(Excel导出)
|
||||
|
||||
### 1.2 项目结构
|
||||
|
||||
```
|
||||
server/
|
||||
├── src/main/java/com/campus/activity/
|
||||
│ ├── CampusActivityApplication.java # 启动类
|
||||
│ ├── common/ # 通用类
|
||||
│ │ ├── Result.java # 统一响应结果
|
||||
│ │ ├── PageResult.java # 分页结果
|
||||
│ │ └── ResultCode.java # 响应状态码
|
||||
│ ├── config/ # 配置类
|
||||
│ │ ├── SecurityConfig.java # Spring Security配置
|
||||
│ │ ├── CorsConfig.java # 跨域配置
|
||||
│ │ ├── Knife4jConfig.java # API文档配置
|
||||
│ │ ├── MybatisPlusConfig.java # MyBatis-Plus配置
|
||||
│ │ └── MyMetaObjectHandler.java # 自动填充处理器
|
||||
│ ├── controller/ # 控制器层
|
||||
│ │ ├── AuthController.java # 认证模块
|
||||
│ │ ├── ActivityController.java # 活动模块
|
||||
│ │ ├── RegistrationController.java # 报名模块
|
||||
│ │ ├── CheckInController.java # 签到模块
|
||||
│ │ ├── ReviewController.java # 评价模块(我负责)
|
||||
│ │ └── StatisticsController.java # 统计模块(我负责)
|
||||
│ ├── dto/ # 数据传输对象
|
||||
│ │ ├── request/ # 请求DTO
|
||||
│ │ │ ├── ReviewRequest.java # 评价请求
|
||||
│ │ │ └── ...
|
||||
│ │ └── response/ # 响应DTO
|
||||
│ │ └── ...
|
||||
│ ├── entity/ # 实体类
|
||||
│ │ ├── User.java # 用户实体
|
||||
│ │ ├── Activity.java # 活动实体
|
||||
│ │ ├── Registration.java # 报名实体
|
||||
│ │ ├── CheckIn.java # 签到实体
|
||||
│ │ └── Review.java # 评价实体
|
||||
│ ├── exception/ # 异常处理
|
||||
│ │ ├── BusinessException.java # 业务异常
|
||||
│ │ └── GlobalExceptionHandler.java # 全局异常处理器
|
||||
│ ├── mapper/ # 数据访问层
|
||||
│ │ ├── UserMapper.java
|
||||
│ │ ├── ActivityMapper.java
|
||||
│ │ ├── RegistrationMapper.java
|
||||
│ │ ├── CheckInMapper.java
|
||||
│ │ └── ReviewMapper.java # 评价Mapper(我负责)
|
||||
│ ├── security/ # 安全相关
|
||||
│ │ ├── JwtTokenProvider.java # JWT令牌提供者
|
||||
│ │ ├── JwtAuthenticationFilter.java # JWT认证过滤器
|
||||
│ │ └── UserDetailsServiceImpl.java # 用户详情服务
|
||||
│ ├── service/ # 服务层
|
||||
│ │ ├── AuthService.java
|
||||
│ │ ├── ActivityService.java
|
||||
│ │ ├── RegistrationService.java
|
||||
│ │ ├── CheckInService.java
|
||||
│ │ ├── ReviewService.java # 评价服务接口(我负责)
|
||||
│ │ └── StatisticsService.java # 统计服务接口(我负责)
|
||||
│ ├── service/impl/ # 服务实现层
|
||||
│ │ ├── AuthServiceImpl.java
|
||||
│ │ ├── ActivityServiceImpl.java
|
||||
│ │ ├── RegistrationServiceImpl.java
|
||||
│ │ ├── CheckInServiceImpl.java
|
||||
│ │ ├── ReviewServiceImpl.java # 评价服务实现(我负责)
|
||||
│ │ └── StatisticsServiceImpl.java # 统计服务实现(我负责)
|
||||
│ ├── util/ # 工具类
|
||||
│ │ ├── QrCodeUtil.java # 二维码工具
|
||||
│ │ ├── PdfUtil.java # PDF工具
|
||||
│ │ └── CsvUtil.java # CSV工具(我负责)
|
||||
│ └── vo/ # 视图对象
|
||||
│ ├── ReviewVO.java # 评价视图对象(我负责)
|
||||
│ ├── ActivityStatisticsVO.java # 活动统计视图对象(我负责)
|
||||
│ └── OverviewStatisticsVO.java # 总体统计视图对象(我负责)
|
||||
├── src/main/resources/
|
||||
│ ├── application.yml # 应用配置
|
||||
│ └── mapper/ # MyBatis XML映射文件
|
||||
│ ├── ReviewMapper.xml # 评价Mapper XML(我负责)
|
||||
│ └── ...
|
||||
└── pom.xml # Maven配置
|
||||
```
|
||||
|
||||
### 1.3 分层架构
|
||||
|
||||
系统采用经典的分层架构:
|
||||
|
||||
1. **Controller层**: 接收HTTP请求,参数校验,调用Service层,返回响应
|
||||
2. **Service层**: 业务逻辑处理,事务管理
|
||||
3. **Mapper层**: 数据库访问,使用MyBatis-Plus简化CRUD操作
|
||||
4. **Entity层**: 数据库实体映射
|
||||
5. **DTO层**: 数据传输对象,用于接口交互
|
||||
6. **VO层**: 视图对象,用于返回给前端的数据封装
|
||||
|
||||
---
|
||||
|
||||
## 二、我负责的模块
|
||||
|
||||
### 2.1 模块5.4:活动评分与评论模块
|
||||
|
||||
#### 2.1.1 功能概述
|
||||
|
||||
活动结束后,学生可对参加过的活动进行评价。每个学生对同一活动只能评价一次,管理员可查看所有评价。
|
||||
|
||||
#### 2.1.2 核心功能
|
||||
|
||||
1. **提交评价**
|
||||
- 学生对已参加的活动进行评分(1-5分)
|
||||
- 可选填写评论内容(最多500字符)
|
||||
- 每个学生对同一活动只能评价一次
|
||||
- 只有签到过的学生才能评价
|
||||
|
||||
2. **获取活动评价列表**
|
||||
- 分页查询某个活动的所有评价
|
||||
- 显示评价者信息、评分、评论内容、评价时间
|
||||
|
||||
3. **获取我的评价列表**
|
||||
- 学生查看自己的所有评价记录
|
||||
- 支持分页查询
|
||||
|
||||
#### 2.1.3 实现细节
|
||||
|
||||
**Controller层** (`ReviewController.java`):
|
||||
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/reviews")
|
||||
public class ReviewController {
|
||||
|
||||
// 提交评价
|
||||
@PostMapping
|
||||
public Result<ReviewVO> createReview(@Valid @RequestBody ReviewRequest request)
|
||||
|
||||
// 获取活动评价列表
|
||||
@GetMapping("/activity/{activityId}")
|
||||
public Result<IPage<ReviewVO>> getActivityReviews(...)
|
||||
|
||||
// 获取我的评价列表
|
||||
@GetMapping("/my")
|
||||
public Result<IPage<ReviewVO>> getMyReviews(...)
|
||||
}
|
||||
```
|
||||
|
||||
**Service层** (`ReviewServiceImpl.java`):
|
||||
|
||||
核心业务逻辑:
|
||||
1. 验证活动是否存在
|
||||
2. 检查用户是否已评价该活动(通过唯一约束)
|
||||
3. 验证用户是否已签到该活动(只有参加过的学生才能评价)
|
||||
4. 插入评价记录
|
||||
5. 返回评价详情(包含用户信息和活动信息)
|
||||
|
||||
**数据验证**:
|
||||
|
||||
```java
|
||||
@NotNull(message = "活动ID不能为空")
|
||||
private Long activityId;
|
||||
|
||||
@NotNull(message = "评分不能为空")
|
||||
@Min(value = 1, message = "评分最小为1")
|
||||
@Max(value = 5, message = "评分最大为5")
|
||||
private Integer rating;
|
||||
|
||||
@Size(max = 500, message = "评论内容不能超过500个字符")
|
||||
private String content;
|
||||
```
|
||||
|
||||
**数据库设计**:
|
||||
|
||||
```sql
|
||||
CREATE TABLE `review` (
|
||||
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
`user_id` BIGINT NOT NULL,
|
||||
`activity_id` BIGINT NOT NULL,
|
||||
`rating` TINYINT NOT NULL COMMENT '评分(1-5)',
|
||||
`content` TEXT COMMENT '评论内容',
|
||||
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME ON UPDATE CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY `uk_user_activity` (`user_id`, `activity_id`),
|
||||
FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
|
||||
FOREIGN KEY (`activity_id`) REFERENCES `activity` (`id`)
|
||||
);
|
||||
```
|
||||
|
||||
通过唯一索引 `uk_user_activity` 确保每个学生对同一活动只能评价一次。
|
||||
|
||||
**MyBatis XML映射** (`ReviewMapper.xml`):
|
||||
|
||||
```xml
|
||||
<!-- 查询活动评价列表(关联用户和活动信息) -->
|
||||
<select id="selectActivityReviews" resultType="com.campus.activity.vo.ReviewVO">
|
||||
SELECT
|
||||
r.id,
|
||||
r.user_id,
|
||||
u.name AS user_name,
|
||||
u.avatar AS user_avatar,
|
||||
r.activity_id,
|
||||
a.title AS activity_title,
|
||||
r.rating,
|
||||
r.content,
|
||||
r.created_at
|
||||
FROM review r
|
||||
LEFT JOIN user u ON r.user_id = u.id
|
||||
LEFT JOIN activity a ON r.activity_id = a.id
|
||||
WHERE r.activity_id = #{activityId}
|
||||
ORDER BY r.created_at DESC
|
||||
</select>
|
||||
```
|
||||
|
||||
#### 2.1.4 技术亮点
|
||||
|
||||
1. **数据一致性保证**: 通过数据库唯一约束和业务双重验证,确保评价的唯一性
|
||||
2. **权限控制**: 只有签到过的学生才能评价,防止虚假评价
|
||||
3. **分页查询**: 使用MyBatis-Plus的分页插件,提高大数据量查询性能
|
||||
4. **关联查询优化**: 在Mapper XML中使用LEFT JOIN一次性获取用户和活动信息,减少N+1查询问题
|
||||
5. **数据验证**: 使用Jakarta Validation进行参数校验,提高代码健壮性
|
||||
|
||||
---
|
||||
|
||||
### 2.2 模块5.5:数据统计与导出
|
||||
|
||||
#### 2.2.1 功能概述
|
||||
|
||||
系统具备基本统计能力,例如每个活动的报名人数、实际签到人数、平均评分。管理员可导出活动数据(CSV格式)。
|
||||
|
||||
#### 2.2.2 核心功能
|
||||
|
||||
1. **获取活动统计数据**
|
||||
- 报名人数(已报名+已签到)
|
||||
- 签到人数
|
||||
- 签到率(签到人数/报名人数)
|
||||
- 评价人数
|
||||
- 平均评分
|
||||
- 评分分布(1-5星各有多少人)
|
||||
|
||||
2. **导出活动数据**
|
||||
- 支持CSV格式导出
|
||||
- 包含活动基本信息、统计数据
|
||||
- 支持Excel直接打开(使用UTF-8 BOM头)
|
||||
- 文件名格式: `activity_{activityId}_statistics.csv`
|
||||
|
||||
3. **获取总体统计**
|
||||
- 总活动数
|
||||
- 总报名数
|
||||
- 总签到数
|
||||
- 总评价数
|
||||
- 全平台平均评分
|
||||
- 最近6个月的月度统计(活动和报名数量趋势)
|
||||
|
||||
#### 2.2.3 实现细节
|
||||
|
||||
**Controller层** (`StatisticsController.java`):
|
||||
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/statistics")
|
||||
public class StatisticsController {
|
||||
|
||||
// 获取活动统计数据(管理员)
|
||||
@GetMapping("/activity/{activityId}")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public Result<ActivityStatisticsVO> getActivityStatistics(@PathVariable Long activityId)
|
||||
|
||||
// 导出活动数据(管理员)
|
||||
@GetMapping("/activity/{activityId}/export")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseEntity<byte[]> exportActivityData(...)
|
||||
|
||||
// 获取总体统计(管理员)
|
||||
@GetMapping("/overview")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public Result<OverviewStatisticsVO> getOverviewStatistics()
|
||||
}
|
||||
```
|
||||
|
||||
**Service层** (`StatisticsServiceImpl.java`):
|
||||
|
||||
核心业务逻辑:
|
||||
|
||||
1. **活动统计** (`getActivityStatistics`):
|
||||
- 统计报名人数(状态为1或2的报名记录)
|
||||
- 统计签到人数
|
||||
- 计算签到率(保留两位小数)
|
||||
- 统计评价人数和平均评分(保留一位小数)
|
||||
- 计算评分分布(1-5星各有多少人)
|
||||
|
||||
2. **数据导出** (`exportActivityData`):
|
||||
- 调用 `CsvUtil` 生成CSV文件
|
||||
- 设置响应头(Content-Disposition、Content-Type)
|
||||
- 返回文件流
|
||||
|
||||
3. **总体统计** (`getOverviewStatistics`):
|
||||
- 统计全平台的活动、报名、签到、评价总数
|
||||
- 计算全平台平均评分
|
||||
- 计算最近6个月的月度统计数据
|
||||
|
||||
**CSV导出工具类** (`CsvUtil.java`):
|
||||
|
||||
核心功能:
|
||||
1. 生成UTF-8 BOM头(让Excel正确识别中文)
|
||||
2. 写入表头(活动ID、活动名称、开始时间、结束时间、活动地点、报名人数上限、报名人数、签到人数、签到率、评价人数、平均评分、1星、2星、3星、4星、5星)
|
||||
3. 写入数据行(转义特殊字符,处理逗号、引号、换行符)
|
||||
4. 支持Excel直接打开
|
||||
|
||||
```java
|
||||
// 写入BOM头,让Excel正确识别UTF-8编码
|
||||
outputStream.write(0xEF);
|
||||
outputStream.write(0xBB);
|
||||
outputStream.write(0xBF);
|
||||
|
||||
// 写入表头
|
||||
StringBuilder header = new StringBuilder();
|
||||
header.append("活动ID,活动名称,开始时间,结束时间,活动地点,报名人数上限,报名人数,签到人数,签到率,评价人数,平均评分,1星,2星,3星,4星,5星");
|
||||
outputStream.write(header.toString().getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
// CSV转义处理
|
||||
private String escapeCsv(String value) {
|
||||
if (value == null) return "";
|
||||
if (value.contains(",") || value.contains("\"") || value.contains("\n")) {
|
||||
return "\"" + value.replace("\"", "\"\"") + "\"";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
```
|
||||
|
||||
**视图对象**:
|
||||
|
||||
1. **ActivityStatisticsVO**: 活动统计数据视图对象
|
||||
- 活动ID、活动标题
|
||||
- 报名人数、签到人数、签到率
|
||||
- 评价人数、平均评分
|
||||
- 评分分布(Map<Integer, Long>)
|
||||
|
||||
2. **OverviewStatisticsVO**: 总体统计数据视图对象
|
||||
- 总活动数、总报名数、总签到数、总评价数
|
||||
- 平均评分
|
||||
- 月度统计列表(MonthlyStats内部类)
|
||||
|
||||
#### 2.2.4 技术亮点
|
||||
|
||||
1. **权限控制**: 使用 `@PreAuthorize("hasRole('ADMIN')")` 注解,确保只有管理员可以访问统计和导出功能
|
||||
2. **性能优化**:
|
||||
- 使用流式处理(Stream)计算平均评分和评分分布
|
||||
- 一次性查询所有数据,避免多次数据库访问
|
||||
3. **数据精度控制**:
|
||||
- 签到率保留两位小数
|
||||
- 平均评分保留一位小数
|
||||
4. **CSV导出优化**:
|
||||
- 添加UTF-8 BOM头,解决Excel中文乱码问题
|
||||
- 实现CSV转义处理,正确处理包含逗号、引号、换行符的数据
|
||||
- 使用ByteArrayOutputStream提高性能
|
||||
5. **月度统计算法**:
|
||||
- 动态计算最近6个月的起止时间
|
||||
- 使用DateTimeFormatter格式化月份
|
||||
- 支持跨年统计
|
||||
|
||||
---
|
||||
|
||||
## 三、答辩模拟
|
||||
|
||||
### 3.1 自我介绍
|
||||
|
||||
各位老师好,我是XXX,负责校园活动组织与报名系统的模块5.4(活动评分与评论模块)和模块5.5(数据统计与导出模块)的开发工作。
|
||||
|
||||
### 3.2 模块5.4:活动评分与评论模块
|
||||
|
||||
**老师提问**: 请介绍一下你负责的评分与评论模块的设计思路。
|
||||
|
||||
**我的回答**:
|
||||
|
||||
评分与评论模块的核心功能是让学生对已参加的活动进行评价。我在设计时考虑了以下几点:
|
||||
|
||||
1. **数据一致性**: 通过数据库唯一索引 `uk_user_activity` 确保每个学生对同一活动只能评价一次,防止重复评价。
|
||||
|
||||
2. **权限控制**: 只有签到过的学生才能评价,防止虚假评价。在 `ReviewServiceImpl.createReview` 方法中,我会先查询签到表,验证用户是否已签到该活动。
|
||||
|
||||
3. **数据验证**: 使用Jakarta Validation注解对评分和评论内容进行校验,评分必须在1-5分之间,评论内容不能超过500字符。
|
||||
|
||||
4. **分页查询**: 使用MyBatis-Plus的分页插件,支持活动评价列表和我的评价列表的分页查询,提高大数据量查询性能。
|
||||
|
||||
5. **关联查询优化**: 在 `ReviewMapper.xml` 中使用LEFT JOIN一次性获取用户和活动信息,避免N+1查询问题。
|
||||
|
||||
**老师提问**: 如何防止学生评价自己没有参加的活动?
|
||||
|
||||
**我的回答**:
|
||||
|
||||
在 `ReviewServiceImpl.createReview` 方法中,我会先查询签到表:
|
||||
|
||||
```java
|
||||
CheckIn checkIn = checkInMapper.selectOne(
|
||||
new LambdaQueryWrapper<CheckIn>()
|
||||
.eq(CheckIn::getUserId, currentUser.getId())
|
||||
.eq(CheckIn::getActivityId, request.getActivityId())
|
||||
);
|
||||
|
||||
if (checkIn == null) {
|
||||
throw new BusinessException(ResultCode.NOT_PARTICIPATED);
|
||||
}
|
||||
```
|
||||
|
||||
如果签到记录不存在,说明用户没有参加该活动,抛出业务异常,返回错误码 `NOT_PARTICIPATED`(您未参加该活动,无法评价)。
|
||||
|
||||
**老师提问**: 评分分布是如何计算的?
|
||||
|
||||
**我的回答**:
|
||||
|
||||
评分分布在统计模块中计算,使用Java Stream的 `Collectors.groupingBy` 方法:
|
||||
|
||||
```java
|
||||
Map<Integer, Long> ratingDistribution = reviews.stream()
|
||||
.collect(Collectors.groupingBy(Review::getRating, Collectors.counting()));
|
||||
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
ratingDistribution.putIfAbsent(i, 0L);
|
||||
}
|
||||
```
|
||||
|
||||
首先按评分分组统计,然后确保1-5星都有数据(没有的设为0),最后返回给前端展示。
|
||||
|
||||
### 3.3 模块5.5:数据统计与导出
|
||||
|
||||
**老师提问**: 请介绍一下统计模块的功能和实现方式。
|
||||
|
||||
**我的回答**:
|
||||
|
||||
统计模块提供三个核心功能:
|
||||
|
||||
1. **活动统计**: 统计单个活动的报名人数、签到人数、签到率、评价人数、平均评分和评分分布。
|
||||
|
||||
2. **数据导出**: 支持将活动统计数据导出为CSV格式,方便管理员进行数据分析。
|
||||
|
||||
3. **总体统计**: 统计全平台的活动、报名、签到、评价总数,以及最近6个月的月度趋势。
|
||||
|
||||
实现上,我使用了MyBatis-Plus的LambdaQueryWrapper进行条件查询,使用Java Stream进行数据聚合计算,确保查询效率和代码可读性。
|
||||
|
||||
**老师提问**: CSV导出时如何解决Excel中文乱码问题?
|
||||
|
||||
**我的回答**:
|
||||
|
||||
在 `CsvUtil.exportActivityData` 方法中,我添加了UTF-8 BOM头:
|
||||
|
||||
```java
|
||||
// 写入BOM头,让Excel正确识别UTF-8编码
|
||||
outputStream.write(0xEF);
|
||||
outputStream.write(0xBB);
|
||||
outputStream.write(0xBF);
|
||||
```
|
||||
|
||||
BOM(Byte Order Mark)是UTF-8编码的特殊标记,Excel会自动识别BOM头,从而正确显示中文字符。
|
||||
|
||||
**老师提问**: 如果数据中包含逗号、引号或换行符,如何处理?
|
||||
|
||||
**我的回答**:
|
||||
|
||||
我实现了 `escapeCsv` 方法进行CSV转义处理:
|
||||
|
||||
```java
|
||||
private String escapeCsv(String value) {
|
||||
if (value == null) return "";
|
||||
// 如果包含逗号、引号或换行符,需要用引号包裹并转义
|
||||
if (value.contains(",") || value.contains("\"") || value.contains("\n")) {
|
||||
return "\"" + value.replace("\"", "\"\"") + "\"";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
```
|
||||
|
||||
如果数据中包含逗号、引号或换行符,就用双引号包裹,并将原有的双引号替换为两个双引号(CSV标准转义方式)。
|
||||
|
||||
**老师提问**: 月度统计是如何计算的?
|
||||
|
||||
**我的回答**:
|
||||
|
||||
在 `calculateMonthlyStats` 方法中,我动态计算最近6个月的起止时间:
|
||||
|
||||
```java
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
|
||||
|
||||
for (int i = 5; i >= 0; i--) {
|
||||
LocalDateTime monthStart = now.minusMonths(i).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
|
||||
LocalDateTime monthEnd = monthStart.plusMonths(1).minusSeconds(1);
|
||||
String monthKey = monthStart.format(formatter);
|
||||
|
||||
// 统计该月的活动数和报名数
|
||||
Long activityCount = activityMapper.selectCount(
|
||||
new LambdaQueryWrapper<Activity>()
|
||||
.eq(Activity::getDeleted, 0)
|
||||
.between(Activity::getCreatedAt, monthStart, monthEnd)
|
||||
);
|
||||
|
||||
Long registrationCount = registrationMapper.selectCount(
|
||||
new LambdaQueryWrapper<Registration>()
|
||||
.eq(Registration::getStatus, 1)
|
||||
.between(Registration::getCreatedAt, monthStart, monthEnd)
|
||||
);
|
||||
|
||||
stats.add(OverviewStatisticsVO.MonthlyStats.builder()
|
||||
.month(monthKey)
|
||||
.activityCount(activityCount)
|
||||
.registrationCount(registrationCount)
|
||||
.build());
|
||||
}
|
||||
```
|
||||
|
||||
使用 `minusMonths` 方法计算过去6个月,使用 `withDayOfMonth(1)` 获取每月第一天,使用 `plusMonths(1).minusSeconds(1)` 获取每月最后一秒,然后统计该月创建的活动和报名数量。
|
||||
|
||||
### 3.4 技术难点与解决方案
|
||||
|
||||
**老师提问**: 在开发过程中遇到了哪些技术难点?你是如何解决的?
|
||||
|
||||
**我的回答**:
|
||||
|
||||
1. **CSV导出中文乱码问题**: 通过添加UTF-8 BOM头解决,让Excel正确识别中文字符。
|
||||
|
||||
2. **CSV转义问题**: 实现了 `escapeCsv` 方法,正确处理包含逗号、引号、换行符的数据,符合CSV标准。
|
||||
|
||||
3. **评分分布计算**: 使用Java Stream的 `groupingBy` 方法进行分组统计,确保代码简洁高效。
|
||||
|
||||
4. **月度统计跨年问题**: 使用 `DateTimeFormatter` 格式化月份,支持跨年统计(如2025-12到2026-01)。
|
||||
|
||||
5. **数据精度控制**: 使用 `Math.round` 方法保留指定小数位数,确保签到率保留两位小数,平均评分保留一位小数。
|
||||
|
||||
### 3.5 总结
|
||||
|
||||
**老师提问**: 总结一下你在项目中的收获。
|
||||
|
||||
**我的回答**:
|
||||
|
||||
通过参与校园活动组织与报名系统的开发,我收获了很多:
|
||||
|
||||
1. **技术能力提升**: 熟练掌握了Spring Boot、MyBatis-Plus、Spring Security等框架的使用,深入理解了分层架构设计。
|
||||
|
||||
2. **业务理解能力**: 通过需求分析和数据库设计,提升了业务理解和抽象能力。
|
||||
|
||||
3. **问题解决能力**: 在开发过程中遇到了CSV导出、数据统计等技术难点,通过查阅文档和调试,成功解决了这些问题。
|
||||
|
||||
4. **团队协作能力**: 与团队成员密切配合,共同完成了系统的开发和测试工作。
|
||||
|
||||
5. **文档编写能力**: 编写了详细的API文档和答辩文档,提升了文档编写能力。
|
||||
|
||||
这次项目开发让我对软件工程有了更深入的理解,也为我今后的学习和工作打下了坚实的基础。
|
||||
|
||||
---
|
||||
|
||||
## 四、项目演示
|
||||
|
||||
### 4.1 API文档访问
|
||||
|
||||
系统使用Knife4j生成API文档,访问地址:`http://localhost:8080/doc.html`
|
||||
|
||||
### 4.2 模块5.4 API接口
|
||||
|
||||
1. **提交评价**
|
||||
- 接口: `POST /api/v1/reviews`
|
||||
- 权限: 需要认证
|
||||
- 请求体:
|
||||
```json
|
||||
{
|
||||
"activityId": 1,
|
||||
"rating": 5,
|
||||
"content": "非常精彩的活动!"
|
||||
}
|
||||
```
|
||||
|
||||
2. **获取活动评价列表**
|
||||
- 接口: `GET /api/v1/reviews/activity/{activityId}`
|
||||
- 权限: 公开
|
||||
- 参数: current, size
|
||||
|
||||
3. **获取我的评价列表**
|
||||
- 接口: `GET /api/v1/reviews/my`
|
||||
- 权限: 需要认证
|
||||
- 参数: current, size
|
||||
|
||||
### 4.3 模块5.5 API接口
|
||||
|
||||
1. **获取活动统计数据**
|
||||
- 接口: `GET /api/v1/statistics/activity/{activityId}`
|
||||
- 权限: 管理员
|
||||
|
||||
2. **导出活动数据**
|
||||
- 接口: `GET /api/v1/statistics/activity/{activityId}/export`
|
||||
- 权限: 管理员
|
||||
- 参数: format (csv)
|
||||
|
||||
3. **获取总体统计**
|
||||
- 接口: `GET /api/v1/statistics/overview`
|
||||
- 权限: 管理员
|
||||
|
||||
---
|
||||
|
||||
## 五、数据库表结构
|
||||
|
||||
### 5.1 评价表 (review)
|
||||
|
||||
| 字段名 | 类型 | 约束 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| id | BIGINT | PK, AUTO_INCREMENT | 评价ID |
|
||||
| user_id | BIGINT | FK, NOT NULL | 用户ID |
|
||||
| activity_id | BIGINT | FK, NOT NULL | 活动ID |
|
||||
| rating | TINYINT | NOT NULL | 评分(1-5) |
|
||||
| content | TEXT | | 评论内容 |
|
||||
| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | 评价时间 |
|
||||
| updated_at | DATETIME | ON UPDATE CURRENT_TIMESTAMP | 更新时间 |
|
||||
|
||||
**索引**:
|
||||
- `uk_user_activity` (user_id, activity_id) UNIQUE - 确保每个学生对同一活动只能评价一次
|
||||
- `idx_activity_id` (activity_id)
|
||||
|
||||
### 5.2 关联表
|
||||
|
||||
- **user**: 用户表
|
||||
- **activity**: 活动表
|
||||
- **registration**: 报名表
|
||||
- **check_in**: 签到表
|
||||
|
||||
---
|
||||
|
||||
## 六、核心代码位置
|
||||
|
||||
### 6.1 模块5.4(评价模块)
|
||||
|
||||
- Controller: `src/main/java/com/campus/activity/controller/ReviewController.java`
|
||||
- Service接口: `src/main/java/com/campus/activity/service/ReviewService.java`
|
||||
- Service实现: `src/main/java/com/campus/activity/service/impl/ReviewServiceImpl.java`
|
||||
- Mapper接口: `src/main/java/com/campus/activity/mapper/ReviewMapper.java`
|
||||
- Mapper XML: `src/main/resources/mapper/ReviewMapper.xml`
|
||||
- Entity: `src/main/java/com/campus/activity/entity/Review.java`
|
||||
- VO: `src/main/java/com/campus/activity/vo/ReviewVO.java`
|
||||
- Request DTO: `src/main/java/com/campus/activity/dto/request/ReviewRequest.java`
|
||||
|
||||
### 6.2 模块5.5(统计模块)
|
||||
|
||||
- Controller: `src/main/java/com/campus/activity/controller/StatisticsController.java`
|
||||
- Service接口: `src/main/java/com/campus/activity/service/StatisticsService.java`
|
||||
- Service实现: `src/main/java/com/campus/activity/service/impl/StatisticsServiceImpl.java`
|
||||
- VO: `src/main/java/com/campus/activity/vo/ActivityStatisticsVO.java`
|
||||
- VO: `src/main/java/com/campus/activity/vo/OverviewStatisticsVO.java`
|
||||
- Util: `src/main/java/com/campus/activity/util/CsvUtil.java`
|
||||
|
||||
---
|
||||
|
||||
## 七、测试建议
|
||||
|
||||
### 7.1 评价模块测试
|
||||
|
||||
1. **正常评价**: 学生对已参加的活动进行评价,验证评价成功
|
||||
2. **重复评价**: 同一学生对同一活动再次评价,验证返回错误
|
||||
3. **未参加评价**: 学生对未参加的活动进行评价,验证返回错误
|
||||
4. **评分边界测试**: 测试评分为1和5的情况
|
||||
5. **评论长度测试**: 测试评论内容超过500字符的情况
|
||||
6. **分页查询**: 测试活动评价列表和我的评价列表的分页功能
|
||||
|
||||
### 7.2 统计模块测试
|
||||
|
||||
1. **活动统计**: 验证报名人数、签到人数、签到率、平均评分计算正确
|
||||
2. **评分分布**: 验证1-5星分布统计正确
|
||||
3. **数据导出**: 验证CSV文件生成正确,Excel可以打开
|
||||
4. **中文乱码**: 验证CSV文件中文显示正常
|
||||
5. **总体统计**: 验证全平台统计数据正确
|
||||
6. **月度统计**: 验证最近6个月统计数据正确,支持跨年
|
||||
|
||||
---
|
||||
|
||||
## 八、总结
|
||||
|
||||
本次答辩文档详细介绍了校园活动组织与报名系统的整体框架结构,以及我负责的模块5.4(活动评分与评论模块)和模块5.5(数据统计与导出模块)的设计与实现。
|
||||
|
||||
在开发过程中,我深入理解了Spring Boot、MyBatis-Plus、Spring Security等框架的使用,掌握了分层架构设计、数据验证、权限控制、CSV导出等技术,提升了自己的技术能力和问题解决能力。
|
||||
|
||||
通过本次项目开发,我对软件工程有了更深入的理解,也为我今后的学习和工作打下了坚实的基础。
|
||||
|
||||
谢谢各位老师!
|
||||
3979
server/docs/软件设计说明书.md
Normal file
3979
server/docs/软件设计说明书.md
Normal file
File diff suppressed because it is too large
Load Diff
BIN
server/docs/软件需求分析说明书.docx
Normal file
BIN
server/docs/软件需求分析说明书.docx
Normal file
Binary file not shown.
@@ -29,7 +29,7 @@ public class CsvUtil {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
|
||||
try {
|
||||
// 写入BOM头,让Excel正确识别UTF-8编码
|
||||
// 写入BOM头,正确识别UTF-8编码
|
||||
outputStream.write(0xEF);
|
||||
outputStream.write(0xBB);
|
||||
outputStream.write(0xBF);
|
||||
|
||||
1208
web/docs/API接口设计.md
Normal file
1208
web/docs/API接口设计.md
Normal file
File diff suppressed because it is too large
Load Diff
106
web/docs/init.sql
Normal file
106
web/docs/init.sql
Normal file
@@ -0,0 +1,106 @@
|
||||
-- 创建数据库
|
||||
CREATE DATABASE IF NOT EXISTS `campus_activity`
|
||||
DEFAULT CHARACTER SET utf8mb4
|
||||
COLLATE utf8mb4_general_ci;
|
||||
|
||||
USE `campus_activity`;
|
||||
|
||||
-- 创建用户表
|
||||
CREATE TABLE `user` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '用户ID',
|
||||
`username` VARCHAR(50) NOT NULL COMMENT '登录用户名',
|
||||
`password` VARCHAR(255) NOT NULL COMMENT '密码',
|
||||
`name` VARCHAR(50) NOT NULL COMMENT '真实姓名',
|
||||
`student_id` VARCHAR(20) DEFAULT NULL COMMENT '学号',
|
||||
`email` VARCHAR(100) DEFAULT NULL COMMENT '邮箱',
|
||||
`phone` VARCHAR(20) DEFAULT NULL COMMENT '手机号',
|
||||
`avatar` VARCHAR(255) DEFAULT NULL COMMENT '头像URL',
|
||||
`role` TINYINT NOT NULL DEFAULT 0 COMMENT '角色:0-学生,1-管理员',
|
||||
`status` TINYINT DEFAULT 1 COMMENT '状态:0-禁用,1-正常',
|
||||
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` TINYINT DEFAULT 0 COMMENT '逻辑删除',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_username` (`username`),
|
||||
UNIQUE KEY `uk_student_id` (`student_id`),
|
||||
KEY `idx_role` (`role`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户表';
|
||||
|
||||
-- 创建活动表
|
||||
CREATE TABLE `activity` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '活动ID',
|
||||
`title` VARCHAR(100) NOT NULL COMMENT '活动名称',
|
||||
`description` TEXT DEFAULT NULL COMMENT '活动简介',
|
||||
`cover_image` VARCHAR(255) DEFAULT NULL COMMENT '封面图片',
|
||||
`start_time` DATETIME NOT NULL COMMENT '开始时间',
|
||||
`end_time` DATETIME NOT NULL COMMENT '结束时间',
|
||||
`registration_deadline` DATETIME DEFAULT NULL COMMENT '报名截止时间',
|
||||
`location` VARCHAR(200) NOT NULL COMMENT '活动地点',
|
||||
`max_participants` INT NOT NULL COMMENT '报名人数上限',
|
||||
`current_participants` INT DEFAULT 0 COMMENT '当前报名人数',
|
||||
`status` TINYINT DEFAULT 0 COMMENT '状态:0-未开始,1-报名中,2-进行中,3-已结束',
|
||||
`category` VARCHAR(50) DEFAULT NULL COMMENT '活动分类',
|
||||
`admin_id` BIGINT NOT NULL COMMENT '创建者ID',
|
||||
`qr_code` VARCHAR(255) DEFAULT NULL COMMENT '签到二维码',
|
||||
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` TINYINT DEFAULT 0 COMMENT '逻辑删除',
|
||||
`version` INT DEFAULT 0 COMMENT '乐观锁版本号',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_start_time` (`start_time`),
|
||||
KEY `idx_admin_id` (`admin_id`),
|
||||
CONSTRAINT `fk_activity_admin` FOREIGN KEY (`admin_id`) REFERENCES `user` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='活动表';
|
||||
|
||||
-- 创建报名表
|
||||
CREATE TABLE `registration` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '报名ID',
|
||||
`user_id` BIGINT NOT NULL COMMENT '用户ID',
|
||||
`activity_id` BIGINT NOT NULL COMMENT '活动ID',
|
||||
`ticket_code` VARCHAR(100) DEFAULT NULL COMMENT '电子票唯一码',
|
||||
`ticket_pdf_url` VARCHAR(255) DEFAULT NULL COMMENT '电子票PDF地址',
|
||||
`status` TINYINT DEFAULT 1 COMMENT '状态:0-已取消,1-已报名,2-已签到',
|
||||
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '报名时间',
|
||||
`updated_at` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`canceled_at` DATETIME DEFAULT NULL COMMENT '取消时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_user_activity` (`user_id`, `activity_id`),
|
||||
UNIQUE KEY `uk_ticket_code` (`ticket_code`),
|
||||
KEY `idx_activity_id` (`activity_id`),
|
||||
CONSTRAINT `fk_registration_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
|
||||
CONSTRAINT `fk_registration_activity` FOREIGN KEY (`activity_id`) REFERENCES `activity` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='报名表';
|
||||
|
||||
-- 创建签到表
|
||||
CREATE TABLE `check_in` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '签到ID',
|
||||
`registration_id` BIGINT NOT NULL COMMENT '报名ID',
|
||||
`user_id` BIGINT NOT NULL COMMENT '用户ID',
|
||||
`activity_id` BIGINT NOT NULL COMMENT '活动ID',
|
||||
`check_in_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '签到时间',
|
||||
`check_in_method` TINYINT DEFAULT 0 COMMENT '签到方式:0-扫码,1-管理员代签',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_registration_id` (`registration_id`),
|
||||
KEY `idx_activity_id` (`activity_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
CONSTRAINT `fk_checkin_registration` FOREIGN KEY (`registration_id`) REFERENCES `registration` (`id`),
|
||||
CONSTRAINT `fk_checkin_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
|
||||
CONSTRAINT `fk_checkin_activity` FOREIGN KEY (`activity_id`) REFERENCES `activity` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='签到表';
|
||||
|
||||
-- 创建评价表
|
||||
CREATE TABLE `review` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '评价ID',
|
||||
`user_id` BIGINT NOT NULL COMMENT '用户ID',
|
||||
`activity_id` BIGINT NOT NULL COMMENT '活动ID',
|
||||
`rating` TINYINT NOT NULL COMMENT '评分(1-5)',
|
||||
`content` TEXT DEFAULT NULL COMMENT '评论内容',
|
||||
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '评价时间',
|
||||
`updated_at` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_user_activity` (`user_id`, `activity_id`),
|
||||
KEY `idx_activity_id` (`activity_id`),
|
||||
CONSTRAINT `fk_review_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
|
||||
CONSTRAINT `fk_review_activity` FOREIGN KEY (`activity_id`) REFERENCES `activity` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='评价表';
|
||||
107
web/docs/需求文档.md
Normal file
107
web/docs/需求文档.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# 校园活动组织与报名系统 - 需求文档
|
||||
|
||||
## 1. 课程信息
|
||||
|
||||
- **课程名称**: 校园活动组织与报名系统
|
||||
- **课题来源**: 教师自拟
|
||||
- **课题类型**: 综合型
|
||||
- **完成时间**: 2025年X月X日
|
||||
- **课题分组**: 2-3人一组
|
||||
|
||||
## 2. 目的和意义
|
||||
|
||||
1. 软件工程方法的综合运用能力
|
||||
2. Java语言解决实际问题的能力
|
||||
3. 数据库设计与系统集成能力
|
||||
4. 规范化文档编写能力
|
||||
|
||||
## 3. 需求概要
|
||||
|
||||
系统面向校园内的活动组织与参与场景,实现活动从发布 → 报名 → 签到 → 评价 → 统计分析的一体化管理。
|
||||
|
||||
## 4. 用户角色说明
|
||||
|
||||
### 4.1 普通学生用户
|
||||
- 浏览活动
|
||||
- 报名/取消报名
|
||||
- 签到
|
||||
- 对活动进行评分与评论
|
||||
|
||||
### 4.2 活动管理员
|
||||
- 发布活动
|
||||
- 管理报名信息
|
||||
- 查看签到与评价
|
||||
- 导出活动数据
|
||||
|
||||
## 5. 功能模块
|
||||
|
||||
### 5.1 活动发布与管理模块
|
||||
|
||||
管理员可以创建并管理校园活动,至少包含以下信息:
|
||||
- 活动名称
|
||||
- 活动简介
|
||||
- 活动时间(开始时间、结束时间)
|
||||
- 活动地点
|
||||
- 报名人数上限
|
||||
- 活动状态(未开始/报名中/已结束)
|
||||
|
||||
**功能列表**:
|
||||
- 新增活动
|
||||
- 修改活动信息
|
||||
- 删除活动(或逻辑删除)
|
||||
- 查询活动列表(按时间或状态)
|
||||
- 以日历形式展示活动
|
||||
- 检测活动时间冲突并提示
|
||||
|
||||
### 5.2 报名与取消报名模块
|
||||
|
||||
学生可以对活动进行报名和取消报名操作。
|
||||
|
||||
**功能列表**:
|
||||
- 学生报名活动,报名成功后自动生成电子票(PDF),包含活动信息、学生姓名、二维码
|
||||
- 系统检查:
|
||||
- 是否已报名
|
||||
- 是否时间冲突
|
||||
- 是否超过人数上限
|
||||
- 学生取消报名(活动未开始前)
|
||||
|
||||
### 5.3 签到管理(二维码)模块
|
||||
|
||||
系统需支持活动签到功能。
|
||||
|
||||
**功能列表**:
|
||||
- 管理员为某个活动生成签到二维码
|
||||
- 学生通过"扫码"或者管理员扫学生电子票完成签到
|
||||
- 系统记录签到时间
|
||||
|
||||
### 5.4 活动评分与评论模块
|
||||
|
||||
活动结束后,学生可对参加过的活动进行评价。
|
||||
|
||||
**功能列表**:
|
||||
- 评分(如1-5分)
|
||||
- 评论内容
|
||||
- 每个学生对同一活动只能评价一次
|
||||
- 管理员可查看所有评价
|
||||
|
||||
### 5.5 数据统计与导出
|
||||
|
||||
系统需具备基本统计能力,例如每个活动的报名人数、实际签到人数、平均评分。管理员可导出活动数据(如CSV或Excel)。
|
||||
|
||||
## 6. 提交成果
|
||||
|
||||
### 6.1 文档
|
||||
包括软件需求分析说明书、软件设计说明书、软件使用手册。
|
||||
|
||||
### 6.2 作品
|
||||
可以采用基于Java桌面应用(Swing/JavaFX)、前后端分离系统(后端Java)。
|
||||
|
||||
## 7. 评分标准
|
||||
|
||||
1. **功能完整性**: 50%
|
||||
2. **数据库设计**: 20%
|
||||
3. **软件文档规范性**: 30%
|
||||
|
||||
## 8. 答辩要求
|
||||
|
||||
答辩时交付纸质软件过程文档(每组1份)。
|
||||
@@ -30,7 +30,7 @@
|
||||
<van-cell-group class="menu-group" inset v-if="authStore.isLoggedIn">
|
||||
<van-cell title="我的报名" is-link to="/registrations/my" />
|
||||
<van-cell title="我的评价" is-link to="/reviews/my" />
|
||||
<van-cell title="修改密码" is-link to="/auth/password" />
|
||||
<!-- <van-cell title="修改密码" is-link to="/auth/password" /> -->
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group class="menu-group" inset v-if="user?.role === 1">
|
||||
|
||||
Reference in New Issue
Block a user