Browse Source

团员管理功能模块

大数据与最优化研究所 8 months ago
parent
commit
38aecd6477
21 changed files with 1511 additions and 70 deletions
  1. 2 9
      src/main/java/com/xjrsoft/module/base/service/impl/BaseClassCourseServiceImpl.java
  2. 289 0
      src/main/java/com/xjrsoft/module/student/controller/LeagueMembersManageController.java
  3. 62 0
      src/main/java/com/xjrsoft/module/student/dto/AddLeagueMembersManageDto.java
  4. 58 0
      src/main/java/com/xjrsoft/module/student/dto/LeagueMembersExportQueryDto.java
  5. 63 0
      src/main/java/com/xjrsoft/module/student/dto/LeagueMembersImportDto.java
  6. 58 0
      src/main/java/com/xjrsoft/module/student/dto/LeagueMembersManagePageDto.java
  7. 32 0
      src/main/java/com/xjrsoft/module/student/dto/UpdateLeagueMembersManageDto.java
  8. 109 0
      src/main/java/com/xjrsoft/module/student/entity/LeagueMembersManage.java
  9. 17 0
      src/main/java/com/xjrsoft/module/student/mapper/LeagueMembersManageMapper.java
  10. 33 0
      src/main/java/com/xjrsoft/module/student/service/ILeagueMembersManageService.java
  11. 394 0
      src/main/java/com/xjrsoft/module/student/service/impl/LeagueMembersManageServiceImpl.java
  12. 27 0
      src/main/java/com/xjrsoft/module/student/vo/ClassWithLMNumTreeVo.java
  13. 97 0
      src/main/java/com/xjrsoft/module/student/vo/LeagueMembersExportQueryListVo.java
  14. 87 0
      src/main/java/com/xjrsoft/module/student/vo/LeagueMembersManagePageVo.java
  15. 59 0
      src/main/java/com/xjrsoft/module/student/vo/LeagueMembersManageVo.java
  16. 1 1
      src/main/java/com/xjrsoft/module/textbook/controller/TextbookController.java
  17. 1 1
      src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookIssueRecordServiceImpl.java
  18. 1 1
      src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookSubscriptionServiceImpl.java
  19. 13 8
      src/main/java/com/xjrsoft/module/veb/util/ImportExcelUtil.java
  20. 83 50
      src/main/resources/sqlScript/20250408_sql.sql
  21. 25 0
      src/test/java/com/xjrsoft/xjrsoftboot/FreeMarkerGeneratorTest.java

+ 2 - 9
src/main/java/com/xjrsoft/module/base/service/impl/BaseClassCourseServiceImpl.java

@@ -41,14 +41,7 @@ import com.xjrsoft.module.textbook.mapper.TextbookStudentClaimMapper;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.CellStyle;
-import org.apache.poi.ss.usermodel.Font;
-import org.apache.poi.ss.usermodel.HorizontalAlignment;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.usermodel.VerticalAlignment;
-import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.beans.BeanUtils;
@@ -590,7 +583,7 @@ public class BaseClassCourseServiceImpl extends MPJBaseServiceImpl<BaseClassCour
         List<ImportConfig> importConfigs = allFields(new ClassCourseTextbookExportQueryVo());
 
         // 表头
-        createHead(workbook, sheet, importConfigs, 0);
+        createHead(workbook, sheet, importConfigs, IndexedColors.YELLOW.getIndex(), IndexedColors.RED.getIndex(), 0);
 
         // 内容
         int dataRowNumber = 1;

+ 289 - 0
src/main/java/com/xjrsoft/module/student/controller/LeagueMembersManageController.java

