1. 项目背景与核心价值
这个SpringBoot慈善公益平台的设计初衷,源于我在参与社区志愿服务时的实际痛点。传统公益活动组织往往依赖微信群、Excel表格手工管理,活动报名信息分散,捐赠物资流向不透明,志愿者调度效率低下。去年为山区儿童筹款时,我们就因为信息不同步导致三箱图书重复邮寄。
平台采用B/S架构设计,主要解决三大核心问题:
- 活动发布标准化:机构可快速创建包含图文详情、时间地点、人数限制的规范化活动模板
- 全流程追踪:从报名审核、物资分配到服务时长记录形成闭环
- 数据可视化:实时生成捐赠明细、志愿者活跃度等统计报表
技术选型上,SpringBoot 2.7 + MyBatis-Plus的组合提供了快速开发基础,配合Vue3前端实现响应式管理界面。特别在权限控制方面,采用RBAC模型实现多级管理(超级管理员/机构管理员/普通用户),确保敏感操作的安全隔离。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计解析
2.1 技术栈选型考量
后端核心框架选择SpringBoot而非传统SSM,主要基于三个实际考量:
- 内嵌Tomcat简化部署,毕业生可免去复杂的环境配置
- Starter依赖自动装配,快速集成Redis缓存、RabbitMQ消息队列
- Actuator端点监控,方便答辩时演示系统健康状态
数据库采用MySQL 8.0,关键表设计遵循以下原则:
- 活动表(activity)包含status字段(0草稿/1待审核/2已发布/3已结束)
- 捐赠记录表(donation)设置triple校验机制(机构初审+财务复核+管理员终审)
- 志愿者表(volunteer)建立service_hour累积字段,与信用评级挂钩
2.2 核心功能模块实现
活动发布模块的典型代码结构:
java复制@RestController
@RequestMapping("/activity")
public class ActivityController {
@Autowired
private ActivityService activityService;
@PostMapping("/publish")
@PreAuthorize("hasRole('ORG_ADMIN')")
public Result publishActivity(@Valid @RequestBody ActivityDTO dto) {
return activityService.publishActivity(dto);
}
@GetMapping("/list")
public PageResult<ActivityVO> getActivityList(
@RequestParam(required = false) Integer type,
@RequestParam(defaultValue = "1") Integer pageNum) {
return activityService.getActivityPage(type, pageNum);
}
}
特别注意的几个技术细节:
- 使用Hibernate Validator进行DTO参数校验
- @PreAuthorize实现方法级权限控制
- 分页查询统一返回PageResult包装类
3. 关键业务逻辑实现
3.1 爱心物资追踪流程
物资管理采用区块链思想设计(非真正区块链,而是借鉴其不可篡改特性):
- 捐赠登记时生成唯一二维码ID
- 每次流转记录包含操作人、时间戳、GPS定位
- 前台捐赠者可通过扫码查看全链路流转轨迹
核心SQL示例:
sql复制SELECT
m.material_name,
r.from_org,
r.to_org,
r.transfer_time,
u.real_name AS operator
FROM
material_transfer_record r
JOIN
material m ON r.material_id = m.id
JOIN
sys_user u ON r.operator_id = u.id
WHERE
m.qrcode_id = 'MAT_20231125_001'
ORDER BY
r.transfer_time DESC;
3.2 志愿者信用体系设计
为解决活动爽约问题,设计动态信用评分模型:
java复制public class CreditCalculator {
// 基础分
private static final int BASE_SCORE = 80;
// 加分项
public int calculateAddScore(Volunteer volunteer) {
int score = 0;
score += volunteer.getCompletedCount() * 2;
score += (int)(volunteer.getTotalHours() / 10);
if(volunteer.getCertificateLevel() > 0) {
score += 10;
}
return Math.min(score, 20); // 加分上限20
}
// 减分项
public int calculateDeduction(Volunteer volunteer) {
int deduction = 0;
deduction += volunteer.getAbsenceCount() * 5;
deduction += volunteer.getComplaintCount() * 3;
return Math.min(deduction, 30); // 扣分上限30
}
}
4. 典型问题解决方案
4.1 高并发报名场景处理
在"免费午餐"公益活动中遇到的典型问题:
- 活动开放报名后1分钟内涌入3000+请求
- 库存超卖导致已报名人数超过限额
最终解决方案:
java复制@Transactional
public Result signUpActivity(Long activityId, Long userId) {
// 1. 使用SELECT...FOR UPDATE加行锁
Activity activity = activityMapper.selectByIdForUpdate(activityId);
// 2. 校验剩余名额
if(activity.getSignedUp() >= activity.getPeopleLimit()) {
throw new BusinessException("活动名额已满");
}
// 3. 使用乐观锁更新
int update = activityMapper.updateSignedUp(
activityId,
activity.getSignedUp() + 1,
activity.getVersion());
if(update == 0) {
throw new ConcurrentUpdateException("报名冲突请重试");
}
// 4. 记录报名信息
ActivitySignUp signUp = new ActivitySignUp();
signUp.setActivityId(activityId);
signUp.setUserId(userId);
signUp.setSignUpTime(new Date());
signUpMapper.insert(signUp);
return Result.success("报名成功");
}
4.2 敏感数据脱敏处理
捐赠人隐私保护方案:
- 数据库层面使用AES加密存储手机号、身份证号
- 接口返回时进行字段脱敏
- 日志过滤敏感关键词
MyBatis拦截器实现示例:
java复制@Intercepts(@Signature(type= ResultSetHandler.class,
method="handleResultSets",
args={Statement.class}))
public class DataMaskInterceptor implements Interceptor {
private static final String PHONE_REGEX = "(\\d{3})\\d{4}(\\d{4})";
@Override
public Object intercept(Invocation invocation) throws Throwable {
List<Object> records = (List<Object>) invocation.proceed();
records.forEach(this::maskSensitiveData);
return records;
}
private void maskSensitiveData(Object record) {
if(record instanceof DonationVO) {
DonationVO vo = (DonationVO) record;
vo.setPhone(vo.getPhone().replaceAll(PHONE_REGEX, "$1****$2"));
}
}
}
5. 部署与运维实践
5.1 多环境配置方案
采用SpringBoot Profile机制管理环境配置:
code复制resources/
├── application.yml
├── application-dev.yml
├── application-test.yml
└── application-prod.yml
关键配置项差异:
- dev环境:开启Swagger、H2控制台
- test环境:使用测试支付接口
- prod环境:启用HTTPS、审计日志
启动参数示例:
bash复制java -jar charity-platform.jar \
--spring.profiles.active=prod \
--spring.datasource.password=${DB_PASSWORD}
5.2 健康检查端点配置
为满足答辩演示需求,特别强化监控端点:
yaml复制management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
metrics:
enabled: true
metrics:
export:
prometheus:
enabled: true
典型监控看板包含:
- 活动发布趋势折线图
- 捐赠金额统计饼图
- 接口响应时间热力图
6. 毕业设计答辩技巧
6.1 演示数据准备建议
准备三套典型数据场景:
- 正常流程:完整展示活动发布-报名-执行-归档
- 异常情况:演示名额已满提示、审核驳回等
- 管理功能:展示数据导出、志愿者黑名单管理
推荐使用Postman的Collection功能预置测试用例,避免现场操作失误。
6.2 常见答辩问题应对
高频技术问题清单:
-
Q:为什么选择SpringBoot而不是SpringCloud?
A:考虑到毕业设计的复杂度控制,单体架构足够满足需求。但我们在package划分上已经做好了微服务拆分准备。 -
Q:如何保证捐赠资金流向透明?
A:系统采用三重审核机制,所有转账记录自动关联活动ID,支持导出PDF对账单。 -
Q:遇到恶意刷单怎么处理?
A:前端验证码+后端接口限流(Redis实现),单个IP每分钟最多5次报名请求。
项目扩展性方面,可以补充说明未来可接入微信小程序、增加智能客服机器人等演进方向。
