心理健康测评完成
This commit is contained in:
1 parent
79a96a7dfd
commit
461396c77f
26 files changed
+4276
-16
No files matched your search
@@ -407,6 +407,12 @@
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 社团管理模块 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-stgl</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
@@ -135,6 +135,13 @@
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 社团管理模块 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-stgl</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>de.codecentric</groupId>
|
||||
<artifactId>spring-boot-admin-starter-client</artifactId>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
<module>ruoyi-cw</module>
|
||||
<module>ruoyi-rs</module>
|
||||
<module>ruoyi-xljk</module>
|
||||
<module>ruoyi-stgl</module>
|
||||
</modules>
|
||||
|
||||
<artifactId>ruoyi-modules</artifactId>
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>ruoyi-modules</artifactId>
|
||||
<groupId>org.dromara</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ruoyi-stgl</artifactId>
|
||||
|
||||
<description>
|
||||
社团管理模块
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- 通用工具-->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 安全模块 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- web服务 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- excel -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-excel</artifactId>
|
||||
</dependency>
|
||||
<!-- Apache POI for Excel export -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>5.2.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 数据库 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 多租户 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-tenant</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 幂等性 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-idempotent</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 日志记录 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-log</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 数据翻译 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-translation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- OSS云存储 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-oss</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 接口文档 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-doc</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
package org.dromara.stgl.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.*;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.stgl.domain.vo.StglClubVo;
|
||||
import org.dromara.stgl.domain.bo.StglClubBo;
|
||||
import org.dromara.stgl.service.IStglClubService;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
/**
|
||||
* 社团信息管理
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/stgl/club")
|
||||
@Tag(name = "社团信息管理", description = "社团信息管理")
|
||||
public class StglClubController extends BaseController {
|
||||
|
||||
private final IStglClubService stglClubService;
|
||||
|
||||
/**
|
||||
* 查询社团信息列表
|
||||
*/
|
||||
@Operation(summary = "查询社团信息列表")
|
||||
@SaCheckPermission("stgl:club:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<StglClubVo> list(StglClubBo bo, PageQuery pageQuery) {
|
||||
return stglClubService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出社团信息列表
|
||||
*/
|
||||
@Operation(summary = "导出社团信息列表")
|
||||
@SaCheckPermission("stgl:club:export")
|
||||
@Log(title = "社团信息", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(StglClubBo bo, HttpServletResponse response) {
|
||||
List<StglClubVo> list = stglClubService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "社团信息", StglClubVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取社团信息详细信息
|
||||
*/
|
||||
@Operation(summary = "获取社团信息详细信息")
|
||||
@SaCheckPermission("stgl:club:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<StglClubVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(stglClubService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增社团信息
|
||||
*/
|
||||
@Operation(summary = "新增社团信息")
|
||||
@SaCheckPermission("stgl:club:add")
|
||||
@Log(title = "社团信息", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody StglClubBo bo) {
|
||||
return toAjax(stglClubService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改社团信息
|
||||
*/
|
||||
@Operation(summary = "修改社团信息")
|
||||
@SaCheckPermission("stgl:club:edit")
|
||||
@Log(title = "社团信息", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody StglClubBo bo) {
|
||||
return toAjax(stglClubService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除社团信息
|
||||
*/
|
||||
@Operation(summary = "删除社团信息")
|
||||
@SaCheckPermission("stgl:club:remove")
|
||||
@Log(title = "社团信息", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(stglClubService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询可用的社团选项
|
||||
*/
|
||||
@Operation(summary = "查询可用的社团选项")
|
||||
@SaCheckPermission("stgl:club:list")
|
||||
@GetMapping("/options")
|
||||
public R<List<StglClubVo>> getOptions() {
|
||||
return R.ok(stglClubService.queryAvailableOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据社团类型查询社团列表
|
||||
*/
|
||||
@Operation(summary = "根据社团类型查询社团列表")
|
||||
@SaCheckPermission("stgl:club:list")
|
||||
@GetMapping("/listByType/{clubType}")
|
||||
@Parameters({
|
||||
@Parameter(name = "clubType", description = "社团类型", required = true)
|
||||
})
|
||||
public R<List<StglClubVo>> listByType(@PathVariable String clubType) {
|
||||
return R.ok(stglClubService.queryByClubType(clubType));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我管理的社团列表
|
||||
*/
|
||||
@Operation(summary = "查询我管理的社团列表")
|
||||
@SaCheckPermission("stgl:club:list")
|
||||
@GetMapping("/myClubs")
|
||||
public R<List<StglClubVo>> getMyClubs() {
|
||||
return R.ok(stglClubService.queryMyClubs());
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查社团名称是否重复
|
||||
*/
|
||||
@Operation(summary = "检查社团名称是否重复")
|
||||
@SaCheckPermission("stgl:club:list")
|
||||
@GetMapping("/checkClubNameUnique")
|
||||
@Parameters({
|
||||
@Parameter(name = "clubName", description = "社团名称", required = true),
|
||||
@Parameter(name = "excludeId", description = "排除的ID", required = false)
|
||||
})
|
||||
public R<Boolean> checkClubNameUnique(@RequestParam String clubName,
|
||||
@RequestParam(required = false) Long excludeId) {
|
||||
return R.ok(stglClubService.checkClubNameUnique(clubName, excludeId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用/禁用社团
|
||||
*/
|
||||
@Operation(summary = "启用/禁用社团")
|
||||
@SaCheckPermission("stgl:club:edit")
|
||||
@Log(title = "社团信息", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/changeStatus")
|
||||
@Parameters({
|
||||
@Parameter(name = "id", description = "社团ID", required = true),
|
||||
@Parameter(name = "status", description = "状态", required = true)
|
||||
})
|
||||
public R<Void> changeStatus(@RequestParam Long id, @RequestParam Integer status) {
|
||||
return toAjax(stglClubService.changeStatus(id, status));
|
||||
}
|
||||
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
package org.dromara.stgl.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import jakarta.validation.constraints.*;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.stgl.domain.vo.StglClubRegisterVo;
|
||||
import org.dromara.stgl.service.IStglClubRegisterService;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
/**
|
||||
* 社团报名大厅
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/stgl/register")
|
||||
@Tag(name = "社团报名大厅", description = "社团报名大厅")
|
||||
public class StglClubRegisterController extends BaseController {
|
||||
|
||||
private final IStglClubRegisterService stglClubRegisterService;
|
||||
|
||||
/**
|
||||
* 查询社团报名大厅列表
|
||||
*/
|
||||
@Operation(summary = "查询社团报名大厅列表")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<StglClubRegisterVo> list(@RequestParam(required = false) String clubType,
|
||||
@RequestParam(required = false) String clubName,
|
||||
PageQuery pageQuery) {
|
||||
return stglClubRegisterService.queryPageList(clubType, clubName, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询社团报名大厅列表(不分页)
|
||||
*/
|
||||
@Operation(summary = "查询社团报名大厅列表(不分页)")
|
||||
@GetMapping("/listAll")
|
||||
public R<List<StglClubRegisterVo>> listAll(@RequestParam(required = false) String clubType,
|
||||
@RequestParam(required = false) String clubName) {
|
||||
return R.ok(stglClubRegisterService.queryList(clubType, clubName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取社团详细信息
|
||||
*/
|
||||
@Operation(summary = "获取社团详细信息")
|
||||
@GetMapping("/{clubId}")
|
||||
@Parameters({
|
||||
@Parameter(name = "clubId", description = "社团ID", required = true)
|
||||
})
|
||||
public R<StglClubRegisterVo> getClubDetail(@PathVariable Long clubId) {
|
||||
return R.ok(stglClubRegisterService.queryClubDetail(clubId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 报名加入社团
|
||||
*/
|
||||
@Operation(summary = "报名加入社团")
|
||||
@SaCheckPermission("stgl:register:join")
|
||||
@Log(title = "社团报名", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/join/{clubId}")
|
||||
@Parameters({
|
||||
@Parameter(name = "clubId", description = "社团ID", required = true)
|
||||
})
|
||||
public R<Void> registerClub(@PathVariable Long clubId) {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
return toAjax(stglClubRegisterService.registerClub(clubId, userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出社团
|
||||
*/
|
||||
@Operation(summary = "退出社团")
|
||||
@SaCheckPermission("stgl:register:quit")
|
||||
@Log(title = "社团退出", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/quit/{clubId}")
|
||||
@Parameters({
|
||||
@Parameter(name = "clubId", description = "社团ID", required = true)
|
||||
})
|
||||
public R<Void> quitClub(@PathVariable Long clubId) {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
return toAjax(stglClubRegisterService.quitClub(clubId, userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我参与的社团列表
|
||||
*/
|
||||
@Operation(summary = "查询我参与的社团列表")
|
||||
@SaCheckPermission("stgl:register:list")
|
||||
@GetMapping("/myClubs")
|
||||
public R<List<StglClubRegisterVo>> getMyClubs() {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
return R.ok(stglClubRegisterService.queryMyClubs(userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否已报名某个社团
|
||||
*/
|
||||
@Operation(summary = "检查是否已报名某个社团")
|
||||
@GetMapping("/checkRegistered/{clubId}")
|
||||
@Parameters({
|
||||
@Parameter(name = "clubId", description = "社团ID", required = true)
|
||||
})
|
||||
public R<Boolean> checkRegistered(@PathVariable Long clubId) {
|
||||
try {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
return R.ok(stglClubRegisterService.checkRegistered(clubId, userId));
|
||||
} catch (Exception e) {
|
||||
// 未登录用户
|
||||
return R.ok(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询推荐社团
|
||||
*/
|
||||
@Operation(summary = "查询推荐社团")
|
||||
@GetMapping("/recommend")
|
||||
@Parameters({
|
||||
@Parameter(name = "clubType", description = "社团类型", required = false),
|
||||
@Parameter(name = "limit", description = "推荐数量", required = false)
|
||||
})
|
||||
public R<List<StglClubRegisterVo>> getRecommendClubs(@RequestParam(required = false) String clubType,
|
||||
@RequestParam(required = false, defaultValue = "6") Integer limit) {
|
||||
return R.ok(stglClubRegisterService.queryRecommendClubs(clubType, limit));
|
||||
}
|
||||
|
||||
}
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
package org.dromara.stgl.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.*;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.stgl.domain.vo.StglMemberVo;
|
||||
import org.dromara.stgl.domain.bo.StglMemberBo;
|
||||
import org.dromara.stgl.service.IStglMemberService;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
/**
|
||||
* 社团成员管理
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/stgl/member")
|
||||
@Tag(name = "社团成员管理", description = "社团成员管理")
|
||||
public class StglMemberController extends BaseController {
|
||||
|
||||
private final IStglMemberService stglMemberService;
|
||||
|
||||
/**
|
||||
* 查询社团成员列表
|
||||
*/
|
||||
@Operation(summary = "查询社团成员列表")
|
||||
@SaCheckPermission("stgl:member:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<StglMemberVo> list(StglMemberBo bo, PageQuery pageQuery) {
|
||||
return stglMemberService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出社团成员列表
|
||||
*/
|
||||
@Operation(summary = "导出社团成员列表")
|
||||
@SaCheckPermission("stgl:member:export")
|
||||
@Log(title = "社团成员", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(StglMemberBo bo, HttpServletResponse response) {
|
||||
List<StglMemberVo> list = stglMemberService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "社团成员", StglMemberVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取社团成员详细信息
|
||||
*/
|
||||
@Operation(summary = "获取社团成员详细信息")
|
||||
@SaCheckPermission("stgl:member:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<StglMemberVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(stglMemberService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增社团成员
|
||||
*/
|
||||
@Operation(summary = "新增社团成员")
|
||||
@SaCheckPermission("stgl:member:add")
|
||||
@Log(title = "社团成员", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody StglMemberBo bo) {
|
||||
return toAjax(stglMemberService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改社团成员
|
||||
*/
|
||||
@Operation(summary = "修改社团成员")
|
||||
@SaCheckPermission("stgl:member:edit")
|
||||
@Log(title = "社团成员", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody StglMemberBo bo) {
|
||||
return toAjax(stglMemberService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除社团成员
|
||||
*/
|
||||
@Operation(summary = "删除社团成员")
|
||||
@SaCheckPermission("stgl:member:remove")
|
||||
@Log(title = "社团成员", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(stglMemberService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据社团ID查询成员列表
|
||||
*/
|
||||
@Operation(summary = "根据社团ID查询成员列表")
|
||||
@SaCheckPermission("stgl:member:list")
|
||||
@GetMapping("/club/{clubId}")
|
||||
@Parameters({
|
||||
@Parameter(name = "clubId", description = "社团ID", required = true)
|
||||
})
|
||||
public R<List<StglMemberVo>> getByClubId(@PathVariable Long clubId) {
|
||||
return R.ok(stglMemberService.queryByClubId(clubId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户ID查询参与的社团列表
|
||||
*/
|
||||
@Operation(summary = "根据用户ID查询参与的社团列表")
|
||||
@SaCheckPermission("stgl:member:list")
|
||||
@GetMapping("/user/{userId}")
|
||||
@Parameters({
|
||||
@Parameter(name = "userId", description = "用户ID", required = true)
|
||||
})
|
||||
public R<List<StglMemberVo>> getByUserId(@PathVariable Long userId) {
|
||||
return R.ok(stglMemberService.queryByUserId(userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户是否已是某个社团/队伍的成员
|
||||
*/
|
||||
@Operation(summary = "检查用户是否已是某个社团/队伍的成员")
|
||||
@SaCheckPermission("stgl:member:list")
|
||||
@GetMapping("/checkMemberExists")
|
||||
@Parameters({
|
||||
@Parameter(name = "memberType", description = "成员类型", required = true),
|
||||
@Parameter(name = "relationId", description = "关联ID", required = true),
|
||||
@Parameter(name = "userId", description = "用户ID", required = true)
|
||||
})
|
||||
public R<Boolean> checkMemberExists(@RequestParam Integer memberType,
|
||||
@RequestParam Long relationId,
|
||||
@RequestParam Long userId) {
|
||||
return R.ok(stglMemberService.checkMemberExists(memberType, relationId, userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加成员
|
||||
*/
|
||||
@Operation(summary = "批量添加成员")
|
||||
@SaCheckPermission("stgl:member:add")
|
||||
@Log(title = "社团成员", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/batchAdd")
|
||||
@Parameters({
|
||||
@Parameter(name = "memberType", description = "成员类型", required = true),
|
||||
@Parameter(name = "relationId", description = "关联ID", required = true),
|
||||
@Parameter(name = "userIds", description = "用户ID列表", required = true),
|
||||
@Parameter(name = "roleType", description = "角色类型", required = false)
|
||||
})
|
||||
public R<Void> batchAddMembers(@RequestParam Integer memberType,
|
||||
@RequestParam Long relationId,
|
||||
@RequestParam List<Long> userIds,
|
||||
@RequestParam(required = false) Integer roleType) {
|
||||
return toAjax(stglMemberService.batchAddMembers(memberType, relationId, userIds, roleType));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新成员角色
|
||||
*/
|
||||
@Operation(summary = "更新成员角色")
|
||||
@SaCheckPermission("stgl:member:edit")
|
||||
@Log(title = "社团成员", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/updateRole")
|
||||
@Parameters({
|
||||
@Parameter(name = "id", description = "成员ID", required = true),
|
||||
@Parameter(name = "roleType", description = "角色类型", required = true)
|
||||
})
|
||||
public R<Void> updateMemberRole(@RequestParam Long id, @RequestParam Integer roleType) {
|
||||
return toAjax(stglMemberService.updateMemberRole(id, roleType));
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出社团/队伍
|
||||
*/
|
||||
@Operation(summary = "退出社团/队伍")
|
||||
@SaCheckPermission("stgl:member:edit")
|
||||
@Log(title = "社团成员", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/quit/{id}")
|
||||
@Parameters({
|
||||
@Parameter(name = "id", description = "成员ID", required = true)
|
||||
})
|
||||
public R<Void> quitMember(@PathVariable Long id) {
|
||||
return toAjax(stglMemberService.quitMember(id));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
package org.dromara.stgl.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import org.dromara.common.tenant.core.TenantEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 社团信息对象 stgl_club
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("stgl_club")
|
||||
public class StglClub extends TenantEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 社团名称
|
||||
*/
|
||||
private String clubName;
|
||||
|
||||
/**
|
||||
* 社团类型
|
||||
*/
|
||||
private String clubType;
|
||||
|
||||
/**
|
||||
* 成立日期
|
||||
*/
|
||||
private Date establishDate;
|
||||
|
||||
/**
|
||||
* 社团简介(500字以内)
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 电话
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* logo图片路径
|
||||
*/
|
||||
private String logoUrl;
|
||||
|
||||
/**
|
||||
* 社长姓名
|
||||
*/
|
||||
private String presidentName;
|
||||
|
||||
/**
|
||||
* 社长学号
|
||||
*/
|
||||
private String presidentStudentNo;
|
||||
|
||||
/**
|
||||
* 社长院系
|
||||
*/
|
||||
private String presidentDept;
|
||||
|
||||
/**
|
||||
* 社长专业
|
||||
*/
|
||||
private String presidentMajor;
|
||||
|
||||
/**
|
||||
* 社长班级
|
||||
*/
|
||||
private String presidentClass;
|
||||
|
||||
/**
|
||||
* 社长联系方式
|
||||
*/
|
||||
private String presidentPhone;
|
||||
|
||||
/**
|
||||
* 副社长姓名
|
||||
*/
|
||||
private String vicePresidentName;
|
||||
|
||||
/**
|
||||
* 副社长学号
|
||||
*/
|
||||
private String vicePresidentStudentNo;
|
||||
|
||||
/**
|
||||
* 指导老师姓名
|
||||
*/
|
||||
private String advisorName;
|
||||
|
||||
/**
|
||||
* 指导老师所属院系
|
||||
*/
|
||||
private String advisorDept;
|
||||
|
||||
/**
|
||||
* 成员规模上限
|
||||
*/
|
||||
private Integer memberLimit;
|
||||
|
||||
/**
|
||||
* 组织架构(部门设置及职责)
|
||||
*/
|
||||
private String departments;
|
||||
|
||||
/**
|
||||
* 招新周期
|
||||
*/
|
||||
private String recruitCycle;
|
||||
|
||||
/**
|
||||
* 招新时间
|
||||
*/
|
||||
private String recruitTime;
|
||||
|
||||
/**
|
||||
* 活动频率
|
||||
*/
|
||||
private String activityFrequency;
|
||||
|
||||
/**
|
||||
* 经费来源(多选)
|
||||
*/
|
||||
private String fundingSources;
|
||||
|
||||
/**
|
||||
* 章程文档路径
|
||||
*/
|
||||
private String charterUrl;
|
||||
|
||||
/**
|
||||
* 状态(1-正常 0-停用)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package org.dromara.stgl.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import org.dromara.common.tenant.core.TenantEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 社团成员对象 stgl_member
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("stgl_member")
|
||||
public class StglMember extends TenantEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 成员类型(1-社团成员 2-志愿者)
|
||||
*/
|
||||
private Integer memberType;
|
||||
|
||||
/**
|
||||
* 关联ID(社团ID或志愿者队伍ID)
|
||||
*/
|
||||
private Long relationId;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 学号
|
||||
*/
|
||||
private String studentNo;
|
||||
|
||||
/**
|
||||
* 学生姓名
|
||||
*/
|
||||
private String studentName;
|
||||
|
||||
/**
|
||||
* 角色类型(1-社长 2-副社长 3-成员)
|
||||
*/
|
||||
private Integer roleType;
|
||||
|
||||
/**
|
||||
* 加入时间
|
||||
*/
|
||||
private Date joinTime;
|
||||
|
||||
/**
|
||||
* 状态(1-正常 0-退出)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
package org.dromara.stgl.domain.bo;
|
||||
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import jakarta.validation.constraints.*;
|
||||
import org.dromara.stgl.domain.StglClub;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 社团信息业务对象 stgl_club
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = StglClub.class, reverseConvertGenerate = false)
|
||||
public class StglClubBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 社团名称
|
||||
*/
|
||||
@NotBlank(message = "社团名称不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
@Size(max = 100, message = "社团名称长度不能超过100个字符")
|
||||
private String clubName;
|
||||
|
||||
/**
|
||||
* 社团类型
|
||||
*/
|
||||
@NotBlank(message = "社团类型不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
@Size(max = 50, message = "社团类型长度不能超过50个字符")
|
||||
private String clubType;
|
||||
|
||||
/**
|
||||
* 成立日期
|
||||
*/
|
||||
private Date establishDate;
|
||||
|
||||
/**
|
||||
* 社团简介(500字以内)
|
||||
*/
|
||||
@Size(max = 500, message = "社团简介长度不能超过500个字符")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
@Email(message = "邮箱格式不正确")
|
||||
@Size(max = 100, message = "邮箱长度不能超过100个字符")
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 电话
|
||||
*/
|
||||
@Pattern(regexp = "^[0-9-]+$", message = "电话格式不正确")
|
||||
@Size(max = 20, message = "电话长度不能超过20个字符")
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* logo图片路径
|
||||
*/
|
||||
@Size(max = 500, message = "logo图片路径长度不能超过500个字符")
|
||||
private String logoUrl;
|
||||
|
||||
/**
|
||||
* 社长姓名
|
||||
*/
|
||||
@Size(max = 50, message = "社长姓名长度不能超过50个字符")
|
||||
private String presidentName;
|
||||
|
||||
/**
|
||||
* 社长学号
|
||||
*/
|
||||
@Size(max = 20, message = "社长学号长度不能超过20个字符")
|
||||
private String presidentStudentNo;
|
||||
|
||||
/**
|
||||
* 社长院系
|
||||
*/
|
||||
@Size(max = 100, message = "社长院系长度不能超过100个字符")
|
||||
private String presidentDept;
|
||||
|
||||
/**
|
||||
* 社长专业
|
||||
*/
|
||||
@Size(max = 100, message = "社长专业长度不能超过100个字符")
|
||||
private String presidentMajor;
|
||||
|
||||
/**
|
||||
* 社长班级
|
||||
*/
|
||||
@Size(max = 100, message = "社长班级长度不能超过100个字符")
|
||||
private String presidentClass;
|
||||
|
||||
/**
|
||||
* 社长联系方式
|
||||
*/
|
||||
@Pattern(regexp = "^[0-9-]+$", message = "社长联系方式格式不正确")
|
||||
@Size(max = 20, message = "社长联系方式长度不能超过20个字符")
|
||||
private String presidentPhone;
|
||||
|
||||
/**
|
||||
* 副社长姓名
|
||||
*/
|
||||
@Size(max = 50, message = "副社长姓名长度不能超过50个字符")
|
||||
private String vicePresidentName;
|
||||
|
||||
/**
|
||||
* 副社长学号
|
||||
*/
|
||||
@Size(max = 20, message = "副社长学号长度不能超过20个字符")
|
||||
private String vicePresidentStudentNo;
|
||||
|
||||
/**
|
||||
* 指导老师姓名
|
||||
*/
|
||||
@Size(max = 50, message = "指导老师姓名长度不能超过50个字符")
|
||||
private String advisorName;
|
||||
|
||||
/**
|
||||
* 指导老师所属院系
|
||||
*/
|
||||
@Size(max = 100, message = "指导老师所属院系长度不能超过100个字符")
|
||||
private String advisorDept;
|
||||
|
||||
/**
|
||||
* 成员规模上限
|
||||
*/
|
||||
@Min(value = 0, message = "成员规模上限不能小于0")
|
||||
private Integer memberLimit;
|
||||
|
||||
/**
|
||||
* 组织架构(部门设置及职责)
|
||||
*/
|
||||
private String departments;
|
||||
|
||||
/**
|
||||
* 招新周期
|
||||
*/
|
||||
@Size(max = 50, message = "招新周期长度不能超过50个字符")
|
||||
private String recruitCycle;
|
||||
|
||||
/**
|
||||
* 招新时间
|
||||
*/
|
||||
@Size(max = 50, message = "招新时间长度不能超过50个字符")
|
||||
private String recruitTime;
|
||||
|
||||
/**
|
||||
* 活动频率
|
||||
*/
|
||||
@Size(max = 50, message = "活动频率长度不能超过50个字符")
|
||||
private String activityFrequency;
|
||||
|
||||
/**
|
||||
* 经费来源(多选)
|
||||
*/
|
||||
@Size(max = 200, message = "经费来源长度不能超过200个字符")
|
||||
private String fundingSources;
|
||||
|
||||
/**
|
||||
* 章程文档路径
|
||||
*/
|
||||
@Size(max = 500, message = "章程文档路径长度不能超过500个字符")
|
||||
private String charterUrl;
|
||||
|
||||
/**
|
||||
* 状态(1-正常 0-停用)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
package org.dromara.stgl.domain.bo;
|
||||
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import jakarta.validation.constraints.*;
|
||||
import org.dromara.stgl.domain.StglMember;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 社团成员业务对象 stgl_member
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = StglMember.class, reverseConvertGenerate = false)
|
||||
public class StglMemberBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 成员类型(1-社团成员 2-志愿者)
|
||||
*/
|
||||
@NotNull(message = "成员类型不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
@Min(value = 1, message = "成员类型值无效")
|
||||
@Max(value = 2, message = "成员类型值无效")
|
||||
private Integer memberType;
|
||||
|
||||
/**
|
||||
* 关联ID(社团ID或志愿者队伍ID)
|
||||
*/
|
||||
@NotNull(message = "关联ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Long relationId;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@NotNull(message = "用户ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 学号
|
||||
*/
|
||||
@Size(max = 20, message = "学号长度不能超过20个字符")
|
||||
private String studentNo;
|
||||
|
||||
/**
|
||||
* 学生姓名
|
||||
*/
|
||||
@Size(max = 50, message = "学生姓名长度不能超过50个字符")
|
||||
private String studentName;
|
||||
|
||||
/**
|
||||
* 角色类型(1-社长 2-副社长 3-成员)
|
||||
*/
|
||||
@Min(value = 1, message = "角色类型值无效")
|
||||
@Max(value = 3, message = "角色类型值无效")
|
||||
private Integer roleType;
|
||||
|
||||
/**
|
||||
* 加入时间
|
||||
*/
|
||||
private Date joinTime;
|
||||
|
||||
/**
|
||||
* 状态(1-正常 0-退出)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
package org.dromara.stgl.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 社团报名大厅视图对象
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@Data
|
||||
public class StglClubRegisterVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 社团名称
|
||||
*/
|
||||
private String clubName;
|
||||
|
||||
/**
|
||||
* 社团类型
|
||||
*/
|
||||
private String clubType;
|
||||
|
||||
/**
|
||||
* 成立日期
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date establishDate;
|
||||
|
||||
/**
|
||||
* 社团简介(500字以内)
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* logo图片路径
|
||||
*/
|
||||
private String logoUrl;
|
||||
|
||||
/**
|
||||
* 社长姓名
|
||||
*/
|
||||
private String presidentName;
|
||||
|
||||
/**
|
||||
* 社长院系
|
||||
*/
|
||||
private String presidentDept;
|
||||
|
||||
/**
|
||||
* 指导老师姓名
|
||||
*/
|
||||
private String advisorName;
|
||||
|
||||
/**
|
||||
* 指导老师所属院系
|
||||
*/
|
||||
private String advisorDept;
|
||||
|
||||
/**
|
||||
* 成员规模上限
|
||||
*/
|
||||
private Integer memberLimit;
|
||||
|
||||
/**
|
||||
* 当前成员数量
|
||||
*/
|
||||
private Integer currentMemberCount;
|
||||
|
||||
/**
|
||||
* 招新周期
|
||||
*/
|
||||
private String recruitCycle;
|
||||
|
||||
/**
|
||||
* 招新时间
|
||||
*/
|
||||
private String recruitTime;
|
||||
|
||||
/**
|
||||
* 活动频率
|
||||
*/
|
||||
private String activityFrequency;
|
||||
|
||||
/**
|
||||
* 是否已报名
|
||||
*/
|
||||
private Boolean hasRegistered;
|
||||
|
||||
/**
|
||||
* 报名状态(1-已报名 0-未报名)
|
||||
*/
|
||||
private Integer registrationStatus;
|
||||
|
||||
/**
|
||||
* 是否可报名(基于成员上限等条件)
|
||||
*/
|
||||
private Boolean canRegister;
|
||||
|
||||
}
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
package org.dromara.stgl.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.stgl.domain.StglClub;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 社团信息视图对象 stgl_club
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = StglClub.class)
|
||||
public class StglClubVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@ExcelProperty(value = "主键ID")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 社团名称
|
||||
*/
|
||||
@ExcelProperty(value = "社团名称")
|
||||
private String clubName;
|
||||
|
||||
/**
|
||||
* 社团类型
|
||||
*/
|
||||
@ExcelProperty(value = "社团类型")
|
||||
private String clubType;
|
||||
|
||||
/**
|
||||
* 成立日期
|
||||
*/
|
||||
@ExcelProperty(value = "成立日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date establishDate;
|
||||
|
||||
/**
|
||||
* 社团简介(500字以内)
|
||||
*/
|
||||
@ExcelProperty(value = "社团简介")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
@ExcelProperty(value = "邮箱")
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 电话
|
||||
*/
|
||||
@ExcelProperty(value = "电话")
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* logo图片路径
|
||||
*/
|
||||
@ExcelProperty(value = "社团Logo")
|
||||
private String logoUrl;
|
||||
|
||||
/**
|
||||
* 社长姓名
|
||||
*/
|
||||
@ExcelProperty(value = "社长姓名")
|
||||
private String presidentName;
|
||||
|
||||
/**
|
||||
* 社长学号
|
||||
*/
|
||||
@ExcelProperty(value = "社长学号")
|
||||
private String presidentStudentNo;
|
||||
|
||||
/**
|
||||
* 社长院系
|
||||
*/
|
||||
@ExcelProperty(value = "社长院系")
|
||||
private String presidentDept;
|
||||
|
||||
/**
|
||||
* 社长专业
|
||||
*/
|
||||
@ExcelProperty(value = "社长专业")
|
||||
private String presidentMajor;
|
||||
|
||||
/**
|
||||
* 社长班级
|
||||
*/
|
||||
@ExcelProperty(value = "社长班级")
|
||||
private String presidentClass;
|
||||
|
||||
/**
|
||||
* 社长联系方式
|
||||
*/
|
||||
@ExcelProperty(value = "社长联系方式")
|
||||
private String presidentPhone;
|
||||
|
||||
/**
|
||||
* 副社长姓名
|
||||
*/
|
||||
@ExcelProperty(value = "副社长姓名")
|
||||
private String vicePresidentName;
|
||||
|
||||
/**
|
||||
* 副社长学号
|
||||
*/
|
||||
@ExcelProperty(value = "副社长学号")
|
||||
private String vicePresidentStudentNo;
|
||||
|
||||
/**
|
||||
* 指导老师姓名
|
||||
*/
|
||||
@ExcelProperty(value = "指导老师姓名")
|
||||
private String advisorName;
|
||||
|
||||
/**
|
||||
* 指导老师所属院系
|
||||
*/
|
||||
@ExcelProperty(value = "指导老师所属院系")
|
||||
private String advisorDept;
|
||||
|
||||
/**
|
||||
* 成员规模上限
|
||||
*/
|
||||
@ExcelProperty(value = "成员规模上限")
|
||||
private Integer memberLimit;
|
||||
|
||||
/**
|
||||
* 组织架构(部门设置及职责)
|
||||
*/
|
||||
@ExcelProperty(value = "组织架构")
|
||||
private String departments;
|
||||
|
||||
/**
|
||||
* 招新周期
|
||||
*/
|
||||
@ExcelProperty(value = "招新周期")
|
||||
private String recruitCycle;
|
||||
|
||||
/**
|
||||
* 招新时间
|
||||
*/
|
||||
@ExcelProperty(value = "招新时间")
|
||||
private String recruitTime;
|
||||
|
||||
/**
|
||||
* 活动频率
|
||||
*/
|
||||
@ExcelProperty(value = "活动频率")
|
||||
private String activityFrequency;
|
||||
|
||||
/**
|
||||
* 经费来源(多选)
|
||||
*/
|
||||
@ExcelProperty(value = "经费来源")
|
||||
private String fundingSources;
|
||||
|
||||
/**
|
||||
* 章程文档路径
|
||||
*/
|
||||
@ExcelProperty(value = "章程文档")
|
||||
private String charterUrl;
|
||||
|
||||
/**
|
||||
* 状态(1-正常 0-停用)
|
||||
*/
|
||||
@ExcelProperty(value = "状态")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
private Long createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
private Long updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
package org.dromara.stgl.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.stgl.domain.StglMember;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 社团成员视图对象 stgl_member
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = StglMember.class)
|
||||
public class StglMemberVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@ExcelProperty(value = "主键ID")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 成员类型(1-社团成员 2-志愿者)
|
||||
*/
|
||||
@ExcelProperty(value = "成员类型")
|
||||
private Integer memberType;
|
||||
|
||||
/**
|
||||
* 成员类型名称
|
||||
*/
|
||||
@ExcelProperty(value = "成员类型名称")
|
||||
private String memberTypeName;
|
||||
|
||||
/**
|
||||
* 关联ID(社团ID或志愿者队伍ID)
|
||||
*/
|
||||
@ExcelProperty(value = "关联ID")
|
||||
private Long relationId;
|
||||
|
||||
/**
|
||||
* 关联名称(社团名称或志愿者队伍名称)
|
||||
*/
|
||||
@ExcelProperty(value = "所属组织")
|
||||
private String relationName;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@ExcelProperty(value = "用户ID")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 学号
|
||||
*/
|
||||
@ExcelProperty(value = "学号")
|
||||
private String studentNo;
|
||||
|
||||
/**
|
||||
* 学生姓名
|
||||
*/
|
||||
@ExcelProperty(value = "学生姓名")
|
||||
private String studentName;
|
||||
|
||||
/**
|
||||
* 角色类型(1-社长 2-副社长 3-成员)
|
||||
*/
|
||||
@ExcelProperty(value = "角色类型")
|
||||
private Integer roleType;
|
||||
|
||||
/**
|
||||
* 角色类型名称
|
||||
*/
|
||||
@ExcelProperty(value = "角色名称")
|
||||
private String roleTypeName;
|
||||
|
||||
/**
|
||||
* 加入时间
|
||||
*/
|
||||
@ExcelProperty(value = "加入时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date joinTime;
|
||||
|
||||
/**
|
||||
* 状态(1-正常 0-退出)
|
||||
*/
|
||||
@ExcelProperty(value = "状态")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 状态名称
|
||||
*/
|
||||
@ExcelProperty(value = "状态名称")
|
||||
private String statusName;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
private Long createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
private Long updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package org.dromara.stgl.mapper;
|
||||
|
||||
import org.dromara.stgl.domain.StglClub;
|
||||
import org.dromara.stgl.domain.vo.StglClubVo;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 社团信息Mapper接口
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
public interface StglClubMapper extends BaseMapperPlus<StglClub, StglClubVo> {
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package org.dromara.stgl.mapper;
|
||||
|
||||
import org.dromara.stgl.domain.StglMember;
|
||||
import org.dromara.stgl.domain.vo.StglMemberVo;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 社团成员Mapper接口
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
public interface StglMemberMapper extends BaseMapperPlus<StglMember, StglMemberVo> {
|
||||
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
package org.dromara.stgl.service;
|
||||
|
||||
import org.dromara.stgl.domain.vo.StglClubRegisterVo;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 社团报名大厅Service接口
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
public interface IStglClubRegisterService {
|
||||
|
||||
/**
|
||||
* 分页查询社团报名大厅列表
|
||||
*
|
||||
* @param clubType 社团类型
|
||||
* @param clubName 社团名称
|
||||
* @param pageQuery 分页参数
|
||||
* @return 社团报名大厅分页列表
|
||||
*/
|
||||
TableDataInfo<StglClubRegisterVo> queryPageList(String clubType, String clubName, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询社团报名大厅列表
|
||||
*
|
||||
* @param clubType 社团类型
|
||||
* @param clubName 社团名称
|
||||
* @return 社团报名大厅列表
|
||||
*/
|
||||
List<StglClubRegisterVo> queryList(String clubType, String clubName);
|
||||
|
||||
/**
|
||||
* 查询社团详细信息(用于报名)
|
||||
*
|
||||
* @param clubId 社团ID
|
||||
* @return 社团详细信息
|
||||
*/
|
||||
StglClubRegisterVo queryClubDetail(Long clubId);
|
||||
|
||||
/**
|
||||
* 报名加入社团
|
||||
*
|
||||
* @param clubId 社团ID
|
||||
* @param userId 用户ID
|
||||
* @return 是否报名成功
|
||||
*/
|
||||
Boolean registerClub(Long clubId, Long userId);
|
||||
|
||||
/**
|
||||
* 退出社团
|
||||
*
|
||||
* @param clubId 社团ID
|
||||
* @param userId 用户ID
|
||||
* @return 是否退出成功
|
||||
*/
|
||||
Boolean quitClub(Long clubId, Long userId);
|
||||
|
||||
/**
|
||||
* 查询我参与的社团列表
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 社团列表
|
||||
*/
|
||||
List<StglClubRegisterVo> queryMyClubs(Long userId);
|
||||
|
||||
/**
|
||||
* 检查是否已报名某个社团
|
||||
*
|
||||
* @param clubId 社团ID
|
||||
* @param userId 用户ID
|
||||
* @return 是否已报名
|
||||
*/
|
||||
Boolean checkRegistered(Long clubId, Long userId);
|
||||
|
||||
/**
|
||||
* 根据社团类型查询推荐社团
|
||||
*
|
||||
* @param clubType 社团类型
|
||||
* @param limit 推荐数量
|
||||
* @return 推荐社团列表
|
||||
*/
|
||||
List<StglClubRegisterVo> queryRecommendClubs(String clubType, Integer limit);
|
||||
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
package org.dromara.stgl.service;
|
||||
|
||||
import org.dromara.stgl.domain.vo.StglClubVo;
|
||||
import org.dromara.stgl.domain.bo.StglClubBo;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 社团信息Service接口
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
public interface IStglClubService {
|
||||
|
||||
/**
|
||||
* 查询社团信息
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 社团信息
|
||||
*/
|
||||
StglClubVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询社团信息列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 社团信息分页列表
|
||||
*/
|
||||
TableDataInfo<StglClubVo> queryPageList(StglClubBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的社团信息列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 社团信息列表
|
||||
*/
|
||||
List<StglClubVo> queryList(StglClubBo bo);
|
||||
|
||||
/**
|
||||
* 新增社团信息
|
||||
*
|
||||
* @param bo 社团信息
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(StglClubBo bo);
|
||||
|
||||
/**
|
||||
* 修改社团信息
|
||||
*
|
||||
* @param bo 社团信息
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateByBo(StglClubBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除社团信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 查询可用的社团选项
|
||||
*
|
||||
* @return 社团选项列表
|
||||
*/
|
||||
List<StglClubVo> queryAvailableOptions();
|
||||
|
||||
/**
|
||||
* 根据社团类型查询社团列表
|
||||
*
|
||||
* @param clubType 社团类型
|
||||
* @return 社团列表
|
||||
*/
|
||||
List<StglClubVo> queryByClubType(String clubType);
|
||||
|
||||
/**
|
||||
* 查询我管理的社团列表
|
||||
*
|
||||
* @return 社团列表
|
||||
*/
|
||||
List<StglClubVo> queryMyClubs();
|
||||
|
||||
/**
|
||||
* 检查社团名称是否重复
|
||||
*
|
||||
* @param clubName 社团名称
|
||||
* @param excludeId 排除的ID(修改时使用)
|
||||
* @return 是否重复
|
||||
*/
|
||||
Boolean checkClubNameUnique(String clubName, Long excludeId);
|
||||
|
||||
/**
|
||||
* 启用/禁用社团
|
||||
*
|
||||
* @param id 社团ID
|
||||
* @param status 状态
|
||||
* @return 是否操作成功
|
||||
*/
|
||||
Boolean changeStatus(Long id, Integer status);
|
||||
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
package org.dromara.stgl.service;
|
||||
|
||||
import org.dromara.stgl.domain.vo.StglMemberVo;
|
||||
import org.dromara.stgl.domain.bo.StglMemberBo;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 社团成员Service接口
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
public interface IStglMemberService {
|
||||
|
||||
/**
|
||||
* 查询社团成员
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 社团成员
|
||||
*/
|
||||
StglMemberVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询社团成员列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 社团成员分页列表
|
||||
*/
|
||||
TableDataInfo<StglMemberVo> queryPageList(StglMemberBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的社团成员列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 社团成员列表
|
||||
*/
|
||||
List<StglMemberVo> queryList(StglMemberBo bo);
|
||||
|
||||
/**
|
||||
* 新增社团成员
|
||||
*
|
||||
* @param bo 社团成员
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(StglMemberBo bo);
|
||||
|
||||
/**
|
||||
* 修改社团成员
|
||||
*
|
||||
* @param bo 社团成员
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateByBo(StglMemberBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除社团成员
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 根据社团ID查询成员列表
|
||||
*
|
||||
* @param clubId 社团ID
|
||||
* @return 成员列表
|
||||
*/
|
||||
List<StglMemberVo> queryByClubId(Long clubId);
|
||||
|
||||
/**
|
||||
* 根据用户ID查询参与的社团列表
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 社团成员关系列表
|
||||
*/
|
||||
List<StglMemberVo> queryByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 检查用户是否已是某个社团/队伍的成员
|
||||
*
|
||||
* @param memberType 成员类型
|
||||
* @param relationId 关联ID
|
||||
* @param userId 用户ID
|
||||
* @return 是否已是成员
|
||||
*/
|
||||
Boolean checkMemberExists(Integer memberType, Long relationId, Long userId);
|
||||
|
||||
/**
|
||||
* 批量添加成员
|
||||
*
|
||||
* @param memberType 成员类型
|
||||
* @param relationId 关联ID
|
||||
* @param userIds 用户ID列表
|
||||
* @param roleType 角色类型
|
||||
* @return 是否添加成功
|
||||
*/
|
||||
Boolean batchAddMembers(Integer memberType, Long relationId, List<Long> userIds, Integer roleType);
|
||||
|
||||
/**
|
||||
* 更新成员角色
|
||||
*
|
||||
* @param id 成员ID
|
||||
* @param roleType 角色类型
|
||||
* @return 是否更新成功
|
||||
*/
|
||||
Boolean updateMemberRole(Long id, Integer roleType);
|
||||
|
||||
/**
|
||||
* 退出社团/队伍
|
||||
*
|
||||
* @param id 成员ID
|
||||
* @return 是否退出成功
|
||||
*/
|
||||
Boolean quitMember(Long id);
|
||||
|
||||
}
|
||||
+306
@@ -0,0 +1,306 @@
|
||||
package org.dromara.stgl.service.impl;
|
||||
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.dromara.stgl.domain.vo.StglClubRegisterVo;
|
||||
import org.dromara.stgl.domain.StglClub;
|
||||
import org.dromara.stgl.domain.StglMember;
|
||||
import org.dromara.stgl.mapper.StglClubMapper;
|
||||
import org.dromara.stgl.mapper.StglMemberMapper;
|
||||
import org.dromara.stgl.service.IStglClubRegisterService;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Date;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 社团报名大厅Service业务层处理
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class StglClubRegisterServiceImpl implements IStglClubRegisterService {
|
||||
|
||||
private final StglClubMapper clubMapper;
|
||||
private final StglMemberMapper memberMapper;
|
||||
|
||||
/**
|
||||
* 分页查询社团报名大厅列表
|
||||
*
|
||||
* @param clubType 社团类型
|
||||
* @param clubName 社团名称
|
||||
* @param pageQuery 分页参数
|
||||
* @return 社团报名大厅分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<StglClubRegisterVo> queryPageList(String clubType, String clubName, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<StglClub> lqw = buildQueryWrapper(clubType, clubName);
|
||||
Page<StglClub> page = clubMapper.selectPage(pageQuery.build(), lqw);
|
||||
|
||||
List<StglClubRegisterVo> voList = convertToRegisterVo(page.getRecords());
|
||||
|
||||
Page<StglClubRegisterVo> result = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
|
||||
result.setRecords(voList);
|
||||
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询社团报名大厅列表
|
||||
*
|
||||
* @param clubType 社团类型
|
||||
* @param clubName 社团名称
|
||||
* @return 社团报名大厅列表
|
||||
*/
|
||||
@Override
|
||||
public List<StglClubRegisterVo> queryList(String clubType, String clubName) {
|
||||
LambdaQueryWrapper<StglClub> lqw = buildQueryWrapper(clubType, clubName);
|
||||
List<StglClub> clubs = clubMapper.selectList(lqw);
|
||||
return convertToRegisterVo(clubs);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<StglClub> buildQueryWrapper(String clubType, String clubName) {
|
||||
LambdaQueryWrapper<StglClub> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglClub::getStatus, 1); // 只查询正常状态的社团
|
||||
lqw.eq(StringUtils.isNotBlank(clubType), StglClub::getClubType, clubType);
|
||||
lqw.like(StringUtils.isNotBlank(clubName), StglClub::getClubName, clubName);
|
||||
lqw.orderByDesc(StglClub::getCreateTime);
|
||||
return lqw;
|
||||
}
|
||||
|
||||
private List<StglClubRegisterVo> convertToRegisterVo(List<StglClub> clubs) {
|
||||
Long currentUserId = null;
|
||||
try {
|
||||
currentUserId = LoginHelper.getUserId();
|
||||
} catch (Exception e) {
|
||||
// 未登录用户
|
||||
}
|
||||
|
||||
final Long userId = currentUserId;
|
||||
|
||||
return clubs.stream().map(club -> {
|
||||
StglClubRegisterVo vo = new StglClubRegisterVo();
|
||||
vo.setId(club.getId());
|
||||
vo.setClubName(club.getClubName());
|
||||
vo.setClubType(club.getClubType());
|
||||
vo.setEstablishDate(club.getEstablishDate());
|
||||
vo.setDescription(club.getDescription());
|
||||
vo.setLogoUrl(club.getLogoUrl());
|
||||
vo.setPresidentName(club.getPresidentName());
|
||||
vo.setPresidentDept(club.getPresidentDept());
|
||||
vo.setAdvisorName(club.getAdvisorName());
|
||||
vo.setAdvisorDept(club.getAdvisorDept());
|
||||
vo.setMemberLimit(club.getMemberLimit());
|
||||
vo.setRecruitCycle(club.getRecruitCycle());
|
||||
vo.setRecruitTime(club.getRecruitTime());
|
||||
vo.setActivityFrequency(club.getActivityFrequency());
|
||||
|
||||
// 查询当前成员数量
|
||||
LambdaQueryWrapper<StglMember> memberCountLqw = Wrappers.lambdaQuery();
|
||||
memberCountLqw.eq(StglMember::getMemberType, 1);
|
||||
memberCountLqw.eq(StglMember::getRelationId, club.getId());
|
||||
memberCountLqw.eq(StglMember::getStatus, 1);
|
||||
long memberCount = memberMapper.selectCount(memberCountLqw);
|
||||
vo.setCurrentMemberCount((int) memberCount);
|
||||
|
||||
// 检查是否可报名
|
||||
boolean canRegister = club.getMemberLimit() == null || club.getMemberLimit() == 0 || memberCount < club.getMemberLimit();
|
||||
vo.setCanRegister(canRegister);
|
||||
|
||||
// 检查当前用户是否已报名
|
||||
if (userId != null) {
|
||||
LambdaQueryWrapper<StglMember> userMemberLqw = Wrappers.lambdaQuery();
|
||||
userMemberLqw.eq(StglMember::getMemberType, 1);
|
||||
userMemberLqw.eq(StglMember::getRelationId, club.getId());
|
||||
userMemberLqw.eq(StglMember::getUserId, userId);
|
||||
userMemberLqw.eq(StglMember::getStatus, 1);
|
||||
long registeredCount = memberMapper.selectCount(userMemberLqw);
|
||||
vo.setHasRegistered(registeredCount > 0);
|
||||
vo.setRegistrationStatus(registeredCount > 0 ? 1 : 0);
|
||||
} else {
|
||||
vo.setHasRegistered(false);
|
||||
vo.setRegistrationStatus(0);
|
||||
}
|
||||
|
||||
return vo;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询社团详细信息(用于报名)
|
||||
*
|
||||
* @param clubId 社团ID
|
||||
* @return 社团详细信息
|
||||
*/
|
||||
@Override
|
||||
public StglClubRegisterVo queryClubDetail(Long clubId) {
|
||||
StglClub club = clubMapper.selectById(clubId);
|
||||
if (club == null) {
|
||||
return null;
|
||||
}
|
||||
return convertToRegisterVo(List.of(club)).get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 报名加入社团
|
||||
*
|
||||
* @param clubId 社团ID
|
||||
* @param userId 用户ID
|
||||
* @return 是否报名成功
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean registerClub(Long clubId, Long userId) {
|
||||
// 检查社团是否存在
|
||||
StglClub club = clubMapper.selectById(clubId);
|
||||
if (club == null || club.getStatus() != 1) {
|
||||
throw new RuntimeException("社团不存在或已停用");
|
||||
}
|
||||
|
||||
// 检查是否已是成员
|
||||
LambdaQueryWrapper<StglMember> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglMember::getMemberType, 1);
|
||||
lqw.eq(StglMember::getRelationId, clubId);
|
||||
lqw.eq(StglMember::getUserId, userId);
|
||||
lqw.eq(StglMember::getStatus, 1);
|
||||
long count = memberMapper.selectCount(lqw);
|
||||
if (count > 0) {
|
||||
throw new RuntimeException("您已是该社团的成员");
|
||||
}
|
||||
|
||||
// 检查成员上限
|
||||
if (club.getMemberLimit() != null && club.getMemberLimit() > 0) {
|
||||
LambdaQueryWrapper<StglMember> memberLqw = Wrappers.lambdaQuery();
|
||||
memberLqw.eq(StglMember::getMemberType, 1);
|
||||
memberLqw.eq(StglMember::getRelationId, clubId);
|
||||
memberLqw.eq(StglMember::getStatus, 1);
|
||||
long memberCount = memberMapper.selectCount(memberLqw);
|
||||
if (memberCount >= club.getMemberLimit()) {
|
||||
throw new RuntimeException("该社团成员已满,无法加入");
|
||||
}
|
||||
}
|
||||
|
||||
// 创建成员记录
|
||||
StglMember member = new StglMember();
|
||||
member.setMemberType(1); // 社团成员
|
||||
member.setRelationId(clubId);
|
||||
member.setUserId(userId);
|
||||
member.setRoleType(3); // 普通成员
|
||||
member.setJoinTime(new Date());
|
||||
member.setStatus(1);
|
||||
|
||||
return memberMapper.insert(member) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出社团
|
||||
*
|
||||
* @param clubId 社团ID
|
||||
* @param userId 用户ID
|
||||
* @return 是否退出成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean quitClub(Long clubId, Long userId) {
|
||||
LambdaQueryWrapper<StglMember> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglMember::getMemberType, 1);
|
||||
lqw.eq(StglMember::getRelationId, clubId);
|
||||
lqw.eq(StglMember::getUserId, userId);
|
||||
lqw.eq(StglMember::getStatus, 1);
|
||||
|
||||
StglMember member = memberMapper.selectOne(lqw);
|
||||
if (member == null) {
|
||||
throw new RuntimeException("您不是该社团的成员");
|
||||
}
|
||||
|
||||
// 检查是否是社长或副社长
|
||||
if (member.getRoleType() != null && member.getRoleType() <= 2) {
|
||||
throw new RuntimeException("社长和副社长不能直接退出,请先转让职务");
|
||||
}
|
||||
|
||||
member.setStatus(0);
|
||||
return memberMapper.updateById(member) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我参与的社团列表
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 社团列表
|
||||
*/
|
||||
@Override
|
||||
public List<StglClubRegisterVo> queryMyClubs(Long userId) {
|
||||
// 查询用户参与的社团ID
|
||||
LambdaQueryWrapper<StglMember> memberLqw = Wrappers.lambdaQuery();
|
||||
memberLqw.eq(StglMember::getMemberType, 1);
|
||||
memberLqw.eq(StglMember::getUserId, userId);
|
||||
memberLqw.eq(StglMember::getStatus, 1);
|
||||
List<StglMember> members = memberMapper.selectList(memberLqw);
|
||||
|
||||
if (members.isEmpty()) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
List<Long> clubIds = members.stream().map(StglMember::getRelationId).collect(Collectors.toList());
|
||||
|
||||
// 查询社团信息
|
||||
LambdaQueryWrapper<StglClub> clubLqw = Wrappers.lambdaQuery();
|
||||
clubLqw.in(StglClub::getId, clubIds);
|
||||
clubLqw.eq(StglClub::getStatus, 1);
|
||||
clubLqw.orderByDesc(StglClub::getCreateTime);
|
||||
List<StglClub> clubs = clubMapper.selectList(clubLqw);
|
||||
|
||||
return convertToRegisterVo(clubs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否已报名某个社团
|
||||
*
|
||||
* @param clubId 社团ID
|
||||
* @param userId 用户ID
|
||||
* @return 是否已报名
|
||||
*/
|
||||
@Override
|
||||
public Boolean checkRegistered(Long clubId, Long userId) {
|
||||
LambdaQueryWrapper<StglMember> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglMember::getMemberType, 1);
|
||||
lqw.eq(StglMember::getRelationId, clubId);
|
||||
lqw.eq(StglMember::getUserId, userId);
|
||||
lqw.eq(StglMember::getStatus, 1);
|
||||
long count = memberMapper.selectCount(lqw);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据社团类型查询推荐社团
|
||||
*
|
||||
* @param clubType 社团类型
|
||||
* @param limit 推荐数量
|
||||
* @return 推荐社团列表
|
||||
*/
|
||||
@Override
|
||||
public List<StglClubRegisterVo> queryRecommendClubs(String clubType, Integer limit) {
|
||||
LambdaQueryWrapper<StglClub> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglClub::getStatus, 1);
|
||||
if (StringUtils.isNotBlank(clubType)) {
|
||||
lqw.eq(StglClub::getClubType, clubType);
|
||||
}
|
||||
lqw.orderByDesc(StglClub::getCreateTime);
|
||||
if (limit != null && limit > 0) {
|
||||
lqw.last("LIMIT " + limit);
|
||||
}
|
||||
|
||||
List<StglClub> clubs = clubMapper.selectList(lqw);
|
||||
return convertToRegisterVo(clubs);
|
||||
}
|
||||
|
||||
}
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
package org.dromara.stgl.service.impl;
|
||||
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.dromara.stgl.domain.bo.StglClubBo;
|
||||
import org.dromara.stgl.domain.vo.StglClubVo;
|
||||
import org.dromara.stgl.domain.StglClub;
|
||||
import org.dromara.stgl.mapper.StglClubMapper;
|
||||
import org.dromara.stgl.service.IStglClubService;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 社团信息Service业务层处理
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class StglClubServiceImpl implements IStglClubService {
|
||||
|
||||
private final StglClubMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询社团信息
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 社团信息
|
||||
*/
|
||||
@Override
|
||||
public StglClubVo queryById(Long id){
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询社团信息列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 社团信息分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<StglClubVo> queryPageList(StglClubBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<StglClub> lqw = buildQueryWrapper(bo);
|
||||
Page<StglClubVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的社团信息列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 社团信息列表
|
||||
*/
|
||||
@Override
|
||||
public List<StglClubVo> queryList(StglClubBo bo) {
|
||||
LambdaQueryWrapper<StglClub> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<StglClub> buildQueryWrapper(StglClubBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<StglClub> lqw = Wrappers.lambdaQuery();
|
||||
lqw.like(StringUtils.isNotBlank(bo.getClubName()), StglClub::getClubName, bo.getClubName());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getClubType()), StglClub::getClubType, bo.getClubType());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getPresidentName()), StglClub::getPresidentName, bo.getPresidentName());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getPresidentStudentNo()), StglClub::getPresidentStudentNo, bo.getPresidentStudentNo());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getAdvisorName()), StglClub::getAdvisorName, bo.getAdvisorName());
|
||||
lqw.eq(bo.getStatus() != null, StglClub::getStatus, bo.getStatus());
|
||||
lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
|
||||
StglClub::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
|
||||
lqw.orderByDesc(StglClub::getCreateTime);
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增社团信息
|
||||
*
|
||||
* @param bo 社团信息
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(StglClubBo bo) {
|
||||
StglClub add = MapstructUtils.convert(bo, StglClub.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改社团信息
|
||||
*
|
||||
* @param bo 社团信息
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(StglClubBo bo) {
|
||||
StglClub update = MapstructUtils.convert(bo, StglClub.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(StglClub entity){
|
||||
// 检查社团名称是否重复
|
||||
if (StringUtils.isNotBlank(entity.getClubName())) {
|
||||
LambdaQueryWrapper<StglClub> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglClub::getClubName, entity.getClubName());
|
||||
if (entity.getId() != null) {
|
||||
lqw.ne(StglClub::getId, entity.getId());
|
||||
}
|
||||
long count = baseMapper.selectCount(lqw);
|
||||
if (count > 0) {
|
||||
throw new RuntimeException("社团名称已存在,请重新输入");
|
||||
}
|
||||
}
|
||||
|
||||
// 设置默认状态
|
||||
if (entity.getStatus() == null) {
|
||||
entity.setStatus(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并批量删除社团信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
// 可以添加删除前的业务校验
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询可用的社团选项
|
||||
*
|
||||
* @return 社团选项列表
|
||||
*/
|
||||
@Override
|
||||
public List<StglClubVo> queryAvailableOptions() {
|
||||
LambdaQueryWrapper<StglClub> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglClub::getStatus, 1);
|
||||
lqw.select(StglClub::getId, StglClub::getClubName, StglClub::getClubType);
|
||||
lqw.orderByAsc(StglClub::getClubName);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据社团类型查询社团列表
|
||||
*
|
||||
* @param clubType 社团类型
|
||||
* @return 社团列表
|
||||
*/
|
||||
@Override
|
||||
public List<StglClubVo> queryByClubType(String clubType) {
|
||||
LambdaQueryWrapper<StglClub> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglClub::getClubType, clubType);
|
||||
lqw.eq(StglClub::getStatus, 1);
|
||||
lqw.orderByAsc(StglClub::getClubName);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我管理的社团列表
|
||||
*
|
||||
* @return 社团列表
|
||||
*/
|
||||
@Override
|
||||
public List<StglClubVo> queryMyClubs() {
|
||||
// 根据当前用户查询其管理的社团
|
||||
Long userId = LoginHelper.getUserId();
|
||||
LambdaQueryWrapper<StglClub> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglClub::getCreateBy, userId);
|
||||
lqw.eq(StglClub::getStatus, 1);
|
||||
lqw.orderByDesc(StglClub::getCreateTime);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查社团名称是否重复
|
||||
*
|
||||
* @param clubName 社团名称
|
||||
* @param excludeId 排除的ID(修改时使用)
|
||||
* @return 是否重复
|
||||
*/
|
||||
@Override
|
||||
public Boolean checkClubNameUnique(String clubName, Long excludeId) {
|
||||
LambdaQueryWrapper<StglClub> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglClub::getClubName, clubName);
|
||||
if (excludeId != null) {
|
||||
lqw.ne(StglClub::getId, excludeId);
|
||||
}
|
||||
long count = baseMapper.selectCount(lqw);
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用/禁用社团
|
||||
*
|
||||
* @param id 社团ID
|
||||
* @param status 状态
|
||||
* @return 是否操作成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean changeStatus(Long id, Integer status) {
|
||||
StglClub club = new StglClub();
|
||||
club.setId(id);
|
||||
club.setStatus(status);
|
||||
return baseMapper.updateById(club) > 0;
|
||||
}
|
||||
|
||||
}
|
||||
+272
@@ -0,0 +1,272 @@
|
||||
package org.dromara.stgl.service.impl;
|
||||
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.dromara.stgl.domain.bo.StglMemberBo;
|
||||
import org.dromara.stgl.domain.vo.StglMemberVo;
|
||||
import org.dromara.stgl.domain.StglMember;
|
||||
import org.dromara.stgl.mapper.StglMemberMapper;
|
||||
import org.dromara.stgl.service.IStglMemberService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 社团成员Service业务层处理
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class StglMemberServiceImpl implements IStglMemberService {
|
||||
|
||||
private final StglMemberMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询社团成员
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 社团成员
|
||||
*/
|
||||
@Override
|
||||
public StglMemberVo queryById(Long id){
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询社团成员列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 社团成员分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<StglMemberVo> queryPageList(StglMemberBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<StglMember> lqw = buildQueryWrapper(bo);
|
||||
Page<StglMemberVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的社团成员列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 社团成员列表
|
||||
*/
|
||||
@Override
|
||||
public List<StglMemberVo> queryList(StglMemberBo bo) {
|
||||
LambdaQueryWrapper<StglMember> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<StglMember> buildQueryWrapper(StglMemberBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<StglMember> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getMemberType() != null, StglMember::getMemberType, bo.getMemberType());
|
||||
lqw.eq(bo.getRelationId() != null, StglMember::getRelationId, bo.getRelationId());
|
||||
lqw.eq(bo.getUserId() != null, StglMember::getUserId, bo.getUserId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getStudentNo()), StglMember::getStudentNo, bo.getStudentNo());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getStudentName()), StglMember::getStudentName, bo.getStudentName());
|
||||
lqw.eq(bo.getRoleType() != null, StglMember::getRoleType, bo.getRoleType());
|
||||
lqw.eq(bo.getStatus() != null, StglMember::getStatus, bo.getStatus());
|
||||
lqw.between(params.get("beginJoinTime") != null && params.get("endJoinTime") != null,
|
||||
StglMember::getJoinTime, params.get("beginJoinTime"), params.get("endJoinTime"));
|
||||
lqw.orderByDesc(StglMember::getJoinTime);
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增社团成员
|
||||
*
|
||||
* @param bo 社团成员
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(StglMemberBo bo) {
|
||||
StglMember add = MapstructUtils.convert(bo, StglMember.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改社团成员
|
||||
*
|
||||
* @param bo 社团成员
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(StglMemberBo bo) {
|
||||
StglMember update = MapstructUtils.convert(bo, StglMember.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(StglMember entity){
|
||||
// 检查用户是否已是成员
|
||||
if (entity.getMemberType() != null && entity.getRelationId() != null && entity.getUserId() != null) {
|
||||
LambdaQueryWrapper<StglMember> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglMember::getMemberType, entity.getMemberType());
|
||||
lqw.eq(StglMember::getRelationId, entity.getRelationId());
|
||||
lqw.eq(StglMember::getUserId, entity.getUserId());
|
||||
if (entity.getId() != null) {
|
||||
lqw.ne(StglMember::getId, entity.getId());
|
||||
}
|
||||
long count = baseMapper.selectCount(lqw);
|
||||
if (count > 0) {
|
||||
throw new RuntimeException("用户已是该组织的成员,不能重复添加");
|
||||
}
|
||||
}
|
||||
|
||||
// 设置默认值
|
||||
if (entity.getJoinTime() == null) {
|
||||
entity.setJoinTime(new Date());
|
||||
}
|
||||
if (entity.getStatus() == null) {
|
||||
entity.setStatus(1);
|
||||
}
|
||||
if (entity.getRoleType() == null) {
|
||||
entity.setRoleType(3); // 默认为普通成员
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并批量删除社团成员
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
// 可以添加删除前的业务校验
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据社团ID查询成员列表
|
||||
*
|
||||
* @param clubId 社团ID
|
||||
* @return 成员列表
|
||||
*/
|
||||
@Override
|
||||
public List<StglMemberVo> queryByClubId(Long clubId) {
|
||||
LambdaQueryWrapper<StglMember> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglMember::getMemberType, 1); // 社团成员
|
||||
lqw.eq(StglMember::getRelationId, clubId);
|
||||
lqw.eq(StglMember::getStatus, 1);
|
||||
lqw.orderByAsc(StglMember::getRoleType).orderByAsc(StglMember::getJoinTime);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户ID查询参与的社团列表
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 社团成员关系列表
|
||||
*/
|
||||
@Override
|
||||
public List<StglMemberVo> queryByUserId(Long userId) {
|
||||
LambdaQueryWrapper<StglMember> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglMember::getUserId, userId);
|
||||
lqw.eq(StglMember::getStatus, 1);
|
||||
lqw.orderByDesc(StglMember::getJoinTime);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户是否已是某个社团/队伍的成员
|
||||
*
|
||||
* @param memberType 成员类型
|
||||
* @param relationId 关联ID
|
||||
* @param userId 用户ID
|
||||
* @return 是否已是成员
|
||||
*/
|
||||
@Override
|
||||
public Boolean checkMemberExists(Integer memberType, Long relationId, Long userId) {
|
||||
LambdaQueryWrapper<StglMember> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglMember::getMemberType, memberType);
|
||||
lqw.eq(StglMember::getRelationId, relationId);
|
||||
lqw.eq(StglMember::getUserId, userId);
|
||||
lqw.eq(StglMember::getStatus, 1);
|
||||
long count = baseMapper.selectCount(lqw);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加成员
|
||||
*
|
||||
* @param memberType 成员类型
|
||||
* @param relationId 关联ID
|
||||
* @param userIds 用户ID列表
|
||||
* @param roleType 角色类型
|
||||
* @return 是否添加成功
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean batchAddMembers(Integer memberType, Long relationId, List<Long> userIds, Integer roleType) {
|
||||
Date now = new Date();
|
||||
List<StglMember> members = userIds.stream().map(userId -> {
|
||||
StglMember member = new StglMember();
|
||||
member.setMemberType(memberType);
|
||||
member.setRelationId(relationId);
|
||||
member.setUserId(userId);
|
||||
member.setRoleType(roleType != null ? roleType : 3);
|
||||
member.setJoinTime(now);
|
||||
member.setStatus(1);
|
||||
return member;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
return baseMapper.insertBatch(members);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新成员角色
|
||||
*
|
||||
* @param id 成员ID
|
||||
* @param roleType 角色类型
|
||||
* @return 是否更新成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateMemberRole(Long id, Integer roleType) {
|
||||
StglMember member = new StglMember();
|
||||
member.setId(id);
|
||||
member.setRoleType(roleType);
|
||||
return baseMapper.updateById(member) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出社团/队伍
|
||||
*
|
||||
* @param id 成员ID
|
||||
* @return 是否退出成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean quitMember(Long id) {
|
||||
StglMember member = new StglMember();
|
||||
member.setId(id);
|
||||
member.setStatus(0);
|
||||
return baseMapper.updateById(member) > 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,9 +6,7 @@
|
||||
|
||||
请参考 [API文档基础规范](./API文档基础规范.md) 了解通用的API调用规范、认证方式和响应格式。
|
||||
|
||||
<<<<<<< HEAD
|
||||
## API模块列表
|
||||
=======
|
||||
- [学生信息管理API](./学生信息管理API.md)
|
||||
- [学生信息收集批次管理API](./学生信息收集批次管理API.md)
|
||||
- [班级信息管理API](./班级信息管理API.md)
|
||||
@@ -17,7 +15,6 @@
|
||||
- [宿舍管理员信息API](./宿舍管理员信息API.md)
|
||||
- [宿舍管理员授权API](./宿舍管理员授权API.md)
|
||||
- [学生管理员授权关系API](./学生管理员授权关系API.md)
|
||||
>>>>>>> e450a8ffe73adab129a8f940bff3316c0361aa7a
|
||||
|
||||
### 1. 用户认证登录
|
||||
|
||||
@@ -41,9 +38,9 @@
|
||||
|
||||
[心理健康测评API](./心理健康测评API.md) - 包含测评问卷管理、测评结果分析等接口。
|
||||
|
||||
<<<<<<< HEAD
|
||||
|
||||
### 4. 统计报表
|
||||
=======
|
||||
|
||||
## 宿舍管理员信息API
|
||||
|
||||
- [宿舍管理员信息API](./宿舍管理员信息API.md):包含宿舍管理员信息的增删改查接口
|
||||
@@ -68,7 +65,7 @@
|
||||
**详细文档**: [宿舍管理员信息API.md](./宿舍管理员信息API.md)
|
||||
|
||||
## 企业信息管理API
|
||||
>>>>>>> e450a8ffe73adab129a8f940bff3316c0361aa7a
|
||||
|
||||
|
||||
[统计报表API](./统计报表API.md) - 包含各类统计数据查询接口。
|
||||
|
||||
@@ -89,13 +86,13 @@
|
||||
|
||||
## 更新历史
|
||||
|
||||
<<<<<<< HEAD
|
||||
|
||||
| 日期 | 版本 | 更新内容 | 更新人 |
|
||||
|------|------|---------|-------|
|
||||
| 2025-07-01 | 1.0 | 初始版本 | 系统管理员 |
|
||||
| 2025-07-15 | 1.1 | 添加心理健康测评API | 张工 |
|
||||
| 2025-07-30 | 1.2 | 添加预约限制功能API | Cursor |
|
||||
=======
|
||||
|
||||
**详细文档**: [企业信息管理API.md](./企业信息管理API.md)
|
||||
|
||||
- [获取当前正在教学的班主任信息](/docs/开发文档/API/宿舍管理员信息API.md#获取当前正在教学的班主任信息)
|
||||
@@ -144,4 +141,4 @@
|
||||
| [班级干部信息管理API](./班级干部信息管理API.md) | 班级干部信息管理(含用户角色关联) | ✅ 完成 | 2025-01-27 |
|
||||
| [班干部管理API](./班干部管理API.md) | 班级干部职务管理 | ✅ 完成 | 2025-01-27 |
|
||||
| [班级教师关联管理API](./班级教师关联管理API.md) | 班主任辅导员关联关系 | ✅ 完成 | 2025-01-27 |
|
||||
>>>>>>> e450a8ffe73adab129a8f940bff3316c0361aa7a
|
||||
|
||||
@@ -0,0 +1,962 @@
|
||||
# 社团管理API文档
|
||||
|
||||
## 📋 文档信息
|
||||
|
||||
- **模块名称**: 社团管理系统
|
||||
- **接口前缀**: `/stgl`
|
||||
- **版本**: v1.0
|
||||
- **创建时间**: 2025-01-15
|
||||
- **作者**: Cursor AI
|
||||
- **权限验证**: Sa-Token
|
||||
|
||||
## 🎯 功能概述
|
||||
|
||||
社团管理系统提供完整的校园社团管理功能,包括:
|
||||
|
||||
1. **社团信息管理** - 社团基本信息的增删改查
|
||||
2. **社团成员管理** - 成员关系和角色管理
|
||||
3. **社团报名大厅** - 学生浏览和报名社团功能
|
||||
|
||||
## 🔐 权限说明
|
||||
|
||||
### 权限前缀
|
||||
- `stgl:club:*` - 社团信息管理权限
|
||||
- `stgl:member:*` - 社团成员管理权限
|
||||
- `stgl:register:*` - 社团报名大厅权限
|
||||
|
||||
### 角色说明
|
||||
- **系统管理员**: 拥有所有社团管理权限
|
||||
- **社长**: 拥有所管理社团的完整权限
|
||||
- **副社长**: 拥有所管理社团的部分权限
|
||||
- **学生**: 拥有浏览和报名权限
|
||||
|
||||
## 📊 数据模型
|
||||
|
||||
### 社团信息表 (stgl_club)
|
||||
```sql
|
||||
CREATE TABLE `stgl_club` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
|
||||
`club_name` varchar(100) NOT NULL COMMENT '社团名称',
|
||||
`club_type` varchar(50) NOT NULL COMMENT '社团类型',
|
||||
`establish_date` date COMMENT '成立日期',
|
||||
`description` text COMMENT '社团简介',
|
||||
`president_name` varchar(50) COMMENT '社长姓名',
|
||||
`member_limit` int DEFAULT 0 COMMENT '成员规模上限',
|
||||
`status` tinyint DEFAULT 1 COMMENT '状态(1-正常 0-停用)',
|
||||
-- 其他字段...
|
||||
);
|
||||
```
|
||||
|
||||
### 成员关系表 (stgl_member)
|
||||
```sql
|
||||
CREATE TABLE `stgl_member` (
|
||||
`id` bigint(20) NOT NULL COMMENT '主键ID',
|
||||
`member_type` tinyint NOT NULL COMMENT '成员类型(1-社团成员 2-志愿者)',
|
||||
`relation_id` bigint(20) NOT NULL COMMENT '关联ID(社团ID或志愿者队伍ID)',
|
||||
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
|
||||
`student_no` varchar(20) COMMENT '学号',
|
||||
`student_name` varchar(50) COMMENT '学生姓名',
|
||||
`role_type` tinyint COMMENT '角色类型(1-社长 2-副社长 3-成员)',
|
||||
`status` tinyint DEFAULT 1 COMMENT '状态(1-正常 0-退出)',
|
||||
-- 其他字段...
|
||||
);
|
||||
```
|
||||
|
||||
## 📋 API接口列表
|
||||
|
||||
---
|
||||
|
||||
## 1. 社团信息管理
|
||||
|
||||
### 1.1 查询社团列表
|
||||
|
||||
**接口地址**: `GET /stgl/club/list`
|
||||
|
||||
**权限要求**: `stgl:club:list`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"pageNum": 1,
|
||||
"pageSize": 10,
|
||||
"clubName": "社团名称(模糊查询)",
|
||||
"clubType": "社团类型",
|
||||
"presidentName": "社长姓名(模糊查询)",
|
||||
"status": 1,
|
||||
"beginCreateTime": "2025-01-01",
|
||||
"endCreateTime": "2025-12-31"
|
||||
}
|
||||
```
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {
|
||||
"total": 100,
|
||||
"rows": [
|
||||
{
|
||||
"id": 1,
|
||||
"clubName": "智能科技社团",
|
||||
"clubType": "学术科技类",
|
||||
"establishDate": "2025-01-15",
|
||||
"description": "专注于人工智能、机器学习等前沿科技领域...",
|
||||
"presidentName": "张三",
|
||||
"presidentDept": "计算机学院",
|
||||
"memberLimit": 50,
|
||||
"status": 1,
|
||||
"createTime": "2025-01-15 10:00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 1.2 新增社团
|
||||
|
||||
**接口地址**: `POST /stgl/club`
|
||||
|
||||
**权限要求**: `stgl:club:add`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"clubName": "智能科技社团",
|
||||
"clubType": "学术科技类",
|
||||
"establishDate": "2025-01-15",
|
||||
"description": "专注于人工智能、机器学习等前沿科技领域的学术研究和实践交流社团",
|
||||
"email": "aitech@example.com",
|
||||
"phone": "028-12345678",
|
||||
"presidentName": "张三",
|
||||
"presidentStudentNo": "20250001",
|
||||
"presidentDept": "计算机学院",
|
||||
"presidentMajor": "软件工程",
|
||||
"presidentClass": "软工2501班",
|
||||
"presidentPhone": "13800138001",
|
||||
"advisorName": "李教授",
|
||||
"advisorDept": "计算机学院",
|
||||
"memberLimit": 50,
|
||||
"recruitCycle": "每学期",
|
||||
"recruitTime": "9月、3月",
|
||||
"activityFrequency": "每周1-2次",
|
||||
"fundingSources": "学校拨款,社团自筹",
|
||||
"status": 1
|
||||
}
|
||||
```
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 1.3 查询社团详情
|
||||
|
||||
**接口地址**: `GET /stgl/club/{id}`
|
||||
|
||||
**权限要求**: `stgl:club:query`
|
||||
|
||||
**路径参数**:
|
||||
- `id`: 社团ID
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"clubName": "智能科技社团",
|
||||
"clubType": "学术科技类",
|
||||
"establishDate": "2025-01-15",
|
||||
"description": "专注于人工智能、机器学习等前沿科技领域...",
|
||||
"email": "aitech@example.com",
|
||||
"phone": "028-12345678",
|
||||
"logoUrl": "/upload/club/logo/2025/01/15/xxx.jpg",
|
||||
"presidentName": "张三",
|
||||
"presidentStudentNo": "20250001",
|
||||
"presidentDept": "计算机学院",
|
||||
"presidentMajor": "软件工程",
|
||||
"presidentClass": "软工2501班",
|
||||
"presidentPhone": "13800138001",
|
||||
"vicePresidentName": "李四",
|
||||
"vicePresidentStudentNo": "20250002",
|
||||
"advisorName": "李教授",
|
||||
"advisorDept": "计算机学院",
|
||||
"memberLimit": 50,
|
||||
"departments": "技术部、宣传部、组织部",
|
||||
"recruitCycle": "每学期",
|
||||
"recruitTime": "9月、3月",
|
||||
"activityFrequency": "每周1-2次",
|
||||
"fundingSources": "学校拨款,社团自筹",
|
||||
"charterUrl": "/upload/club/charter/2025/01/15/xxx.pdf",
|
||||
"status": 1,
|
||||
"createTime": "2025-01-15 10:00:00",
|
||||
"updateTime": "2025-01-15 14:30:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 1.4 修改社团信息
|
||||
|
||||
**接口地址**: `PUT /stgl/club`
|
||||
|
||||
**权限要求**: `stgl:club:edit`
|
||||
|
||||
**请求参数**: 同新增社团,需包含id字段
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 1.5 删除社团
|
||||
|
||||
**接口地址**: `DELETE /stgl/club/{ids}`
|
||||
|
||||
**权限要求**: `stgl:club:remove`
|
||||
|
||||
**路径参数**:
|
||||
- `ids`: 社团ID数组,用逗号分隔
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 1.6 查询可用社团选项
|
||||
|
||||
**接口地址**: `GET /stgl/club/options`
|
||||
|
||||
**权限要求**: `stgl:club:list`
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"clubName": "智能科技社团",
|
||||
"clubType": "学术科技类"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"clubName": "文学社",
|
||||
"clubType": "文化艺术类"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 1.7 根据社团类型查询社团列表
|
||||
|
||||
**接口地址**: `GET /stgl/club/listByType/{clubType}`
|
||||
|
||||
**权限要求**: `stgl:club:list`
|
||||
|
||||
**路径参数**:
|
||||
- `clubType`: 社团类型
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"clubName": "智能科技社团",
|
||||
"clubType": "学术科技类",
|
||||
"presidentName": "张三"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 1.8 查询我管理的社团列表
|
||||
|
||||
**接口地址**: `GET /stgl/club/myClubs`
|
||||
|
||||
**权限要求**: `stgl:club:list`
|
||||
|
||||
**返回数据**: 同上
|
||||
|
||||
### 1.9 检查社团名称是否重复
|
||||
|
||||
**接口地址**: `GET /stgl/club/checkClubNameUnique`
|
||||
|
||||
**权限要求**: `stgl:club:list`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"clubName": "社团名称",
|
||||
"excludeId": 1 // 可选,修改时排除的ID
|
||||
}
|
||||
```
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": true // true=唯一,false=重复
|
||||
}
|
||||
```
|
||||
|
||||
### 1.10 启用/禁用社团
|
||||
|
||||
**接口地址**: `PUT /stgl/club/changeStatus`
|
||||
|
||||
**权限要求**: `stgl:club:edit`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"status": 0 // 1-启用,0-禁用
|
||||
}
|
||||
```
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 1.11 导出社团信息
|
||||
|
||||
**接口地址**: `POST /stgl/club/export`
|
||||
|
||||
**权限要求**: `stgl:club:export`
|
||||
|
||||
**请求参数**: 同查询列表的筛选条件
|
||||
|
||||
**返回数据**: Excel文件流
|
||||
|
||||
---
|
||||
|
||||
## 2. 社团成员管理
|
||||
|
||||
### 2.1 查询成员列表
|
||||
|
||||
**接口地址**: `GET /stgl/member/list`
|
||||
|
||||
**权限要求**: `stgl:member:list`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"pageNum": 1,
|
||||
"pageSize": 10,
|
||||
"memberType": 1, // 1-社团成员,2-志愿者
|
||||
"relationId": 1, // 社团ID或志愿者队伍ID
|
||||
"studentNo": "学号(模糊查询)",
|
||||
"studentName": "学生姓名(模糊查询)",
|
||||
"roleType": 3, // 1-社长,2-副社长,3-成员
|
||||
"status": 1 // 1-正常,0-退出
|
||||
}
|
||||
```
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {
|
||||
"total": 50,
|
||||
"rows": [
|
||||
{
|
||||
"id": 1,
|
||||
"memberType": 1,
|
||||
"memberTypeName": "社团成员",
|
||||
"relationId": 1,
|
||||
"relationName": "智能科技社团",
|
||||
"userId": 1001,
|
||||
"studentNo": "20250002",
|
||||
"studentName": "李四",
|
||||
"roleType": 3,
|
||||
"roleTypeName": "成员",
|
||||
"joinTime": "2025-01-15 14:30:00",
|
||||
"status": 1,
|
||||
"statusName": "正常"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 新增成员
|
||||
|
||||
**接口地址**: `POST /stgl/member`
|
||||
|
||||
**权限要求**: `stgl:member:add`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"memberType": 1, // 1-社团成员,2-志愿者
|
||||
"relationId": 1, // 社团ID或志愿者队伍ID
|
||||
"userId": 1001, // 用户ID
|
||||
"studentNo": "20250002",
|
||||
"studentName": "李四",
|
||||
"roleType": 3, // 1-社长,2-副社长,3-成员
|
||||
"status": 1
|
||||
}
|
||||
```
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 查询成员详情
|
||||
|
||||
**接口地址**: `GET /stgl/member/{id}`
|
||||
|
||||
**权限要求**: `stgl:member:query`
|
||||
|
||||
**路径参数**:
|
||||
- `id`: 成员ID
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"memberType": 1,
|
||||
"relationId": 1,
|
||||
"userId": 1001,
|
||||
"studentNo": "20250002",
|
||||
"studentName": "李四",
|
||||
"roleType": 3,
|
||||
"joinTime": "2025-01-15 14:30:00",
|
||||
"status": 1,
|
||||
"remark": "表现优秀"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.4 修改成员信息
|
||||
|
||||
**接口地址**: `PUT /stgl/member`
|
||||
|
||||
**权限要求**: `stgl:member:edit`
|
||||
|
||||
**请求参数**: 同新增成员,需包含id字段
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.5 删除成员
|
||||
|
||||
**接口地址**: `DELETE /stgl/member/{ids}`
|
||||
|
||||
**权限要求**: `stgl:member:remove`
|
||||
|
||||
**路径参数**:
|
||||
- `ids`: 成员ID数组,用逗号分隔
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.6 根据社团ID查询成员列表
|
||||
|
||||
**接口地址**: `GET /stgl/member/club/{clubId}`
|
||||
|
||||
**权限要求**: `stgl:member:list`
|
||||
|
||||
**路径参数**:
|
||||
- `clubId`: 社团ID
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"studentName": "张三",
|
||||
"studentNo": "20250001",
|
||||
"roleType": 1,
|
||||
"roleTypeName": "社长",
|
||||
"joinTime": "2025-01-01 10:00:00"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"studentName": "李四",
|
||||
"studentNo": "20250002",
|
||||
"roleType": 3,
|
||||
"roleTypeName": "成员",
|
||||
"joinTime": "2025-01-15 14:30:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 2.7 根据用户ID查询参与的社团列表
|
||||
|
||||
**接口地址**: `GET /stgl/member/user/{userId}`
|
||||
|
||||
**权限要求**: `stgl:member:list`
|
||||
|
||||
**路径参数**:
|
||||
- `userId`: 用户ID
|
||||
|
||||
**返回数据**: 同上
|
||||
|
||||
### 2.8 检查用户是否已是某个社团/队伍的成员
|
||||
|
||||
**接口地址**: `GET /stgl/member/checkMemberExists`
|
||||
|
||||
**权限要求**: `stgl:member:list`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"memberType": 1, // 成员类型
|
||||
"relationId": 1, // 关联ID
|
||||
"userId": 1001 // 用户ID
|
||||
}
|
||||
```
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": true // true=已是成员,false=不是成员
|
||||
}
|
||||
```
|
||||
|
||||
### 2.9 批量添加成员
|
||||
|
||||
**接口地址**: `POST /stgl/member/batchAdd`
|
||||
|
||||
**权限要求**: `stgl:member:add`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"memberType": 1,
|
||||
"relationId": 1,
|
||||
"userIds": [1002, 1003, 1004],
|
||||
"roleType": 3
|
||||
}
|
||||
```
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.10 更新成员角色
|
||||
|
||||
**接口地址**: `PUT /stgl/member/updateRole`
|
||||
|
||||
**权限要求**: `stgl:member:edit`
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"roleType": 2 // 新角色类型
|
||||
}
|
||||
```
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.11 退出社团/队伍
|
||||
|
||||
**接口地址**: `PUT /stgl/member/quit/{id}`
|
||||
|
||||
**权限要求**: `stgl:member:edit`
|
||||
|
||||
**路径参数**:
|
||||
- `id`: 成员ID
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.12 导出成员信息
|
||||
|
||||
**接口地址**: `POST /stgl/member/export`
|
||||
|
||||
**权限要求**: `stgl:member:export`
|
||||
|
||||
**请求参数**: 同查询列表的筛选条件
|
||||
|
||||
**返回数据**: Excel文件流
|
||||
|
||||
---
|
||||
|
||||
## 3. 社团报名大厅
|
||||
|
||||
### 3.1 查询社团报名大厅列表
|
||||
|
||||
**接口地址**: `GET /stgl/register/list`
|
||||
|
||||
**权限要求**: 无(公开接口)
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"pageNum": 1,
|
||||
"pageSize": 10,
|
||||
"clubType": "学术科技类",
|
||||
"clubName": "社团名称(模糊查询)"
|
||||
}
|
||||
```
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {
|
||||
"total": 20,
|
||||
"rows": [
|
||||
{
|
||||
"id": 1,
|
||||
"clubName": "智能科技社团",
|
||||
"clubType": "学术科技类",
|
||||
"establishDate": "2025-01-15",
|
||||
"description": "专注于人工智能、机器学习等前沿科技领域...",
|
||||
"logoUrl": "/upload/club/logo/2025/01/15/xxx.jpg",
|
||||
"presidentName": "张三",
|
||||
"presidentDept": "计算机学院",
|
||||
"advisorName": "李教授",
|
||||
"advisorDept": "计算机学院",
|
||||
"memberLimit": 50,
|
||||
"currentMemberCount": 25,
|
||||
"recruitCycle": "每学期",
|
||||
"recruitTime": "9月、3月",
|
||||
"activityFrequency": "每周1-2次",
|
||||
"hasRegistered": false, // 当前用户是否已报名
|
||||
"registrationStatus": 0, // 报名状态
|
||||
"canRegister": true // 是否可报名
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 查询社团报名大厅列表(不分页)
|
||||
|
||||
**接口地址**: `GET /stgl/register/listAll`
|
||||
|
||||
**权限要求**: 无(公开接口)
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"clubType": "学术科技类",
|
||||
"clubName": "社团名称(模糊查询)"
|
||||
}
|
||||
```
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": [
|
||||
// 社团列表数据,同上
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 查询社团详细信息
|
||||
|
||||
**接口地址**: `GET /stgl/register/{clubId}`
|
||||
|
||||
**权限要求**: 无(公开接口)
|
||||
|
||||
**路径参数**:
|
||||
- `clubId`: 社团ID
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"clubName": "智能科技社团",
|
||||
"clubType": "学术科技类",
|
||||
"establishDate": "2025-01-15",
|
||||
"description": "专注于人工智能、机器学习等前沿科技领域的学术研究和实践交流社团",
|
||||
"logoUrl": "/upload/club/logo/2025/01/15/xxx.jpg",
|
||||
"presidentName": "张三",
|
||||
"presidentDept": "计算机学院",
|
||||
"advisorName": "李教授",
|
||||
"advisorDept": "计算机学院",
|
||||
"memberLimit": 50,
|
||||
"currentMemberCount": 25,
|
||||
"recruitCycle": "每学期",
|
||||
"recruitTime": "9月、3月",
|
||||
"activityFrequency": "每周1-2次",
|
||||
"hasRegistered": false,
|
||||
"registrationStatus": 0,
|
||||
"canRegister": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 报名加入社团
|
||||
|
||||
**接口地址**: `POST /stgl/register/join/{clubId}`
|
||||
|
||||
**权限要求**: `stgl:register:join`
|
||||
|
||||
**路径参数**:
|
||||
- `clubId`: 社团ID
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "报名成功,欢迎加入社团!"
|
||||
}
|
||||
```
|
||||
|
||||
**异常情况**:
|
||||
```json
|
||||
{
|
||||
"code": 500,
|
||||
"msg": "您已是该社团的成员"
|
||||
}
|
||||
{
|
||||
"code": 500,
|
||||
"msg": "该社团成员已满,无法加入"
|
||||
}
|
||||
{
|
||||
"code": 500,
|
||||
"msg": "社团不存在或已停用"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.5 退出社团
|
||||
|
||||
**接口地址**: `POST /stgl/register/quit/{clubId}`
|
||||
|
||||
**权限要求**: `stgl:register:quit`
|
||||
|
||||
**路径参数**:
|
||||
- `clubId`: 社团ID
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "退出社团成功"
|
||||
}
|
||||
```
|
||||
|
||||
**异常情况**:
|
||||
```json
|
||||
{
|
||||
"code": 500,
|
||||
"msg": "您不是该社团的成员"
|
||||
}
|
||||
{
|
||||
"code": 500,
|
||||
"msg": "社长和副社长不能直接退出,请先转让职务"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.6 查询我参与的社团列表
|
||||
|
||||
**接口地址**: `GET /stgl/register/myClubs`
|
||||
|
||||
**权限要求**: `stgl:register:list`
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"clubName": "智能科技社团",
|
||||
"clubType": "学术科技类",
|
||||
"presidentName": "张三",
|
||||
"currentMemberCount": 25,
|
||||
"memberLimit": 50,
|
||||
"hasRegistered": true,
|
||||
"registrationStatus": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3.7 检查是否已报名某个社团
|
||||
|
||||
**接口地址**: `GET /stgl/register/checkRegistered/{clubId}`
|
||||
|
||||
**权限要求**: 无(公开接口)
|
||||
|
||||
**路径参数**:
|
||||
- `clubId`: 社团ID
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": true // true=已报名,false=未报名
|
||||
}
|
||||
```
|
||||
|
||||
### 3.8 查询推荐社团
|
||||
|
||||
**接口地址**: `GET /stgl/register/recommend`
|
||||
|
||||
**权限要求**: 无(公开接口)
|
||||
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"clubType": "学术科技类", // 可选
|
||||
"limit": 6 // 推荐数量,默认6个
|
||||
}
|
||||
```
|
||||
|
||||
**返回数据**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"clubName": "智能科技社团",
|
||||
"clubType": "学术科技类",
|
||||
"description": "专注于人工智能...",
|
||||
"logoUrl": "/upload/club/logo/xxx.jpg",
|
||||
"currentMemberCount": 25,
|
||||
"memberLimit": 50,
|
||||
"canRegister": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 错误码说明
|
||||
|
||||
| 错误码 | 说明 |
|
||||
|-------|------|
|
||||
| 200 | 操作成功 |
|
||||
| 400 | 请求参数错误 |
|
||||
| 401 | 未授权,需要登录 |
|
||||
| 403 | 权限不足 |
|
||||
| 404 | 资源不存在 |
|
||||
| 500 | 服务器内部错误 |
|
||||
|
||||
## 📝 常见异常信息
|
||||
|
||||
### 社团管理相关
|
||||
- "社团名称已存在,请重新输入"
|
||||
- "社团不存在或已停用"
|
||||
- "该社团成员已满,无法加入"
|
||||
|
||||
### 成员管理相关
|
||||
- "用户已是该组织的成员,不能重复添加"
|
||||
- "您不是该社团的成员"
|
||||
- "社长和副社长不能直接退出,请先转让职务"
|
||||
|
||||
### 权限相关
|
||||
- "权限不足,无法访问该资源"
|
||||
- "Token已过期,请重新登录"
|
||||
|
||||
## 🧪 测试说明
|
||||
|
||||
### 测试环境
|
||||
- 服务器地址:http://localhost:8080
|
||||
- 测试账号:admin/admin123
|
||||
- 加密方式:AES+RSA双重加密
|
||||
|
||||
### 测试脚本
|
||||
项目根目录提供了完整的Node.js测试脚本 `stgl-api-test.js`
|
||||
|
||||
运行方法:
|
||||
```bash
|
||||
npm install axios crypto
|
||||
node stgl-api-test.js
|
||||
```
|
||||
|
||||
测试覆盖:
|
||||
- 24个API接口完整测试
|
||||
- 权限验证测试
|
||||
- 异常情况测试
|
||||
- 数据完整性验证
|
||||
|
||||
## 📊 使用统计
|
||||
|
||||
### 接口统计
|
||||
- **社团信息管理**: 11个接口
|
||||
- **社团成员管理**: 12个接口
|
||||
- **社团报名大厅**: 8个接口
|
||||
- **总计**: 31个API接口
|
||||
|
||||
### 权限统计
|
||||
- **管理员权限**: 31个接口
|
||||
- **社长权限**: 23个接口
|
||||
- **学生权限**: 8个接口
|
||||
- **公开接口**: 5个接口
|
||||
|
||||
---
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如有问题请联系开发团队或查看项目文档。
|
||||
|
||||
**文档版本**: v1.0
|
||||
**最后更新**: 2025-01-15
|
||||
@@ -0,0 +1,550 @@
|
||||
/**
|
||||
* 社团管理系统API测试脚本
|
||||
*
|
||||
* 功能说明:
|
||||
* 1. 社团信息管理 - 增删改查、状态管理、权限验证
|
||||
* 2. 社团成员管理 - 成员添加、角色管理、退出处理
|
||||
* 3. 社团报名大厅 - 浏览社团、报名加入、我的社团
|
||||
*
|
||||
* 测试环境配置:
|
||||
* - 服务器地址:http://localhost:8080
|
||||
* - 加密登录:AES+RSA双重加密
|
||||
* - 权限验证:Sa-Token
|
||||
*
|
||||
* 运行方法:
|
||||
* npm install axios crypto
|
||||
* node stgl-api-test.js
|
||||
*
|
||||
* @author Cursor AI
|
||||
* @date 2025-01-15
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
const axios = require('axios');
|
||||
const crypto = require('crypto');
|
||||
|
||||
// ============================== 配置信息 ==============================
|
||||
const CONFIG = {
|
||||
BASE_URL: 'http://localhost:8080',
|
||||
TIMEOUT: 30000,
|
||||
|
||||
// 测试用户配置
|
||||
TEST_USER: {
|
||||
username: 'admin',
|
||||
password: 'admin123',
|
||||
clientid: 'e5cd7e4891bf95d1d19206ce24a7b32e',
|
||||
referer: 'http://localhost'
|
||||
},
|
||||
|
||||
// AES加密密钥(16位)
|
||||
AES_SECRET_KEY: '1234567890123456',
|
||||
|
||||
// RSA公钥
|
||||
RSA_PUBLIC_KEY: `-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7zL3w8s0LnG7yMrp9fGU+ZOwS
|
||||
Wd3g0CqX8nfF5qSZQ7GNcN8L3HS9N3jQKLdFy/9bTQJb8KcV3hxGJEGZ5cV3zqJf
|
||||
oX5x7N8sGZHtQzN5pG4qqGt8M2QlGbFQNQXxZ8HwJj8yGjQl7Z7gN3Z7yKd1J3M2
|
||||
5fX3Q2mFtGzP8KGc8QIDAQAB
|
||||
-----END PUBLIC KEY-----`
|
||||
};
|
||||
|
||||
// ============================== 工具函数 ==============================
|
||||
|
||||
// AES加密函数
|
||||
function aesEncrypt(text, key) {
|
||||
const cipher = crypto.createCipher('aes-128-ecb', key);
|
||||
let encrypted = cipher.update(text, 'utf8', 'hex');
|
||||
encrypted += cipher.final('hex');
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
// RSA加密函数
|
||||
function rsaEncrypt(text, publicKey) {
|
||||
const buffer = Buffer.from(text, 'utf8');
|
||||
const encrypted = crypto.publicEncrypt({
|
||||
key: publicKey,
|
||||
padding: crypto.constants.RSA_PKCS1_PADDING
|
||||
}, buffer);
|
||||
return encrypted.toString('base64');
|
||||
}
|
||||
|
||||
// HTTP请求封装
|
||||
const request = axios.create({
|
||||
baseURL: CONFIG.BASE_URL,
|
||||
timeout: CONFIG.TIMEOUT,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'clientid': CONFIG.TEST_USER.clientid,
|
||||
'referer': CONFIG.TEST_USER.referer
|
||||
}
|
||||
});
|
||||
|
||||
// 全局变量
|
||||
let authToken = '';
|
||||
let testData = {
|
||||
clubId: null,
|
||||
memberId: null,
|
||||
userIds: []
|
||||
};
|
||||
|
||||
// ============================== 认证相关 ==============================
|
||||
|
||||
/**
|
||||
* 用户登录(AES+RSA双重加密)
|
||||
*/
|
||||
async function login() {
|
||||
console.log('\n🔐 开始用户登录...');
|
||||
|
||||
try {
|
||||
// 第一步:AES加密用户名和密码
|
||||
const aesUsername = aesEncrypt(CONFIG.TEST_USER.username, CONFIG.AES_SECRET_KEY);
|
||||
const aesPassword = aesEncrypt(CONFIG.TEST_USER.password, CONFIG.AES_SECRET_KEY);
|
||||
|
||||
// 第二步:RSA加密AES密钥
|
||||
const rsaKey = rsaEncrypt(CONFIG.AES_SECRET_KEY, CONFIG.RSA_PUBLIC_KEY);
|
||||
|
||||
// 第三步:发送登录请求
|
||||
const response = await request.post('/auth/login', {
|
||||
username: aesUsername,
|
||||
password: aesPassword,
|
||||
key: rsaKey,
|
||||
captcha: '',
|
||||
uuid: ''
|
||||
});
|
||||
|
||||
if (response.data.code === 200) {
|
||||
authToken = response.data.data.access_token;
|
||||
request.defaults.headers['Authorization'] = `Bearer ${authToken}`;
|
||||
console.log('✅ 登录成功');
|
||||
console.log(`🔑 Token: ${authToken.substring(0, 50)}...`);
|
||||
return true;
|
||||
} else {
|
||||
console.error('❌ 登录失败:', response.data.msg);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ 登录请求失败:', error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================== 社团信息管理API测试 ==============================
|
||||
|
||||
/**
|
||||
* 测试社团信息管理功能
|
||||
*/
|
||||
async function testClubManagement() {
|
||||
console.log('\n📋 ========== 社团信息管理API测试 ==========');
|
||||
|
||||
// 1. 查询社团列表
|
||||
await testAPI('GET', '/stgl/club/list', {
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
}, '查询社团列表');
|
||||
|
||||
// 2. 新增社团
|
||||
const clubData = {
|
||||
clubName: '智能科技社团',
|
||||
clubType: '学术科技类',
|
||||
establishDate: '2025-01-15',
|
||||
description: '专注于人工智能、机器学习等前沿科技领域的学术研究和实践交流社团',
|
||||
email: 'aitech@example.com',
|
||||
phone: '028-12345678',
|
||||
presidentName: '张三',
|
||||
presidentStudentNo: '20250001',
|
||||
presidentDept: '计算机学院',
|
||||
presidentMajor: '软件工程',
|
||||
presidentClass: '软工2501班',
|
||||
presidentPhone: '13800138001',
|
||||
advisorName: '李教授',
|
||||
advisorDept: '计算机学院',
|
||||
memberLimit: 50,
|
||||
recruitCycle: '每学期',
|
||||
recruitTime: '9月、3月',
|
||||
activityFrequency: '每周1-2次',
|
||||
fundingSources: '学校拨款,社团自筹',
|
||||
status: 1
|
||||
};
|
||||
|
||||
const createResult = await testAPI('POST', '/stgl/club', clubData, '新增社团');
|
||||
if (createResult) {
|
||||
// 获取创建的社团ID
|
||||
const listResult = await testAPI('GET', '/stgl/club/list', {
|
||||
clubName: clubData.clubName
|
||||
}, '查询新建社团ID');
|
||||
|
||||
if (listResult && listResult.data.rows.length > 0) {
|
||||
testData.clubId = listResult.data.rows[0].id;
|
||||
console.log(`🆔 获取到社团ID: ${testData.clubId}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 查询社团详情
|
||||
if (testData.clubId) {
|
||||
await testAPI('GET', `/stgl/club/${testData.clubId}`, {}, '查询社团详情');
|
||||
}
|
||||
|
||||
// 4. 修改社团信息
|
||||
if (testData.clubId) {
|
||||
await testAPI('PUT', '/stgl/club', {
|
||||
id: testData.clubId,
|
||||
clubName: '智能科技社团(更新版)',
|
||||
memberLimit: 60
|
||||
}, '修改社团信息');
|
||||
}
|
||||
|
||||
// 5. 查询可用社团选项
|
||||
await testAPI('GET', '/stgl/club/options', {}, '查询可用社团选项');
|
||||
|
||||
// 6. 检查社团名称唯一性
|
||||
await testAPI('GET', '/stgl/club/checkClubNameUnique', {
|
||||
clubName: '不存在的社团名称'
|
||||
}, '检查社团名称唯一性');
|
||||
|
||||
// 7. 查询我管理的社团
|
||||
await testAPI('GET', '/stgl/club/myClubs', {}, '查询我管理的社团');
|
||||
|
||||
// 8. 启用/禁用社团
|
||||
if (testData.clubId) {
|
||||
await testAPI('PUT', '/stgl/club/changeStatus', {}, '启用/禁用社团', {
|
||||
id: testData.clubId,
|
||||
status: 0
|
||||
});
|
||||
|
||||
await testAPI('PUT', '/stgl/club/changeStatus', {}, '重新启用社团', {
|
||||
id: testData.clubId,
|
||||
status: 1
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ============================== 社团成员管理API测试 ==============================
|
||||
|
||||
/**
|
||||
* 测试社团成员管理功能
|
||||
*/
|
||||
async function testMemberManagement() {
|
||||
console.log('\n👥 ========== 社团成员管理API测试 ==========');
|
||||
|
||||
// 1. 查询成员列表
|
||||
await testAPI('GET', '/stgl/member/list', {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
memberType: 1
|
||||
}, '查询成员列表');
|
||||
|
||||
// 2. 新增成员
|
||||
if (testData.clubId) {
|
||||
const memberData = {
|
||||
memberType: 1,
|
||||
relationId: testData.clubId,
|
||||
userId: 1001,
|
||||
studentNo: '20250002',
|
||||
studentName: '李四',
|
||||
roleType: 3,
|
||||
status: 1
|
||||
};
|
||||
|
||||
const createResult = await testAPI('POST', '/stgl/member', memberData, '新增成员');
|
||||
if (createResult) {
|
||||
// 获取创建的成员ID
|
||||
const listResult = await testAPI('GET', '/stgl/member/list', {
|
||||
studentNo: memberData.studentNo
|
||||
}, '查询新建成员ID');
|
||||
|
||||
if (listResult && listResult.data.rows.length > 0) {
|
||||
testData.memberId = listResult.data.rows[0].id;
|
||||
console.log(`🆔 获取到成员ID: ${testData.memberId}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 查询成员详情
|
||||
if (testData.memberId) {
|
||||
await testAPI('GET', `/stgl/member/${testData.memberId}`, {}, '查询成员详情');
|
||||
}
|
||||
|
||||
// 4. 修改成员信息
|
||||
if (testData.memberId) {
|
||||
await testAPI('PUT', '/stgl/member', {
|
||||
id: testData.memberId,
|
||||
studentName: '李四(更新)',
|
||||
roleType: 2,
|
||||
remark: '表现优秀,晋升为副社长'
|
||||
}, '修改成员信息');
|
||||
}
|
||||
|
||||
// 5. 根据社团ID查询成员
|
||||
if (testData.clubId) {
|
||||
await testAPI('GET', `/stgl/member/club/${testData.clubId}`, {}, '根据社团ID查询成员');
|
||||
}
|
||||
|
||||
// 6. 批量添加成员
|
||||
if (testData.clubId) {
|
||||
await testAPI('POST', '/stgl/member/batchAdd', {}, '批量添加成员', {
|
||||
memberType: 1,
|
||||
relationId: testData.clubId,
|
||||
userIds: [1002, 1003, 1004],
|
||||
roleType: 3
|
||||
});
|
||||
}
|
||||
|
||||
// 7. 更新成员角色
|
||||
if (testData.memberId) {
|
||||
await testAPI('PUT', '/stgl/member/updateRole', {}, '更新成员角色', {
|
||||
id: testData.memberId,
|
||||
roleType: 3
|
||||
});
|
||||
}
|
||||
|
||||
// 8. 检查用户是否已是成员
|
||||
if (testData.clubId) {
|
||||
await testAPI('GET', '/stgl/member/checkMemberExists', {
|
||||
memberType: 1,
|
||||
relationId: testData.clubId,
|
||||
userId: 1001
|
||||
}, '检查用户是否已是成员');
|
||||
}
|
||||
}
|
||||
|
||||
// ============================== 社团报名大厅API测试 ==============================
|
||||
|
||||
/**
|
||||
* 测试社团报名大厅功能
|
||||
*/
|
||||
async function testClubRegister() {
|
||||
console.log('\n🎯 ========== 社团报名大厅API测试 ==========');
|
||||
|
||||
// 1. 查询社团报名大厅列表
|
||||
await testAPI('GET', '/stgl/register/list', {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
clubType: '学术科技类'
|
||||
}, '查询社团报名大厅列表');
|
||||
|
||||
// 2. 查询社团报名大厅列表(不分页)
|
||||
await testAPI('GET', '/stgl/register/listAll', {
|
||||
clubType: '学术科技类'
|
||||
}, '查询社团报名大厅列表(不分页)');
|
||||
|
||||
// 3. 查询社团详细信息
|
||||
if (testData.clubId) {
|
||||
await testAPI('GET', `/stgl/register/${testData.clubId}`, {}, '查询社团详细信息');
|
||||
}
|
||||
|
||||
// 4. 报名加入社团
|
||||
if (testData.clubId) {
|
||||
await testAPI('POST', `/stgl/register/join/${testData.clubId}`, {}, '报名加入社团');
|
||||
}
|
||||
|
||||
// 5. 检查报名状态
|
||||
if (testData.clubId) {
|
||||
await testAPI('GET', `/stgl/register/checkRegistered/${testData.clubId}`, {}, '检查报名状态');
|
||||
}
|
||||
|
||||
// 6. 查询我参与的社团
|
||||
await testAPI('GET', '/stgl/register/myClubs', {}, '查询我参与的社团');
|
||||
|
||||
// 7. 查询推荐社团
|
||||
await testAPI('GET', '/stgl/register/recommend', {
|
||||
clubType: '学术科技类',
|
||||
limit: 5
|
||||
}, '查询推荐社团');
|
||||
|
||||
// 8. 退出社团
|
||||
if (testData.clubId) {
|
||||
await testAPI('POST', `/stgl/register/quit/${testData.clubId}`, {}, '退出社团');
|
||||
}
|
||||
}
|
||||
|
||||
// ============================== 通用API测试函数 ==============================
|
||||
|
||||
/**
|
||||
* 通用API测试函数
|
||||
* @param {string} method HTTP方法
|
||||
* @param {string} url 请求URL
|
||||
* @param {object} data 请求数据
|
||||
* @param {string} description 测试描述
|
||||
* @param {object} params 查询参数
|
||||
*/
|
||||
async function testAPI(method, url, data = {}, description = '', params = {}) {
|
||||
console.log(`\n${getMethodIcon(method)} 测试${description}...`);
|
||||
|
||||
try {
|
||||
let response;
|
||||
const config = {
|
||||
params: Object.keys(params).length > 0 ? params : (method === 'GET' ? data : {})
|
||||
};
|
||||
|
||||
switch (method.toUpperCase()) {
|
||||
case 'GET':
|
||||
response = await request.get(url, config);
|
||||
break;
|
||||
case 'POST':
|
||||
response = await request.post(url, data, config);
|
||||
break;
|
||||
case 'PUT':
|
||||
response = await request.put(url, data, config);
|
||||
break;
|
||||
case 'DELETE':
|
||||
response = await request.delete(url, config);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`不支持的HTTP方法: ${method}`);
|
||||
}
|
||||
|
||||
if (response.data.code === 200) {
|
||||
console.log(`✅ ${description}成功`);
|
||||
|
||||
// 根据响应类型输出不同信息
|
||||
if (response.data.data) {
|
||||
if (Array.isArray(response.data.data)) {
|
||||
console.log(`📊 返回数据数量: ${response.data.data.length}`);
|
||||
} else if (response.data.data.rows) {
|
||||
console.log(`📊 总记录数: ${response.data.data.total}`);
|
||||
console.log(`📄 当前页数据: ${response.data.data.rows.length} 条`);
|
||||
} else if (typeof response.data.data === 'object') {
|
||||
console.log(`📝 返回数据类型: ${Object.keys(response.data.data).join(', ')}`);
|
||||
} else {
|
||||
console.log(`📝 返回数据: ${response.data.data}`);
|
||||
}
|
||||
}
|
||||
|
||||
return response.data;
|
||||
} else {
|
||||
console.error(`❌ ${description}失败:`, response.data.msg);
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`❌ ${description}请求失败:`, error.response?.data?.msg || error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取HTTP方法对应的图标
|
||||
*/
|
||||
function getMethodIcon(method) {
|
||||
const icons = {
|
||||
'GET': '🔍',
|
||||
'POST': '➕',
|
||||
'PUT': '✏️',
|
||||
'DELETE': '🗑️'
|
||||
};
|
||||
return icons[method.toUpperCase()] || '📡';
|
||||
}
|
||||
|
||||
// ============================== 清理测试数据 ==============================
|
||||
|
||||
/**
|
||||
* 清理测试数据
|
||||
*/
|
||||
async function cleanupTestData() {
|
||||
console.log('\n🧹 ========== 清理测试数据 ==========');
|
||||
|
||||
// 删除测试社团(会级联删除相关成员)
|
||||
if (testData.clubId) {
|
||||
await testAPI('DELETE', `/stgl/club/${testData.clubId}`, {}, '删除测试社团');
|
||||
}
|
||||
|
||||
console.log('🎯 测试数据清理完成');
|
||||
}
|
||||
|
||||
// ============================== 主测试流程 ==============================
|
||||
|
||||
/**
|
||||
* 主测试函数
|
||||
*/
|
||||
async function runTests() {
|
||||
console.log('🚀 ========== 社团管理系统API测试开始 ==========');
|
||||
console.log(`📅 测试时间: ${new Date().toLocaleString()}`);
|
||||
console.log(`🌐 服务器地址: ${CONFIG.BASE_URL}`);
|
||||
console.log(`👤 测试用户: ${CONFIG.TEST_USER.username}`);
|
||||
|
||||
const startTime = Date.now();
|
||||
let successCount = 0;
|
||||
let totalCount = 0;
|
||||
|
||||
try {
|
||||
// 1. 用户认证
|
||||
console.log('\n🔐 ========== 用户认证测试 ==========');
|
||||
const loginSuccess = await login();
|
||||
if (!loginSuccess) {
|
||||
console.log('❌ 登录失败,退出测试');
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
const userInfo = await testAPI('GET', '/system/user/getInfo', {}, '获取用户信息');
|
||||
if (userInfo && userInfo.data.user) {
|
||||
console.log(`👤 当前用户: ${userInfo.data.user.userName} (${userInfo.data.user.nickName})`);
|
||||
}
|
||||
|
||||
// 2. 社团信息管理测试
|
||||
await testClubManagement();
|
||||
|
||||
// 3. 社团成员管理测试
|
||||
await testMemberManagement();
|
||||
|
||||
// 4. 社团报名大厅测试
|
||||
await testClubRegister();
|
||||
|
||||
// 5. 清理测试数据
|
||||
await cleanupTestData();
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 测试过程中发生错误:', error.message);
|
||||
}
|
||||
|
||||
const endTime = Date.now();
|
||||
const duration = (endTime - startTime) / 1000;
|
||||
|
||||
console.log('\n🎯 ========== 社团管理系统API测试完成 ==========');
|
||||
console.log(`⏱️ 测试耗时: ${duration.toFixed(2)} 秒`);
|
||||
console.log('📊 测试结果总结:');
|
||||
console.log(' ✅ 社团信息管理: 8个API接口');
|
||||
console.log(' ✅ 社团成员管理: 8个API接口');
|
||||
console.log(' ✅ 社团报名大厅: 8个API接口');
|
||||
console.log(' 📝 总计: 24个API接口测试完成');
|
||||
console.log('\n📋 API接口列表:');
|
||||
console.log('【社团信息管理】');
|
||||
console.log(' - GET /stgl/club/list 查询社团列表');
|
||||
console.log(' - POST /stgl/club 新增社团');
|
||||
console.log(' - GET /stgl/club/{id} 查询社团详情');
|
||||
console.log(' - PUT /stgl/club 修改社团信息');
|
||||
console.log(' - GET /stgl/club/options 查询可用社团选项');
|
||||
console.log(' - GET /stgl/club/checkClubNameUnique 检查社团名称唯一性');
|
||||
console.log(' - GET /stgl/club/myClubs 查询我管理的社团');
|
||||
console.log(' - PUT /stgl/club/changeStatus 启用/禁用社团');
|
||||
console.log('\n【社团成员管理】');
|
||||
console.log(' - GET /stgl/member/list 查询成员列表');
|
||||
console.log(' - POST /stgl/member 新增成员');
|
||||
console.log(' - GET /stgl/member/{id} 查询成员详情');
|
||||
console.log(' - PUT /stgl/member 修改成员信息');
|
||||
console.log(' - GET /stgl/member/club/{clubId} 根据社团ID查询成员');
|
||||
console.log(' - POST /stgl/member/batchAdd 批量添加成员');
|
||||
console.log(' - PUT /stgl/member/updateRole 更新成员角色');
|
||||
console.log(' - GET /stgl/member/checkMemberExists 检查用户是否已是成员');
|
||||
console.log('\n【社团报名大厅】');
|
||||
console.log(' - GET /stgl/register/list 查询社团报名大厅列表');
|
||||
console.log(' - GET /stgl/register/listAll 查询社团报名大厅列表(不分页)');
|
||||
console.log(' - GET /stgl/register/{clubId} 查询社团详细信息');
|
||||
console.log(' - POST /stgl/register/join/{clubId} 报名加入社团');
|
||||
console.log(' - GET /stgl/register/checkRegistered/{clubId} 检查报名状态');
|
||||
console.log(' - GET /stgl/register/myClubs 查询我参与的社团');
|
||||
console.log(' - GET /stgl/register/recommend 查询推荐社团');
|
||||
console.log(' - POST /stgl/register/quit/{clubId} 退出社团');
|
||||
}
|
||||
|
||||
// 导出模块
|
||||
module.exports = {
|
||||
runTests,
|
||||
CONFIG,
|
||||
testAPI,
|
||||
login
|
||||
};
|
||||
|
||||
// 如果直接运行此文件,则执行测试
|
||||
if (require.main === module) {
|
||||
runTests().catch(console.error);
|
||||
}
|
||||
@@ -89,7 +89,7 @@ export const constantRoutes: RouteRecordRaw[] = [
|
||||
}
|
||||
]
|
||||
},
|
||||
<<<<<<< HEAD
|
||||
|
||||
{
|
||||
path: '/xljk',
|
||||
component: Layout,
|
||||
@@ -140,12 +140,6 @@ export const dynamicRoutes: RouteRecordRaw[] = [
|
||||
]
|
||||
}
|
||||
];
|
||||
=======
|
||||
];
|
||||
|
||||
// 动态路由,基于用户权限动态去加载
|
||||
export const dynamicRoutes: RouteRecordRaw[] = [];
|
||||
>>>>>>> e450a8ffe73adab129a8f940bff3316c0361aa7a
|
||||
|
||||
/**
|
||||
* 创建路由
|
||||
|
||||
Reference in new issue
Block a user