@@ -0,0 +1,289 @@
+package com.xjrsoft.module.student.controller;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.xjrsoft.common.constant.GlobalConstant;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.xjrsoft.common.enums.DeleteMark;
+import com.xjrsoft.common.exception.MyException;
+import com.xjrsoft.common.model.result.R;
+import com.xjrsoft.common.page.ConventPage;
+import com.xjrsoft.common.page.PageOutput;
+import com.xjrsoft.common.model.result.RT;
+import com.xjrsoft.common.utils.TreeUtil;
+import com.xjrsoft.common.utils.VoToColumnUtil;
+import com.xjrsoft.module.base.entity.BaseClass;
+import com.xjrsoft.module.base.entity.BaseGrade;
+import com.xjrsoft.module.databoard.vo.DistributionVo;
+import com.xjrsoft.module.oa.vo.MeetingRoomListVo;
+import com.xjrsoft.module.student.dto.AddLeagueMembersManageDto;
+import com.xjrsoft.module.student.dto.LeagueMembersExportQueryDto;
+import com.xjrsoft.module.student.dto.UpdateLeagueMembersManageDto;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.xjrsoft.common.annotation.XjrLog;
+
+import com.xjrsoft.module.student.dto.LeagueMembersManagePageDto;
+import com.xjrsoft.module.student.entity.BaseStudent;
+import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll;
+import com.xjrsoft.module.student.entity.LeagueMembersManage;
+import com.xjrsoft.module.student.service.ILeagueMembersManageService;
+import com.xjrsoft.module.student.vo.ClassWithLMNumTreeVo;
+import com.xjrsoft.module.student.vo.LeagueMembersManagePageVo;
+
+import com.xjrsoft.module.student.vo.LeagueMembersManageVo;
+import com.xjrsoft.module.student.vo.StudentHonorsTreeVo;
+import com.xjrsoft.module.system.entity.DictionaryDetail;
+import com.xjrsoft.module.teacher.entity.XjrUser;
+import com.xjrsoft.module.textbook.dto.TextbookSubscriptionExportQueryListDto;
+import com.xjrsoft.module.textbook.vo.TextbookSubscriptionExportQueryListVo;
+import com.xjrsoft.module.veb.util.ImportExcelUtil;
+import com.xjrsoft.module.veb.vo.BaseCourseSubjectImportVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+/**
+ * @title: 团员管理
+ * @Author phoenix
+ * @Date: 2025-04-08
+ * @Version 1.0
+ */
+@RestController
+@RequestMapping("/student" + "/leagueMembersManage")
+@Api(value = "/student" + "/leagueMembersManage", tags = "团员管理代码")
+@AllArgsConstructor
+public class LeagueMembersManageController {
+
+    private final ILeagueMembersManageService leagueMembersManageService;
+
+    @GetMapping(value = "/tree")
+    @ApiOperation(value = "团员管理班级附带统计数量列表(树)")
+    @SaCheckPermission("leaguemembersmanage:detail")
+    @XjrLog(value = "团员管理班级附带统计数量列表(树)")
+    public RT<List<ClassWithLMNumTreeVo>> tree() {
+        MPJLambdaWrapper<LeagueMembersManage> leagueMembersManageMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        leagueMembersManageMPJLambdaWrapper
+                .disableSubLogicDel()
+                .select(LeagueMembersManage::getId)
+                .leftJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId, LeagueMembersManage::getUserId,
+                        wrappers -> wrappers
+                                .selectAs(BaseStudentSchoolRoll::getClassId, LeagueMembersManage::getCreateUserId) // 暂时将班级id放到createUserId字段
+                                .leftJoin(BaseClass.class, BaseClass::getId, BaseStudentSchoolRoll::getClassId,
+                                        wrap -> wrap
+                                                .selectAs(BaseClass::getName, LeagueMembersManage::getLeagueMembersNum) // 暂时将班级名称放到leagueMembersNum字段
+                                                .selectAs(BaseClass::getGradeId, LeagueMembersManage::getModifyUserId) // 暂时将年级id放到modifyUserId字段
+                                                .leftJoin(BaseGrade.class, BaseGrade::getId, BaseClass::getGradeId,
+                                                        wr -> wr
+                                                                .selectAs(BaseGrade::getName, LeagueMembersManage::getAddress) // 暂时将年级名称放到address字段
+                                                )
+                                )
+                                .eq(BaseStudentSchoolRoll::getDeleteMark, DeleteMark.NODELETE.getCode())
+                )
+                ;
+        List<LeagueMembersManage> leagueMembersManages = leagueMembersManageService.selectJoinList(LeagueMembersManage.class, leagueMembersManageMPJLambdaWrapper);
+
+        // 开始构建树并处理总数
+        List<ClassWithLMNumTreeVo> dataList = new ArrayList<>();
+        Map<Long, Integer> numMap = new LinkedHashMap<>();
+        int total = 0;
+        for (LeagueMembersManage l : leagueMembersManages){
+            // 当前班级已经处理
+            if(numMap.containsKey(l.getCreateUserId())){
+                numMap.put(l.getCreateUserId(), numMap.get(l.getCreateUserId()) + 1);
+                numMap.put(l.getModifyUserId(), numMap.get(l.getModifyUserId()) + 1);
+            } else {
+                numMap.put(l.getCreateUserId(), 1);
+                dataList.add(new ClassWithLMNumTreeVo(){{
+                    setId(Long.toString(l.getCreateUserId()));
+                    setName(l.getLeagueMembersNum());
+                    setParentId(Long.toString(l.getModifyUserId()));
+                    setChildren(new ArrayList<>());
+                }});
+                // 当前年级已经处理
+                if(numMap.containsKey(l.getModifyUserId())){
+                    numMap.put(l.getModifyUserId(), numMap.get(l.getModifyUserId()) + 1);
+                }else {
+                    numMap.put(l.getModifyUserId(), 1);
+                    dataList.add(new ClassWithLMNumTreeVo(){{
+                        setId(Long.toString(l.getModifyUserId()));
+                        setName(l.getAddress());
+                        setParentId("8888");
+                        setChildren(new ArrayList<>());
+                    }});
+                }
+            }
+            total++;
+        }
+
+        // 为每一个节点匹配数字
+        for (ClassWithLMNumTreeVo vo : dataList){
+            Integer num = numMap.get(Long.parseLong(vo.getId()));
+            vo.setNum(num);
+        }
+
+        dataList.sort(Comparator.comparing(ClassWithLMNumTreeVo::getName).reversed());
+
+        int finalTotal = total;
+        dataList.add(new ClassWithLMNumTreeVo(){{
+            setId("8888");
+            setName("总览");
+            setParentId("0");
+            setNum(finalTotal);
+            setChildren(new ArrayList<>());
+        }});
+
+        List<ClassWithLMNumTreeVo> treeVoList = TreeUtil.build(dataList);
+
+        return RT.ok(treeVoList);
+    }
+
+    @GetMapping(value = "/page")
+    @ApiOperation(value = "团员管理列表(分页)")
+    @SaCheckPermission("leaguemembersmanage:detail")
+    @XjrLog(value = "团员管理列表(分页)")
+    public RT<PageOutput<LeagueMembersManagePageVo>> page(@Valid LeagueMembersManagePageDto dto) {
+        MPJLambdaWrapper<LeagueMembersManage> queryWrapper = new MPJLambdaWrapper<>();
+        queryWrapper
+                .disableSubLogicDel()
+                .select(LeagueMembersManage::getId)
+                .select(LeagueMembersManage.class, x -> VoToColumnUtil.fieldsToColumns(LeagueMembersManagePageVo.class).contains(x.getProperty()))
+                .innerJoin(XjrUser.class, XjrUser::getId, LeagueMembersManage::getUserId,
+                        wrappers -> wrappers
+                                .selectAs(XjrUser::getName, LeagueMembersManagePageVo::getStudentName)
+                                .selectAs(XjrUser::getCredentialNumber, LeagueMembersManagePageVo::getIdCard)
+                                .selectAs(XjrUser::getMobile, LeagueMembersManagePageVo::getPhone)
+                                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, XjrUser::getGender,
+                                        wrap -> wrap
+                                                .selectAs(DictionaryDetail::getName, LeagueMembersManagePageVo::getGenderCn)
+                                )
+                                .like(StringUtils.isNotEmpty(dto.getStudentName()), XjrUser::getName, dto.getStudentName())
+                                .like(StringUtils.isNotEmpty(dto.getIdCard()), XjrUser::getCredentialNumber, dto.getIdCard())
+                                .eq(XjrUser::getDeleteMark, DeleteMark.NODELETE.getCode())
+                )
+                .leftJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId, LeagueMembersManage::getUserId,
+                        wrappers -> wrappers
+                                .selectAs(BaseStudentSchoolRoll::getArchivesStatus, LeagueMembersManagePageVo::getArchivesStatus)
+                                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, BaseStudentSchoolRoll::getArchivesStatus,
+                                        wrap -> wrap
+                                                .selectAs(DictionaryDetail::getName, LeagueMembersManagePageVo::getStatusCn)
+                                )
+                                .leftJoin(BaseClass.class, BaseClass::getId, BaseStudentSchoolRoll::getClassId,
+                                        wrap -> wrap
+                                                .selectAs(BaseClass::getName, LeagueMembersManagePageVo::getClassName)
+                                                .leftJoin(XjrUser.class, XjrUser::getId, BaseClass::getTeacherId,
+                                                        wr -> wr
+                                                                .selectAs(XjrUser::getName, LeagueMembersManagePageVo::getTeacherName)
+                                                )
+                                                .eq(ObjectUtils.isNotEmpty(dto.getGradeId()), BaseClass::getGradeId, dto.getGradeId())
+                                )
+                                .like(StringUtils.isNotEmpty(dto.getArchivesStatus()), BaseStudentSchoolRoll::getArchivesStatus, dto.getArchivesStatus())
+                                .eq(ObjectUtils.isNotEmpty(dto.getClassId()), BaseStudentSchoolRoll::getClassId, dto.getClassId())
+                                .eq(BaseStudentSchoolRoll::getDeleteMark, DeleteMark.NODELETE.getCode())
+                )
+                .leftJoin(BaseStudent.class, BaseStudent::getUserId, LeagueMembersManage::getUserId,
+                        wrappers -> wrappers
+                                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, BaseStudent::getNation,
+                                        wrap -> wrap
+                                                .selectAs(DictionaryDetail::getName, LeagueMembersManagePageVo::getNation)
+                                )
+                                .eq(BaseStudent::getDeleteMark, DeleteMark.NODELETE.getCode())
+                )
+                .like(StringUtils.isNotEmpty(dto.getLeagueMembersNum()), LeagueMembersManage::getLeagueMembersNum, dto.getLeagueMembersNum())
+                .ge(ObjectUtils.isNotEmpty(dto.getJoinTimeStart()), LeagueMembersManage::getJoinTime, dto.getJoinTimeStart())
+                .le(ObjectUtils.isNotEmpty(dto.getJoinTimeEnd()), LeagueMembersManage::getJoinTime, dto.getJoinTimeEnd())
+                .ge(ObjectUtils.isNotEmpty(dto.getTransferTimeStart()), LeagueMembersManage::getTransferTime, dto.getTransferTimeStart())
+                .le(ObjectUtils.isNotEmpty(dto.getTransferTimeEnd()), LeagueMembersManage::getTransferTime, dto.getTransferTimeEnd())
+                .orderByAsc(BaseStudentSchoolRoll::getArchivesStatus)
+        ;
+
+        IPage<LeagueMembersManagePageVo> page = leagueMembersManageService.selectJoinListPage(ConventPage.getPage(dto), LeagueMembersManagePageVo.class, queryWrapper);
+        PageOutput<LeagueMembersManagePageVo> pageOutput = ConventPage.getPageOutput(page, LeagueMembersManagePageVo.class);
+        return RT.ok(pageOutput);
+    }
+
+    @PostMapping
+    @ApiOperation(value = "新增团员管理")
+    @SaCheckPermission("leaguemembersmanage:add")
+    @XjrLog(value = "新增团员管理")
+    public RT<Boolean> add(@Valid @RequestBody AddLeagueMembersManageDto dto) {
+        return RT.ok(leagueMembersManageService.addRubAndHand(dto));
+    }
+
+    @PutMapping
+    @ApiOperation(value = "修改团员管理")
+    @SaCheckPermission("leaguemembersmanage:edit")
+    @XjrLog(value = "修改团员管理")
+    public RT<Boolean> update(@Valid @RequestBody UpdateLeagueMembersManageDto dto) {
+        LeagueMembersManage leagueMembersManage = BeanUtil.toBean(dto, LeagueMembersManage.class);
+        return RT.ok(leagueMembersManageService.updateById(leagueMembersManage));
+    }
+
+    @DeleteMapping
+    @ApiOperation(value = "删除团员管理")
+    @SaCheckPermission("leaguemembersmanage:delete")
+    @XjrLog(value = "删除团员管理")
+    public RT<Boolean> delete(@Valid @RequestBody List<Long> ids) {
+        return RT.ok(leagueMembersManageService.deleteRubAndHand(ids));
+    }
+
+//    @PostMapping("/league-members-import-template")
+//    @ApiOperation(value = "团员信息导入模板下载")
+//    @XjrLog(value = "团员信息导入模板下载")
+//    public ResponseEntity<byte[]> leagueMembersImportTemplate() throws IOException {
+    @GetMapping("/league-members-import-template")
+    @ApiOperation(value = "团员信息导入模板下载")
+    @XjrLog(value = "团员信息导入模板下载")
+    public ResponseEntity<byte[]> leagueMembersImportTemplate() throws IOException {
+        ByteArrayOutputStream bot = leagueMembersManageService.leagueMembersImportTemplate();
+
+        String fileName = "团员信息导入模板";
+        fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
+        return R.fileStream(bot.toByteArray(), fileName + System.currentTimeMillis() + ExcelTypeEnum.XLSX.getValue());
+    }
+
+    @PostMapping("/import")
+    @ApiOperation(value = "团员信息导入")
+    @XjrLog(value = "团员信息导入", saveRequestData = false, saveResponseData = true)
+    public RT<Boolean> leagueMembersImport(@Valid @RequestParam MultipartFile file) throws IOException, IllegalAccessException {
+        String result = leagueMembersManageService.leagueMembersImport(file);
+        if (!result.isEmpty()) {
+            throw new MyException(result);
+        }
+        return RT.ok("全部成功", true);
+    }
+
+//    @PostMapping("/league-members-export-query")
+//    @ApiOperation(value = "团员信息条件导出")
+//    @XjrLog(value = "团员信息条件导出")
+//    public ResponseEntity<byte[]> leagueMembersExportQuery(@Valid @RequestBody LeagueMembersExportQueryListDto dto) {
+    @GetMapping("/league-members-export-query")
+    @ApiOperation(value = "团员信息条件导出")
+    @XjrLog(value = "团员信息条件导出")
+    public ResponseEntity<byte[]> leagueMembersExportQuery(@Valid LeagueMembersExportQueryDto dto) throws IOException {
+        ByteArrayOutputStream bot = leagueMembersManageService.textbookSubscriptionExportQuery(dto);
+
+        String fileName = "团员信息列表";
+        fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
+        return RT.fileStream(bot.toByteArray(), fileName +  System.currentTimeMillis() + ExcelTypeEnum.XLSX.getValue());
+    }
+}

