Background and Motivation
Charitable giving plays a vital role in societal development, addressing critical needs and supporting vulnerable populations. Traditional donation methods often suffer from cumbersome workflows, opacity, and inconsistent management practices. Implementing a Spring Boot-based charity donation platform addresses these challenges by streamlining processes, enhancing transparency, and fostering trust between donors and charitable organizations. This digitization encourages broader participation and drives the sustainable growth of philanthropic initiatives.
System Architecture and Methodology
The development lifecycle follows a structured approach:
- Feature Definition: Core modules include donation tracking, donor management, fund allocation, and project oversight.
- Technology Selection: Spring Boot serves as the foundational backend framework.
- Database Modeling: Relational schemas are designed for tracking donations, user profiles, and project metadata.
- Architecture Design: Modular decomposition ensures separation of concerns between presentation, business logic, and data access layers.
- Implementation: Parallel development of RESTful backend services and reactive frontend components.
- Quality Assurance: Rigorous testing and performance tuning to guarantee system reliability.
- Deployment: Production rollout and operational monitoring.
Technology Stack
- Backend: Spring Boot, Spring Security, Spring Data JPA, MyBatis-Plus
- Database: MySQL
- Frontend: Vue.js, Vue Router, Vuex, Element UI, Axios, HTML/CSS/JavaScript
- Build & Environment: Maven, JDK 1.8, Tomcat 7.0, Node.js, IntelliJ IDEA, VS Code, Navicat
Code Implementation: Recommendation Logic
/**
* Popularity-based sorting endpoint
*/
@IgnoreAuth
@GetMapping("/sort/popularity")
public ResponseEntity<?> sortProjectsByPopularity(
@RequestParam Map<String, Object> queryParams,
DonationProjectEntity projectFilter,
HttpServletRequest req) {
EntityWrapper<DonationProjectEntity> wrapper = new EntityWrapper<>();
Map<String, Object> mappedParams = new HashMap<>(queryParams);
mappedParams.put("sort", "view_count");
mappedParams.put("order", "desc");
PageUtils resultPage = donationProjectService.queryPage(
mappedParams,
MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(wrapper, projectFilter), mappedParams), mappedParams)
);
return ResponseEntity.ok(Collections.singletonMap("data", resultPage));
}
/**
* Collaborative recommendation based on donor history
*/
@GetMapping("/recommend/history")
public ResponseEntity<?> recommendByHistory(
@RequestParam Map<String, Object> queryParams,
DonationProjectEntity projectFilter,
HttpServletRequest req) {
String currentUserId = req.getSession().getAttribute("userId").toString();
String categoryField = "cause_category";
List<DonationRecordEntity> pastRecords = donationRecordService.selectList(
new EntityWrapper<DonationRecordEntity>()
.eq("donor_id", currentUserId)
.orderBy("donation_time", false)
);
int resultLimit = queryParams.get("limit") == null ? 10 : Integer.parseInt(queryParams.get("limit").toString());
List<DonationProjectEntity> recommendedProjects = new ArrayList<>();
Set<String> seenCategories = new HashSet<>();
for (DonationRecordEntity record : pastRecords) {
if (seenCategories.add(record.getCategory())) {
recommendedProjects.addAll(
donationProjectService.selectList(
new EntityWrapper<DonationProjectEntity>().eq(categoryField, record.getCategory())
)
);
}
}
if (recommendedProjects.size() < resultLimit) {
EntityWrapper<DonationProjectEntity> fallbackWrapper = new EntityWrapper<>();
queryParams.put("sort", "project_id");
queryParams.put("order", "desc");
PageUtils fallbackPage = donationProjectService.queryPage(
queryParams,
MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(fallbackWrapper, projectFilter), queryParams), queryParams)
);
List<DonationProjectEntity> fallbackList = (List<DonationProjectEntity>) fallbackPage.getList();
int needed = resultLimit - recommendedProjects.size();
Set<Integer> existingIds = recommendedProjects.stream().map(DonationProjectEntity::getProjectId).collect(Collectors.toSet());
for (DonationProjectEntity fallbackItem : fallbackList) {
if (existingIds.add(fallbackItem.getProjectId())) {
recommendedProjects.add(fallbackItem);
if (--needed == 0) break;
}
}
}
return ResponseEntity.ok(Collections.singletonMap("data", recommendedProjects));
}Database Configuration
spring.datasource.validation-query=SELECT 1
spring.datasource.url=jdbc:mysql://localhost:3306/charity_donation_db?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false
spring.datasource.username=charity_admin
spring.datasource.password=secure_password_123