diff --git a/readme.md b/readme.md new file mode 100644 index 00000000..a13088e7 --- /dev/null +++ b/readme.md @@ -0,0 +1,140 @@ +# 校园社团活动管理系统 + +[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.4.2-green)](https://spring.io/) +[![Vue.js](https://img.shields.io/badge/Vue.js-3.2.0-brightgreen)](https://vuejs.org/) +[![License](https://img.shields.io/badge/License-MIT-blue)](LICENSE) + +> 基于SpringBoot + Vue的校园社团活动全流程管理平台 +> 毕业设计项目 | 山东建筑大学 | 2025届 + +--- + +## 项目简介 +本系统旨在解决传统校园社团活动管理的痛点,提供数字化全流程解决方案: +- **角色分层管理**:支持管理员、组织者、参与者三级权限体系 +- **活动全生命周期管理**:覆盖活动申请、审核、执行到归档全流程 +- **数据可视化**:实时统计活动参与度与社团活跃度 +- **安全可靠**:采用JWT鉴权+BCrypt加密+操作日志审计 + +[👉 **在线演示**](https://demo.club-manager.com) | [📚 需求文档](/docs/需求分析说明书1.4.docx) + +--- + +## 功能特性 + +### 🎯 核心功能 +| 模块 | 功能描述 | +|--------------|--------------------------------------------------------------------------| +| **社团管理** | 社团信息维护/成员审核/权限分级/数据统计 | +| **活动管理** | 在线申请-审核-发布全流程/扫码签到/评论互动/实时通知推送 | +| **用户中心** | 多角色视图切换/我的活动追踪/消息通知中心 | + +### 🚀 特色功能 +- **智能推荐**:基于用户兴趣的活动推送 +- **扫码签到**:动态二维码防作弊机制 +- **数据看板**:社团活跃度排行榜 + +--- + +## 技术栈 + +### 前端技术 +| 技术 | 说明 | 版本 | +|------------------|--------------------------------|--------| +| Vue.js | 渐进式JavaScript框架 | 3.2.0 | +| Element-Plus | UI组件库 | 2.2.0 | +| Axios | HTTP客户端 | 1.1.3 | +| ECharts | 数据可视化 | 5.4.0 | + +### 后端技术 +| 技术 | 说明 | 版本 | +|------------------|--------------------------------|--------| +| Spring Boot | Java开发框架 | 2.7.0 | +| MyBatis-Plus | ORM框架 | 3.5.2 | +| JWT | 身份认证 | 0.11.2 | +| Redis | 缓存管理 | 6.2.6 | +| Swagger | API文档生成 | 3.0.0 | + +### 基础设施 +| 组件 | 用途 | +|--------------|--------------------------------| +| MySQL 8.0 | 主数据库 | +| Nginx | 反向代理/负载均衡 | +| Docker | 容器化部署 | + +--- + +## 快速开始 + +### 环境要求 +- JDK 17+ +- Node.js 16.x +- MySQL 8.0+ +- Redis 6.x + +### 本地部署 + todo + +4. **初始化数据库** + 执行 [/sql/init.sql](/sql/init.sql) 脚本 + +--- + +## 项目结构 +```text +campus-club-system/ +├── server/ # 后端服务 +│ ├── src/ +│ │ ├── main/ +│ │ │ ├── java/com/bruce/sams/ +│ │ │ │ ├── controller # API接口层 +│ │ │ │ ├── service # 业务逻辑层 +│ │ │ │ ├── mapper # 数据访问层 +│ │ │ │ └── config # 安全/缓存配置 +│ │ │ └── resources/ # 配置文件 +│ └── pom.xml +│ +├── client/ # 前端应用 +│ ├── src/ +│ │ ├── api/ # 接口封装 +│ │ ├── router/ # 路由配置 +│ │ ├── views/ # 页面组件 +│ │ └── store/ # 状态管理 +│ └── package.json +│ +├── docs/ # 文档资料 +│ ├── 需求分析说明书.docx +│ └── 数据库设计.md +│ +└── sql/ # 数据库脚本 + ├── init.sql # 初始化脚本 + └── sample_data.sql # 测试数据 +``` + +--- + +## 数据库设计 +![ER Diagram](/docs/er-diagram.png) + +关键数据表说明: +- **用户表(user)**:存储用户基础信息与角色权限 +- **活动表(activity)**:记录活动全生命周期状态 +- **报名表(signup_record)**:管理用户报名与签到信息 +- **操作日志(admin_log)**:审计所有管理操作 + +[🔍 查看完整数据库设计](/docs/数据库设计.md) + +--- + +## 贡献指南 +欢迎通过Issue或PR参与改进! +1. Fork本仓库 +2. 创建特性分支 (`git checkout -b feature/your-feature`) +3. 提交修改 (`git commit -m 'Add some feature'`) +4. 推送到分支 (`git push origin feature/your-feature`) +5. 创建Pull Request + +--- + +## 许可证 +[MIT License](LICENSE) © 2025 孙之烨 | 山东建筑大学 diff --git a/src/main/java/com/bruce/sams/config/SecurityConfig.java b/src/main/java/com/bruce/sams/config/SecurityConfig.java index 763fe15f..12a7c426 100644 --- a/src/main/java/com/bruce/sams/config/SecurityConfig.java +++ b/src/main/java/com/bruce/sams/config/SecurityConfig.java @@ -23,6 +23,7 @@ public class SecurityConfig { .requestMatchers("/api/auth/login").permitAll() .requestMatchers("/api/admin/**").hasAuthority("leader") .requestMatchers("/api/user/**").hasAuthority("participant") + .requestMatchers("/api/activity/**").authenticated() .anyRequest().authenticated() ) .addFilterBefore(new JwtAuthFilter(), UsernamePasswordAuthenticationFilter.class); diff --git a/src/main/java/com/bruce/sams/controller/ams/ActivityController.java b/src/main/java/com/bruce/sams/controller/ams/ActivityController.java new file mode 100644 index 00000000..ee6e613d --- /dev/null +++ b/src/main/java/com/bruce/sams/controller/ams/ActivityController.java @@ -0,0 +1,59 @@ +package com.bruce.sams.controller.ams; + +import com.bruce.sams.utils.AjaxResult; +import com.bruce.sams.domain.ams.Activity; +import com.bruce.sams.service.ActivityService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 活动管理控制器 + */ +@RestController +@RequestMapping("/api/activity") +public class ActivityController { + + @Autowired + private ActivityService activityService; + + @GetMapping("/list") + public AjaxResult getAllActivities() { + return AjaxResult.success("查询成功", activityService.getAllActivities()); + } + + @GetMapping("/{actId}") + public AjaxResult getActivityById(@PathVariable Long actId) { + return AjaxResult.success("查询成功", activityService.getActivityById(actId)); + } + + @GetMapping("/club/{clubId}") + public AjaxResult getActivitiesByClubId(@PathVariable Long clubId) { + return AjaxResult.success("查询成功", activityService.getActivitiesByClubId(clubId)); + } + + @PostMapping("/add") + public AjaxResult addActivity(@RequestBody Activity activity) { + activityService.addActivity(activity); + return AjaxResult.success("活动添加成功"); + } + + @PutMapping("/update") + public AjaxResult updateActivity(@RequestBody Activity activity) { + activityService.updateActivity(activity); + return AjaxResult.success("活动信息更新成功"); + } + + @DeleteMapping("/delete/{actId}") + public AjaxResult deleteActivity(@PathVariable Long actId) { + activityService.deleteActivity(actId); + return AjaxResult.success("活动删除成功"); + } + + @PutMapping("/{actId}/status") + public AjaxResult changeActivityStatus(@PathVariable Long actId, @RequestParam String status) { + activityService.changeActivityStatus(actId, status); + return AjaxResult.success("活动状态更新成功"); + } +} diff --git a/src/main/java/com/bruce/sams/controller/sms/ClubController.java b/src/main/java/com/bruce/sams/controller/sms/ClubController.java new file mode 100644 index 00000000..6a94236e --- /dev/null +++ b/src/main/java/com/bruce/sams/controller/sms/ClubController.java @@ -0,0 +1,64 @@ +package com.bruce.sams.controller.sms; + + +import com.bruce.sams.utils.AjaxResult; +import com.bruce.sams.domain.sms.Club; +import com.bruce.sams.service.ClubService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +/** + * 社团管理控制器 + */ +@RestController +@RequestMapping("/api/club") +public class ClubController { + + @Autowired + private ClubService clubService; + + @GetMapping("/list") + public AjaxResult getAllClubs() { + return AjaxResult.success("查询成功", clubService.getAllClubs()); + } + + @GetMapping("/{clubId}") + public AjaxResult getClubById(@PathVariable Long clubId) { + return AjaxResult.success("查询成功", clubService.getClubById(clubId)); + } + + @PostMapping("/add") + public AjaxResult addClub(@RequestBody Club club) { + clubService.addClub(club); + return AjaxResult.success("社团添加成功"); + } + + @PutMapping("/update") + public AjaxResult updateClub(@RequestBody Club club) { + clubService.updateClub(club); + return AjaxResult.success("社团信息更新成功"); + } + + @DeleteMapping("/delete/{clubId}") + public AjaxResult deleteClub(@PathVariable Long clubId) { + clubService.deleteClub(clubId); + return AjaxResult.success("社团删除成功"); + } + + @PostMapping("/join/{clubId}") + public AjaxResult joinClub(@RequestAttribute Long userId, @PathVariable Long clubId) { + clubService.joinClub(userId, clubId); + return AjaxResult.success("加入社团成功"); + } + + @DeleteMapping("/leave/{clubId}") + public AjaxResult leaveClub(@RequestAttribute Long userId, @PathVariable Long clubId) { + clubService.leaveClub(userId, clubId); + return AjaxResult.success("退出社团成功"); + } + + @GetMapping("/{clubId}/members") + public AjaxResult getClubMembers(@PathVariable Long clubId) { + return AjaxResult.success("查询成功", clubService.getClubMembers(clubId)); + } +} diff --git a/src/main/java/com/bruce/sams/controller/CollegeController.java b/src/main/java/com/bruce/sams/controller/sms/CollegeController.java similarity index 98% rename from src/main/java/com/bruce/sams/controller/CollegeController.java rename to src/main/java/com/bruce/sams/controller/sms/CollegeController.java index 188239fc..c2f77d93 100644 --- a/src/main/java/com/bruce/sams/controller/CollegeController.java +++ b/src/main/java/com/bruce/sams/controller/sms/CollegeController.java @@ -1,4 +1,4 @@ -package com.bruce.sams.controller; +package com.bruce.sams.controller.sms; import com.bruce.sams.utils.AjaxResult; import com.bruce.sams.domain.sms.College; diff --git a/src/main/java/com/bruce/sams/controller/CollegeLeaderController.java b/src/main/java/com/bruce/sams/controller/sms/CollegeLeaderController.java similarity index 97% rename from src/main/java/com/bruce/sams/controller/CollegeLeaderController.java rename to src/main/java/com/bruce/sams/controller/sms/CollegeLeaderController.java index 16c23c31..1eef57a9 100644 --- a/src/main/java/com/bruce/sams/controller/CollegeLeaderController.java +++ b/src/main/java/com/bruce/sams/controller/sms/CollegeLeaderController.java @@ -1,4 +1,4 @@ -package com.bruce.sams.controller; +package com.bruce.sams.controller.sms; import com.bruce.sams.domain.sms.CollegeLeader; import com.bruce.sams.service.CollegeLeaderService; diff --git a/src/main/java/com/bruce/sams/controller/AuthController.java b/src/main/java/com/bruce/sams/controller/sys/AuthController.java similarity index 95% rename from src/main/java/com/bruce/sams/controller/AuthController.java rename to src/main/java/com/bruce/sams/controller/sys/AuthController.java index 76934deb..56089c0d 100644 --- a/src/main/java/com/bruce/sams/controller/AuthController.java +++ b/src/main/java/com/bruce/sams/controller/sys/AuthController.java @@ -1,4 +1,4 @@ -package com.bruce.sams.controller; +package com.bruce.sams.controller.sys; import com.bruce.sams.domain.entity.LoginRequest; import com.bruce.sams.service.AuthService; diff --git a/src/main/java/com/bruce/sams/controller/UserController.java b/src/main/java/com/bruce/sams/controller/sys/UserController.java similarity index 97% rename from src/main/java/com/bruce/sams/controller/UserController.java rename to src/main/java/com/bruce/sams/controller/sys/UserController.java index 3d6a784a..e3c22d89 100644 --- a/src/main/java/com/bruce/sams/controller/UserController.java +++ b/src/main/java/com/bruce/sams/controller/sys/UserController.java @@ -1,4 +1,4 @@ -package com.bruce.sams.controller; +package com.bruce.sams.controller.sys; import com.bruce.sams.domain.sys.User; import com.bruce.sams.utils.AjaxResult; diff --git a/src/main/java/com/bruce/sams/controller/UserProfileController.java b/src/main/java/com/bruce/sams/controller/sys/UserProfileController.java similarity index 97% rename from src/main/java/com/bruce/sams/controller/UserProfileController.java rename to src/main/java/com/bruce/sams/controller/sys/UserProfileController.java index 341d0142..84b3670d 100644 --- a/src/main/java/com/bruce/sams/controller/UserProfileController.java +++ b/src/main/java/com/bruce/sams/controller/sys/UserProfileController.java @@ -1,4 +1,4 @@ -package com.bruce.sams.controller; +package com.bruce.sams.controller.sys; import com.bruce.sams.domain.sys.User; import com.bruce.sams.utils.AjaxResult; diff --git a/src/main/java/com/bruce/sams/domain/ams/Activity.java b/src/main/java/com/bruce/sams/domain/ams/Activity.java new file mode 100644 index 00000000..ca2432ec --- /dev/null +++ b/src/main/java/com/bruce/sams/domain/ams/Activity.java @@ -0,0 +1,161 @@ +package com.bruce.sams.domain.ams; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.math.BigDecimal; +import java.util.Date; +import lombok.Data; + +/** + * 活动表 + * @TableName ams_activity + */ +@TableName(value ="ams_activity") +@Data +public class Activity { + /** + * 活动ID + */ + @TableId(type = IdType.AUTO) + private Long actId; + + /** + * 活动标题 + */ + private String title; + + /** + * 活动描述 + */ + private String description; + + /** + * 开始时间 + */ + private Date startTime; + + /** + * 结束时间 + */ + private Date endTime; + + /** + * 地点 + */ + private String location; + + /** + * 预算 + */ + private BigDecimal budget; + + /** + * 最大参与人数 + */ + private Integer maxParticipants; + + /** + * 创建者ID + */ + private Long creatorId; + + /** + * 所属社团ID + */ + private Long clubId; + + /** + * 是否公开 + */ + private Object visibility; + + /** + * 活动状态 + */ + private String status; + + /** + * 创建时间 + */ + private Date createdAt; + + /** + * 最后更新时间 + */ + private Date updatedAt; + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that == null) { + return false; + } + if (getClass() != that.getClass()) { + return false; + } + Activity other = (Activity) that; + return (this.getActId() == null ? other.getActId() == null : this.getActId().equals(other.getActId())) + && (this.getTitle() == null ? other.getTitle() == null : this.getTitle().equals(other.getTitle())) + && (this.getDescription() == null ? other.getDescription() == null : this.getDescription().equals(other.getDescription())) + && (this.getStartTime() == null ? other.getStartTime() == null : this.getStartTime().equals(other.getStartTime())) + && (this.getEndTime() == null ? other.getEndTime() == null : this.getEndTime().equals(other.getEndTime())) + && (this.getLocation() == null ? other.getLocation() == null : this.getLocation().equals(other.getLocation())) + && (this.getBudget() == null ? other.getBudget() == null : this.getBudget().equals(other.getBudget())) + && (this.getMaxParticipants() == null ? other.getMaxParticipants() == null : this.getMaxParticipants().equals(other.getMaxParticipants())) + && (this.getCreatorId() == null ? other.getCreatorId() == null : this.getCreatorId().equals(other.getCreatorId())) + && (this.getClubId() == null ? other.getClubId() == null : this.getClubId().equals(other.getClubId())) + && (this.getVisibility() == null ? other.getVisibility() == null : this.getVisibility().equals(other.getVisibility())) + && (this.getStatus() == null ? other.getStatus() == null : this.getStatus().equals(other.getStatus())) + && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt())) + && (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt())); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((getActId() == null) ? 0 : getActId().hashCode()); + result = prime * result + ((getTitle() == null) ? 0 : getTitle().hashCode()); + result = prime * result + ((getDescription() == null) ? 0 : getDescription().hashCode()); + result = prime * result + ((getStartTime() == null) ? 0 : getStartTime().hashCode()); + result = prime * result + ((getEndTime() == null) ? 0 : getEndTime().hashCode()); + result = prime * result + ((getLocation() == null) ? 0 : getLocation().hashCode()); + result = prime * result + ((getBudget() == null) ? 0 : getBudget().hashCode()); + result = prime * result + ((getMaxParticipants() == null) ? 0 : getMaxParticipants().hashCode()); + result = prime * result + ((getCreatorId() == null) ? 0 : getCreatorId().hashCode()); + result = prime * result + ((getClubId() == null) ? 0 : getClubId().hashCode()); + result = prime * result + ((getVisibility() == null) ? 0 : getVisibility().hashCode()); + result = prime * result + ((getStatus() == null) ? 0 : getStatus().hashCode()); + result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode()); + result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode()); + return result; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()); + sb.append(" ["); + sb.append("Hash = ").append(hashCode()); + sb.append(", actId=").append(actId); + sb.append(", title=").append(title); + sb.append(", description=").append(description); + sb.append(", startTime=").append(startTime); + sb.append(", endTime=").append(endTime); + sb.append(", location=").append(location); + sb.append(", budget=").append(budget); + sb.append(", maxParticipants=").append(maxParticipants); + sb.append(", creatorId=").append(creatorId); + sb.append(", clubId=").append(clubId); + sb.append(", visibility=").append(visibility); + sb.append(", status=").append(status); + sb.append(", createdAt=").append(createdAt); + sb.append(", updatedAt=").append(updatedAt); + sb.append("]"); + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/bruce/sams/domain/sms/Club.java b/src/main/java/com/bruce/sams/domain/sms/Club.java new file mode 100644 index 00000000..caf789a9 --- /dev/null +++ b/src/main/java/com/bruce/sams/domain/sms/Club.java @@ -0,0 +1,104 @@ +package com.bruce.sams.domain.sms; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.util.Date; +import lombok.Data; + +/** + * 社团表 + * @TableName sms_club + */ +@TableName(value ="sms_club") +@Data +public class Club { + /** + * 社团ID + */ + @TableId(type = IdType.AUTO) + private Long clubId; + + /** + * 社团名称 + */ + private String clubName; + + /** + * 社团简介 + */ + private String description; + + /** + * 社团类型 + */ + private String category; + + /** + * 所属院系 + */ + private Long collegeId; + + /** + * 负责人ID + */ + private Long leaderId; + + /** + * 创建时间 + */ + private Date createdAt; + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that == null) { + return false; + } + if (getClass() != that.getClass()) { + return false; + } + Club other = (Club) that; + return (this.getClubId() == null ? other.getClubId() == null : this.getClubId().equals(other.getClubId())) + && (this.getClubName() == null ? other.getClubName() == null : this.getClubName().equals(other.getClubName())) + && (this.getDescription() == null ? other.getDescription() == null : this.getDescription().equals(other.getDescription())) + && (this.getCategory() == null ? other.getCategory() == null : this.getCategory().equals(other.getCategory())) + && (this.getCollegeId() == null ? other.getCollegeId() == null : this.getCollegeId().equals(other.getCollegeId())) + && (this.getLeaderId() == null ? other.getLeaderId() == null : this.getLeaderId().equals(other.getLeaderId())) + && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt())); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((getClubId() == null) ? 0 : getClubId().hashCode()); + result = prime * result + ((getClubName() == null) ? 0 : getClubName().hashCode()); + result = prime * result + ((getDescription() == null) ? 0 : getDescription().hashCode()); + result = prime * result + ((getCategory() == null) ? 0 : getCategory().hashCode()); + result = prime * result + ((getCollegeId() == null) ? 0 : getCollegeId().hashCode()); + result = prime * result + ((getLeaderId() == null) ? 0 : getLeaderId().hashCode()); + result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode()); + return result; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()); + sb.append(" ["); + sb.append("Hash = ").append(hashCode()); + sb.append(", clubId=").append(clubId); + sb.append(", clubName=").append(clubName); + sb.append(", description=").append(description); + sb.append(", category=").append(category); + sb.append(", collegeId=").append(collegeId); + sb.append(", leaderId=").append(leaderId); + sb.append(", createdAt=").append(createdAt); + sb.append("]"); + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/bruce/sams/domain/sms/UserClub.java b/src/main/java/com/bruce/sams/domain/sms/UserClub.java new file mode 100644 index 00000000..77ec8acc --- /dev/null +++ b/src/main/java/com/bruce/sams/domain/sms/UserClub.java @@ -0,0 +1,96 @@ +package com.bruce.sams.domain.sms; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.util.Date; +import lombok.Data; + +/** + * 用户社团关系表 + * @TableName sms_user_club + */ +@TableName(value ="sms_user_club") +@Data +public class UserClub { + /** + * ID + */ + @TableId(type = IdType.AUTO) + private Long sucId; + + /** + * 用户ID + */ + private Long userId; + + /** + * 社团ID + */ + private Long clubId; + + /** + * 角色ID + */ + private Long roleId; + + /** + * 是否活跃 + */ + private Integer isActive; + + /** + * 加入日期 + */ + private Date joinDate; + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that == null) { + return false; + } + if (getClass() != that.getClass()) { + return false; + } + UserClub other = (UserClub) that; + return (this.getSucId() == null ? other.getSucId() == null : this.getSucId().equals(other.getSucId())) + && (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId())) + && (this.getClubId() == null ? other.getClubId() == null : this.getClubId().equals(other.getClubId())) + && (this.getRoleId() == null ? other.getRoleId() == null : this.getRoleId().equals(other.getRoleId())) + && (this.getIsActive() == null ? other.getIsActive() == null : this.getIsActive().equals(other.getIsActive())) + && (this.getJoinDate() == null ? other.getJoinDate() == null : this.getJoinDate().equals(other.getJoinDate())); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((getSucId() == null) ? 0 : getSucId().hashCode()); + result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode()); + result = prime * result + ((getClubId() == null) ? 0 : getClubId().hashCode()); + result = prime * result + ((getRoleId() == null) ? 0 : getRoleId().hashCode()); + result = prime * result + ((getIsActive() == null) ? 0 : getIsActive().hashCode()); + result = prime * result + ((getJoinDate() == null) ? 0 : getJoinDate().hashCode()); + return result; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()); + sb.append(" ["); + sb.append("Hash = ").append(hashCode()); + sb.append(", sucId=").append(sucId); + sb.append(", userId=").append(userId); + sb.append(", clubId=").append(clubId); + sb.append(", roleId=").append(roleId); + sb.append(", isActive=").append(isActive); + sb.append(", joinDate=").append(joinDate); + sb.append("]"); + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/bruce/sams/mapper/ActivityMapper.java b/src/main/java/com/bruce/sams/mapper/ActivityMapper.java new file mode 100644 index 00000000..a6473d1c --- /dev/null +++ b/src/main/java/com/bruce/sams/mapper/ActivityMapper.java @@ -0,0 +1,20 @@ +package com.bruce.sams.mapper; + +import com.bruce.sams.domain.ams.Activity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** +* @author bruce +* @description 针对表【ams_activity(活动表)】的数据库操作Mapper +* @createDate 2025-02-17 11:41:53 +* @Entity com.bruce.sams.domain.ams.Activity +*/ +@Mapper +public interface ActivityMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/bruce/sams/mapper/ClubMapper.java b/src/main/java/com/bruce/sams/mapper/ClubMapper.java new file mode 100644 index 00000000..e1b31839 --- /dev/null +++ b/src/main/java/com/bruce/sams/mapper/ClubMapper.java @@ -0,0 +1,20 @@ +package com.bruce.sams.mapper; + +import com.bruce.sams.domain.sms.Club; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** +* @author bruce +* @description 针对表【sms_club(社团表)】的数据库操作Mapper +* @createDate 2025-02-15 14:13:32 +* @Entity com.bruce.sams.domain.sms.Club +*/ +@Mapper +public interface ClubMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/bruce/sams/mapper/UserClubMapper.java b/src/main/java/com/bruce/sams/mapper/UserClubMapper.java new file mode 100644 index 00000000..d73a10cb --- /dev/null +++ b/src/main/java/com/bruce/sams/mapper/UserClubMapper.java @@ -0,0 +1,20 @@ +package com.bruce.sams.mapper; + +import com.bruce.sams.domain.sms.UserClub; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** +* @author bruce +* @description 针对表【sms_user_club(用户社团关系表)】的数据库操作Mapper +* @createDate 2025-02-15 15:00:18 +* @Entity com.bruce.sams.domain.sms.UserClub +*/ +@Mapper +public interface UserClubMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/bruce/sams/service/ActivityService.java b/src/main/java/com/bruce/sams/service/ActivityService.java new file mode 100644 index 00000000..bbc152db --- /dev/null +++ b/src/main/java/com/bruce/sams/service/ActivityService.java @@ -0,0 +1,49 @@ +package com.bruce.sams.service; + +import com.bruce.sams.domain.ams.Activity; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** +* @author bruce +* @description 针对表【ams_activity(活动表)】的数据库操作Service +* @createDate 2025-02-17 11:41:53 +*/ +public interface ActivityService extends IService { + /** + * 获取所有活动 + */ + List getAllActivities(); + + /** + * 获取活动详情 + */ + Activity getActivityById(Long actId); + + /** + * 获取某个社团的所有活动 + */ + List getActivitiesByClubId(Long clubId); + + /** + * 添加活动 + */ + void addActivity(Activity activity); + + /** + * 更新活动信息 + */ + void updateActivity(Activity activity); + + /** + * 删除活动 + */ + void deleteActivity(Long actId); + + /** + * 启动/暂停/取消活动 + */ + void changeActivityStatus(Long actId, String newStatus); + +} diff --git a/src/main/java/com/bruce/sams/service/ClubService.java b/src/main/java/com/bruce/sams/service/ClubService.java new file mode 100644 index 00000000..87898fdb --- /dev/null +++ b/src/main/java/com/bruce/sams/service/ClubService.java @@ -0,0 +1,56 @@ +package com.bruce.sams.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.bruce.sams.domain.sms.Club; +import com.baomidou.mybatisplus.extension.service.IService; +import com.bruce.sams.domain.sms.UserClub; + +import java.util.List; + +/** +* @author bruce +* @description 针对表【sms_club(社团表)】的数据库操作Service +* @createDate 2025-02-15 14:13:32 +*/ +public interface ClubService extends IService { + + /** + * 获取所有社团 + */ + public List getAllClubs(); + + /** + * 获取社团详情 + */ + public Club getClubById(Long clubId); + + /** + * 添加社团 + */ + public void addClub(Club club); + + /** + * 更新社团信息 + */ + public void updateClub(Club club); + + /** + * 删除社团 + */ + public void deleteClub(Long clubId); + + /** + * 加入社团 + */ + public void joinClub(Long userId, Long clubId); + + /** + * 退出社团 + */ + public void leaveClub(Long userId, Long clubId); + + /** + * 获取社团成员 + */ + public List getClubMembers(Long clubId); +} diff --git a/src/main/java/com/bruce/sams/service/impl/ActivityServiceImpl.java b/src/main/java/com/bruce/sams/service/impl/ActivityServiceImpl.java new file mode 100644 index 00000000..bfbc2802 --- /dev/null +++ b/src/main/java/com/bruce/sams/service/impl/ActivityServiceImpl.java @@ -0,0 +1,84 @@ +package com.bruce.sams.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bruce.sams.domain.ams.Activity; +import com.bruce.sams.mapper.ActivityMapper; +import com.bruce.sams.service.ActivityService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 管理社团活动 + * + * @author bruce + * @description 针对表【ams_activity(活动表)】的数据库操作Service实现 + * @createDate 2025-02-17 11:41:53 + */ +@Service +public class ActivityServiceImpl extends ServiceImpl + implements ActivityService { + @Autowired + private ActivityMapper activityMapper; + + /** + * 获取所有活动 + */ + public List getAllActivities() { + return activityMapper.selectList(null); + } + + /** + * 获取活动详情 + */ + public Activity getActivityById(Long actId) { + return activityMapper.selectById(actId); + } + + /** + * 获取某个社团的所有活动 + */ + public List getActivitiesByClubId(Long clubId) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(Activity::getClubId, clubId); + return activityMapper.selectList(wrapper); + } + + /** + * 添加活动 + */ + public void addActivity(Activity activity) { + activityMapper.insert(activity); + } + + /** + * 更新活动信息 + */ + public void updateActivity(Activity activity) { + activityMapper.updateById(activity); + } + + /** + * 删除活动 + */ + public void deleteActivity(Long actId) { + activityMapper.deleteById(actId); + } + + /** + * 启动/暂停/取消活动 + */ + public void changeActivityStatus(Long actId, String newStatus) { + Activity activity = activityMapper.selectById(actId); + if (activity != null) { + activity.setStatus(newStatus); + activityMapper.updateById(activity); + } + } +} + + + + diff --git a/src/main/java/com/bruce/sams/service/impl/ClubServiceImpl.java b/src/main/java/com/bruce/sams/service/impl/ClubServiceImpl.java new file mode 100644 index 00000000..6b5eeb45 --- /dev/null +++ b/src/main/java/com/bruce/sams/service/impl/ClubServiceImpl.java @@ -0,0 +1,99 @@ +package com.bruce.sams.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bruce.sams.domain.sms.Club; +import com.bruce.sams.domain.sms.UserClub; +import com.bruce.sams.mapper.UserClubMapper; +import com.bruce.sams.service.ClubService; +import com.bruce.sams.mapper.ClubMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; + +/** +* @author bruce +* @description 针对表【sms_club(社团表)】的数据库操作Service实现 +* @createDate 2025-02-15 14:13:32 +*/ +@Service +public class ClubServiceImpl extends ServiceImpl + implements ClubService{ + @Autowired + private ClubMapper clubMapper; + + @Autowired + private UserClubMapper userClubMapper; + + /** + * 获取所有社团 + */ + public List getAllClubs() { + return clubMapper.selectList(null); + } + + /** + * 获取社团详情 + */ + public Club getClubById(Long clubId) { + return clubMapper.selectById(clubId); + } + + /** + * 添加社团 + */ + public void addClub(Club club) { + clubMapper.insert(club); + } + + /** + * 更新社团信息 + */ + public void updateClub(Club club) { + clubMapper.updateById(club); + } + + /** + * 删除社团 + */ + public void deleteClub(Long clubId) { + clubMapper.deleteById(clubId); + } + + /** + * 加入社团 + */ + public void joinClub(Long userId, Long clubId) { + UserClub userClub = new UserClub(); + userClub.setUserId(userId); + userClub.setClubId(clubId); + userClub.setRoleId(0L); // 普通成员 + userClub.setIsActive(1); + userClub.setJoinDate(new Date(System.currentTimeMillis())); + userClubMapper.insert(userClub); + } + + /** + * 退出社团 + */ + public void leaveClub(Long userId, Long clubId) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(UserClub::getUserId, userId).eq(UserClub::getClubId, clubId); + userClubMapper.delete(wrapper); + } + + /** + * 获取社团成员 + */ + public List getClubMembers(Long clubId) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(UserClub::getClubId, clubId); + return userClubMapper.selectList(wrapper); + } +} + + + + diff --git a/src/main/resources/mapper/ActivityMapper.xml b/src/main/resources/mapper/ActivityMapper.xml new file mode 100644 index 00000000..a0ba7178 --- /dev/null +++ b/src/main/resources/mapper/ActivityMapper.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + act_id,title,description,start_time,end_time,location, + budget,max_participants,creator_id,club_id,visibility, + status,created_at,updated_at + + diff --git a/src/main/resources/mapper/ClubMapper.xml b/src/main/resources/mapper/ClubMapper.xml new file mode 100644 index 00000000..ef4affcd --- /dev/null +++ b/src/main/resources/mapper/ClubMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + club_id,club_name,description,category,college_id,leader_id, + created_at + + diff --git a/src/main/resources/mapper/UserClubMapper.xml b/src/main/resources/mapper/UserClubMapper.xml new file mode 100644 index 00000000..273dc58d --- /dev/null +++ b/src/main/resources/mapper/UserClubMapper.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + suc_id,user_id,club_id,role_id,is_active,join_date + +