+ 62 - 0
src/main/java/com/xjrsoft/module/student/dto/AddLeagueMembersManageDto.java

@@ -0,0 +1,62 @@
+package com.xjrsoft.module.student.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Date;
+
+
+
+/**
+* @title: 团员管理
+* @Author phoenix
+* @Date: 2025-04-08
+* @Version 1.0
+*/
+@Data
+public class AddLeagueMembersManageDto implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+    * 学生主键id(xjr_user)
+    */
+    @ApiModelProperty("学生主键id(xjr_user)")
+    private Long userId;
+    /**
+    * 团员编号
+    */
+    @ApiModelProperty("团员编号")
+    private String leagueMembersNum;
+    /**
+    * 常住地址
+    */
+    @ApiModelProperty("常住地址")
+    private String address;
+    /**
+    * 加入时间
+    */
+    @ApiModelProperty("加入时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate joinTime;
+    /**
+    * 转入时间
+    */
+    @ApiModelProperty("转入时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate transferTime;
+    /**
+    * 备注
+    */
+    @ApiModelProperty("备注")
+    private String remark;
+
+}

+ 58 - 0
src/main/java/com/xjrsoft/module/student/dto/LeagueMembersExportQueryDto.java

@@ -0,0 +1,58 @@
+package com.xjrsoft.module.student.dto;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ContentStyle;
+import com.xjrsoft.common.annotation.Required;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+
+
+/**
+ * @title: 团员信息有参导出入参
+ * @Author phoenix
+ * @Date: 2025年04月08日
+ * @Version 1.0
+ */
+@Data
+public class LeagueMembersExportQueryDto implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("所属年级(base_grade)")
+    private Long gradeId;
+
+    @ApiModelProperty("所属班级(base_class)")
+    private Long classId;
+
+    @ApiModelProperty("学生姓名")
+    private String studentName;
+
+    @ApiModelProperty("身份证号")
+    private String idCard;
+
+    @ApiModelProperty("团员编号")
+    private String leagueMembersNum;
+
+    @ApiModelProperty("学籍状态(xjr_dictionary_item[archives_status])")
+    private String archivesStatus;
+
+    @ApiModelProperty("加入时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate joinTimeStart;
+
+    @ApiModelProperty("加入时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate joinTimeEnd;
+
+    @ApiModelProperty("转入时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate transferTimeStart;
+
+    @ApiModelProperty("转入时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate transferTimeEnd;
+}

+ 63 - 0
src/main/java/com/xjrsoft/module/student/dto/LeagueMembersImportDto.java

@@ -0,0 +1,63 @@
+package com.xjrsoft.module.student.dto;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ContentStyle;
+import com.xjrsoft.common.annotation.Required;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+
+
+/**
+ * @title: 团员信息导入映射实体对象
+ * @Author phoenix
+ * @Date: 2025年04月08日
+ * @Version 1.0
+ */
+@Data
+public class LeagueMembersImportDto {
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("姓名")
+    @ApiModelProperty("姓名")
+    @Required
+    private String studentName;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("身份证号")
+    @ApiModelProperty("身份证号")
+    @Required
+    private String idCard;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("常住地址")
+    @ApiModelProperty("常住地址")
+    @Required(value = false)
+    private String address;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("团员编号")
+    @ApiModelProperty("团员编号")
+    @Required(value = false)
+    private String leagueMembersNum;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("入团时间")
+    @ApiModelProperty("入团时间")
+    @Required(value = false)
+    private String joinTime;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("转入时间")
+    @ApiModelProperty("转入时间")
+    @Required(value = false)
+    private String transferTime;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("备注")
+    @ApiModelProperty("备注")
+    @Required(value = false)
+    private String remark;
+}

+ 58 - 0
src/main/java/com/xjrsoft/module/student/dto/LeagueMembersManagePageDto.java

@@ -0,0 +1,58 @@
+package com.xjrsoft.module.student.dto;
+
+import com.xjrsoft.common.page.PageInput;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.Date;
+
+
+/**
+* @title: 团员管理分页查询入参
+* @Author phoenix
+* @Date: 2025-04-08
+* @Version 1.0
+*/
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class LeagueMembersManagePageDto extends PageInput {
+    @ApiModelProperty("所属年级(base_grade)")
+    private Long gradeId;
+
+    @ApiModelProperty("所属班级(base_class)")
+    private Long classId;
+
+    @ApiModelProperty("学生姓名")
+    private String studentName;
+
+    @ApiModelProperty("身份证号")
+    private String idCard;
+
+    @ApiModelProperty("团员编号")
+    private String leagueMembersNum;
+
+    @ApiModelProperty("学籍状态(xjr_dictionary_item[archives_status])")
+    private String archivesStatus;
+
+    @ApiModelProperty("加入时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate joinTimeStart;
+
+    @ApiModelProperty("加入时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate joinTimeEnd;
+
+    @ApiModelProperty("转入时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate transferTimeStart;
+
+    @ApiModelProperty("转入时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate transferTimeEnd;
+}

+ 32 - 0
src/main/java/com/xjrsoft/module/student/dto/UpdateLeagueMembersManageDto.java

@@ -0,0 +1,32 @@
+package com.xjrsoft.module.student.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.List;
+import java.util.Date;
+
+
+
+/**
+* @title: 团员管理
+* @Author phoenix
+* @Date: 2025-04-08
+* @Version 1.0
+*/
+@Data
+public class UpdateLeagueMembersManageDto extends AddLeagueMembersManageDto {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+    * 主键编号
+    */
+    @ApiModelProperty("主键编号")
+    private Long id;
+}

+ 109 - 0
src/main/java/com/xjrsoft/module/student/entity/LeagueMembersManage.java

@@ -0,0 +1,109 @@
+package com.xjrsoft.module.student.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.github.yulichang.annotation.EntityMapping;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Date;
+
+
+/**
+* @title: 团员管理
+* @Author phoenix
+* @Date: 2025-04-08
+* @Version 1.0
+*/
+@Data
+@TableName("league_members_manage")
+@ApiModel(value = "league_members_manage", description = "团员管理")
+public class LeagueMembersManage implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+    * 主键编号
+    */
+    @ApiModelProperty("主键编号")
+    @TableId
+    private Long id;
+    /**
+    * 创建人
+    */
+    @ApiModelProperty("创建人")
+    @TableField(fill = FieldFill.INSERT)
+    private Long createUserId;
+    /**
+    * 创建时间
+    */
+    @ApiModelProperty("创建时间")
+    @TableField(fill = FieldFill.INSERT)
+    private Date createDate;
+    /**
+    * 修改人
+    */
+    @ApiModelProperty("修改人")
+    @TableField(fill = FieldFill.UPDATE)
+    private Long modifyUserId;
+    /**
+    * 修改时间
+    */
+    @ApiModelProperty("修改时间")
+    @TableField(fill = FieldFill.UPDATE)
+    private Date modifyDate;
+    /**
+    * 删除标记
+    */
+    @ApiModelProperty("删除标记")
+    @TableField(fill = FieldFill.INSERT)
+    @TableLogic
+    private Integer deleteMark;
+    /**
+    * 有效标志
+    */
+    @ApiModelProperty("有效标志")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer enabledMark;
+    /**
+    * 学生主键id(xjr_user)
+    */
+    @ApiModelProperty("学生主键id(xjr_user)")
+    private Long userId;
+    /**
+    * 团员编号
+    */
+    @ApiModelProperty("团员编号")
+    private String leagueMembersNum;
+    /**
+    * 常住地址
+    */
+    @ApiModelProperty("常住地址")
+    private String address;
+    /**
+    * 加入时间
+    */
+    @ApiModelProperty("加入时间")
+    private LocalDate joinTime;
+    /**
+    * 转入时间
+    */
+    @ApiModelProperty("转入时间")
+    private LocalDate transferTime;
+    /**
+    * 备注
+    */
+    @ApiModelProperty("备注")
+    private String remark;
+
+
+}

+ 17 - 0
src/main/java/com/xjrsoft/module/student/mapper/LeagueMembersManageMapper.java

@@ -0,0 +1,17 @@
+package com.xjrsoft.module.student.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.github.yulichang.base.MPJBaseMapper;
+import com.xjrsoft.module.student.entity.LeagueMembersManage;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @title: 团员管理
+* @Author phoenix
+* @Date: 2025-04-08
+* @Version 1.0
+*/
+@Mapper
+public interface LeagueMembersManageMapper extends MPJBaseMapper<LeagueMembersManage> {
+
+}

+ 33 - 0
src/main/java/com/xjrsoft/module/student/service/ILeagueMembersManageService.java

@@ -0,0 +1,33 @@
+package com.xjrsoft.module.student.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.yulichang.base.MPJBaseService;
+import com.xjrsoft.module.student.dto.AddLeagueMembersManageDto;
+import com.xjrsoft.module.student.dto.LeagueMembersExportQueryDto;
+import com.xjrsoft.module.student.entity.LeagueMembersManage;
+import lombok.Data;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+/**
+* @title: 团员管理
+* @Author phoenix
+* @Date: 2025-04-08
+* @Version 1.0
+*/
+
+public interface ILeagueMembersManageService extends MPJBaseService<LeagueMembersManage> {
+
+    Boolean addRubAndHand(AddLeagueMembersManageDto dto);
+
+    Boolean deleteRubAndHand(List<Long> ids);
+
+    ByteArrayOutputStream leagueMembersImportTemplate() throws IOException;
+
+    String leagueMembersImport(MultipartFile file) throws IOException, IllegalAccessException;
+
+    ByteArrayOutputStream textbookSubscriptionExportQuery(LeagueMembersExportQueryDto dto) throws IOException;
+}

+ 394 - 0
src/main/java/com/xjrsoft/module/student/service/impl/LeagueMembersManageServiceImpl.java

@@ -0,0 +1,394 @@
+package com.xjrsoft.module.student.service.impl;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import com.alibaba.excel.EasyExcel;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.yulichang.base.MPJBaseServiceImpl;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.xjrsoft.common.enums.DeleteMark;
+import com.xjrsoft.common.utils.VoToColumnUtil;
+import com.xjrsoft.module.base.entity.BaseClass;
+import com.xjrsoft.module.generator.entity.ImportConfig;
+import com.xjrsoft.module.organization.entity.User;
+import com.xjrsoft.module.organization.mapper.UserMapper;
+import com.xjrsoft.module.student.dto.AddLeagueMembersManageDto;
+import com.xjrsoft.module.student.dto.LeagueMembersExportQueryDto;
+import com.xjrsoft.module.student.dto.LeagueMembersImportDto;
+import com.xjrsoft.module.student.entity.BaseStudent;
+import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll;
+import com.xjrsoft.module.student.entity.LeagueMembersManage;
+import com.xjrsoft.module.student.mapper.BaseStudentMapper;
+import com.xjrsoft.module.student.mapper.LeagueMembersManageMapper;
+import com.xjrsoft.module.student.service.ILeagueMembersManageService;
+import com.xjrsoft.module.student.vo.LeagueMembersExportQueryListVo;
+import com.xjrsoft.module.student.vo.LeagueMembersManagePageVo;
+import com.xjrsoft.module.system.entity.DictionaryDetail;
+import com.xjrsoft.module.teacher.entity.XjrUser;
+import com.xjrsoft.module.veb.util.ImportExcelUtil;
+import com.xjrsoft.module.veb.vo.InternshipPlanImportVo;
+import lombok.AllArgsConstructor;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.time.LocalDate;
+import java.time.YearMonth;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.springframework.web.multipart.MultipartFile;
+
+import static com.xjrsoft.module.veb.util.ImportExcelUtil.isRequiredFieldsFilled;
+
+/**
+* @title: 团员管理
+* @Author phoenix
+* @Date: 2025-04-08
+* @Version 1.0
+*/
+@Service
+@AllArgsConstructor
+public class LeagueMembersManageServiceImpl extends MPJBaseServiceImpl<LeagueMembersManageMapper, LeagueMembersManage> implements ILeagueMembersManageService {
+
+    private final BaseStudentMapper baseStudentMapper;
+
+    private final UserMapper userMapper;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean addRubAndHand(AddLeagueMembersManageDto dto) {
+        LeagueMembersManage leagueMembersManage = BeanUtil.toBean(dto, LeagueMembersManage.class);
+
+        // 更改原有的团员状态
+        LambdaUpdateWrapper<BaseStudent> baseStudentLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+        baseStudentLambdaUpdateWrapper
+                .eq(BaseStudent::getUserId, dto.getUserId())
+                ;
+        BaseStudent baseStudent = new BaseStudent();
+        baseStudent.setPoliticalState("FB1204");
+        baseStudentMapper.update(baseStudent, baseStudentLambdaUpdateWrapper);
+
+        return this.save(leagueMembersManage);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean deleteRubAndHand(List<Long> ids) {
+        // 更改原有的团员状态
+        List<LeagueMembersManage> leagueMembersManages = this.listByIds(ids);
+        BaseStudent baseStudent = new BaseStudent();
+        baseStudent.setPoliticalState("FB1214");
+        LambdaUpdateWrapper<BaseStudent> baseStudentLambdaUpdateWrapper;
+        for(LeagueMembersManage leagueMembersManage : leagueMembersManages){
+            baseStudentLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+            baseStudentLambdaUpdateWrapper
+                    .eq(BaseStudent::getUserId, leagueMembersManage.getUserId())
+            ;
+            baseStudentMapper.update(baseStudent, baseStudentLambdaUpdateWrapper);
+        }
+        return this.removeBatchByIds(ids);
+    }
+
+    @Override
+    public ByteArrayOutputStream leagueMembersImportTemplate() throws IOException {
+        // 开始写入
+        Workbook workbook = new XSSFWorkbook();
+        // 创建一个工作表(sheet)
+        String sheetName = "sheet1";
+        Sheet sheet = workbook.createSheet(sheetName);
+
+        LeagueMembersImportDto obj = new LeagueMembersImportDto();
+        List<ImportConfig> importConfigs = ImportExcelUtil.allFields(obj);
+
+        // 大标题
+        ImportExcelUtil.createBigHead(workbook, sheet, "团员导入模板", 0, importConfigs.size() - 1);
+
+        // 提示必填
+        String content = "说明:黄底红色背景为必填项,白底黑字为非必填项,导入时请将实例数据删除,避免导入失败!";
+        ImportExcelUtil.createCautionHead(workbook, sheet, 1, content, importConfigs.size() - 1, 12, IndexedColors.RED.getIndex());
+
+        // 表头
+        ImportExcelUtil.createHead(workbook, sheet, importConfigs, IndexedColors.YELLOW.getIndex(), IndexedColors.RED.getIndex(), 2);
+
+        //写入文件
+        ByteArrayOutputStream bot = new ByteArrayOutputStream();
+        workbook.write(bot);
+        return bot;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public String leagueMembersImport(MultipartFile file) throws IOException, IllegalAccessException {
+        List<LeagueMembersImportDto> excelDataList = EasyExcel.read(file.getInputStream()).headRowNumber(3).head(LeagueMembersImportDto.class).sheet().doReadSync();
+        StringBuilder sb = new StringBuilder();
+
+        // 用户根据身份证号映射
+        List<User> users = userMapper.selectList(
+                Wrappers
+                        .lambdaQuery(User.class)
+                        .eq(User::getDeleteMark, DeleteMark.NODELETE.getCode())
+        );
+        Map<String, User> userByCredentialNumberMap = users.stream()
+                .filter(u -> StringUtils.isNotEmpty(u.getCredentialNumber()))
+                .collect(Collectors.toMap(User::getCredentialNumber, u -> u,  (o1, o2) -> o1));
+
+        // 团员信息身份证号映射
+        MPJLambdaWrapper<LeagueMembersManage> leagueMembersManageMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        leagueMembersManageMPJLambdaWrapper
+                .select(LeagueMembersManage::getId)
+                .selectAs(XjrUser::getCredentialNumber, LeagueMembersManage::getLeagueMembersNum) // 暂时将身份证号存在团员编号字段中
+                .innerJoin(XjrUser.class, XjrUser::getId, LeagueMembersManage::getUserId)
+                ;
+        List<LeagueMembersManage> olds = this.selectJoinList(LeagueMembersManage.class, leagueMembersManageMPJLambdaWrapper);
+        Map<String, Long> idByCredentialNumberMap = olds.stream()
+                .filter(u -> StringUtils.isNotEmpty(u.getLeagueMembersNum()))
+                .collect(Collectors.toMap(LeagueMembersManage::getLeagueMembersNum, LeagueMembersManage::getId,  (o1, o2) -> o1));
+
+        List<LeagueMembersManage> leagueMembersManages = new ArrayList<>();
+        LeagueMembersManage leagueMembersManage;
+        Date nowDate = new Date();
+        // 定义输入格式 (YYYYMM)
+        DateTimeFormatter joinTimeFormatter = DateTimeFormatter.ofPattern("yyyyMM");
+        // 定义输入格式 (YYYY.MM)
+        DateTimeFormatter transferFormatter = DateTimeFormatter.ofPattern("yyyy.MM");
+        for (int i = 0; i < excelDataList.size(); i++) {
+            LeagueMembersImportDto dto = excelDataList.get(i);
+            leagueMembersManage = new LeagueMembersManage();
+
+            // 判断必填字段
+            if (ImportExcelUtil.isRequiredFieldsFilled(dto,
+                    sb,
+                    i + 3)) {
+                return sb.toString();
+            }
+
+            // 判断身份证对应的用户是否存在
+            User user = userByCredentialNumberMap.get(dto.getIdCard());
+            if(ObjectUtils.isEmpty(user)){
+                sb.append("第").append(i + 3).append("行数据的用户不存在!");
+                return sb.toString();
+            }
+
+            // 判断团员编号值是否为整数
+            if(StringUtils.isNotEmpty(dto.getLeagueMembersNum()) && !StringUtils.isNumeric(dto.getLeagueMembersNum())){
+                sb.append("第").append(i + 3).append("行数据的团员编号包含非数字字符!");
+                return sb.toString();
+            }
+
+            // 处理入团时间
+            if(StringUtils.isNotEmpty(dto.getJoinTime())){
+                // 将字符串解析为 YearMonth
+                YearMonth yearMonth = YearMonth.parse(dto.getJoinTime(), joinTimeFormatter);
+
+                // 设置为当月的第一天并转换为 LocalDate
+                LocalDate localDate = yearMonth.atDay(1);
+
+                leagueMembersManage.setJoinTime(localDate);
+            }
+
+            // 处理转入时间
+            if(StringUtils.isNotEmpty(dto.getTransferTime())){
+                // 将字符串解析为 YearMonth
+                YearMonth yearMonth = YearMonth.parse(dto.getTransferTime(), transferFormatter);
+
+                // 设置为当月的第一天并转换为 LocalDate
+                LocalDate localDate = yearMonth.atDay(1);
+
+                leagueMembersManage.setTransferTime(localDate);
+            }
+
+            leagueMembersManage.setUserId(user.getId());
+            leagueMembersManage.setLeagueMembersNum(dto.getLeagueMembersNum());
+            leagueMembersManage.setAddress(dto.getAddress());
+            leagueMembersManage.setRemark(dto.getRemark());
+
+            leagueMembersManage.setCreateDate(nowDate);
+            leagueMembersManage.setCreateUserId(StpUtil.getLoginIdAsLong());
+
+            Long leagueMembersManageId = idByCredentialNumberMap.get(dto.getIdCard());
+            if(ObjectUtils.isNotEmpty(leagueMembersManageId)){
+                leagueMembersManage.setId(leagueMembersManageId);
+            }
+
+            leagueMembersManages.add(leagueMembersManage);
+        }
+
+        if(CollectionUtils.isNotEmpty(leagueMembersManages)){
+            this.saveOrUpdateBatch(leagueMembersManages);
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    public ByteArrayOutputStream textbookSubscriptionExportQuery(LeagueMembersExportQueryDto dto) throws IOException {
+        MPJLambdaWrapper<LeagueMembersManage> leagueMembersManageMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        leagueMembersManageMPJLambdaWrapper
+                .disableSubLogicDel()
+                .select(LeagueMembersManage::getId)
+                .select(LeagueMembersManage.class, x -> VoToColumnUtil.fieldsToColumns(LeagueMembersExportQueryListVo.class).contains(x.getProperty()))
+                .innerJoin(XjrUser.class, XjrUser::getId, LeagueMembersManage::getUserId,
+                        wrappers -> wrappers
+                                .selectAs(XjrUser::getName, LeagueMembersExportQueryListVo::getStudentName)
+                                .selectAs(XjrUser::getCredentialNumber, LeagueMembersExportQueryListVo::getIdCard)
+                                .selectAs(XjrUser::getMobile, LeagueMembersExportQueryListVo::getPhone)
+                                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, XjrUser::getGender,
+                                        wrap -> wrap
+                                                .selectAs(DictionaryDetail::getName, LeagueMembersExportQueryListVo::getGenderCn)
+                                )
+                                .like(StringUtils.isNotEmpty(dto.getStudentName()), XjrUser::getName, dto.getStudentName())
+                                .like(StringUtils.isNotEmpty(dto.getIdCard()), XjrUser::getCredentialNumber, dto.getIdCard())
+                                .eq(XjrUser::getDeleteMark, DeleteMark.NODELETE.getCode())
+                )
+                .leftJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId, LeagueMembersManage::getUserId,
+                        wrappers -> wrappers
+                                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, BaseStudentSchoolRoll::getArchivesStatus,
+                                        wrap -> wrap
+                                                .selectAs(DictionaryDetail::getName, LeagueMembersExportQueryListVo::getStatusCn)
+                                )
+                                .like(StringUtils.isNotEmpty(dto.getArchivesStatus()), BaseStudentSchoolRoll::getArchivesStatus, dto.getArchivesStatus())
+                                .eq(ObjectUtils.isNotEmpty(dto.getClassId()), BaseStudentSchoolRoll::getClassId, dto.getClassId())
+                                .eq(BaseStudentSchoolRoll::getDeleteMark, DeleteMark.NODELETE.getCode())
+                )
+                .leftJoin(BaseClass.class, BaseClass::getId, BaseStudentSchoolRoll::getClassId,
+                        wrappers -> wrappers
+                                .selectAs(BaseClass::getName, LeagueMembersExportQueryListVo::getClassName)
+                                .leftJoin(XjrUser.class, XjrUser::getId, BaseClass::getTeacherId,
+                                        wrap -> wrap
+                                                .selectAs(XjrUser::getName, LeagueMembersExportQueryListVo::getTeacherName)
+                                )
+                                .eq(ObjectUtils.isNotEmpty(dto.getGradeId()), BaseClass::getGradeId, dto.getGradeId())
+                )
+                .leftJoin(BaseStudent.class, BaseStudent::getUserId, LeagueMembersManage::getUserId,
+                        wrappers -> wrappers
+                                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, BaseStudent::getNation,
+                                        wrap -> wrap
+                                                .selectAs(DictionaryDetail::getName, LeagueMembersExportQueryListVo::getNation)
+                                )
+                                .eq(BaseStudent::getDeleteMark, DeleteMark.NODELETE.getCode())
+                )
+                .like(StringUtils.isNotEmpty(dto.getLeagueMembersNum()), LeagueMembersManage::getLeagueMembersNum, dto.getLeagueMembersNum())
+                .ge(ObjectUtils.isNotEmpty(dto.getJoinTimeStart()), LeagueMembersManage::getJoinTime, dto.getJoinTimeStart())
+                .le(ObjectUtils.isNotEmpty(dto.getJoinTimeEnd()), LeagueMembersManage::getJoinTime, dto.getJoinTimeEnd())
+                .ge(ObjectUtils.isNotEmpty(dto.getTransferTimeStart()), LeagueMembersManage::getTransferTime, dto.getTransferTimeStart())
+                .le(ObjectUtils.isNotEmpty(dto.getTransferTimeEnd()), LeagueMembersManage::getTransferTime, dto.getTransferTimeEnd())
+                .orderByAsc(BaseClass::getName)
+        ;
+        List<LeagueMembersExportQueryListVo> lmeqList = this.selectJoinList(LeagueMembersExportQueryListVo.class, leagueMembersManageMPJLambdaWrapper);
+
+        // 开始写入
+        Workbook workbook = new XSSFWorkbook();
+        // 创建一个工作表(sheet)
+        String sheetName = "sheet1";
+        Sheet sheet = workbook.createSheet(sheetName);
+
+        // 出参vo字段数量
+        LeagueMembersExportQueryListVo obj = new LeagueMembersExportQueryListVo();
+        List<ImportConfig> importConfigs = ImportExcelUtil.allFields(obj);
+
+        // 写大标题
+        int rowNumber = 0;
+        ImportExcelUtil.createBigHead(workbook, sheet, "团员信息列表", rowNumber++, importConfigs.size());
+
+        // 表头
+        ImportExcelUtil.createHead(workbook, sheet, importConfigs, IndexedColors.YELLOW.getIndex(), IndexedColors.RED.getIndex(), rowNumber++);
+
+        // 字体内容格式
+        Font font = workbook.createFont();
+        font.setBold(false);// 设置为粗体
+        font.setFontName("宋体");
+        font.setFontHeightInPoints((short) 12);
+
+        // 单元格样式
+        CellStyle cellStyle = workbook.createCellStyle();
+        cellStyle.setFont(font); // 将字体应用到样式
+        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+        cellStyle.setAlignment(HorizontalAlignment.CENTER);
+
+        // 设置边框样式为细线
+        cellStyle.setBorderTop(BorderStyle.THIN);
+        cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); // 设置顶部边框颜色
+
+        cellStyle.setBorderBottom(BorderStyle.THIN);
+        cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); // 设置底部边框颜色
+
+        cellStyle.setBorderLeft(BorderStyle.THIN);
+        cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); // 设置左边框颜色
+
+        cellStyle.setBorderRight(BorderStyle.THIN);
+        cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); // 设置右边框颜色
+
+        // 构建数据
+        List<List<String>> resultList = new ArrayList<>();
+        List<String> oneResult;
+        int sortCode = 1;
+        // 定义输出格式 (YYYY.MM)
+        DateTimeFormatter transferFormatter = DateTimeFormatter.ofPattern("yyyy.MM");
+        DateTimeFormatter joinFormatter = DateTimeFormatter.ofPattern("yyyyMM");
+        for (LeagueMembersExportQueryListVo vo : lmeqList){
+            oneResult = new ArrayList<>();
+            oneResult.add("" + sortCode++);
+            oneResult.add(vo.getClassName());
+            oneResult.add(vo.getTeacherName());
+            oneResult.add(vo.getStudentName());
+            oneResult.add(vo.getGenderCn());
+            oneResult.add(vo.getNation());
+            oneResult.add(vo.getIdCard());
+            oneResult.add(vo.getPhone());
+            oneResult.add(vo.getLeagueMembersNum());
+            oneResult.add(vo.getAddress());
+
+            // 处理加入时间
+            if(ObjectUtils.isNotEmpty(vo.getJoinTime())){
+                // 将 LocalDate 转换为字符串
+                String joinTime = vo.getJoinTime().format(joinFormatter);
+                oneResult.add(joinTime);
+            } else {
+                oneResult.add("");
+            }
+
+            // 处理转入时间
+            if(ObjectUtils.isNotEmpty(vo.getTransferTime())){
+                // 将 LocalDate 转换为字符串
+                String transferTime = vo.getTransferTime().format(transferFormatter);
+                oneResult.add(transferTime);
+            } else {
+                oneResult.add("");
+            }
+
+            oneResult.add(vo.getStatusCn());
+            oneResult.add(vo.getRemark());
+            resultList.add(oneResult);
+        }
+
+        // 写入数据
+        for (List<String> rowData : resultList) {
+            Row dataRow = sheet.createRow(rowNumber);
+            for (int j = 0; j < rowData.size(); j++) {
+                String content = rowData.get(j);
+                Cell cell = dataRow.createCell(j);
+                cell.setCellValue(content);
+                cell.setCellStyle(cellStyle);
+            }
+            rowNumber++;
+        }
+
+        // 自动列宽
+        for (int i = 0; i < importConfigs.size(); i++) {
+            sheet.autoSizeColumn(i);
+        }
+
+        ByteArrayOutputStream bot = new ByteArrayOutputStream();
+        workbook.write(bot);
+        return bot;
+    }
+}

+ 27 - 0
src/main/java/com/xjrsoft/module/student/vo/ClassWithLMNumTreeVo.java

@@ -0,0 +1,27 @@
+package com.xjrsoft.module.student.vo;
+
+import com.xjrsoft.common.model.tree.ITreeNode;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class ClassWithLMNumTreeVo implements ITreeNode<ClassWithLMNumTreeVo, String>, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String id;
+
+    @ApiModelProperty("名字")
+    private String name;
+
+    @ApiModelProperty("当前级别的数量")
+    private Integer num;
+
+    @ApiModelProperty("父级id")
+    private String parentId;
+
+    private List<ClassWithLMNumTreeVo> children;
+}

+ 97 - 0
src/main/java/com/xjrsoft/module/student/vo/LeagueMembersExportQueryListVo.java

@@ -0,0 +1,97 @@
+package com.xjrsoft.module.student.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ContentStyle;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDate;
+
+/**
+ * @title: 团员信息有参导出列表出参
+ * @Author dzx
+ * @Date: 2024-06-27
+ * @Version 1.0
+ */
+@Data
+public class LeagueMembersExportQueryListVo {
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("序号")
+    @ApiModelProperty("序号")
+    private String sortCode;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("班级")
+    @ApiModelProperty("班级")
+    private String className;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("班主任")
+    @ApiModelProperty("班主任")
+    private String teacherName;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("学生姓名")
+    @ApiModelProperty("学生姓名")
+    private String studentName;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("性别")
+    @ApiModelProperty("性别")
+    private String genderCn;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("民族")
+    @ApiModelProperty("民族")
+    private String nation;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("身份证号")
+    @ApiModelProperty("身份证号")
+    private String idCard;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("手机号")
+    @ApiModelProperty("手机号")
+    private String phone;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("团员编号")
+    @ApiModelProperty("团员编号")
+    private String leagueMembersNum;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("常住地址")
+    @ApiModelProperty("常住地址")
+    private String address;
+
+    @ExcelIgnore
+    @ApiModelProperty("加入时间")
+    private LocalDate joinTime;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("加入时间")
+    @ApiModelProperty("加入时间")
+    private String joinTimeStr;
+
+    @ExcelIgnore
+    @ApiModelProperty("转入时间")
+    private LocalDate transferTime;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("转入时间")
+    @ApiModelProperty("转入时间")
+    private String transferTimeStr;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("在读状态")
+    @ApiModelProperty("学籍状态(xjr_dictionary_item[archives_status])")
+    private String statusCn;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("备注")
+    @ApiModelProperty("备注")
+    private String remark;
+}

+ 87 - 0
src/main/java/com/xjrsoft/module/student/vo/LeagueMembersManagePageVo.java

@@ -0,0 +1,87 @@
+package com.xjrsoft.module.student.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import com.xjrsoft.common.annotation.Trans;
+import com.xjrsoft.common.enums.TransType;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+* @title: 团员管理分页列表出参
+* @Author phoenix
+* @Date: 2025-04-08
+* @Version 1.0
+*/
+@Data
+public class LeagueMembersManagePageVo {
+    /**
+     * 主键编号
+     */
+    @ApiModelProperty("主键编号")
+    private String id;
+
+    @ApiModelProperty("班级")
+    private String className;
+
+    @ApiModelProperty("班主任")
+    private String teacherName;
+
+    /**
+     * 学生主键id(xjr_user)
+     */
+    @ApiModelProperty("学生主键id(xjr_user)")
+    private Long userId;
+
+    @ApiModelProperty("学生姓名")
+    private String studentName;
+
+    @ApiModelProperty("性别")
+    private String genderCn;
+
+    @ApiModelProperty("民族")
+    private String nation;
+
+    @ApiModelProperty("身份证号")
+    private String idCard;
+
+    @ApiModelProperty("手机号")
+    private String phone;
+
+    @ApiModelProperty("常住地址")
+    private String address;
+
+    /**
+     * 团员编号
+     */
+    @ApiModelProperty("团员编号")
+    private String leagueMembersNum;
+    /**
+     * 加入时间
+     */
+    @ApiModelProperty("加入时间")
+    private LocalDate joinTime;
+    /**
+     * 转入时间
+     */
+    @ApiModelProperty("转入时间")
+    private LocalDate transferTime;
+
+    @ApiModelProperty("学籍状态(xjr_dictionary_item[archives_status])")
+    private String archivesStatus;
+
+    @ApiModelProperty("学籍状态(xjr_dictionary_item[archives_status])")
+    private String statusCn;
+
+    /**
+     * 备注
+     */
+    @ApiModelProperty("备注")
+    private String remark;
+}

+ 59 - 0
src/main/java/com/xjrsoft/module/student/vo/LeagueMembersManageVo.java

@@ -0,0 +1,59 @@
+package com.xjrsoft.module.student.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Date;
+
+/**
+* @title: 团员管理表单出参
+* @Author phoenix
+* @Date: 2025-04-08
+* @Version 1.0
+*/
+@Data
+public class LeagueMembersManageVo {
+
+    /**
+    * 主键编号
+    */
+    @ApiModelProperty("主键编号")
+    private Long id;
+    /**
+    * 学生主键id(xjr_user)
+    */
+    @ApiModelProperty("学生主键id(xjr_user)")
+    private Long userId;
+    /**
+    * 团员编号
+    */
+    @ApiModelProperty("团员编号")
+    private String leagueMembersNum;
+    /**
+    * 常住地址
+    */
+    @ApiModelProperty("常住地址")
+    private String address;
+    /**
+    * 加入时间
+    */
+    @ApiModelProperty("加入时间")
+    private Date joinTime;
+    /**
+    * 转入时间
+    */
+    @ApiModelProperty("转入时间")
+    private Date transferTime;
+    /**
+    * 备注
+    */
+    @ApiModelProperty("备注")
+    private String remark;
+
+
+
+}

+ 1 - 1
src/main/java/com/xjrsoft/module/textbook/controller/TextbookController.java

@@ -292,7 +292,7 @@ public class TextbookController {
         ImportExcelUtil.createCautionHead(workbook, sheet, 1, content, importConfigs.size() - 1, 12, IndexedColors.RED.getIndex());
 
         // 表头
-        ImportExcelUtil.createHead(workbook, sheet, importConfigs, 2);
+        ImportExcelUtil.createHead(workbook, sheet, importConfigs, IndexedColors.YELLOW.getIndex(), IndexedColors.RED.getIndex(), 2);
 
         //写入文件
         ByteArrayOutputStream bot = new ByteArrayOutputStream();

+ 1 - 1
src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookIssueRecordServiceImpl.java

@@ -455,7 +455,7 @@ public class TextbookIssueRecordServiceImpl extends MPJBaseServiceImpl<TextbookI
 
 
             // 表头
-            ImportExcelUtil.createHead(workbook, sheet, eachImportConfigs, rowNumber++);
+            ImportExcelUtil.createHead(workbook, sheet, eachImportConfigs, IndexedColors.YELLOW.getIndex(), IndexedColors.RED.getIndex(), rowNumber++);
 
             // 处理每个单元格的内容
             resultList = new ArrayList<>();

+ 1 - 1
src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookSubscriptionServiceImpl.java

@@ -1090,7 +1090,7 @@ public class TextbookSubscriptionServiceImpl extends MPJBaseServiceImpl<Textbook
         ImportExcelUtil.createCautionHead(workbook, sheet, 1, cautionHead, importConfigs.size() - 1, 12, IndexedColors.RED.getIndex());
 
         // 表头
-        ImportExcelUtil.createHead(workbook, sheet, importConfigs, 2);
+        ImportExcelUtil.createHead(workbook, sheet, importConfigs, IndexedColors.YELLOW.getIndex(), IndexedColors.RED.getIndex(), 2);
 
         //生成数据
         int dataRowNumber = 3;

+ 13 - 8
src/main/java/com/xjrsoft/module/veb/util/ImportExcelUtil.java

@@ -53,7 +53,7 @@ public class ImportExcelUtil {
         List<ImportConfig> importConfigs = allFields(obj);
 
         // 表头
-        createHead(workbook, sheet, importConfigs, 0);
+        createHead(workbook, sheet, importConfigs, IndexedColors.YELLOW.getIndex(), IndexedColors.RED.getIndex(), 0);
 
         // 提示必填
         String content = "红色背景为必填项,导入时请删除本行。";
@@ -158,14 +158,14 @@ public class ImportExcelUtil {
      * @param importConfigs
      * @param rowNumber
      */
-    public static void createHead(Workbook workbook, Sheet sheet, List<ImportConfig> importConfigs, int rowNumber) {
-        Font font = workbook.createFont();
-        font.setFontName("宋体");
-        font.setFontHeightInPoints((short) 12);
+    public static void createHead(Workbook workbook, Sheet sheet, List<ImportConfig> importConfigs, short requiredFieldForegroundColor, short requiredFieldFontColor, int rowNumber) {
+        Font normalFont = workbook.createFont();
+        normalFont.setFontName("宋体");
+        normalFont.setFontHeightInPoints((short) 12);
 
         // 正常样式
         CellStyle normalCellStyle = workbook.createCellStyle();
-        normalCellStyle.setFont(font); // 将字体应用到样式
+        normalCellStyle.setFont(normalFont); // 将字体应用到样式
         normalCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
         normalCellStyle.setAlignment(HorizontalAlignment.CENTER);
 
@@ -183,11 +183,16 @@ public class ImportExcelUtil {
         normalCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); // 设置右边框颜色
 
         // 必填样式
+        Font requiredFont = workbook.createFont();
+        requiredFont.setFontName("宋体");
+        requiredFont.setFontHeightInPoints((short) 12);
+
         CellStyle requiredCellStyle = workbook.createCellStyle();
-        requiredCellStyle.setFont(font); // 将字体应用到样式
+        requiredCellStyle.setFont(requiredFont); // 将字体应用到样式
         requiredCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
         requiredCellStyle.setAlignment(HorizontalAlignment.CENTER);
-        requiredCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());//设置背景颜色
+//        requiredCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());//设置背景颜色
+        requiredCellStyle.setFillForegroundColor(requiredFieldForegroundColor);//设置背景颜色s
         requiredCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);//设置填充模式
 
         // 设置边框样式为细线

+ 83 - 50
src/main/resources/sqlScript/20250408_sql.sql

@@ -1,62 +1,95 @@
 -- ---------------------------------------------------------------
 -- 学生复读流程
 -- ---------------------------------------------------------------
-CREATE TABLE `wf_student_repeat_study` (
-  `id` BIGINT NOT NULL COMMENT '主键',
-  `create_user_id` BIGINT DEFAULT NULL COMMENT '创建人',
-  `create_date` DATETIME(3) DEFAULT NULL COMMENT '创建时间',
-  `modify_user_id` BIGINT DEFAULT NULL COMMENT '修改人id',
-  `modify_date` DATETIME(3) DEFAULT NULL COMMENT '修改日期',
-  `delete_mark` SMALLINT DEFAULT NULL COMMENT '删除标记(0:未删除 1:已删除)',
-  `enabled_mark` SMALLINT DEFAULT NULL COMMENT '有效标记(0:未启用 1:已启用)',
-  `is_original` INT DEFAULT NULL COMMENT '是否本校生(1:是 0:否)',
-  `name` VARCHAR(50) DEFAULT NULL COMMENT '学生姓名',
-  `credential_number` VARCHAR(30) DEFAULT NULL COMMENT '身份证',
-  `old_grade_id` BIGINT DEFAULT NULL COMMENT '原年级id',
-  `old_class_id` BIGINT(30) DEFAULT NULL COMMENT '原班级id',
-  `archives_status` VARCHAR(20) DEFAULT NULL COMMENT '学籍状态',
-  `mobile` VARCHAR(20) DEFAULT NULL COMMENT '手机号',
-  `grade_id` BIGINT DEFAULT NULL COMMENT '年级id(base_grade)',
-  `major_set_id` BIGINT DEFAULT NULL COMMENT '专业方向id',
-  `class_id` BIGINT DEFAULT NULL COMMENT '教务处审批班级',
-  `stduy_status` VARCHAR(30) DEFAULT NULL COMMENT '就读方式',
-  `teacher_id` BIGINT DEFAULT NULL COMMENT '班主任id(xjr_user)',
-  `teacher_name` VARCHAR(20) DEFAULT NULL COMMENT '班主任姓名',
-  `remarks` VARCHAR(500) DEFAULT NULL COMMENT '备注',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='学生复读流程';
+CREATE TABLE `wf_student_repeat_study`
+(
+    `id`                BIGINT NOT NULL COMMENT '主键',
+    `create_user_id`    BIGINT       DEFAULT NULL COMMENT '创建人',
+    `create_date`       DATETIME(3)  DEFAULT NULL COMMENT '创建时间',
+    `modify_user_id`    BIGINT       DEFAULT NULL COMMENT '修改人id',
+    `modify_date`       DATETIME(3)  DEFAULT NULL COMMENT '修改日期',
+    `delete_mark`       SMALLINT     DEFAULT NULL COMMENT '删除标记(0:未删除 1:已删除)',
+    `enabled_mark`      SMALLINT     DEFAULT NULL COMMENT '有效标记(0:未启用 1:已启用)',
+    `is_original`       INT          DEFAULT NULL COMMENT '是否本校生(1:是 0:否)',
+    `name`              VARCHAR(50)  DEFAULT NULL COMMENT '学生姓名',
+    `credential_number` VARCHAR(30)  DEFAULT NULL COMMENT '身份证',
+    `old_grade_id`      BIGINT       DEFAULT NULL COMMENT '原年级id',
+    `old_class_id`      BIGINT(30)   DEFAULT NULL COMMENT '原班级id',
+    `archives_status`   VARCHAR(20)  DEFAULT NULL COMMENT '学籍状态',
+    `mobile`            VARCHAR(20)  DEFAULT NULL COMMENT '手机号',
+    `grade_id`          BIGINT       DEFAULT NULL COMMENT '年级id(base_grade)',
+    `major_set_id`      BIGINT       DEFAULT NULL COMMENT '专业方向id',
+    `class_id`          BIGINT       DEFAULT NULL COMMENT '教务处审批班级',
+    `stduy_status`      VARCHAR(30)  DEFAULT NULL COMMENT '就读方式',
+    `teacher_id`        BIGINT       DEFAULT NULL COMMENT '班主任id(xjr_user)',
+    `teacher_name`      VARCHAR(20)  DEFAULT NULL COMMENT '班主任姓名',
+    `remarks`           VARCHAR(500) DEFAULT NULL COMMENT '备注',
+    PRIMARY KEY (`id`) USING BTREE
+) ENGINE = INNODB
+  DEFAULT CHARSET = utf8mb4
+  COLLATE = utf8mb4_0900_ai_ci COMMENT ='学生复读流程';
 
 
 -- ---------------------------------------------------------------
 -- 班级合并
 -- ---------------------------------------------------------------
-CREATE TABLE `base_class_merge` (
-  `id` BIGINT NOT NULL COMMENT '主键',
-  `create_user_id` BIGINT DEFAULT NULL COMMENT '创建人',
-  `create_date` DATETIME(3) DEFAULT NULL COMMENT '创建时间',
-  `modify_user_id` BIGINT DEFAULT NULL COMMENT '修改人id',
-  `modify_date` DATETIME(3) DEFAULT NULL COMMENT '修改日期',
-  `delete_mark` SMALLINT DEFAULT NULL COMMENT '删除标记(0:未删除 1:已删除)',
-  `enabled_mark` SMALLINT DEFAULT NULL COMMENT '有效标记(0:未启用 1:已启用)',
-  `student_count` INT DEFAULT NULL COMMENT '涉及学生人数',
-  `target_class_id` BIGINT DEFAULT NULL COMMENT '目标班级',
-  `reason` VARCHAR(500) DEFAULT NULL COMMENT '原因',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='班级合并';
+CREATE TABLE `base_class_merge`
+(
+    `id`              BIGINT NOT NULL COMMENT '主键',
+    `create_user_id`  BIGINT       DEFAULT NULL COMMENT '创建人',
+    `create_date`     DATETIME(3)  DEFAULT NULL COMMENT '创建时间',
+    `modify_user_id`  BIGINT       DEFAULT NULL COMMENT '修改人id',
+    `modify_date`     DATETIME(3)  DEFAULT NULL COMMENT '修改日期',
+    `delete_mark`     SMALLINT     DEFAULT NULL COMMENT '删除标记(0:未删除 1:已删除)',
+    `enabled_mark`    SMALLINT     DEFAULT NULL COMMENT '有效标记(0:未启用 1:已启用)',
+    `student_count`   INT          DEFAULT NULL COMMENT '涉及学生人数',
+    `target_class_id` BIGINT       DEFAULT NULL COMMENT '目标班级',
+    `reason`          VARCHAR(500) DEFAULT NULL COMMENT '原因',
+    PRIMARY KEY (`id`) USING BTREE
+) ENGINE = INNODB
+  DEFAULT CHARSET = utf8mb4
+  COLLATE = utf8mb4_0900_ai_ci COMMENT ='班级合并';
 
 -- ---------------------------------------------------------------
 -- 班级合并涉及学生
 -- ---------------------------------------------------------------
-CREATE TABLE `base_class_merge_student` (
-  `id` BIGINT NOT NULL COMMENT '主键',
-  `create_user_id` BIGINT DEFAULT NULL COMMENT '创建人',
-  `create_date` DATETIME(3) DEFAULT NULL COMMENT '创建时间',
-  `modify_user_id` BIGINT DEFAULT NULL COMMENT '修改人id',
-  `modify_date` DATETIME(3) DEFAULT NULL COMMENT '修改日期',
-  `delete_mark` SMALLINT DEFAULT NULL COMMENT '删除标记(0:未删除 1:已删除)',
-  `enabled_mark` SMALLINT DEFAULT NULL COMMENT '有效标记(0:未启用 1:已启用)',
-  `base_class_merge_id` BIGINT DEFAULT NULL COMMENT '班级合并id(base_class_merge)',
-  `class_id` BIGINT DEFAULT NULL COMMENT '原有班级',
-  `user_id` BIGINT DEFAULT NULL COMMENT '学生id',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='班级合并涉及学生';
+CREATE TABLE `base_class_merge_student`
+(
+    `id`                  BIGINT NOT NULL COMMENT '主键',
+    `create_user_id`      BIGINT      DEFAULT NULL COMMENT '创建人',
+    `create_date`         DATETIME(3) DEFAULT NULL COMMENT '创建时间',
+    `modify_user_id`      BIGINT      DEFAULT NULL COMMENT '修改人id',
+    `modify_date`         DATETIME(3) DEFAULT NULL COMMENT '修改日期',
+    `delete_mark`         SMALLINT    DEFAULT NULL COMMENT '删除标记(0:未删除 1:已删除)',
+    `enabled_mark`        SMALLINT    DEFAULT NULL COMMENT '有效标记(0:未启用 1:已启用)',
+    `base_class_merge_id` BIGINT      DEFAULT NULL COMMENT '班级合并id(base_class_merge)',
+    `class_id`            BIGINT      DEFAULT NULL COMMENT '原有班级',
+    `user_id`             BIGINT      DEFAULT NULL COMMENT '学生id',
+    PRIMARY KEY (`id`) USING BTREE
+) ENGINE = INNODB
+  DEFAULT CHARSET = utf8mb4
+  COLLATE = utf8mb4_0900_ai_ci COMMENT ='班级合并涉及学生';
+
+-- ---------------------------------------------------------------
+-- 团员管理
+-- ---------------------------------------------------------------
+DROP TABLE IF EXISTS `league_members_manage`;
+CREATE TABLE `league_members_manage`
+(
+    id                   bigint   not null comment '主键编号'
+        primary key,
+    create_user_id       BIGINT   NULL COMMENT '创建人',
+    create_date          DATETIME NULL COMMENT '创建时间',
+    modify_user_id       BIGINT   NULL COMMENT '修改人',
+    modify_date          DATETIME NULL COMMENT '修改时间',
+    delete_mark          INT      NOT NULL COMMENT '删除标记',
+    enabled_mark         INT      NOT NULL COMMENT '有效标志',
+
+    `user_id`            BIGINT   NOT NULL COMMENT '学生主键id(xjr_user)',
+    `league_members_num` varchar(64)   DEFAULT NULL COMMENT '团员编号',
+    `address`            varchar(256)  DEFAULT NULL COMMENT '常住地址',
+    `join_time`          DATE          DEFAULT NULL COMMENT '加入时间',
+    `transfer_time`      DATE          DEFAULT NULL COMMENT '转入时间',
+    remark               varchar(1024) DEFAULT NULL COMMENT '备注'
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4 COMMENT = '团员管理';

+ 25 - 0
src/test/java/com/xjrsoft/xjrsoftboot/FreeMarkerGeneratorTest.java

@@ -4628,4 +4628,29 @@ public class FreeMarkerGeneratorTest {
 
         apiGeneratorService.generateCodes(params);
     }
+
+    @Test
+    public void gcLeagueMembersManage() throws IOException {
+        List<TableConfig> tableConfigs = new ArrayList<>();
+        TableConfig mainTable = new TableConfig();
+        mainTable.setTableName("league_members_manage");//init_sql中的表名
+        mainTable.setIsMain(true);//是否是主表,一般默认为true
+        mainTable.setPkField(GlobalConstant.DEFAULT_PK);//设置主键
+        mainTable.setPkType(GlobalConstant.DEFAULT_PK_TYPE);//设置主键类型
+        tableConfigs.add(mainTable);
+
+        ApiGenerateCodesDto params = new ApiGenerateCodesDto();
+        params.setAuthor("phoenix");//作者名称
+        params.setPackageName("student");//包名
+        params.setTableConfigs(tableConfigs);
+        params.setPage(true);//是否生成分页接口
+        params.setImport(false);//是否生成导入接口
+        params.setExport(false);//是否生成导出接口
+        params.setOutMainDir(false);//是否生成在主目录,前期测试可设置成false
+        params.setDs(ds);
+
+        IApiGeneratorService apiGeneratorService = new ApiGeneratorServiceImpl();
+
+        apiGeneratorService.generateCodes(params);
+    }
 }