wuzhen更新社团管理新需求
This commit is contained in:
1 parent
52d892337e
commit
0745d287f5
32 files changed
+1638
-76
No files matched your search
+9
@@ -98,4 +98,13 @@ public class StglClassController extends BaseController {
|
||||
List<StglClassVo> list = stglClassService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "班级学生参与情况", StglClassVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询班主任所辖班级中当前正在参加活动的学生列表
|
||||
*/
|
||||
//@SaCheckPermission("stgl:stclass:list")
|
||||
@GetMapping("/current-activities")
|
||||
public TableDataInfo<Map<String, Object>> currentActivities(StglClassBo bo, PageQuery pageQuery) {
|
||||
return stglClassService.getCurrentActiveStudents(bo, pageQuery);
|
||||
}
|
||||
}
|
||||
+44
@@ -29,6 +29,9 @@ import org.dromara.stgl.domain.vo.StglMemberVo;
|
||||
import org.dromara.stgl.domain.vo.StglMemberImportVo;
|
||||
import org.dromara.stgl.domain.bo.StglMemberBo;
|
||||
import org.dromara.stgl.service.IStglMemberService;
|
||||
import org.dromara.stgl.service.IStglMemberApprovalService;
|
||||
import org.dromara.stgl.domain.bo.StglMemberApprovalBo;
|
||||
import org.dromara.stgl.domain.vo.StglMemberApprovalVo;
|
||||
import org.dromara.stgl.listener.StglMemberImportListener;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -51,6 +54,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
public class StglMemberController extends BaseController {
|
||||
|
||||
private final IStglMemberService stglMemberService;
|
||||
private final IStglMemberApprovalService memberApprovalService;
|
||||
|
||||
/**
|
||||
* 查询社团成员列表
|
||||
@@ -232,4 +236,44 @@ public class StglMemberController extends BaseController {
|
||||
ExcelUtil.exportExcel(templateData, "社团成员导入模板", StglMemberImportVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 社长审批成员申请
|
||||
*/
|
||||
@Operation(summary = "社长审批成员申请")
|
||||
@Log(title = "社长审批", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/presidentApprove")
|
||||
public R<Void> presidentApprove(@RequestBody StglMemberApprovalBo bo) {
|
||||
return toAjax(memberApprovalService.presidentApprove(bo.getMemberId(), bo.getApproved(), bo.getOpinion()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 指导老师审批成员申请
|
||||
*/
|
||||
@Operation(summary = "指导老师审批成员申请")
|
||||
@Log(title = "指导老师审批", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/advisorApprove")
|
||||
public R<Void> advisorApprove(@RequestBody StglMemberApprovalBo bo) {
|
||||
return toAjax(memberApprovalService.advisorApprove(bo.getMemberId(), bo.getApproved(), bo.getOpinion()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员申请的审批流程
|
||||
*/
|
||||
@Operation(summary = "获取成员申请的审批流程")
|
||||
@GetMapping("/approvalFlow/{memberId}")
|
||||
public R<List<StglMemberApprovalVo>> getApprovalFlow(@PathVariable Long memberId) {
|
||||
return R.ok(memberApprovalService.getApprovalFlow(memberId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取待当前用户审批的成员列表
|
||||
*/
|
||||
@Operation(summary = "获取待当前用户审批的成员列表")
|
||||
@GetMapping("/pendingApprovals")
|
||||
public R<List<StglMemberApprovalVo>> getPendingApprovals(@RequestParam(required = false) Long clubId) {
|
||||
return R.ok(memberApprovalService.getPendingApprovals(clubId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -152,6 +152,11 @@ public class StglClub extends TenantEntity {
|
||||
*/
|
||||
private String advisorsJson;
|
||||
|
||||
/**
|
||||
* 归属(部门ID)
|
||||
*/
|
||||
private Long affiliation;
|
||||
|
||||
/**
|
||||
* 成员规模上限
|
||||
*/
|
||||
@@ -197,6 +202,21 @@ public class StglClub extends TenantEntity {
|
||||
*/
|
||||
private String sighOpen;
|
||||
|
||||
/**
|
||||
* 社长用户ID
|
||||
*/
|
||||
private Long presidentUserId;
|
||||
|
||||
/**
|
||||
* 物资保管员用户ID
|
||||
*/
|
||||
private Long materialKeeperUserId;
|
||||
|
||||
/**
|
||||
* 物资保管员姓名
|
||||
*/
|
||||
private String materialKeeperName;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
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.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 成员申请审批流程对象 stgl_member_approval
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("stgl_member_approval")
|
||||
public class StglMemberApproval extends TenantEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/** 成员记录ID(关联stgl_member) */
|
||||
private Long memberId;
|
||||
|
||||
/** 社团ID */
|
||||
private Long clubId;
|
||||
|
||||
/** 节点代码(president_approve/advisor_approve) */
|
||||
private String nodeCode;
|
||||
|
||||
/** 节点名称(社长审批/指导老师审批) */
|
||||
private String nodeName;
|
||||
|
||||
/** 节点顺序(1.0, 2.0) */
|
||||
private BigDecimal nodeOrder;
|
||||
|
||||
/** 审批人ID */
|
||||
private Long approverId;
|
||||
|
||||
/** 审批人姓名 */
|
||||
private String approverName;
|
||||
|
||||
/** 审批结果(通过/不通过) */
|
||||
private String approveResult;
|
||||
|
||||
/** 审批状态(pending/approved/rejected) */
|
||||
private String auditStatus;
|
||||
|
||||
/** 审批意见 */
|
||||
private String auditOpinion;
|
||||
|
||||
/** 审批时间 */
|
||||
private Date auditTime;
|
||||
}
|
||||
+6
-1
@@ -12,6 +12,7 @@ import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.stgl.domain.StglActivity;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 活动信息业务对象 stgl_activity
|
||||
@@ -229,4 +230,8 @@ public class StglActivityBo extends BaseEntity {
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
||||
/**
|
||||
* 邀请成员ID列表(非数据库字段,用于创建报名记录)
|
||||
*/
|
||||
private List<Long> invitedMemberIds;
|
||||
}
|
||||
+21
@@ -184,6 +184,11 @@ public class StglClubBo extends BaseEntity {
|
||||
*/
|
||||
private String advisorsJson;
|
||||
|
||||
/**
|
||||
* 归属(部门ID)
|
||||
*/
|
||||
private Long affiliation;
|
||||
|
||||
/**
|
||||
* 成员规模上限
|
||||
*/
|
||||
@@ -240,6 +245,22 @@ public class StglClubBo extends BaseEntity {
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 社长用户ID(创建时选择学生)
|
||||
*/
|
||||
private Long presidentUserId;
|
||||
|
||||
/**
|
||||
* 物资保管员用户ID(创建时选择学生)
|
||||
*/
|
||||
private Long materialKeeperUserId;
|
||||
|
||||
/**
|
||||
* 物资保管员姓名
|
||||
*/
|
||||
@Size(max = 50, message = "物资保管员姓名长度不能超过50个字符")
|
||||
private String materialKeeperName;
|
||||
|
||||
/**
|
||||
* 社团ID列表(用于数据权限控制)
|
||||
*/
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package org.dromara.stgl.domain.bo;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 成员审批请求对象
|
||||
*/
|
||||
@Data
|
||||
public class StglMemberApprovalBo {
|
||||
|
||||
/** 成员记录ID */
|
||||
@NotNull(message = "成员记录ID不能为空")
|
||||
private Long memberId;
|
||||
|
||||
/** 是否通过 */
|
||||
@NotNull(message = "审批结果不能为空")
|
||||
private Boolean approved;
|
||||
|
||||
/** 审批意见 */
|
||||
private String opinion;
|
||||
}
|
||||
+21
@@ -178,6 +178,11 @@ public class StglClubVo implements Serializable {
|
||||
*/
|
||||
private String advisorsJson;
|
||||
|
||||
/**
|
||||
* 归属(部门ID)
|
||||
*/
|
||||
private Long affiliation;
|
||||
|
||||
/**
|
||||
* 成员规模上限
|
||||
*/
|
||||
@@ -232,6 +237,22 @@ public class StglClubVo implements Serializable {
|
||||
@ExcelProperty(value = "开启报名")
|
||||
private String sighOpen;
|
||||
|
||||
/**
|
||||
* 社长用户ID
|
||||
*/
|
||||
private Long presidentUserId;
|
||||
|
||||
/**
|
||||
* 物资保管员用户ID
|
||||
*/
|
||||
private Long materialKeeperUserId;
|
||||
|
||||
/**
|
||||
* 物资保管员姓名
|
||||
*/
|
||||
@ExcelProperty(value = "物资保管员")
|
||||
private String materialKeeperName;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package org.dromara.stgl.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 成员申请审批流程视图对象
|
||||
*/
|
||||
@Data
|
||||
public class StglMemberApprovalVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
private Long memberId;
|
||||
private Long clubId;
|
||||
private String nodeCode;
|
||||
private String nodeName;
|
||||
private BigDecimal nodeOrder;
|
||||
private Long approverId;
|
||||
private String approverName;
|
||||
private String approveResult;
|
||||
private String auditStatus;
|
||||
private String auditOpinion;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date auditTime;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
}
|
||||
+16
@@ -62,4 +62,20 @@ public interface StglClassMapper extends BaseMapperPlus<StglClass, StglClassVo>
|
||||
* @return 活动详情列表
|
||||
*/
|
||||
List<Map<String, Object>> selectStudentActivities(Long studentId);
|
||||
|
||||
/**
|
||||
* 查询指定班级中当前正在参加活动的学生列表
|
||||
*
|
||||
* @param params 查询参数(classId, studentName, studentNo, offset, pageSize)
|
||||
* @return 正在参加活动的学生列表
|
||||
*/
|
||||
List<Map<String, Object>> selectCurrentActiveStudents(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 查询指定班级中当前正在参加活动的学生总数
|
||||
*
|
||||
* @param params 查询参数(classId, studentName, studentNo)
|
||||
* @return 学生总数
|
||||
*/
|
||||
Integer selectCurrentActiveStudentsCount(Map<String, Object> params);
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package org.dromara.stgl.mapper;
|
||||
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.stgl.domain.StglMemberApproval;
|
||||
import org.dromara.stgl.domain.vo.StglMemberApprovalVo;
|
||||
|
||||
/**
|
||||
* 成员申请审批流程Mapper接口
|
||||
*/
|
||||
public interface StglMemberApprovalMapper extends BaseMapperPlus<StglMemberApproval, StglMemberApprovalVo> {
|
||||
}
|
||||
+9
@@ -65,4 +65,13 @@ public interface IStglClassService {
|
||||
* @return 活动详情列表
|
||||
*/
|
||||
List<Map<String, Object>> getStudentActivities(Long studentId);
|
||||
|
||||
/**
|
||||
* 查询班主任所辖班级中当前正在参加活动的学生分页列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 分页结果
|
||||
*/
|
||||
TableDataInfo<Map<String, Object>> getCurrentActiveStudents(StglClassBo bo, PageQuery pageQuery);
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package org.dromara.stgl.service;
|
||||
|
||||
import org.dromara.stgl.domain.vo.StglMemberApprovalVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 成员申请审批流程Service接口
|
||||
*/
|
||||
public interface IStglMemberApprovalService {
|
||||
|
||||
/**
|
||||
* 为成员申请创建审批流程(社长审批 → 指导老师审批)
|
||||
*
|
||||
* @param memberId 成员记录ID
|
||||
* @param clubId 社团ID
|
||||
* @return 是否创建成功
|
||||
*/
|
||||
Boolean createApprovalFlow(Long memberId, Long clubId);
|
||||
|
||||
/**
|
||||
* 获取成员申请的审批流程列表
|
||||
*
|
||||
* @param memberId 成员记录ID
|
||||
* @return 审批节点列表
|
||||
*/
|
||||
List<StglMemberApprovalVo> getApprovalFlow(Long memberId);
|
||||
|
||||
/**
|
||||
* 获取待当前用户审批的列表
|
||||
*
|
||||
* @param clubId 社团ID(可选)
|
||||
* @return 待审批的成员列表
|
||||
*/
|
||||
List<StglMemberApprovalVo> getPendingApprovals(Long clubId);
|
||||
|
||||
/**
|
||||
* 社长审批
|
||||
*
|
||||
* @param memberId 成员记录ID
|
||||
* @param approved 是否通过
|
||||
* @param opinion 审批意见
|
||||
* @return 是否审批成功
|
||||
*/
|
||||
Boolean presidentApprove(Long memberId, Boolean approved, String opinion);
|
||||
|
||||
/**
|
||||
* 指导老师审批
|
||||
*
|
||||
* @param memberId 成员记录ID
|
||||
* @param approved 是否通过
|
||||
* @param opinion 审批意见
|
||||
* @return 是否审批成功
|
||||
*/
|
||||
Boolean advisorApprove(Long memberId, Boolean approved, String opinion);
|
||||
}
|
||||
+40
-3
@@ -47,10 +47,13 @@ import org.dromara.common.json.utils.JsonUtils;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import org.dromara.stgl.domain.StglClub;
|
||||
import org.dromara.stgl.domain.StglVolunteerTeam;
|
||||
import org.dromara.stgl.domain.StglActivityRegistration;
|
||||
import org.dromara.stgl.domain.StglMember;
|
||||
import org.dromara.stgl.domain.vo.StglClubVo;
|
||||
import org.dromara.stgl.domain.vo.StglVolunteerTeamVo;
|
||||
import org.dromara.stgl.mapper.StglClubMapper;
|
||||
import org.dromara.stgl.mapper.StglVolunteerTeamMapper;
|
||||
import org.dromara.stgl.mapper.StglActivityRegistrationMapper;
|
||||
import org.dromara.system.domain.SysUser;
|
||||
import org.dromara.system.domain.vo.SysUserVo;
|
||||
import org.dromara.system.service.ISysUserService;
|
||||
@@ -76,6 +79,7 @@ public class StglActivityServiceImpl extends ServiceImpl<StglActivityMapper, Stg
|
||||
private final IStglActivityAuditService activityAuditService;
|
||||
private final StglActivityAuditMapper activityAuditMapper;
|
||||
private final IStglClubService clubService;
|
||||
private final StglActivityRegistrationMapper registrationMapper;
|
||||
|
||||
/**
|
||||
* 查询活动信息
|
||||
@@ -283,8 +287,8 @@ public class StglActivityServiceImpl extends ServiceImpl<StglActivityMapper, Stg
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
// 为指导老师分配角色
|
||||
assignAdvisorRoles(add);
|
||||
createInvitedRegistrations(add.getId(), bo.getInvitedMemberIds());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
@@ -311,8 +315,8 @@ public class StglActivityServiceImpl extends ServiceImpl<StglActivityMapper, Stg
|
||||
boolean updateResult = baseMapper.updateById(update) > 0;
|
||||
|
||||
if (updateResult) {
|
||||
// 处理指导老师角色分配
|
||||
handleAdvisorRoleAssignment(oldActivity, update);
|
||||
createInvitedRegistrations(update.getId(), bo.getInvitedMemberIds());
|
||||
|
||||
// 监听状态变化:如果状态从0(草稿)变为8(已提交),自动创建审批记录
|
||||
if (oldActivity != null &&
|
||||
@@ -1018,4 +1022,37 @@ public class StglActivityServiceImpl extends ServiceImpl<StglActivityMapper, Stg
|
||||
|
||||
// 注意:submitActivityForApproval 和 withdrawActivityApproval 方法已废弃
|
||||
// 功能已整合到 updateByBo 方法中,通过监听状态变化自动处理审批记录
|
||||
}
|
||||
|
||||
private void createInvitedRegistrations(Long activityId, List<Long> invitedMemberIds) {
|
||||
if (invitedMemberIds == null || invitedMemberIds.isEmpty() || activityId == null) {
|
||||
return;
|
||||
}
|
||||
Date now = new Date();
|
||||
for (Long userId : invitedMemberIds) {
|
||||
LambdaQueryWrapper<StglActivityRegistration> existLqw = Wrappers.lambdaQuery();
|
||||
existLqw.eq(StglActivityRegistration::getActivityId, activityId)
|
||||
.eq(StglActivityRegistration::getUserId, userId);
|
||||
if (registrationMapper.selectCount(existLqw) > 0) {
|
||||
continue;
|
||||
}
|
||||
StglMember member = stglMemberMapper.selectOne(
|
||||
Wrappers.<StglMember>lambdaQuery()
|
||||
.eq(StglMember::getUserId, userId)
|
||||
.eq(StglMember::getStatus, 2)
|
||||
.last("LIMIT 1")
|
||||
);
|
||||
StglActivityRegistration reg = new StglActivityRegistration();
|
||||
reg.setActivityId(activityId);
|
||||
reg.setUserId(userId);
|
||||
reg.setStudentNo(member != null ? member.getStudentNo() : "");
|
||||
reg.setStudentName(member != null ? member.getStudentName() : "");
|
||||
reg.setRegistrationType("1");
|
||||
reg.setRegistrationTime(now);
|
||||
reg.setApprovalStatus("1");
|
||||
reg.setApprovalTime(now);
|
||||
reg.setRemark("活动邀请自动报名");
|
||||
registrationMapper.insert(reg);
|
||||
}
|
||||
log.info("活动邀请报名完成: activityId={}, 邀请人数={}", activityId, invitedMemberIds.size());
|
||||
}
|
||||
}
|
||||
+17
@@ -115,6 +115,23 @@ public class StglClassServiceImpl implements IStglClassService {
|
||||
return baseMapper.selectStudentActivities(studentId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDataInfo<Map<String, Object>> getCurrentActiveStudents(StglClassBo bo, PageQuery pageQuery) {
|
||||
Map<String, Object> params = buildQueryParams(bo);
|
||||
params.put("offset", (pageQuery.getPageNum() - 1) * pageQuery.getPageSize());
|
||||
params.put("pageSize", pageQuery.getPageSize());
|
||||
|
||||
List<Map<String, Object>> list = baseMapper.selectCurrentActiveStudents(params);
|
||||
|
||||
Map<String, Object> countParams = buildQueryParams(bo);
|
||||
Integer total = baseMapper.selectCurrentActiveStudentsCount(countParams);
|
||||
|
||||
TableDataInfo<Map<String, Object>> result = new TableDataInfo<>();
|
||||
result.setRows(list);
|
||||
result.setTotal(total != null ? total : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建查询参数
|
||||
*
|
||||
|
||||
+11
-4
@@ -15,6 +15,7 @@ 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.stgl.service.IStglMemberApprovalService;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.stgl.domain.vo.StglClubVo;
|
||||
import org.dromara.system.domain.SysUser;
|
||||
@@ -40,6 +41,7 @@ public class StglClubRegisterServiceImpl implements IStglClubRegisterService {
|
||||
private final StglMemberMapper memberMapper;
|
||||
private final SysUserMapper sysUserMapper;
|
||||
private final XgStudentMsgMapper xgStudentMsgMapper;
|
||||
private final IStglMemberApprovalService memberApprovalService;
|
||||
|
||||
/**
|
||||
* 分页查询社团报名大厅列表
|
||||
@@ -247,10 +249,15 @@ public class StglClubRegisterServiceImpl implements IStglClubRegisterService {
|
||||
member.setStudentName(studentName != null ? studentName : user.getNickName()); // 如果没有学生信息,使用用户昵称
|
||||
// 申请时不设置roleType,等待审核通过后再设置
|
||||
member.setJoinTime(new Date());
|
||||
member.setStatus(0); // 待审核状态(stgl_member_status字典,新报名需审核)
|
||||
member.setRemark(reason); // 将申请理由存储到备注字段
|
||||
|
||||
return memberMapper.insert(member) > 0;
|
||||
member.setStatus(0); // 待审核状态
|
||||
member.setRemark(reason);
|
||||
|
||||
boolean inserted = memberMapper.insert(member) > 0;
|
||||
if (inserted) {
|
||||
// 创建两级审批流程:社长审批 → 指导老师审批
|
||||
memberApprovalService.createApprovalFlow(member.getId(), clubId);
|
||||
}
|
||||
return inserted;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+164
-13
@@ -334,23 +334,162 @@ public class StglClubServiceImpl implements IStglClubService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean insertByBo(StglClubBo bo) {
|
||||
Long currentUserId = LoginHelper.getUserId();
|
||||
if (currentUserId == null) {
|
||||
throw new RuntimeException("用户未登录");
|
||||
}
|
||||
|
||||
StglClub add = MapstructUtils.convert(bo, StglClub.class);
|
||||
|
||||
// 根据社长用户ID从学生表查询并填充冗余字段
|
||||
if (add.getPresidentUserId() != null) {
|
||||
fillPresidentInfoFromStudent(add);
|
||||
}
|
||||
|
||||
// 创建者自动设为首席指导老师
|
||||
add.setCreateBy(currentUserId);
|
||||
if (StringUtils.isBlank(add.getAdvisorName())) {
|
||||
// 从用户表获取创建者(老师)信息填充指导老师字段
|
||||
fillCreatorAsAdvisor(add, currentUserId);
|
||||
}
|
||||
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
// 自动创建社长和副社长的成员记录
|
||||
createLeaderMemberRecords(add);
|
||||
// 为指导老师分配角色
|
||||
createMaterialKeeperMemberRecord(add);
|
||||
assignAdvisorRoles(add);
|
||||
// 为社长分配角色
|
||||
assignPresidentRole(add);
|
||||
// 创建指导老师历史记录
|
||||
createAdvisorHistoryRecords(add);
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据社长用户ID从学生表查询信息,自动填充冗余字段
|
||||
*/
|
||||
private void fillPresidentInfoFromStudent(StglClub club) {
|
||||
try {
|
||||
LambdaQueryWrapper<XgStudentMsg> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.eq(XgStudentMsg::getId, club.getPresidentUserId())
|
||||
.eq(XgStudentMsg::getDeleted, 0)
|
||||
.last("LIMIT 1");
|
||||
XgStudentMsg student = studentMsgMapper.selectOne(wrapper);
|
||||
if (student != null) {
|
||||
club.setPresidentName(student.getName());
|
||||
club.setPresidentStudentNo(student.getStudentNo());
|
||||
club.setPresidentDept(student.getCollegeName());
|
||||
club.setPresidentMajor(student.getMajorName());
|
||||
club.setPresidentClass(student.getClassName());
|
||||
club.setPresidentPhone(student.getPhone());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("根据用户ID查询社长学生信息失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将创建者设为首席指导老师
|
||||
*/
|
||||
private void fillCreatorAsAdvisor(StglClub club, Long userId) {
|
||||
try {
|
||||
String nickName = LoginHelper.getLoginUser().getNickname();
|
||||
club.setAdvisorName(nickName);
|
||||
} catch (Exception e) {
|
||||
log.warn("获取创建者老师信息失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建物资保管员成员记录
|
||||
*/
|
||||
private void createMaterialKeeperMemberRecord(StglClub club) {
|
||||
if (club.getMaterialKeeperUserId() == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
LambdaQueryWrapper<XgStudentMsg> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.eq(XgStudentMsg::getId, club.getMaterialKeeperUserId())
|
||||
.eq(XgStudentMsg::getDeleted, 0)
|
||||
.last("LIMIT 1");
|
||||
XgStudentMsg student = studentMsgMapper.selectOne(wrapper);
|
||||
if (student == null) {
|
||||
log.warn("物资保管员学生信息不存在, userId={}", club.getMaterialKeeperUserId());
|
||||
return;
|
||||
}
|
||||
|
||||
StglMember keeper = new StglMember();
|
||||
keeper.setMemberType(1);
|
||||
keeper.setRelationId(club.getId());
|
||||
keeper.setUserId(club.getMaterialKeeperUserId());
|
||||
keeper.setStudentNo(student.getStudentNo());
|
||||
keeper.setStudentName(student.getName());
|
||||
keeper.setRoleType("物资保管员");
|
||||
keeper.setJoinTime(new Date());
|
||||
keeper.setStatus(2);
|
||||
keeper.setRemark("社团创建时自动添加");
|
||||
memberMapper.insert(keeper);
|
||||
|
||||
// 回填物资保管员姓名到社团表
|
||||
if (StringUtils.isBlank(club.getMaterialKeeperName())) {
|
||||
StglClub updateClub = new StglClub();
|
||||
updateClub.setId(club.getId());
|
||||
updateClub.setMaterialKeeperName(student.getName());
|
||||
baseMapper.updateById(updateClub);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("创建物资保管员成员记录失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void syncMaterialKeeperMemberRecord(StglClub newClub, StglClub oldClub) {
|
||||
Long newKeeperId = newClub.getMaterialKeeperUserId();
|
||||
Long oldKeeperId = oldClub != null ? oldClub.getMaterialKeeperUserId() : null;
|
||||
|
||||
if (java.util.Objects.equals(newKeeperId, oldKeeperId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 删除旧的物资保管员成员记录
|
||||
if (oldKeeperId != null) {
|
||||
LambdaQueryWrapper<StglMember> delWrapper = Wrappers.lambdaQuery();
|
||||
delWrapper.eq(StglMember::getRelationId, newClub.getId())
|
||||
.eq(StglMember::getMemberType, 1)
|
||||
.eq(StglMember::getRoleType, "物资保管员");
|
||||
memberMapper.delete(delWrapper);
|
||||
}
|
||||
|
||||
// 创建新的物资保管员成员记录
|
||||
if (newKeeperId != null) {
|
||||
LambdaQueryWrapper<XgStudentMsg> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.eq(XgStudentMsg::getId, newKeeperId)
|
||||
.eq(XgStudentMsg::getDeleted, 0)
|
||||
.last("LIMIT 1");
|
||||
XgStudentMsg student = studentMsgMapper.selectOne(wrapper);
|
||||
if (student != null) {
|
||||
StglMember keeper = new StglMember();
|
||||
keeper.setMemberType(1);
|
||||
keeper.setRelationId(newClub.getId());
|
||||
keeper.setUserId(newKeeperId);
|
||||
keeper.setStudentNo(student.getStudentNo());
|
||||
keeper.setStudentName(student.getName());
|
||||
keeper.setRoleType("物资保管员");
|
||||
keeper.setJoinTime(new Date());
|
||||
keeper.setStatus(2);
|
||||
keeper.setRemark("修改社团信息时更新");
|
||||
memberMapper.insert(keeper);
|
||||
|
||||
if (StringUtils.isBlank(newClub.getMaterialKeeperName())) {
|
||||
StglClub updateName = new StglClub();
|
||||
updateName.setId(newClub.getId());
|
||||
updateName.setMaterialKeeperName(student.getName());
|
||||
baseMapper.updateById(updateName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改社团信息
|
||||
*
|
||||
@@ -375,6 +514,8 @@ public class StglClubServiceImpl implements IStglClubService {
|
||||
if (updateResult) {
|
||||
// 同步更新副社长的成员记录
|
||||
syncVicePresidentsInMembers(update);
|
||||
// 同步物资保管员成员记录
|
||||
syncMaterialKeeperMemberRecord(update, oldClub);
|
||||
// 处理指导老师角色分配
|
||||
handleAdvisorRoleAssignment(oldClub, update);
|
||||
// 更新指导老师历史记录
|
||||
@@ -522,25 +663,35 @@ public class StglClubServiceImpl implements IStglClubService {
|
||||
*/
|
||||
private void createLeaderMemberRecords(StglClub club) {
|
||||
Date now = new Date();
|
||||
|
||||
// 1. 创建社长成员记录
|
||||
if (StringUtils.isNotBlank(club.getPresidentStudentNo())) {
|
||||
|
||||
// 1. 创建社长成员记录(优先用 presidentUserId)
|
||||
if (club.getPresidentUserId() != null) {
|
||||
StglMember president = new StglMember();
|
||||
president.setMemberType(1); // 社团成员
|
||||
president.setMemberType(1);
|
||||
president.setRelationId(club.getId());
|
||||
president.setUserId(club.getPresidentUserId());
|
||||
president.setStudentNo(club.getPresidentStudentNo());
|
||||
president.setStudentName(club.getPresidentName());
|
||||
president.setRoleType("社长");
|
||||
president.setJoinTime(now);
|
||||
president.setStatus(2);
|
||||
president.setRemark("社团创建时自动添加");
|
||||
memberMapper.insert(president);
|
||||
} else if (StringUtils.isNotBlank(club.getPresidentStudentNo())) {
|
||||
// 兼容旧逻辑:通过学号查找
|
||||
StglMember president = new StglMember();
|
||||
president.setMemberType(1);
|
||||
president.setRelationId(club.getId());
|
||||
president.setStudentNo(club.getPresidentStudentNo());
|
||||
president.setStudentName(club.getPresidentName());
|
||||
president.setRoleType("社长"); // 社长
|
||||
president.setRoleType("社长");
|
||||
president.setJoinTime(now);
|
||||
president.setStatus(2); // 已加入状态(stgl_member_status字典)
|
||||
president.setStatus(2);
|
||||
president.setRemark("社团创建时自动添加");
|
||||
|
||||
// 根据学号查找用户ID
|
||||
Long presidentUserId = findUserIdByStudentNo(club.getPresidentStudentNo());
|
||||
if (presidentUserId != null) {
|
||||
president.setUserId(presidentUserId);
|
||||
}
|
||||
|
||||
memberMapper.insert(president);
|
||||
}
|
||||
|
||||
|
||||
+262
@@ -0,0 +1,262 @@
|
||||
package org.dromara.stgl.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.stgl.domain.StglClub;
|
||||
import org.dromara.stgl.domain.StglMember;
|
||||
import org.dromara.stgl.domain.StglMemberApproval;
|
||||
import org.dromara.stgl.domain.vo.StglMemberApprovalVo;
|
||||
import org.dromara.stgl.mapper.StglClubMapper;
|
||||
import org.dromara.stgl.mapper.StglMemberApprovalMapper;
|
||||
import org.dromara.stgl.mapper.StglMemberMapper;
|
||||
import org.dromara.stgl.service.IStglMemberApprovalService;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 成员申请审批流程Service业务层处理
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class StglMemberApprovalServiceImpl implements IStglMemberApprovalService {
|
||||
|
||||
private final StglMemberApprovalMapper approvalMapper;
|
||||
private final StglMemberMapper memberMapper;
|
||||
private final StglClubMapper clubMapper;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean createApprovalFlow(Long memberId, Long clubId) {
|
||||
StglClub club = clubMapper.selectById(clubId);
|
||||
if (club == null) {
|
||||
throw new RuntimeException("社团不存在");
|
||||
}
|
||||
|
||||
// 获取社长信息(审批节点1)
|
||||
Long presidentUserId = club.getPresidentUserId();
|
||||
String presidentName = club.getPresidentName();
|
||||
if (presidentUserId == null) {
|
||||
// 兼容旧数据:从 stgl_member 表查找社长
|
||||
LambdaQueryWrapper<StglMember> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglMember::getMemberType, 1)
|
||||
.eq(StglMember::getRelationId, clubId)
|
||||
.eq(StglMember::getRoleType, "社长")
|
||||
.eq(StglMember::getStatus, 2)
|
||||
.last("LIMIT 1");
|
||||
StglMember president = memberMapper.selectOne(lqw);
|
||||
if (president != null) {
|
||||
presidentUserId = president.getUserId();
|
||||
presidentName = president.getStudentName();
|
||||
}
|
||||
}
|
||||
if (presidentUserId == null) {
|
||||
throw new RuntimeException("社团暂无社长,无法提交申请");
|
||||
}
|
||||
|
||||
// 获取指导老师信息(审批节点2)- 从 advisors_json 中获取首席指导老师
|
||||
Long advisorUserId = null;
|
||||
String advisorName = club.getAdvisorName();
|
||||
String advisorsJson = club.getAdvisorsJson();
|
||||
if (StringUtils.isNotBlank(advisorsJson)) {
|
||||
try {
|
||||
List<Map<String, Object>> advisors = JsonUtils.parseObject(advisorsJson, new TypeReference<List<Map<String, Object>>>() {});
|
||||
if (advisors != null && !advisors.isEmpty()) {
|
||||
Map<String, Object> first = advisors.get(0);
|
||||
Object uid = first.get("userId");
|
||||
if (uid != null) {
|
||||
advisorUserId = Long.parseLong(uid.toString());
|
||||
}
|
||||
if (first.get("teacher") instanceof Map) {
|
||||
Map<?, ?> teacher = (Map<?, ?>) first.get("teacher");
|
||||
if (teacher.get("nickName") != null) {
|
||||
advisorName = teacher.get("nickName").toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("解析advisors_json失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
if (advisorUserId == null) {
|
||||
advisorUserId = club.getCreateBy();
|
||||
}
|
||||
if (advisorUserId == null) {
|
||||
throw new RuntimeException("社团暂无指导老师,无法提交申请");
|
||||
}
|
||||
|
||||
Date now = new Date();
|
||||
Long currentUserId = LoginHelper.getUserId();
|
||||
|
||||
// 节点1:社长审批
|
||||
StglMemberApproval presidentNode = new StglMemberApproval();
|
||||
presidentNode.setMemberId(memberId);
|
||||
presidentNode.setClubId(clubId);
|
||||
presidentNode.setNodeCode("president_approve");
|
||||
presidentNode.setNodeName("社长审批");
|
||||
presidentNode.setNodeOrder(new BigDecimal("1.0"));
|
||||
presidentNode.setApproverId(presidentUserId);
|
||||
presidentNode.setApproverName(presidentName != null ? presidentName : "");
|
||||
presidentNode.setAuditStatus("pending");
|
||||
approvalMapper.insert(presidentNode);
|
||||
|
||||
// 节点2:指导老师审批
|
||||
StglMemberApproval advisorNode = new StglMemberApproval();
|
||||
advisorNode.setMemberId(memberId);
|
||||
advisorNode.setClubId(clubId);
|
||||
advisorNode.setNodeCode("advisor_approve");
|
||||
advisorNode.setNodeName("指导老师审批");
|
||||
advisorNode.setNodeOrder(new BigDecimal("2.0"));
|
||||
advisorNode.setApproverId(advisorUserId);
|
||||
advisorNode.setApproverName(advisorName != null ? advisorName : "");
|
||||
advisorNode.setAuditStatus("pending");
|
||||
approvalMapper.insert(advisorNode);
|
||||
|
||||
log.info("创建成员审批流程: memberId={}, clubId={}, 社长={}, 指导老师={}",
|
||||
memberId, clubId, presidentUserId, advisorUserId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StglMemberApprovalVo> getApprovalFlow(Long memberId) {
|
||||
LambdaQueryWrapper<StglMemberApproval> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglMemberApproval::getMemberId, memberId)
|
||||
.orderByAsc(StglMemberApproval::getNodeOrder);
|
||||
return approvalMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StglMemberApprovalVo> getPendingApprovals(Long clubId) {
|
||||
Long currentUserId = LoginHelper.getUserId();
|
||||
LambdaQueryWrapper<StglMemberApproval> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglMemberApproval::getApproverId, currentUserId)
|
||||
.eq(StglMemberApproval::getAuditStatus, "pending");
|
||||
if (clubId != null) {
|
||||
lqw.eq(StglMemberApproval::getClubId, clubId);
|
||||
}
|
||||
lqw.orderByAsc(StglMemberApproval::getNodeOrder);
|
||||
return approvalMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean presidentApprove(Long memberId, Boolean approved, String opinion) {
|
||||
Boolean result = doApprove(memberId, "president_approve", approved, opinion);
|
||||
|
||||
if (approved) {
|
||||
StglMember member = memberMapper.selectById(memberId);
|
||||
if (member != null) {
|
||||
StglMember updateMember = new StglMember();
|
||||
updateMember.setId(memberId);
|
||||
updateMember.setStatus(1); // 审核中,等待指导老师审批
|
||||
memberMapper.updateById(updateMember);
|
||||
log.info("社长审批通过,进入指导老师审批阶段: memberId={}", memberId);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean advisorApprove(Long memberId, Boolean approved, String opinion) {
|
||||
Boolean result = doApprove(memberId, "advisor_approve", approved, opinion);
|
||||
|
||||
// 指导老师审批是最后一个节点,如果通过则更新成员状态为已加入
|
||||
if (approved) {
|
||||
StglMember member = memberMapper.selectById(memberId);
|
||||
if (member != null) {
|
||||
StglMember updateMember = new StglMember();
|
||||
updateMember.setId(memberId);
|
||||
updateMember.setStatus(2); // 已加入
|
||||
updateMember.setRoleType("普通成员");
|
||||
memberMapper.updateById(updateMember);
|
||||
log.info("成员申请全部审批通过,已加入社团: memberId={}", memberId);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用审批处理逻辑
|
||||
*/
|
||||
private Boolean doApprove(Long memberId, String nodeCode, Boolean approved, String opinion) {
|
||||
Long currentUserId = LoginHelper.getUserId();
|
||||
if (currentUserId == null) {
|
||||
throw new RuntimeException("用户未登录");
|
||||
}
|
||||
|
||||
// 查找待审批的节点
|
||||
LambdaQueryWrapper<StglMemberApproval> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StglMemberApproval::getMemberId, memberId)
|
||||
.eq(StglMemberApproval::getNodeCode, nodeCode)
|
||||
.eq(StglMemberApproval::getAuditStatus, "pending");
|
||||
StglMemberApproval approvalNode = approvalMapper.selectOne(lqw);
|
||||
|
||||
if (approvalNode == null) {
|
||||
throw new RuntimeException("未找到待审批记录或已审批过");
|
||||
}
|
||||
|
||||
// 校验审批人身份
|
||||
log.info("审批人校验: approverId={}, currentUserId={}, equals={}",
|
||||
approvalNode.getApproverId(), currentUserId,
|
||||
approvalNode.getApproverId().equals(currentUserId));
|
||||
log.info("审批人校验类型: approverId.class={}, currentUserId.class={}",
|
||||
approvalNode.getApproverId().getClass().getName(),
|
||||
currentUserId.getClass().getName());
|
||||
|
||||
if (!approvalNode.getApproverId().equals(currentUserId)) {
|
||||
throw new RuntimeException("您不是该节点的审批人(节点审批人:" + approvalNode.getApproverId() + ", 当前用户:" + currentUserId + ")");
|
||||
}
|
||||
|
||||
// 更新审批记录
|
||||
StglMemberApproval updateNode = new StglMemberApproval();
|
||||
updateNode.setId(approvalNode.getId());
|
||||
updateNode.setApproveResult(approved ? "通过" : "不通过");
|
||||
updateNode.setAuditStatus(approved ? "approved" : "rejected");
|
||||
updateNode.setAuditOpinion(opinion);
|
||||
updateNode.setAuditTime(new Date());
|
||||
approvalMapper.updateById(updateNode);
|
||||
|
||||
// 如果拒绝,更新成员状态为已拒绝,并标记后续节点也结束
|
||||
if (!approved) {
|
||||
StglMember member = memberMapper.selectById(memberId);
|
||||
if (member != null) {
|
||||
StglMember updateMember = new StglMember();
|
||||
updateMember.setId(memberId);
|
||||
updateMember.setStatus(3); // 已拒绝
|
||||
updateMember.setRemark(opinion != null ? "审批拒绝: " + opinion : "审批拒绝");
|
||||
memberMapper.updateById(updateMember);
|
||||
}
|
||||
|
||||
// 将后续待审批节点也标记为结束
|
||||
LambdaQueryWrapper<StglMemberApproval> pendingLqw = Wrappers.lambdaQuery();
|
||||
pendingLqw.eq(StglMemberApproval::getMemberId, memberId)
|
||||
.eq(StglMemberApproval::getAuditStatus, "pending")
|
||||
.ne(StglMemberApproval::getId, approvalNode.getId());
|
||||
List<StglMemberApproval> pendingNodes = approvalMapper.selectList(pendingLqw);
|
||||
for (StglMemberApproval pending : pendingNodes) {
|
||||
StglMemberApproval cancelNode = new StglMemberApproval();
|
||||
cancelNode.setId(pending.getId());
|
||||
cancelNode.setAuditStatus("rejected");
|
||||
cancelNode.setApproveResult("前置节点拒绝,自动终止");
|
||||
cancelNode.setAuditTime(new Date());
|
||||
approvalMapper.updateById(cancelNode);
|
||||
}
|
||||
|
||||
log.info("成员申请被拒绝: memberId={}, nodeCode={}, 拒绝人={}", memberId, nodeCode, currentUserId);
|
||||
} else {
|
||||
log.info("成员申请节点审批通过: memberId={}, nodeCode={}, 审批人={}", memberId, nodeCode, currentUserId);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+16
-17
@@ -16,6 +16,7 @@ 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 org.dromara.stgl.service.IStglMemberApprovalService;
|
||||
import org.dromara.system.service.ISysUserService;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
@@ -44,6 +45,7 @@ public class StglMemberServiceImpl implements IStglMemberService {
|
||||
|
||||
private final StglMemberMapper baseMapper;
|
||||
private final ISysUserService userService;
|
||||
private final IStglMemberApprovalService memberApprovalService;
|
||||
|
||||
/**
|
||||
* 查询社团成员
|
||||
@@ -381,28 +383,25 @@ public class StglMemberServiceImpl implements IStglMemberService {
|
||||
if (member == null) {
|
||||
throw new RuntimeException("成员记录不存在");
|
||||
}
|
||||
|
||||
if (member.getStatus() != 0) {
|
||||
|
||||
if (member.getStatus() != 0 && member.getStatus() != 1) {
|
||||
throw new RuntimeException("该申请已审核过,无法重复审核");
|
||||
}
|
||||
|
||||
// 更新成员状态和角色
|
||||
StglMember updateMember = new StglMember();
|
||||
updateMember.setId(id);
|
||||
if (approved) {
|
||||
updateMember.setStatus(2); // 已加入状态(stgl_member_status字典)
|
||||
// 根据成员类型设置不同的角色
|
||||
if (member.getMemberType() == 1) {
|
||||
updateMember.setRoleType("普通成员"); // 社团成员
|
||||
} else if (member.getMemberType() == 2) {
|
||||
updateMember.setRoleType("队员"); // 志愿者队伍成员
|
||||
|
||||
Long currentUserId = LoginHelper.getUserId();
|
||||
java.util.Set<String> roleKeys = LoginHelper.getLoginUser().getRolePermission();
|
||||
|
||||
if (roleKeys.contains("stgl_instructor")) {
|
||||
if (member.getStatus() == 0) {
|
||||
throw new RuntimeException("该申请需等待社长先审批,请稍后再试");
|
||||
}
|
||||
return memberApprovalService.advisorApprove(id, approved, null);
|
||||
} else {
|
||||
updateMember.setStatus(3); // 已驳回状态(stgl_member_status字典)
|
||||
updateMember.setRoleType(null); // 拒绝时清空角色
|
||||
if (member.getStatus() == 1) {
|
||||
throw new RuntimeException("社长已审批通过,等待指导老师审批中");
|
||||
}
|
||||
return memberApprovalService.presidentApprove(id, approved, null);
|
||||
}
|
||||
|
||||
return baseMapper.updateById(updateMember) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<result property="advisorEmail" column="advisor_email"/>
|
||||
<result property="vicePresidentsJson" column="vice_presidents_json"/>
|
||||
<result property="advisorsJson" column="advisors_json"/>
|
||||
<result property="affiliation" column="affiliation"/>
|
||||
<result property="memberLimit" column="member_limit"/>
|
||||
<result property="departments" column="departments"/>
|
||||
<result property="recruitCycle" column="recruit_cycle"/>
|
||||
@@ -56,6 +57,7 @@
|
||||
c.vice_presidents_json,
|
||||
c.advisor_name, c.advisor_dept, c.advisor_phone, c.advisor_email,
|
||||
c.advisors_json,
|
||||
c.affiliation,
|
||||
c.member_limit, c.departments, c.recruit_cycle, c.recruit_time, c.activity_frequency, c.funding_sources,
|
||||
c.charter_url, c.status, c.sigh_open, c.remark, c.create_by, c.create_time, c.update_by, c.update_time, c.tenant_id, c.deleted,
|
||||
COALESCE(m.member_count, 0) as memberCount
|
||||
@@ -76,6 +78,7 @@
|
||||
c.president_dept, c.president_major, c.president_class, c.president_phone,
|
||||
c.vice_president_name, c.vice_president_student_no, c.vice_president_dept, c.vice_president_major, c.vice_president_class, c.vice_president_phone,
|
||||
c.advisor_name, c.advisor_dept, c.advisor_phone, c.advisor_email,
|
||||
c.affiliation,
|
||||
c.member_limit, c.departments, c.recruit_cycle, c.recruit_time,
|
||||
c.activity_frequency, c.funding_sources, c.charter_url, c.status, c.sigh_open, c.remark,
|
||||
c.create_by, c.create_time, c.update_by, c.update_time,
|
||||
@@ -98,6 +101,7 @@
|
||||
c.president_dept, c.president_major, c.president_class, c.president_phone,
|
||||
c.vice_president_name, c.vice_president_student_no, c.vice_president_dept, c.vice_president_major, c.vice_president_class, c.vice_president_phone,
|
||||
c.advisor_name, c.advisor_dept, c.advisor_phone, c.advisor_email,
|
||||
c.affiliation,
|
||||
c.member_limit, c.departments, c.recruit_cycle, c.recruit_time,
|
||||
c.activity_frequency, c.funding_sources, c.charter_url, c.status, c.sigh_open, c.remark,
|
||||
c.create_by, c.create_time, c.update_by, c.update_time,
|
||||
@@ -129,6 +133,7 @@
|
||||
c.vice_presidents_json,
|
||||
c.advisor_name, c.advisor_dept, c.advisor_phone, c.advisor_email,
|
||||
c.advisors_json,
|
||||
c.affiliation,
|
||||
c.member_limit, c.departments, c.recruit_cycle, c.recruit_time,
|
||||
c.activity_frequency, c.funding_sources, c.charter_url, c.status, c.sigh_open, c.remark,
|
||||
c.create_by, c.create_time, c.update_by, c.update_time,
|
||||
|
||||
@@ -445,4 +445,132 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
ORDER BY a.start_time DESC, a.create_time DESC
|
||||
</select>
|
||||
|
||||
<!-- 查询指定班级中当前正在参加活动的学生列表(个人报名 + 团队报名) -->
|
||||
<select id="selectCurrentActiveStudents" parameterType="java.util.Map" resultType="java.util.Map">
|
||||
SELECT
|
||||
s.id,
|
||||
s.student_no AS studentNo,
|
||||
s.name AS studentName,
|
||||
s.gender,
|
||||
s.phone,
|
||||
c.class_name AS className,
|
||||
a.id AS activityId,
|
||||
a.activity_name AS activityName,
|
||||
a.start_time AS startTime,
|
||||
a.end_time AS endTime,
|
||||
a.location,
|
||||
CASE
|
||||
WHEN a.related_type = 1 THEN club.club_name
|
||||
WHEN a.related_type = 2 THEN vt.team_name
|
||||
ELSE NULL
|
||||
END AS organizationName
|
||||
FROM xg_student_msg s
|
||||
LEFT JOIN xg_class_msg c ON s.class_id = c.id AND c.tenant_id = '000000'
|
||||
INNER JOIN (
|
||||
SELECT ar.user_id, ar.activity_id FROM stgl_activity_registration ar
|
||||
INNER JOIN stgl_activity a ON ar.activity_id = a.id AND a.deleted = 0 AND a.tenant_id = '000000'
|
||||
WHERE ar.deleted = 0 AND ar.approval_status = 1 AND ar.tenant_id = '000000'
|
||||
AND NOW() BETWEEN a.start_time AND a.end_time
|
||||
|
||||
UNION
|
||||
|
||||
SELECT
|
||||
CAST(JSON_UNQUOTE(JSON_EXTRACT(ati.team_members, CONCAT('$[', numbers.n, '].userId'))) AS UNSIGNED) AS user_id,
|
||||
ati.activity_id
|
||||
FROM stgl_activity_team_info ati
|
||||
CROSS JOIN (
|
||||
SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
|
||||
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION
|
||||
SELECT 10 UNION SELECT 11 UNION SELECT 12 UNION SELECT 13 UNION SELECT 14 UNION
|
||||
SELECT 15 UNION SELECT 16 UNION SELECT 17 UNION SELECT 18 UNION SELECT 19
|
||||
) numbers
|
||||
INNER JOIN stgl_activity a ON ati.activity_id = a.id AND a.deleted = 0 AND a.tenant_id = '000000'
|
||||
WHERE ati.deleted = 0 AND ati.tenant_id = '000000'
|
||||
AND NOW() BETWEEN a.start_time AND a.end_time
|
||||
AND JSON_UNQUOTE(JSON_EXTRACT(ati.team_members, CONCAT('$[', numbers.n, '].userId'))) IS NOT NULL
|
||||
AND JSON_UNQUOTE(JSON_EXTRACT(ati.team_members, CONCAT('$[', numbers.n, '].userId'))) != ''
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM stgl_activity_registration team_ar
|
||||
WHERE team_ar.team_id = ati.id
|
||||
AND team_ar.deleted = 0
|
||||
AND team_ar.approval_status = 1
|
||||
AND team_ar.registration_type = 2
|
||||
AND team_ar.tenant_id = '000000'
|
||||
)
|
||||
) active ON s.id = active.user_id
|
||||
INNER JOIN stgl_activity a ON active.activity_id = a.id AND a.deleted = 0 AND a.tenant_id = '000000'
|
||||
LEFT JOIN stgl_club club ON a.related_type = 1 AND a.related_club_id = club.id AND club.deleted = 0 AND club.tenant_id = '000000'
|
||||
LEFT JOIN stgl_volunteer_team vt ON a.related_type = 2 AND a.related_club_id = vt.id AND vt.deleted = 0 AND vt.tenant_id = '000000'
|
||||
<where>
|
||||
s.deleted = 0
|
||||
AND s.student_status = '1'
|
||||
AND s.tenant_id = '000000'
|
||||
<if test="classId != null and classId != ''">
|
||||
AND s.class_id = #{classId}
|
||||
</if>
|
||||
<if test="studentName != null and studentName != ''">
|
||||
AND s.name LIKE CONCAT('%', #{studentName}, '%')
|
||||
</if>
|
||||
<if test="studentNo != null and studentNo != ''">
|
||||
AND s.student_no LIKE CONCAT('%', #{studentNo}, '%')
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY a.start_time, s.student_no
|
||||
<if test="offset != null and pageSize != null">
|
||||
LIMIT #{pageSize} OFFSET #{offset}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!-- 查询指定班级中当前正在参加活动的学生总数 -->
|
||||
<select id="selectCurrentActiveStudentsCount" parameterType="java.util.Map" resultType="java.lang.Integer">
|
||||
SELECT COUNT(*)
|
||||
FROM xg_student_msg s
|
||||
INNER JOIN (
|
||||
SELECT ar.user_id, ar.activity_id FROM stgl_activity_registration ar
|
||||
INNER JOIN stgl_activity a ON ar.activity_id = a.id AND a.deleted = 0 AND a.tenant_id = '000000'
|
||||
WHERE ar.deleted = 0 AND ar.approval_status = 1 AND ar.tenant_id = '000000'
|
||||
AND NOW() BETWEEN a.start_time AND a.end_time
|
||||
|
||||
UNION
|
||||
|
||||
SELECT
|
||||
CAST(JSON_UNQUOTE(JSON_EXTRACT(ati.team_members, CONCAT('$[', numbers.n, '].userId'))) AS UNSIGNED) AS user_id,
|
||||
ati.activity_id
|
||||
FROM stgl_activity_team_info ati
|
||||
CROSS JOIN (
|
||||
SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
|
||||
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION
|
||||
SELECT 10 UNION SELECT 11 UNION SELECT 12 UNION SELECT 13 UNION SELECT 14 UNION
|
||||
SELECT 15 UNION SELECT 16 UNION SELECT 17 UNION SELECT 18 UNION SELECT 19
|
||||
) numbers
|
||||
INNER JOIN stgl_activity a ON ati.activity_id = a.id AND a.deleted = 0 AND a.tenant_id = '000000'
|
||||
WHERE ati.deleted = 0 AND ati.tenant_id = '000000'
|
||||
AND NOW() BETWEEN a.start_time AND a.end_time
|
||||
AND JSON_UNQUOTE(JSON_EXTRACT(ati.team_members, CONCAT('$[', numbers.n, '].userId'))) IS NOT NULL
|
||||
AND JSON_UNQUOTE(JSON_EXTRACT(ati.team_members, CONCAT('$[', numbers.n, '].userId'))) != ''
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM stgl_activity_registration team_ar
|
||||
WHERE team_ar.team_id = ati.id
|
||||
AND team_ar.deleted = 0
|
||||
AND team_ar.approval_status = 1
|
||||
AND team_ar.registration_type = 2
|
||||
AND team_ar.tenant_id = '000000'
|
||||
)
|
||||
) active ON s.id = active.user_id
|
||||
<where>
|
||||
s.deleted = 0
|
||||
AND s.student_status = '1'
|
||||
AND s.tenant_id = '000000'
|
||||
<if test="classId != null and classId != ''">
|
||||
AND s.class_id = #{classId}
|
||||
</if>
|
||||
<if test="studentName != null and studentName != ''">
|
||||
AND s.name LIKE CONCAT('%', #{studentName}, '%')
|
||||
</if>
|
||||
<if test="studentNo != null and studentNo != ''">
|
||||
AND s.student_no LIKE CONCAT('%', #{studentNo}, '%')
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
Reference in new issue
Block a user