47 KiB
47 KiB
校园活动系统 - 业务流程图
系统架构概览
本系统采用典型的分层架构,包含以下层次:
- 表现层(Controller层):处理HTTP请求和响应
- 业务逻辑层(Service层):实现核心业务逻辑
- 数据访问层(Mapper层):与数据库交互
- 实体层(Entity层):数据模型定义
- 安全层(Security层):JWT认证和授权
1. 用户认证流程
sequenceDiagram
autonumber
participant Client as 客户端
participant Controller as AuthController<br/>认证控制器
participant Service as AuthServiceImpl<br/>认证服务
participant Security as SecurityConfig<br/>安全配置
participant JwtProvider as JwtTokenProvider<br/>JWT令牌提供者
participant Mapper as UserMapper<br/>用户数据访问
participant DB as MySQL数据库
Note over Client,DB: 1. 用户注册流程
Client->>Controller: POST /api/v1/auth/register<br/>RegisterRequest
Controller->>Service: register(request)
Service->>Mapper: 检查用户名是否存在<br/>selectCount(username)
Mapper->>DB: SELECT COUNT(*) FROM user<br/>WHERE username = ?
DB-->>Mapper: 返回数量
Mapper-->>Service: 返回数量
alt 用户名已存在
Service-->>Controller: 抛出异常<br/>USER_ALREADY_EXISTS
Controller-->>Client: 400 错误
else 用户名不存在
Service->>Mapper: 检查学号是否存在<br/>selectCount(studentId)
Mapper->>DB: SELECT COUNT(*) FROM user<br/>WHERE student_id = ?
DB-->>Mapper: 返回数量
Mapper-->>Service: 返回数量
alt 学号已存在
Service-->>Controller: 抛出异常<br/>STUDENT_ID_ALREADY_EXISTS
Controller-->>Client: 400 错误
else 学号不存在
Service->>Service: 创建用户对象<br/>passwordEncoder.encode()
Service->>Mapper: insert(user)
Mapper->>DB: INSERT INTO user(...)
DB-->>Mapper: 返回插入ID
Mapper-->>Service: 返回结果
Service-->>Controller: 注册成功
Controller-->>Client: 200 成功
end
end
Note over Client,DB: 2. 用户登录流程
Client->>Controller: POST /api/v1/auth/login<br/>LoginRequest
Controller->>Security: authenticationManager.authenticate()
Security->>Mapper: 加载用户信息<br/>loadUserByUsername()
Mapper->>DB: SELECT * FROM user<br/>WHERE username = ?
DB-->>Mapper: 返回用户信息
Mapper-->>Security: 返回UserDetails
Security->>Security: 验证密码<br/>passwordEncoder.matches()
alt 密码错误
Security-->>Controller: 抛出异常
Controller-->>Client: 401 未授权
else 密码正确
Security-->>Controller: 认证成功
Controller->>Service: login(request)
Service->>Mapper: 查询用户<br/>selectById(username)
Mapper->>DB: SELECT * FROM user<br/>WHERE username = ?
DB-->>Mapper: 返回用户信息
Mapper-->>Service: 返回User对象
Service->>JwtProvider: generateToken(userId, username, role)
JwtProvider-->>Service: 返回accessToken
Service->>JwtProvider: generateRefreshToken(userId)
JwtProvider-->>Service: 返回refreshToken
Service-->>Controller: 返回LoginResponse
Controller-->>Client: 200 成功<br/>(包含accessToken和refreshToken)
end
Note over Client,DB: 3. Token刷新流程
Client->>Controller: POST /api/v1/auth/refresh<br/>RefreshTokenRequest
Controller->>Service: refreshToken(request)
Service->>JwtProvider: validateToken(refreshToken)
JwtProvider-->>Service: 返回验证结果
alt Token无效
Service-->>Controller: 抛出异常<br/>UNAUTHORIZED
Controller-->>Client: 401 未授权
else Token有效
Service->>JwtProvider: getUsernameFromToken(refreshToken)
JwtProvider-->>Service: 返回userId
Service->>Mapper: selectById(userId)
Mapper->>DB: SELECT * FROM user<br/>WHERE id = ?
DB-->>Mapper: 返回用户信息
Mapper-->>Service: 返回User对象
Service->>JwtProvider: generateToken(userId, username, role)
JwtProvider-->>Service: 返回新accessToken
Service-->>Controller: 返回RefreshTokenResponse
Controller-->>Client: 200 成功
end
Note over Client,DB: 4. 获取当前用户信息
Client->>Controller: GET /api/v1/auth/me<br/>Header: Authorization: Bearer token
Controller->>Security: JwtAuthenticationFilter<br/>验证token
Security->>JwtProvider: validateToken(accessToken)
JwtProvider-->>Security: 验证通过
Security->>Security: 设置SecurityContext
Controller->>Service: getCurrentUser()
Service->>Mapper: selectById(userId)
Mapper->>DB: SELECT * FROM user<br/>WHERE id = ?
DB-->>Mapper: 返回用户信息
Mapper-->>Service: 返回User对象
Service-->>Controller: 返回用户信息
Controller-->>Client: 200 成功
2. 活动管理流程
sequenceDiagram
autonumber
participant Client as 客户端
participant Controller as ActivityController<br/>活动控制器
participant Service as ActivityServiceImpl<br/>活动服务
participant Mapper as ActivityMapper<br/>活动数据访问
participant RegMapper as RegistrationMapper<br/>报名数据访问
participant UserMapper as UserMapper<br/>用户数据访问
participant Auth as AuthService<br/>认证服务
participant DB as MySQL数据库
Note over Client,DB: 1. 获取活动列表
Client->>Controller: GET /api/v1/activities<br/>(current, size, status, keyword, category, startDate, endDate)
Controller->>Service: pageActivities(page, params)
Service->>Mapper: selectActivityPage(page, params)
Mapper->>DB: SELECT * FROM activity<br/>WHERE conditions<br/>LIMIT offset, size
DB-->>Mapper: 返回活动列表
Mapper-->>Service: 返回IPage<Activity>
Service->>Service: 转换为ActivityVO列表<br/>convertToVO()
Service-->>Controller: 返回IPage<ActivityVO>
Controller-->>Client: 200 成功
Note over Client,DB: 2. 获取活动详情
Client->>Controller: GET /api/v1/activities/{id}
Controller->>Service: getActivityById(id)
Service->>Mapper: selectById(id)
Mapper->>DB: SELECT * FROM activity<br/>WHERE id = ?
DB-->>Mapper: 返回活动信息
Mapper-->>Service: 返回Activity对象
Service->>UserMapper: selectById(adminId)
UserMapper->>DB: SELECT * FROM user<br/>WHERE id = ?
DB-->>UserMapper: 返回管理员信息
UserMapper-->>Service: 返回User对象
alt 用户已登录
Service->>Auth: getCurrentUser()
Auth-->>Service: 返回当前用户
Service->>RegMapper: 检查是否已报名<br/>selectOne(userId, activityId)
RegMapper->>DB: SELECT * FROM registration<br/>WHERE user_id = ? AND activity_id = ?
DB-->>RegMapper: 返回报名记录
RegMapper-->>Service: 返回Registration对象
end
Service->>Service: 转换为ActivityVO<br/>convertToVO()
Service-->>Controller: 返回ActivityVO
Controller-->>Client: 200 成功
Note over Client,DB: 3. 创建活动(管理员)
Client->>Controller: POST /api/v1/activities<br/>ActivityCreateRequest<br/>Header: Authorization: Bearer token
Controller->>Service: createActivity(request)
Service->>Auth: getCurrentUser()
Auth-->>Service: 返回当前用户
alt 用户不是管理员
Service-->>Controller: 抛出异常<br/>FORBIDDEN
Controller-->>Client: 403 禁止访问
else 用户是管理员
Service->>Service: 验证时间参数
alt 开始时间晚于结束时间
Service-->>Controller: 抛出异常<br/>BAD_REQUEST
Controller-->>Client: 400 错误
else 时间参数正确
Service->>Service: checkConflict(startTime, endTime)
Service->>Mapper: selectConflictActivities(startTime, endTime)
Mapper->>DB: SELECT * FROM activity<br/>WHERE time_conflict
DB-->>Mapper: 返回冲突活动列表
Mapper-->>Service: 返回冲突活动
alt 存在时间冲突
Service-->>Controller: 抛出异常<br/>ACTIVITY_TIME_CONFLICT
Controller-->>Client: 409 冲突
else 无冲突
Service->>Service: 创建Activity对象
Service->>Mapper: insert(activity)
Mapper->>DB: INSERT INTO activity(...)
DB-->>Mapper: 返回插入ID
Mapper-->>Service: 返回activityId
Service-->>Controller: 返回activityId
Controller-->>Client: 200 成功
end
end
end
Note over Client,DB: 4. 更新活动(管理员)
Client->>Controller: PUT /api/v1/activities/{id}<br/>ActivityUpdateRequest<br/>Header: Authorization: Bearer token
Controller->>Service: updateActivity(id, request)
Service->>Auth: getCurrentUser()
Auth-->>Service: 返回当前用户
alt 用户不是管理员
Service-->>Controller: 抛出异常<br/>FORBIDDEN
Controller-->>Client: 403 禁止访问
else 用户是管理员
Service->>Mapper: selectById(id)
Mapper->>DB: SELECT * FROM activity<br/>WHERE id = ?
DB-->>Mapper: 返回活动信息
Mapper-->>Service: 返回Activity对象
alt 活动不存在或已删除
Service-->>Controller: 抛出异常<br/>ACTIVITY_NOT_FOUND
Controller-->>Client: 404 未找到
else 活动存在
alt 不是活动创建者
Service-->>Controller: 抛出异常<br/>FORBIDDEN
Controller-->>Client: 403 禁止访问
else 是活动创建者
Service->>Service: 验证时间参数
Service->>Service: checkConflict(startTime, endTime, excludeActivityId)
Service->>Mapper: selectConflictActivities(startTime, endTime, excludeActivityId)
Mapper->>DB: SELECT * FROM activity<br/>WHERE time_conflict AND id != ?
DB-->>Mapper: 返回冲突活动列表
Mapper-->>Service: 返回冲突活动
alt 存在时间冲突
Service-->>Controller: 抛出异常<br/>ACTIVITY_TIME_CONFLICT
Controller-->>Client: 409 冲突
else 无冲突
Service->>Service: 更新Activity对象
Service->>Mapper: updateById(activity)
Mapper->>DB: UPDATE activity SET ...<br/>WHERE id = ?
DB-->>Mapper: 返回更新结果
Mapper-->>Service: 返回成功
Service-->>Controller: 更新成功
Controller-->>Client: 200 成功
end
end
end
end
Note over Client,DB: 5. 删除活动(管理员)
Client->>Controller: DELETE /api/v1/activities/{id}<br/>Header: Authorization: Bearer token
Controller->>Service: deleteActivity(id)
Service->>Auth: getCurrentUser()
Auth-->>Service: 返回当前用户
alt 用户不是管理员
Service-->>Controller: 抛出异常<br/>FORBIDDEN
Controller-->>Client: 403 禁止访问
else 用户是管理员
Service->>Mapper: selectById(id)
Mapper->>DB: SELECT * FROM activity<br/>WHERE id = ?
DB-->>Mapper: 返回活动信息
Mapper-->>Service: 返回Activity对象
alt 活动不存在或已删除
Service-->>Controller: 抛出异常<br/>ACTIVITY_NOT_FOUND
Controller-->>Client: 404 未找到
else 活动存在
alt 不是活动创建者
Service-->>Controller: 抛出异常<br/>FORBIDDEN
Controller-->>Client: 403 禁止访问
else 是活动创建者
Service->>Mapper: deleteById(id)
Mapper->>DB: UPDATE activity SET deleted = 1<br/>WHERE id = ?
DB-->>Mapper: 返回删除结果
Mapper-->>Service: 返回成功
Service-->>Controller: 删除成功
Controller-->>Client: 200 成功
end
end
end
Note over Client,DB: 6. 检测时间冲突(管理员)
Client->>Controller: POST /api/v1/activities/check-conflict<br/>CheckConflictRequest<br/>Header: Authorization: Bearer token
Controller->>Service: checkConflict(request)
Service->>Service: 验证时间参数
Service->>Mapper: selectConflictActivities(startTime, endTime, excludeActivityId)
Mapper->>DB: SELECT * FROM activity<br/>WHERE time_conflict AND id != ?
DB-->>Mapper: 返回冲突活动列表
Mapper-->>Service: 返回冲突活动
Service->>Service: 构建ConflictCheckVO
Service-->>Controller: 返回ConflictCheckVO
Controller-->>Client: 200 成功
3. 活动报名流程
sequenceDiagram
autonumber
participant Client as 客户端
participant Controller as RegistrationController<br/>报名控制器
participant Service as RegistrationServiceImpl<br/>报名服务
participant Mapper as RegistrationMapper<br/>报名数据访问
participant ActMapper as ActivityMapper<br/>活动数据访问
participant Auth as AuthService<br/>认证服务
participant PdfUtil as PdfUtil<br/>PDF工具类
participant DB as MySQL数据库
Note over Client,DB: 1. 报名活动
Client->>Controller: POST /api/v1/registrations<br/>RegistrationRequest<br/>Header: Authorization: Bearer token
Controller->>Service: register(request)
Service->>Auth: getCurrentUser()
Auth-->>Service: 返回当前用户
Service->>ActMapper: selectById(activityId)
ActMapper->>DB: SELECT * FROM activity<br/>WHERE id = ?
DB-->>ActMapper: 返回活动信息
ActMapper-->>Service: 返回Activity对象
alt 活动不存在或已删除
Service-->>Controller: 抛出异常<br/>ACTIVITY_NOT_FOUND
Controller-->>Client: 404 未找到
else 活动存在
alt 活动不在报名中
Service-->>Controller: 抛出异常<br/>BAD_REQUEST
Controller-->>Client: 400 错误
else 活动在报名中
alt 报名已截止
Service-->>Controller: 抛出异常<br/>BAD_REQUEST
Controller-->>Client: 400 错误
else 报名未截止
alt 报名人数已满
Service-->>Controller: 抛出异常<br/>ACTIVITY_FULL
Controller-->>Client: 409 冲突
else 报名未满
Service->>Mapper: 检查是否已报名<br/>selectOne(userId, activityId)
Mapper->>DB: SELECT * FROM registration<br/>WHERE user_id = ? AND activity_id = ?<br/>AND status IN (1, 2)
DB-->>Mapper: 返回报名记录
Mapper-->>Service: 返回Registration对象
alt 已报名该活动
Service-->>Controller: 抛出异常<br/>ALREADY_REGISTERED
Controller-->>Client: 409 冲突
else 未报名该活动
Service->>Mapper: 查询用户所有报名<br/>selectList(userId, status=1)
Mapper->>DB: SELECT * FROM registration<br/>WHERE user_id = ? AND status = 1
DB-->>Mapper: 返回报名列表
Mapper-->>Service: 返回List<Registration>
loop 遍历报名列表
Service->>ActMapper: selectById(reg.activityId)
ActMapper->>DB: SELECT * FROM activity<br/>WHERE id = ?
DB-->>ActMapper: 返回活动信息
ActMapper-->>Service: 返回Activity对象
Service->>Service: isTimeConflict(activity1, activity2)
alt 存在时间冲突
Service-->>Controller: 抛出异常<br/>ACTIVITY_TIME_CONFLICT
Controller-->>Client: 409 冲突
end
end
Service->>Service: 创建Registration对象<br/>generateTicketCode()
Service->>Mapper: insert(registration)
Mapper->>DB: INSERT INTO registration(...)
DB-->>Mapper: 返回插入ID
Mapper-->>Service: 返回registrationId
Service->>ActMapper: 更新活动报名人数<br/>updateById(activity)
ActMapper->>DB: UPDATE activity SET<br/>current_participants = current_participants + 1<br/>WHERE id = ?
DB-->>ActMapper: 返回更新结果
ActMapper-->>Service: 返回成功
Service->>Service: convertToVO()
Service-->>Controller: 返回RegistrationVO
Controller-->>Client: 200 成功
end
end
end
end
end
Note over Client,DB: 2. 取消报名
Client->>Controller: DELETE /api/v1/registrations/{id}<br/>Header: Authorization: Bearer token
Controller->>Service: cancelRegistration(id)
Service->>Auth: getCurrentUser()
Auth-->>Service: 返回当前用户
Service->>Mapper: selectById(id)
Mapper->>DB: SELECT * FROM registration<br/>WHERE id = ?
DB-->>Mapper: 返回报名记录
Mapper-->>Service: 返回Registration对象
alt 报名记录不存在
Service-->>Controller: 抛出异常<br/>REGISTRATION_NOT_FOUND
Controller-->>Client: 404 未找到
else 报名记录存在
alt 不是自己的报名
Service-->>Controller: 抛出异常<br/>FORBIDDEN
Controller-->>Client: 403 禁止访问
else 是自己的报名
alt 报名状态不是已报名
Service-->>Controller: 抛出异常<br/>BAD_REQUEST
Controller-->>Client: 400 错误
else 报名状态是已报名
Service->>ActMapper: selectById(activityId)
ActMapper->>DB: SELECT * FROM activity<br/>WHERE id = ?
DB-->>ActMapper: 返回活动信息
ActMapper-->>Service: 返回Activity对象
alt 活动已开始
Service-->>Controller: 抛出异常<br/>ACTIVITY_ALREADY_STARTED
Controller-->>Client: 409 冲突
else 活动未开始
Service->>Mapper: 更新报名状态<br/>updateById(registration)
Mapper->>DB: UPDATE registration SET<br/>status = 0, canceled_at = NOW()<br/>WHERE id = ?
DB-->>Mapper: 返回更新结果
Mapper-->>Service: 返回成功
Service->>ActMapper: 减少活动报名人数<br/>updateById(activity)
ActMapper->>DB: UPDATE activity SET<br/>current_participants = current_participants - 1<br/>WHERE id = ?
DB-->>ActMapper: 返回更新结果
ActMapper-->>Service: 返回成功
Service-->>Controller: 取消成功
Controller-->>Client: 200 成功
end
end
end
end
Note over Client,DB: 3. 下载电子票PDF
Client->>Controller: GET /api/v1/registrations/{id}/ticket<br/>Header: Authorization: Bearer token
Controller->>Service: generateTicketPdf(id)
Service->>Auth: getCurrentUser()
Auth-->>Service: 返回当前用户
Service->>Mapper: selectById(id)
Mapper->>DB: SELECT * FROM registration<br/>WHERE id = ?
DB-->>Mapper: 返回报名记录
Mapper-->>Service: 返回Registration对象
alt 报名记录不存在
Service-->>Controller: 抛出异常<br/>REGISTRATION_NOT_FOUND
Controller-->>Client: 404 未找到
else 报名记录存在
alt 不是自己的报名
Service-->>Controller: 抛出异常<br/>FORBIDDEN
Controller-->>Client: 403 禁止访问
else 是自己的报名
alt 报名状态不是已报名
Service-->>Controller: 抛出异常<br/>BAD_REQUEST
Controller-->>Client: 400 错误
else 报名状态是已报名
Service->>ActMapper: selectById(activityId)
ActMapper->>DB: SELECT * FROM activity<br/>WHERE id = ?
DB-->>ActMapper: 返回活动信息
ActMapper-->>Service: 返回Activity对象
Service->>PdfUtil: generateTicketPdf(user, activity, registration)
PdfUtil-->>Service: 返回PDF字节数组
Service-->>Controller: 返回PDF字节数组
Controller-->Client: 200 成功<br/>Content-Type: application/pdf
end
end
end
4. 签到管理流程
sequenceDiagram
autonumber
participant Client as 客户端
participant Controller as CheckInController<br/>签到控制器
participant Service as CheckInServiceImpl<br/>签到服务
participant Mapper as CheckInMapper<br/>签到数据访问
participant RegMapper as RegistrationMapper<br/>报名数据访问
participant ActMapper as ActivityMapper<br/>活动数据访问
participant Auth as AuthService<br/>认证服务
participant QrUtil as QrCodeUtil<br/>二维码工具类
participant DB as MySQL数据库
Note over Client,DB: 1. 生成签到二维码(管理员)
Client->>Controller: POST /api/v1/checkin/qrcode/{activityId}<br/>Header: Authorization: Bearer token
Controller->>Service: generateQrCode(activityId)
Service->>Auth: getCurrentUser()
Auth-->>Service: 返回当前用户
alt 用户不是管理员
Service-->>Controller: 抛出异常<br/>FORBIDDEN
Controller-->>Client: 403 禁止访问
else 用户是管理员
Service->>ActMapper: selectById(activityId)
ActMapper->>DB: SELECT * FROM activity<br/>WHERE id = ?
DB-->>ActMapper: 返回活动信息
ActMapper-->>Service: 返回Activity对象
alt 活动不存在或已删除
Service-->>Controller: 抛出异常<br/>ACTIVITY_NOT_FOUND
Controller-->>Client: 404 未找到
else 活动存在
alt 不是活动创建者
Service-->>Controller: 抛出异常<br/>FORBIDDEN
Controller-->>Client: 403 禁止访问
else 是活动创建者
Service->>QrUtil: generateQrCodeContent(activityId)
QrUtil-->>Service: 返回二维码内容
Service->>Service: 构建QrCodeVO
Service-->>Controller: 返回QrCodeVO
Controller-->>Client: 200 成功
end
end
end
Note over Client,DB: 2. 学生扫码签到
Client->>Controller: POST /api/v1/checkin/scan<br/>ScanCheckInRequest<br/>Header: Authorization: Bearer token
Controller->>Service: scanCheckIn(request)
Service->>Auth: getCurrentUser()
Auth-->>Service: 返回当前用户
Service->>QrUtil: parseActivityIdFromQrCode(qrCodeContent)
QrUtil-->>Service: 返回activityId
alt 二维码无效
Service-->>Controller: 抛出异常<br/>BAD_REQUEST
Controller-->>Client: 400 错误
else 二维码有效
Service->>ActMapper: selectById(activityId)
ActMapper->>DB: SELECT * FROM activity<br/>WHERE id = ?
DB-->>ActMapper: 返回活动信息
ActMapper-->>Service: 返回Activity对象
alt 活动不存在或已删除
Service-->>Controller: 抛出异常<br/>ACTIVITY_NOT_FOUND
Controller-->>Client: 404 未找到
else 活动存在
Service->>Service: 检查签到时间<br/>startTime - 1小时 <= now <= endTime
alt 签到时间已过期
Service-->>Controller: 抛出异常<br/>CHECKIN_TIME_EXPIRED
Controller-->>Client: 400 错误
else 签到时间有效
Service->>RegMapper: 查询报名记录<br/>selectOne(userId, activityId, status=1)
RegMapper->>DB: SELECT * FROM registration<br/>WHERE user_id = ? AND activity_id = ?<br/>AND status = 1
DB-->>RegMapper: 返回报名记录
RegMapper-->>Service: 返回Registration对象
alt 未报名该活动
Service-->>Controller: 抛出异常<br/>NOT_REGISTERED
Controller-->>Client: 400 错误
else 已报名该活动
Service->>Mapper: 检查是否已签到<br/>selectOne(registrationId)
Mapper->>DB: SELECT * FROM check_in<br/>WHERE registration_id = ?
DB-->>Mapper: 返回签到记录
Mapper-->>Service: 返回CheckIn对象
alt 已签到
Service-->>Controller: 抛出异常<br/>ALREADY_CHECKED_IN
Controller-->>Client: 409 冲突
else 未签到
Service->>Service: performCheckIn(registration, user, activityId, method=0)
Service->>Mapper: insert(checkIn)
Mapper->>DB: INSERT INTO check_in(...)
DB-->>Mapper: 返回插入ID
Mapper-->>Service: 返回checkInId
Service->>RegMapper: 更新报名状态为已签到<br/>updateById(registration)
RegMapper->>DB: UPDATE registration SET status = 2<br/>WHERE id = ?
DB-->>RegMapper: 返回更新结果
RegMapper-->>Service: 返回成功
Service->>Service: convertToVO()
Service-->>Controller: 返回CheckInVO
Controller-->>Client: 200 成功
end
end
end
end
end
Note over Client,DB: 3. 管理员扫学生票签到
Client->>Controller: POST /api/v1/checkin/ticket<br/>TicketCheckInRequest<br/>Header: Authorization: Bearer token
Controller->>Service: ticketCheckIn(request)
Service->>Auth: getCurrentUser()
Auth-->>Service: 返回当前用户
alt 用户不是管理员
Service-->>Controller: 抛出异常<br/>FORBIDDEN
Controller-->>Client: 403 禁止访问
else 用户是管理员
Service->>ActMapper: selectById(activityId)
ActMapper->>DB: SELECT * FROM activity<br/>WHERE id = ?
DB-->>ActMapper: 返回活动信息
ActMapper-->>Service: 返回Activity对象
alt 活动不存在或已删除
Service-->>Controller: 抛出异常<br/>ACTIVITY_NOT_FOUND
Controller-->>Client: 404 未找到
else 活动存在
alt 不是活动创建者
Service-->>Controller: 抛出异常<br/>FORBIDDEN
Controller-->>Client: 403 禁止访问
else 是活动创建者
Service->>Service: 检查签到时间
alt 签到时间已过期
Service-->>Controller: 抛出异常<br/>CHECKIN_TIME_EXPIRED
Controller-->>Client: 400 错误
else 签到时间有效
Service->>RegMapper: selectByTicketCode(ticketCode)
RegMapper->>DB: SELECT * FROM registration<br/>WHERE ticket_code = ?
DB-->>RegMapper: 返回报名记录
RegMapper-->>Service: 返回Registration对象
alt 电子票无效
Service-->>Controller: 抛出异常<br/>BAD_REQUEST
Controller-->>Client: 400 错误
else 电子票有效
alt 电子票与活动不匹配
Service-->>Controller: 抛出异常<br/>BAD_REQUEST
Controller-->>Client: 400 错误
else 电子票与活动匹配
Service->>Mapper: 检查是否已签到<br/>selectOne(registrationId)
Mapper->>DB: SELECT * FROM check_in<br/>WHERE registration_id = ?
DB-->>Mapper: 返回签到记录
Mapper-->>Service: 返回CheckIn对象
alt 已签到
Service-->>Controller: 抛出异常<br/>ALREADY_CHECKED_IN
Controller-->>Client: 409 冲突
else 未签到
Service->>Auth: getUserById(userId)
Auth-->>Service: 返回学生信息
Service->>Service: performCheckIn(registration, student, activityId, method=1)
Service->>Mapper: insert(checkIn)
Mapper->>DB: INSERT INTO check_in(...)
DB-->>Mapper: 返回插入ID
Mapper-->>Service: 返回checkInId
Service->>RegMapper: 更新报名状态<br/>updateById(registration)
RegMapper->>DB: UPDATE registration SET status = 2<br/>WHERE id = ?
DB-->>RegMapper: 返回更新结果
RegMapper-->>Service: 返回成功
Service->>Service: convertToVO()
Service-->>Controller: 返回CheckInVO
Controller-->>Client: 200 成功
end
end
end
end
end
end
end
5. 评价管理流程
sequenceDiagram
autonumber
participant Client as 客户端
participant Controller as ReviewController<br/>评价控制器
participant Service as ReviewServiceImpl<br/>评价服务
participant Mapper as ReviewMapper<br/>评价数据访问
participant ActMapper as ActivityMapper<br/>活动数据访问
participant CheckInMapper as CheckInMapper<br/>签到数据访问
participant Auth as AuthService<br/>认证服务
participant DB as MySQL数据库
Note over Client,DB: 1. 提交评价
Client->>Controller: POST /api/v1/reviews<br/>ReviewRequest<br/>Header: Authorization: Bearer token
Controller->>Service: createReview(request)
Service->>Auth: getCurrentUser()
Auth-->>Service: 返回当前用户
Service->>ActMapper: selectById(activityId)
ActMapper->>DB: SELECT * FROM activity<br/>WHERE id = ?
DB-->>ActMapper: 返回活动信息
ActMapper-->>Service: 返回Activity对象
alt 活动不存在或已删除
Service-->>Controller: 抛出异常<br/>ACTIVITY_NOT_FOUND
Controller-->>Client: 404 未找到
else 活动存在
Service->>Mapper: 检查是否已评价<br/>selectOne(userId, activityId)
Mapper->>DB: SELECT * FROM review<br/>WHERE user_id = ? AND activity_id = ?
DB-->>Mapper: 返回评价记录
Mapper-->>Service: 返回Review对象
alt 已评价该活动
Service-->>Controller: 抛出异常<br/>REVIEW_ALREADY_EXISTS
Controller-->>Client: 409 冲突
else 未评价该活动
Service->>CheckInMapper: 检查是否已签到<br/>selectOne(userId, activityId)
CheckInMapper->>DB: SELECT * FROM check_in<br/>WHERE user_id = ? AND activity_id = ?
DB-->>CheckInMapper: 返回签到记录
CheckInMapper-->>Service: 返回CheckIn对象
alt 未参加该活动
Service-->>Controller: 抛出异常<br/>NOT_PARTICIPATED
Controller-->>Client: 400 错误
else 已参加该活动
Service->>Service: 创建Review对象
Service->>Mapper: insert(review)
Mapper->>DB: INSERT INTO review(...)
DB-->>Mapper: 返回插入ID
Mapper-->>Service: 返回reviewId
Service->>Service: convertToVO()
Service-->>Controller: 返回ReviewVO
Controller-->>Client: 200 成功
end
end
end
Note over Client,DB: 2. 获取活动评价列表
Client->>Controller: GET /api/v1/reviews/activity/{activityId}<br/>(current, size)
Controller->>Service: getActivityReviews(page, activityId)
Service->>Mapper: selectActivityReviews(page, activityId)
Mapper->>DB: SELECT * FROM review<br/>WHERE activity_id = ?<br/>LIMIT offset, size
DB-->>Mapper: 返回评价列表
Mapper-->>Service: 返回IPage<ReviewVO>
Service-->>Controller: 返回IPage<ReviewVO>
Controller-->>Client: 200 成功
Note over Client,DB: 3. 获取我的评价列表
Client->>Controller: GET /api/v1/reviews/my<br/>(current, size)<br/>Header: Authorization: Bearer token
Controller->>Service: getMyReviews(page)
Service->>Auth: getCurrentUser()
Auth-->>Service: 返回当前用户
Service->>Mapper: selectMyReviews(page, userId)
Mapper->>DB: SELECT * FROM review<br/>WHERE user_id = ?<br/>LIMIT offset, size
DB-->>Mapper: 返回评价列表
Mapper-->>Service: 返回IPage<ReviewVO>
Service-->>Controller: 返回IPage<ReviewVO>
Controller-->>Client: 200 成功
6. 统计数据流程
sequenceDiagram
autonumber
participant Client as 客户端
participant Controller as StatisticsController<br/>统计控制器
participant Service as StatisticsServiceImpl<br/>统计服务
participant RegMapper as RegistrationMapper<br/>报名数据访问
participant CheckInMapper as CheckInMapper<br/>签到数据访问
participant ReviewMapper as ReviewMapper<br/>评价数据访问
participant ActMapper as ActivityMapper<br/>活动数据访问
participant CsvUtil as CsvUtil<br/>CSV工具类
participant DB as MySQL数据库
Note over Client,DB: 1. 获取活动统计数据(管理员)
Client->>Controller: GET /api/v1/statistics/activity/{activityId}<br/>Header: Authorization: Bearer token
Controller->>Service: getActivityStatistics(activityId)
Service->>ActMapper: selectById(activityId)
ActMapper->>DB: SELECT * FROM activity<br/>WHERE id = ?
DB-->>ActMapper: 返回活动信息
ActMapper-->>Service: 返回Activity对象
alt 活动不存在或已删除
Service-->>Controller: 抛出异常<br/>ACTIVITY_NOT_FOUND
Controller-->>Client: 404 未找到
else 活动存在
Service->>RegMapper: 统计报名人数<br/>selectCount(activityId, status IN (1,2))
RegMapper->>DB: SELECT COUNT(*) FROM registration<br/>WHERE activity_id = ?<br/>AND status IN (1, 2)
DB-->>RegMapper: 返回报名人数
RegMapper-->>Service: 返回registeredCount
Service->>CheckInMapper: 查询所有签到记录<br/>selectList(activityId)
CheckInMapper->>DB: SELECT * FROM check_in<br/>WHERE activity_id = ?
DB-->>CheckInMapper: 返回签到列表
CheckInMapper-->>Service: 返回List<CheckIn>
Service->>Service: 计算签到人数
Service->>ReviewMapper: 统计评价数量<br/>selectCount(activityId)
ReviewMapper->>DB: SELECT COUNT(*) FROM review<br/>WHERE activity_id = ?
DB-->>ReviewMapper: 返回评价数量
ReviewMapper-->>Service: 返回reviewCount
Service->>ReviewMapper: 查询所有评价<br/>selectList(activityId)
ReviewMapper->>DB: SELECT * FROM review<br/>WHERE activity_id = ?
DB-->>ReviewMapper: 返回评价列表
ReviewMapper-->>Service: 返回List<Review>
Service->>Service: 计算平均评分
Service->>Service: 计算评分分布
Service->>Service: 计算签到率
Service->>Service: 构建ActivityStatisticsVO
Service-->>Controller: 返回ActivityStatisticsVO
Controller-->>Client: 200 成功
end
Note over Client,DB: 2. 导出活动数据(管理员)
Client->>Controller: GET /api/v1/statistics/activity/{activityId}/export<br/>Header: Authorization: Bearer token
Controller->>Service: exportActivityData(activityId, format)
Service->>ActMapper: selectById(activityId)
ActMapper->>DB: SELECT * FROM activity<br/>WHERE id = ?
DB-->>ActMapper: 返回活动信息
ActMapper-->>Service: 返回Activity对象
alt 活动不存在或已删除
Service-->>Controller: 抛出异常<br/>ACTIVITY_NOT_FOUND
Controller-->>Client: 404 未找到
else 活动存在
Service->>RegMapper: 查询活动报名列表<br/>selectList(activityId)
RegMapper->>DB: SELECT * FROM registration<br/>WHERE activity_id = ?
DB-->>RegMapper: 返回报名列表
RegMapper-->>Service: 返回List<Registration>
Service->>CheckInMapper: 查询活动签到列表<br/>selectList(activityId)
CheckInMapper->>DB: SELECT * FROM check_in<br/>WHERE activity_id = ?
DB-->>CheckInMapper: 返回签到列表
CheckInMapper-->>Service: 返回List<CheckIn>
Service->>ReviewMapper: 查询活动评价列表<br/>selectList(activityId)
ReviewMapper->>DB: SELECT * FROM review<br/>WHERE activity_id = ?
DB-->>ReviewMapper: 返回评价列表
ReviewMapper-->>Service: 返回List<Review>
Service->>CsvUtil: exportActivityData(activity, registrations, checkIns, reviews)
CsvUtil-->>Service: 返回CSV字节数组
Service-->>Controller: 返回CSV字节数组
Controller->>Client: 200 成功<br/>Content-Type: text/csv
end
Note over Client,DB: 3. 获取总体统计(管理员)
Client->>Controller: GET /api/v1/statistics/overview<br/>Header: Authorization: Bearer token
Controller->>Service: getOverviewStatistics()
Service->>ActMapper: 统计活动总数<br/>selectCount(deleted=0)
ActMapper->>DB: SELECT COUNT(*) FROM activity<br/>WHERE deleted = 0
DB-->>ActMapper: 返回活动总数
ActMapper-->>Service: 返回totalActivities
Service->>RegMapper: 统计报名总数<br/>selectCount(status=1)
RegMapper->>DB: SELECT COUNT(*) FROM registration<br/>WHERE status = 1
DB-->>RegMapper: 返回报名总数
RegMapper-->>Service: 返回totalRegistrations
Service->>CheckInMapper: 统计签到总数<br/>selectCount()
CheckInMapper->>DB: SELECT COUNT(*) FROM check_in
DB-->>CheckInMapper: 返回签到总数
CheckInMapper-->>Service: 返回totalCheckIns
Service->>ReviewMapper: 统计评价总数<br/>selectCount()
ReviewMapper->>DB: SELECT COUNT(*) FROM review
DB-->>ReviewMapper: 返回评价总数
ReviewMapper-->>Service: 返回totalReviews
Service->>ReviewMapper: 查询所有评价<br/>selectList()
ReviewMapper->>DB: SELECT * FROM review
DB-->>ReviewMapper: 返回评价列表
ReviewMapper-->>Service: 返回List<Review>
Service->>Service: 计算平均评分
Service->>Service: calculateMonthlyStats()
loop 最近6个月
Service->>ActMapper: 统计月活动数<br/>selectCount(createdAt BETWEEN monthStart AND monthEnd)
ActMapper->>DB: SELECT COUNT(*) FROM activity<br/>WHERE created_at BETWEEN ? AND ?
DB-->>ActMapper: 返回月活动数
ActMapper-->>Service: 返回activityCount
Service->>RegMapper: 统计月报名数<br/>selectCount(createdAt BETWEEN monthStart AND monthEnd)
RegMapper->>DB: SELECT COUNT(*) FROM registration<br/>WHERE created_at BETWEEN ? AND ?
DB-->>RegMapper: 返回月报名数
RegMapper-->>Service: 返回registrationCount
end
Service->>Service: 构建OverviewStatisticsVO
Service-->>Controller: 返回OverviewStatisticsVO
Controller-->>Client: 200 成功
系统分层架构图
graph TB
subgraph "表现层 (Controller Layer)"
A1[AuthController<br/>认证控制器]
A2[ActivityController<br/>活动控制器]
A3[RegistrationController<br/>报名控制器]
A4[CheckInController<br/>签到控制器]
A5[ReviewController<br/>评价控制器]
A6[StatisticsController<br/>统计控制器]
end
subgraph "业务逻辑层 (Service Layer)"
B1[AuthServiceImpl<br/>认证服务]
B2[ActivityServiceImpl<br/>活动服务]
B3[RegistrationServiceImpl<br/>报名服务]
B4[CheckInServiceImpl<br/>签到服务]
B5[ReviewServiceImpl<br/>评价服务]
B6[StatisticsServiceImpl<br/>统计服务]
end
subgraph "数据访问层 (Mapper Layer)"
C1[UserMapper<br/>用户数据访问]
C2[ActivityMapper<br/>活动数据访问]
C3[RegistrationMapper<br/>报名数据访问]
C4[CheckInMapper<br/>签到数据访问]
C5[ReviewMapper<br/>评价数据访问]
end
subgraph "实体层 (Entity Layer)"
D1[User<br/>用户实体]
D2[Activity<br/>活动实体]
D3[Registration<br/>报名实体]
D4[CheckIn<br/>签到实体]
D5[Review<br/>评价实体]
end
subgraph "工具层 (Util Layer)"
E1[JwtTokenProvider<br/>JWT令牌提供者]
E2[PdfUtil<br/>PDF工具类]
E3[QrCodeUtil<br/>二维码工具类]
E4[CsvUtil<br/>CSV工具类]
end
subgraph "安全层 (Security Layer)"
F1[SecurityConfig<br/>安全配置]
F2[JwtAuthenticationFilter<br/>JWT认证过滤器]
F3[UserDetailsServiceImpl<br/>用户详情服务]
end
subgraph "数据库层 (Database Layer)"
G1[(MySQL数据库)]
end
A1 --> B1
A2 --> B2
A3 --> B3
A4 --> B4
A5 --> B5
A6 --> B6
B1 --> C1
B1 --> E1
B2 --> C2
B2 --> C1
B2 --> C3
B3 --> C3
B3 --> C2
B3 --> E2
B4 --> C4
B4 --> C3
B4 --> C2
B4 --> E3
B5 --> C5
B5 --> C2
B5 --> C4
B6 --> C3
B6 --> C4
B6 --> C5
B6 --> C2
B6 --> E4
C1 --> D1
C2 --> D2
C3 --> D3
C4 --> D4
C5 --> D5
C1 --> G1
C2 --> G1
C3 --> G1
C4 --> G1
C5 --> G1
F1 --> F2
F1 --> F3
F2 --> E1
F3 --> C1
style A1 fill:#e1f5ff
style A2 fill:#e1f5ff
style A3 fill:#e1f5ff
style A4 fill:#e1f5ff
style A5 fill:#e1f5ff
style A6 fill:#e1f5ff
style B1 fill:#fff4e1
style B2 fill:#fff4e1
style B3 fill:#fff4e1
style B4 fill:#fff4e1
style B5 fill:#fff4e1
style B6 fill:#fff4e1
style C1 fill:#e8f5e9
style C2 fill:#e8f5e9
style C3 fill:#e8f5e9
style C4 fill:#e8f5e9
style C5 fill:#e8f5e9
style D1 fill:#f3e5f5
style D2 fill:#f3e5f5
style D3 fill:#f3e5f5
style D4 fill:#f3e5f5
style D5 fill:#f3e5f5
style E1 fill:#fce4ec
style E2 fill:#fce4ec
style E3 fill:#fce4ec
style E4 fill:#fce4ec
style F1 fill:#fff9c4
style F2 fill:#fff9c4
style F3 fill:#fff9c4
style G1 fill:#cfd8dc
核心业务流程总览
graph LR
subgraph "用户认证"
A[注册] --> B[登录]
B --> C[获取Token]
end
subgraph "活动管理"
D[创建活动] --> E[发布活动]
E --> F[时间冲突检测]
F --> G[活动列表]
G --> H[活动详情]
H --> I[更新活动]
I --> J[删除活动]
end
subgraph "报名流程"
K[浏览活动] --> L[报名活动]
L --> M[生成电子票]
M --> N[下载PDF]
N --> O[取消报名]
end
subgraph "签到流程"
P[生成二维码] --> Q[学生扫码]
Q --> R[管理员扫码]
R --> S[签到成功]
end
subgraph "评价流程"
T[参加活动] --> U[签到完成]
U --> V[提交评价]
V --> W[查看评价]
end
subgraph "统计分析"
X[活动统计] --> Y[数据导出]
Y --> Z[总体统计]
end
C --> K
C --> D
C --> P
C --> V
C --> X
style A fill:#4CAF50,color:#fff
style B fill:#4CAF50,color:#fff
style C fill:#4CAF50,color:#fff
style D fill:#2196F3,color:#fff
style E fill:#2196F3,color:#fff
style F fill:#2196F3,color:#fff
style G fill:#2196F3,color:#fff
style H fill:#2196F3,color:#fff
style I fill:#2196F3,color:#fff
style J fill:#2196F3,color:#fff
style K fill:#FF9800,color:#fff
style L fill:#FF9800,color:#fff
style M fill:#FF9800,color:#fff
style N fill:#FF9800,color:#fff
style O fill:#FF9800,color:#fff
style P fill:#9C27B0,color:#fff
style Q fill:#9C27B0,color:#fff
style R fill:#9C27B0,color:#fff
style S fill:#9C27B0,color:#fff
style T fill:#E91E63,color:#fff
style U fill:#E91E63,color:#fff
style V fill:#E91E63,color:#fff
style W fill:#E91E63,color:#fff
style X fill:#607D8B,color:#fff
style Y fill:#607D8B,color:#fff
style Z fill:#607D8B,color:#fff
代码文件索引
Controller层
AuthController.java- 认证控制器ActivityController.java- 活动控制器RegistrationController.java- 报名控制器CheckInController.java- 签到控制器ReviewController.java- 评价控制器StatisticsController.java- 统计控制器
Service层
AuthServiceImpl.java- 认证服务实现ActivityServiceImpl.java- 活动服务实现RegistrationServiceImpl.java- 报名服务实现CheckInServiceImpl.java- 签到服务实现ReviewServiceImpl.java- 评价服务实现StatisticsServiceImpl.java- 统计服务实现
Mapper层
UserMapper.java- 用户数据访问ActivityMapper.java- 活动数据访问RegistrationMapper.java- 报名数据访问CheckInMapper.java- 签到数据访问ReviewMapper.java- 评价数据访问
Entity层
User.java- 用户实体Activity.java- 活动实体Registration.java- 报名实体CheckIn.java- 签到实体Review.java- 评价实体
Security层
SecurityConfig.java- 安全配置JwtAuthenticationFilter.java- JWT认证过滤器JwtTokenProvider.java- JWT令牌提供者UserDetailsServiceImpl.java- 用户详情服务
Util层
PdfUtil.java- PDF工具类QrCodeUtil.java- 二维码工具类CsvUtil.java- CSV工具类
总结
本业务流程图详细展示了校园活动系统的核心业务流程,包括:
- 用户认证流程:注册、登录、Token刷新、获取用户信息
- 活动管理流程:创建、查询、更新、删除活动,时间冲突检测
- 活动报名流程:报名、取消报名、生成电子票、下载PDF
- 签到管理流程:生成二维码、学生扫码签到、管理员扫码签到
- 评价管理流程:提交评价、查看活动评价、查看我的评价
- 统计数据流程:活动统计、数据导出、总体统计
每个流程都详细标注了涉及的代码文件、方法名和数据库操作,清晰地展示了从Controller层到Service层、Mapper层,最后到数据库的完整调用链路。
系统采用标准的分层架构,各层职责清晰:
- Controller层:处理HTTP请求和响应
- Service层:实现核心业务逻辑
- Mapper层:与数据库交互
- Entity层:数据模型定义
- Security层:JWT认证和授权
- Util层:提供工具类支持
这种架构设计保证了代码的可维护性、可扩展性和可测试性。