Quellcode durchsuchen

Merge remote-tracking branch 'origin/dev' into dev

dzx vor 5 Monaten
Ursprung
Commit
6b073402b0

+ 2 - 0
src/main/java/com/xjrsoft/common/enums/RoleEnum.java

@@ -23,6 +23,8 @@ public enum RoleEnum {
     PARENT(4L, "家长"),
     VISITOR(5L, "访客"),
 
+    BOOKADMIN(1747874695055732738L, "教材管理员"),
+
     CLASSTE(1745630294430511106L, "班主任");
 
     final Long code;

+ 4 - 2
src/main/java/com/xjrsoft/module/textbook/controller/TextbookStudentClaimController.java

@@ -44,8 +44,10 @@ public class TextbookStudentClaimController {
     @ApiOperation(value = "班主任查看班级教材学期页面")
     @SaCheckPermission("textbookstudentclaim:detail")
     @XjrLog(value = "班主任查看班级教材学期页面")
-    public RT<List<HeadTeaLookClassBookSemesterVo>> headTeaLookClassBookSemester() {
-        return RT.ok(textbookStudentClaimService.headTeaLookClassBookSemester());
+    public RT<PageOutput<HeadTeaLookClassBookSemesterVo>> headTeaLookClassBookSemester(@Valid HeadTeaLookClassBookSemesterDto dto) {
+        IPage<HeadTeaLookClassBookSemesterVo> page = textbookStudentClaimService.headTeaLookClassBookSemester(dto);
+        PageOutput<HeadTeaLookClassBookSemesterVo> pageOutput = ConventPage.getPageOutput(page, HeadTeaLookClassBookSemesterVo.class);
+        return RT.ok(pageOutput);
     }
 
     @GetMapping(value = "/head-tea-look-class-book")

+ 29 - 0
src/main/java/com/xjrsoft/module/textbook/dto/HeadTeaLookClassBookSemesterDto.java

@@ -0,0 +1,29 @@
+package com.xjrsoft.module.textbook.dto;
+
+import com.xjrsoft.common.page.PageInput;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+
+/**
+ * @title: 班主任查看班级教材学期页面入参
+ * @Author szs
+ * @Date: 2025-06-11
+ * @Version 1.0
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class HeadTeaLookClassBookSemesterDto extends PageInput {
+    @ApiModelProperty("学期主键编号")
+    private String baseSemesterId;
+
+    @ApiModelProperty("学期主键编号")
+    private String baseSemesterIdCn;
+
+    @ApiModelProperty("班级主键编号")
+    private String baseClassId;
+
+    @ApiModelProperty("班级主键编号")
+    private String baseClassIdCn;
+}

+ 3 - 0
src/main/java/com/xjrsoft/module/textbook/dto/UpdateDiscountDto.java

@@ -18,4 +18,7 @@ public class UpdateDiscountDto {
 
     @ApiModelProperty("新的折扣")
     private Double discount;
+
+    @ApiModelProperty("新的入库数量")
+    private int warehouseNumber;
 }

+ 10 - 2
src/main/java/com/xjrsoft/module/textbook/entity/TextbookDiscountAlterRecord.java

@@ -96,6 +96,14 @@ public class TextbookDiscountAlterRecord implements Serializable {
      */
     @ApiModelProperty("新的折扣")
     private Double newDiscount;
-
-
+    /**
+     * 旧的入库数量
+     */
+    @ApiModelProperty("旧的入库数量")
+    private Integer oldWarehouseNum;
+    /**
+     * 新的入库数量
+     */
+    @ApiModelProperty("新的入库数量")
+    private Integer newWarehouseNum;
 }

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

@@ -30,7 +30,7 @@ public interface ITextbookStudentClaimService extends MPJBaseService<TextbookStu
      * @param
      * @return
      */
-    List<HeadTeaLookClassBookSemesterVo> headTeaLookClassBookSemester();
+    IPage<HeadTeaLookClassBookSemesterVo> headTeaLookClassBookSemester(HeadTeaLookClassBookSemesterDto dto);
 
     /**
      * 获取页面

+ 2 - 1
src/main/java/com/xjrsoft/module/textbook/service/IWfTextbookClaimService.java

@@ -10,6 +10,7 @@ import com.xjrsoft.module.textbook.vo.WfTextbookClaimPageVo;
 import com.xjrsoft.module.textbook.vo.WfTextbookClaimVo;
 
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.util.List;
 
 /**
@@ -77,5 +78,5 @@ public interface IWfTextbookClaimService extends MPJBaseService<WfTextbookClaim>
 
     Boolean dataHandleAddClaimUserNode(Long id);
 
-    ByteArrayOutputStream claimRecordsExportQuery(ClaimRecordsExportQueryDto dto);
+    ByteArrayOutputStream claimRecordsExportQuery(ClaimRecordsExportQueryDto dto) throws IOException;
 }

+ 15 - 3
src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookStudentClaimServiceImpl.java

@@ -10,6 +10,7 @@ import com.github.yulichang.wrapper.MPJLambdaWrapper;
 import com.xjrsoft.common.enums.ArchivesStatusEnum;
 import com.xjrsoft.common.enums.ClaimTypeEnum;
 import com.xjrsoft.common.enums.DeleteMark;
+import com.xjrsoft.common.enums.RoleEnum;
 import com.xjrsoft.common.exception.MyException;
 import com.xjrsoft.common.page.ConventPage;
 import com.xjrsoft.common.utils.VoToColumnUtil;
@@ -172,7 +173,7 @@ public class TextbookStudentClaimServiceImpl extends MPJBaseServiceImpl<Textbook
     }
 
     @Override
-    public List<HeadTeaLookClassBookSemesterVo> headTeaLookClassBookSemester() {
+    public IPage<HeadTeaLookClassBookSemesterVo> headTeaLookClassBookSemester(HeadTeaLookClassBookSemesterDto dto) {
         Long loginId = StpUtil.getLoginIdAsLong();
 
         MPJLambdaWrapper<BaseClassAdminCourse> baseClassAdminCourseMPJLambdaWrapper = new MPJLambdaWrapper<>();
@@ -184,10 +185,21 @@ public class TextbookStudentClaimServiceImpl extends MPJBaseServiceImpl<Textbook
                 .selectAs(BaseClass::getName, HeadTeaLookClassBookSemesterVo::getBaseClassIdCn)
                 .innerJoin(BaseClass.class, BaseClass::getId, BaseClassAdminCourse::getClassId)
                 .leftJoin(BaseSemester.class, BaseSemester::getId, BaseClassAdminCourse::getBaseSemesterId)
-                .eq(BaseClass::getTeacherId, loginId)
+                .eq(StringUtils.isNotEmpty(dto.getBaseSemesterId()), BaseClassAdminCourse::getBaseSemesterId, dto.getBaseSemesterId())
+                .eq(StringUtils.isNotEmpty(dto.getBaseClassId()), BaseClassAdminCourse::getClassId, dto.getBaseClassId())
+                .like(StringUtils.isNotEmpty(dto.getBaseSemesterIdCn()), BaseSemester::getName, dto.getBaseSemesterIdCn())
+                .like(StringUtils.isNotEmpty(dto.getBaseClassIdCn()), BaseClass::getName, dto.getBaseClassIdCn())
                 .orderByDesc(BaseSemester::getName)
+                .orderByDesc(BaseClass::getName)
         ;
-        return baseClassAdminCourseMapper.selectJoinList(HeadTeaLookClassBookSemesterVo.class, baseClassAdminCourseMPJLambdaWrapper);
+
+        // 权限控制,教材管理员可以看到所有班级所有学期的数据
+        // 班主任只能看到自己班上的
+        if(!StpUtil.hasRole("BOOKAdmin")) {
+            baseClassAdminCourseMPJLambdaWrapper
+                    .eq(BaseClass::getTeacherId, loginId);
+        }
+        return baseClassAdminCourseMapper.selectJoinPage(ConventPage.getPage(dto), HeadTeaLookClassBookSemesterVo.class, baseClassAdminCourseMPJLambdaWrapper);
     }
 
     @Override

+ 11 - 0
src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookWarehouseRecordServiceImpl.java

@@ -218,6 +218,10 @@ public class TextbookWarehouseRecordServiceImpl extends MPJBaseServiceImpl<Textb
             throw new MyException("当前入库记录已经被修改,请重新选择");
         }
 
+        if(textbookWarehouseRecord.getIssuedNumber() > dto.getWarehouseNumber()){
+            throw new MyException("入库数量不能少于已经发放数量");
+        }
+
         // 如果是征订入库
         // 根据入库记录找到对应的征订
 //        MPJLambdaWrapper<TextbookWarehouseRecord> textbookWarehouseRecordMPJLambdaWrapper = new MPJLambdaWrapper<>();
@@ -240,6 +244,11 @@ public class TextbookWarehouseRecordServiceImpl extends MPJBaseServiceImpl<Textb
 
         TextbookWarehouseRecord updateTextbookWarehouseRecord = new TextbookWarehouseRecord();
         updateTextbookWarehouseRecord.setId(textbookWarehouseRecord.getId());
+        updateTextbookWarehouseRecord.setActualWarehouseNumber(dto.getWarehouseNumber() - (textbookWarehouseRecord.getWarehouseNumber() - textbookWarehouseRecord.getActualWarehouseNumber()));
+        if(updateTextbookWarehouseRecord.getActualWarehouseNumber() < 0){
+            throw new MyException("该教材存在退书等操作,修改的入库数量不能少于已发放数量和退书等操作数量的总和。");
+        }
+        updateTextbookWarehouseRecord.setWarehouseNumber(dto.getWarehouseNumber());
         updateTextbookWarehouseRecord.setPrice(ObjectUtils.isNotEmpty(dto.getPrice()) ? dto.getPrice() : BigDecimal.ZERO);
         updateTextbookWarehouseRecord.setDiscount(ObjectUtils.isNotEmpty(dto.getDiscount()) ? dto.getDiscount() : 10);
         updateTextbookWarehouseRecord.setSubtotal(updateTextbookWarehouseRecord.getPrice().multiply(BigDecimal.valueOf(dto.getDiscount() / 10)));
@@ -278,6 +287,8 @@ public class TextbookWarehouseRecordServiceImpl extends MPJBaseServiceImpl<Textb
         textbookDiscountAlterRecord.setNewPrice(dto.getPrice());
         textbookDiscountAlterRecord.setOldDiscount(textbookWarehouseRecord.getDiscount());
         textbookDiscountAlterRecord.setNewDiscount(dto.getDiscount());
+        textbookDiscountAlterRecord.setOldWarehouseNum(textbookWarehouseRecord.getWarehouseNumber());
+        textbookDiscountAlterRecord.setNewWarehouseNum(dto.getWarehouseNumber());
         textbookDiscountAlterRecord.setCreateDate(new Date());
         textbookDiscountAlterRecordMapper.insert(textbookDiscountAlterRecord);
 

+ 300 - 71
src/main/java/com/xjrsoft/module/textbook/service/impl/WfTextbookClaimServiceImpl.java

@@ -1,8 +1,6 @@
 package com.xjrsoft.module.textbook.service.impl;
 
 import cn.dev33.satoken.stp.StpUtil;
-import com.alibaba.excel.EasyExcel;
-import com.alibaba.excel.support.ExcelTypeEnum;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -13,12 +11,11 @@ import com.xjrsoft.common.enums.ClaimTypeEnum;
 import com.xjrsoft.common.enums.DeleteMark;
 import com.xjrsoft.common.enums.IssueModeEnum;
 import com.xjrsoft.common.exception.MyException;
-import com.xjrsoft.common.model.result.RT;
 import com.xjrsoft.common.page.ConventPage;
 import com.xjrsoft.common.utils.VoToColumnUtil;
 import com.xjrsoft.module.base.entity.BaseClass;
 import com.xjrsoft.module.base.entity.BaseSemester;
-import com.xjrsoft.module.oa.entity.WfMeetingApply;
+import com.xjrsoft.module.generator.entity.ImportConfig;
 import com.xjrsoft.module.system.entity.DictionaryDetail;
 import com.xjrsoft.module.teacher.entity.XjrUser;
 import com.xjrsoft.module.teacher.mapper.XjrUserMapper;
@@ -27,21 +24,29 @@ import com.xjrsoft.module.textbook.entity.*;
 import com.xjrsoft.module.textbook.mapper.*;
 import com.xjrsoft.module.textbook.service.IWfTextbookClaimService;
 import com.xjrsoft.module.textbook.vo.*;
+import com.xjrsoft.module.veb.util.ImportExcelUtil;
 import com.xjrsoft.module.workflow.entity.WorkflowFormRelation;
 import com.xjrsoft.module.workflow.mapper.WorkflowFormRelationMapper;
 import lombok.AllArgsConstructor;
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.camunda.bpm.engine.history.HistoricProcessInstance;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -71,6 +76,7 @@ public class WfTextbookClaimServiceImpl extends MPJBaseServiceImpl<WfTextbookCla
 
     @Override
     public IPage<DistributePageVo> distributePage(DistributePageDto dto) {
+        // 申领主表记录
         MPJLambdaWrapper<WfTextbookClaim> wfTextbookClaimMPJLambdaWrapper = new MPJLambdaWrapper<>();
         wfTextbookClaimMPJLambdaWrapper
                 .disableSubLogicDel()
@@ -97,7 +103,6 @@ public class WfTextbookClaimServiceImpl extends MPJBaseServiceImpl<WfTextbookCla
                                 .selectAs(XjrUser::getName, DistributePageVo::getStudentUserIdCn)
                 )
                 .eq(WfTextbookClaim::getBaseSemesterId, dto.getBaseSemesterId())
-                .eq(WfTextbookClaim::getWorkflowStatus, 1)
                 .eq(StringUtils.isNotEmpty(dto.getClaimType()), WfTextbookClaim::getClaimType, dto.getClaimType())
                 .and(StringUtils.isNotEmpty(dto.getName()),
                         wrapper -> wrapper
@@ -106,7 +111,10 @@ public class WfTextbookClaimServiceImpl extends MPJBaseServiceImpl<WfTextbookCla
                                 .like(BaseClass::getName, dto.getName())
                 )
         ;
+
+        // 发放状态(是否有过发放(1:未发放,2:部分发放,3:全部发放,4:有发放))
         if (ObjectUtils.isNotEmpty(dto.getDistributeStatus())) {
+            // 有发放,除了未发放其他所有的状态
             if (dto.getDistributeStatus() == 4) {
                 wfTextbookClaimMPJLambdaWrapper
                         .ne(WfTextbookClaim::getStatus, 1)
@@ -116,8 +124,9 @@ public class WfTextbookClaimServiceImpl extends MPJBaseServiceImpl<WfTextbookCla
                         .eq(WfTextbookClaim::getStatus, dto.getDistributeStatus())
                 ;
             }
-
         }
+
+        // 流程状态(0:未结束,1:已结束,正常通过,2:已结束,未通过,3:作废)
         if (ObjectUtils.isNotEmpty(dto.getWorkflowStatus())) {
             wfTextbookClaimMPJLambdaWrapper
                     .eq(WfTextbookClaim::getWorkflowStatus, dto.getWorkflowStatus())
@@ -131,42 +140,95 @@ public class WfTextbookClaimServiceImpl extends MPJBaseServiceImpl<WfTextbookCla
                     )
             ;
         }
+
         IPage<DistributePageVo> page = this.selectJoinListPage(ConventPage.getPage(dto), DistributePageVo.class, wfTextbookClaimMPJLambdaWrapper);
 
-        List<DistributePageVo> distributePageVos = page.getRecords();
-
-        // 处理申领总数量和已经发放总数量
-        if (ObjectUtils.isNotEmpty(distributePageVos)) {
-            List<Long> textbookClaimIds = distributePageVos.stream()
-                    .map(DistributePageVo::getId)
-                    .collect(Collectors.toList());
-            Map<Long, WfTextbookClaimItem> applicantTatolNumberMap = new HashMap<>();
-            WfTextbookClaimItem wfTextbookClaimItem;
-            if (ObjectUtils.isNotEmpty(textbookClaimIds)) {
-                MPJLambdaWrapper<WfTextbookClaimItem> wfTextbookClaimItemLambdaQueryWrapper = new MPJLambdaWrapper<>();
-                wfTextbookClaimItemLambdaQueryWrapper
-                        .selectAs(WfTextbookClaimItem::getWfTextbookClaimId, WfTextbookClaimItem::getWfTextbookClaimId)
-                        .selectSum(WfTextbookClaimItem::getApplicantNumber, WfTextbookClaimItem::getApplicantNumber)
-                        .selectSum(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItem::getIssueNumber)
-                        .in(WfTextbookClaimItem::getWfTextbookClaimId, textbookClaimIds)
-                        .groupBy(WfTextbookClaimItem::getWfTextbookClaimId)
-                ;
-                List<WfTextbookClaimItem> wfTextbookClaimItemList = wfTextbookClaimWfTextbookClaimItemMapper.selectJoinList(WfTextbookClaimItem.class, wfTextbookClaimItemLambdaQueryWrapper);
-                if (ObjectUtils.isNotEmpty(wfTextbookClaimItemList)) {
-                    applicantTatolNumberMap = wfTextbookClaimItemList.stream()
-                            .collect(Collectors.toMap(WfTextbookClaimItem::getWfTextbookClaimId, w -> w, (w1, w2) -> w1));
-                }
+        // 当申领记录为空
+        List<DistributePageVo> records = page.getRecords();
+
+
+        List<Long> claimIds = records.stream()
+                .map(DistributePageVo::getId)
+                .collect(Collectors.toList());
+
+        // 查询统计数据
+        MPJLambdaWrapper<WfTextbookClaimItem> statsWrapper = new MPJLambdaWrapper<>();
+        statsWrapper
+                .selectAs(WfTextbookClaimItem::getWfTextbookClaimId, WfTextbookClaimItem::getWfTextbookClaimId)
+                .selectSum(WfTextbookClaimItem::getApplicantNumber, WfTextbookClaimItem::getApplicantNumber)
+                .selectSum(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItem::getIssueNumber)
+                .in(WfTextbookClaimItem::getWfTextbookClaimId, claimIds)
+                .groupBy(WfTextbookClaimItem::getWfTextbookClaimId);
+
+        List<WfTextbookClaimItem> statsList = wfTextbookClaimWfTextbookClaimItemMapper.selectJoinList(WfTextbookClaimItem.class, statsWrapper);
+        Map<Long, WfTextbookClaimItem> statsMap = statsList.stream()
+                .collect(Collectors.toMap(
+                        WfTextbookClaimItem::getWfTextbookClaimId,
+                        Function.identity(),
+                        (w1, w2) -> w1)); // 可视情况记录冲突日志
+
+        // 查询子项数据
+        MPJLambdaWrapper<WfTextbookClaimItem> itemWrapper = new MPJLambdaWrapper<>();
+        itemWrapper.disableSubLogicDel()
+                .select(WfTextbookClaimItem::getId)
+                .selectAs(WfTextbookClaimItem::getApplicantNumber, WfTextbookClaimItemVo::getApplicantNumber)
+                .selectAs(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItemVo::getIssueNumber)
+                .select(WfTextbookClaimItem.class, x -> VoToColumnUtil.fieldsToColumns(WfTextbookClaimItemVo.class).contains(x.getProperty()))
+                .leftJoin(Textbook.class, Textbook::getId, WfTextbookClaimItem::getTextbookId,
+                        w -> w
+                                .selectAs(Textbook::getBookName, DistributeRecordVo::getTextbookIdCn)
+                                .selectAs(Textbook::getIssn, DistributeRecordVo::getIssn))
+                .in(WfTextbookClaimItem::getWfTextbookClaimId, claimIds);
+
+        List<WfTextbookClaimItemVo> itemList = wfTextbookClaimWfTextbookClaimItemMapper.selectJoinList(WfTextbookClaimItemVo.class, itemWrapper);
+        Map<Long, List<WfTextbookClaimItemVo>> itemMap = itemList.stream()
+                .collect(Collectors.groupingBy(WfTextbookClaimItemVo::getWfTextbookClaimId));
+
+        // 查询发放记录
+        MPJLambdaWrapper<TextbookIssueRecord> recordWrapper = new MPJLambdaWrapper<>();
+        recordWrapper.disableSubLogicDel()
+                .selectAs(TextbookIssueRecord::getDataId, DistributeRecordVo::getWfTextbookClaimId)
+                .selectAs(TextbookIssueRecord::getDataItemId, DistributeRecordVo::getWfTextbookClaimItemId)
+                .selectAs(TextbookIssueRecord::getCreateDate, DistributeRecordVo::getIssueDate)
+                .selectAs(TextbookIssueRecord::getIssueNumber, DistributeRecordVo::getIssueNumber)
+                .selectAs(TextbookIssueRecord::getOrderNumber, DistributeRecordVo::getOrderNumber)
+                .selectAs(TextbookIssueRecord::getRemark, DistributeRecordVo::getRemark)
+                .leftJoin(Textbook.class, Textbook::getId, TextbookIssueRecord::getTextbookId,
+                        w -> w
+                                .selectAs(Textbook::getBookName, DistributeRecordVo::getTextbookIdCn)
+                                .selectAs(Textbook::getIssn, DistributeRecordVo::getIssn))
+                .leftJoin(XjrUser.class, XjrUser::getId, TextbookIssueRecord::getIssueUserId,
+                        w -> w
+                                .selectAs(XjrUser::getName, DistributeRecordVo::getIssueUser))
+                .in(TextbookIssueRecord::getDataId, claimIds);
+
+        List<DistributeRecordVo> recordList = textbookIssueRecordMapper.selectJoinList(DistributeRecordVo.class, recordWrapper);
+        Map<Long, List<DistributeRecordVo>> recordMap = recordList.stream()
+                .collect(Collectors.groupingBy(DistributeRecordVo::getWfTextbookClaimItemId));
+
+        // 组装数据
+        for (DistributePageVo vo : records) {
+            Long claimId = vo.getId();
+
+            // 填充统计信息
+            if (MapUtils.isNotEmpty(statsMap) && statsMap.containsKey(claimId)) {
+                WfTextbookClaimItem stat = statsMap.get(claimId);
+                vo.setApplicantTatolNumber(stat.getApplicantNumber());
+                vo.setIssueTatolNumber(stat.getIssueNumber());
             }
-            if (ObjectUtils.isNotEmpty(applicantTatolNumberMap)) {
-                for (DistributePageVo distributePageVo : page.getRecords()) {
-                    wfTextbookClaimItem = applicantTatolNumberMap.get(distributePageVo.getId());
-                    if (ObjectUtils.isNotEmpty(wfTextbookClaimItem)) {
-                        distributePageVo.setApplicantTatolNumber(wfTextbookClaimItem.getApplicantNumber());
-                        distributePageVo.setIssueTatolNumber(wfTextbookClaimItem.getIssueNumber());
+
+            // 填充子项及发放记录
+            if (MapUtils.isNotEmpty(itemMap) && CollectionUtils.isNotEmpty(itemMap.get(claimId))) {
+                List<WfTextbookClaimItemVo> items = itemMap.get(claimId);
+                for (WfTextbookClaimItemVo item : items) {
+                    if (recordMap.containsKey(item.getId())) {
+                        item.setDistributeRecordVos(recordMap.get(item.getId()));
                     }
                 }
+                vo.setWfTextbookClaimItemVoList(items);
             }
         }
+
         return page;
     }
 
@@ -697,7 +759,7 @@ public class WfTextbookClaimServiceImpl extends MPJBaseServiceImpl<WfTextbookCla
     }
 
     @Override
-    public ByteArrayOutputStream claimRecordsExportQuery(ClaimRecordsExportQueryDto dto) {
+    public ByteArrayOutputStream claimRecordsExportQuery(ClaimRecordsExportQueryDto dto) throws IOException {
         MPJLambdaWrapper<WfTextbookClaim> wfTextbookClaimMPJLambdaWrapper = new MPJLambdaWrapper<>();
         wfTextbookClaimMPJLambdaWrapper
                 .disableSubLogicDel()
@@ -724,39 +786,112 @@ public class WfTextbookClaimServiceImpl extends MPJBaseServiceImpl<WfTextbookCla
         ;
         List<ClaimRecordsExportQueryVo> dataList = this.selectJoinList(ClaimRecordsExportQueryVo.class, wfTextbookClaimMPJLambdaWrapper);
 
-        // 处理申领总数量和已经发放总数量
-        if (ObjectUtils.isNotEmpty(dataList)) {
-            List<Long> textbookClaimIds = dataList.stream()
-                    .map(ClaimRecordsExportQueryVo::getId)
-                    .collect(Collectors.toList());
-            Map<Long, WfTextbookClaimItem> applicantTatolNumberMap = new HashMap<>();
-            WfTextbookClaimItem wfTextbookClaimItem;
-            if (ObjectUtils.isNotEmpty(textbookClaimIds)) {
-                MPJLambdaWrapper<WfTextbookClaimItem> wfTextbookClaimItemLambdaQueryWrapper = new MPJLambdaWrapper<>();
-                wfTextbookClaimItemLambdaQueryWrapper
-                        .selectAs(WfTextbookClaimItem::getWfTextbookClaimId, WfTextbookClaimItem::getWfTextbookClaimId)
-                        .selectSum(WfTextbookClaimItem::getApplicantNumber, WfTextbookClaimItem::getApplicantNumber)
-                        .selectSum(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItem::getIssueNumber)
-                        .in(WfTextbookClaimItem::getWfTextbookClaimId, textbookClaimIds)
-                        .groupBy(WfTextbookClaimItem::getWfTextbookClaimId)
-                ;
-                List<WfTextbookClaimItem> wfTextbookClaimItemList = wfTextbookClaimWfTextbookClaimItemMapper.selectJoinList(WfTextbookClaimItem.class, wfTextbookClaimItemLambdaQueryWrapper);
-                if (ObjectUtils.isNotEmpty(wfTextbookClaimItemList)) {
-                    applicantTatolNumberMap = wfTextbookClaimItemList.stream()
-                            .collect(Collectors.toMap(WfTextbookClaimItem::getWfTextbookClaimId, w -> w, (w1, w2) -> w1));
-                }
-            }
-            if (ObjectUtils.isNotEmpty(applicantTatolNumberMap)) {
-                for (ClaimRecordsExportQueryVo vo : dataList) {
-                    wfTextbookClaimItem = applicantTatolNumberMap.get(vo.getId());
-                    if (ObjectUtils.isNotEmpty(wfTextbookClaimItem)) {
-                        vo.setApplicantTatolNumber(wfTextbookClaimItem.getApplicantNumber());
-                        vo.setIssueTatolNumber(wfTextbookClaimItem.getIssueNumber());
-                    }
-                }
-            }
-        }
-
+        List<Long> claimIds = dataList.stream()
+                .map(ClaimRecordsExportQueryVo::getId)
+                .collect(Collectors.toList());
+
+        // 查询统计数据
+        MPJLambdaWrapper<WfTextbookClaimItem> statsWrapper = new MPJLambdaWrapper<>();
+        statsWrapper
+                .selectAs(WfTextbookClaimItem::getWfTextbookClaimId, WfTextbookClaimItem::getWfTextbookClaimId)
+                .selectSum(WfTextbookClaimItem::getApplicantNumber, WfTextbookClaimItem::getApplicantNumber)
+                .selectSum(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItem::getIssueNumber)
+                .in(WfTextbookClaimItem::getWfTextbookClaimId, claimIds)
+                .groupBy(WfTextbookClaimItem::getWfTextbookClaimId);
+
+        List<WfTextbookClaimItem> statsList = wfTextbookClaimWfTextbookClaimItemMapper.selectJoinList(WfTextbookClaimItem.class, statsWrapper);
+        Map<Long, WfTextbookClaimItem> statsMap = statsList.stream()
+                .collect(Collectors.toMap(
+                        WfTextbookClaimItem::getWfTextbookClaimId,
+                        Function.identity(),
+                        (w1, w2) -> w1)); // 可视情况记录冲突日志
+
+        // 查询子项数据
+        MPJLambdaWrapper<WfTextbookClaimItem> itemWrapper = new MPJLambdaWrapper<>();
+        itemWrapper.disableSubLogicDel()
+                .select(WfTextbookClaimItem::getId)
+                .selectAs(WfTextbookClaimItem::getApplicantNumber, WfTextbookClaimItemVo::getApplicantNumber)
+                .selectAs(WfTextbookClaimItem::getIssueNumber, WfTextbookClaimItemVo::getIssueNumber)
+                .select(WfTextbookClaimItem.class, x -> VoToColumnUtil.fieldsToColumns(WfTextbookClaimItemVo.class).contains(x.getProperty()))
+                .leftJoin(Textbook.class, Textbook::getId, WfTextbookClaimItem::getTextbookId,
+                        w -> w
+                                .selectAs(Textbook::getBookName, DistributeRecordVo::getTextbookIdCn)
+                                .selectAs(Textbook::getIssn, DistributeRecordVo::getIssn))
+                .in(WfTextbookClaimItem::getWfTextbookClaimId, claimIds);
+
+        List<WfTextbookClaimItemVo> itemList = wfTextbookClaimWfTextbookClaimItemMapper.selectJoinList(WfTextbookClaimItemVo.class, itemWrapper);
+        Map<Long, List<WfTextbookClaimItemVo>> itemMap = itemList.stream()
+                .collect(Collectors.groupingBy(WfTextbookClaimItemVo::getWfTextbookClaimId));
+
+        // 查询发放记录
+        MPJLambdaWrapper<TextbookIssueRecord> recordWrapper = new MPJLambdaWrapper<>();
+        recordWrapper.disableSubLogicDel()
+                .selectAs(TextbookIssueRecord::getDataId, DistributeRecordVo::getWfTextbookClaimId)
+                .selectAs(TextbookIssueRecord::getDataItemId, DistributeRecordVo::getWfTextbookClaimItemId)
+                .selectAs(TextbookIssueRecord::getCreateDate, DistributeRecordVo::getIssueDate)
+                .selectAs(TextbookIssueRecord::getIssueNumber, DistributeRecordVo::getIssueNumber)
+                .selectAs(TextbookIssueRecord::getOrderNumber, DistributeRecordVo::getOrderNumber)
+                .selectAs(TextbookIssueRecord::getRemark, DistributeRecordVo::getRemark)
+                .leftJoin(Textbook.class, Textbook::getId, TextbookIssueRecord::getTextbookId,
+                        w -> w
+                                .selectAs(Textbook::getBookName, DistributeRecordVo::getTextbookIdCn)
+                                .selectAs(Textbook::getIssn, DistributeRecordVo::getIssn))
+                .leftJoin(XjrUser.class, XjrUser::getId, TextbookIssueRecord::getIssueUserId,
+                        w -> w
+                                .selectAs(XjrUser::getName, DistributeRecordVo::getIssueUser))
+                .in(TextbookIssueRecord::getDataId, claimIds);
+
+        List<DistributeRecordVo> recordList = textbookIssueRecordMapper.selectJoinList(DistributeRecordVo.class, recordWrapper);
+        Map<Long, List<DistributeRecordVo>> recordMap = recordList.stream()
+                .collect(Collectors.groupingBy(DistributeRecordVo::getWfTextbookClaimItemId));
+
+        // 开始写入
+        Workbook workbook = new XSSFWorkbook();
+        // 创建一个工作表(sheet)
+        String sheetName = "sheet1";
+        Sheet sheet = workbook.createSheet(sheetName);
+
+        // 出参vo字段数量
+        ClaimRecordsExportQueryVo obj = new ClaimRecordsExportQueryVo();
+        List<ImportConfig> importConfigs = ImportExcelUtil.allFields(obj);
+
+        // 写大标题
+        int rowNumber = 0;
+        ImportExcelUtil.createBigHead(workbook, sheet, "教材申领情况", rowNumber++, importConfigs.size() - 1);
+
+        // 表头
+        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<String> claimVo;
+        List<String> claimItemVo;
+        List<String> claimItemIssueVo;
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
         for (ClaimRecordsExportQueryVo vo : dataList) {
             if (ObjectUtils.isNotEmpty(vo.getClaimType()) && ClaimTypeEnum.ClaimClass.getCode().equals(vo.getClaimType())) {
                 vo.setReceiver(vo.getClassIdCn());
@@ -772,11 +907,105 @@ public class WfTextbookClaimServiceImpl extends MPJBaseServiceImpl<WfTextbookCla
             } else {
                 vo.setStatusStr("未发放");
             }
+
+            Long claimId = vo.getId();
+
+            // 填充统计信息
+            if (MapUtils.isNotEmpty(statsMap) && statsMap.containsKey(claimId)) {
+                WfTextbookClaimItem stat = statsMap.get(claimId);
+                vo.setApplicantTatolNumber(stat.getApplicantNumber());
+                vo.setIssueTatolNumber(stat.getIssueNumber());
+            }
+
+            // 申领总记录
+            claimVo = new ArrayList<>();
+            claimVo.add(vo.getBaseSemesterIdCn());
+            claimVo.add(vo.getClaimTypeCn());
+            claimVo.add(vo.getReceiver());
+            if (StringUtils.isNotEmpty(vo.getClassIdCn())) {
+                claimVo.add(vo.getClassIdCn());
+            } else {
+                claimVo.add("无");
+            }
+            claimVo.add(vo.getApplicantTatolNumber() + "");
+            claimVo.add(vo.getStatusStr());
+            claimVo.add(vo.getIssueTatolNumber() + "");
+
+            // 填充子项及发放记录
+            int mergeClaim = 0;
+            if (MapUtils.isNotEmpty(itemMap) && CollectionUtils.isNotEmpty(itemMap.get(claimId))) {
+                List<WfTextbookClaimItemVo> items = itemMap.get(claimId);
+                for (WfTextbookClaimItemVo item : items) {
+                    mergeClaim++;
+                    claimItemVo = new ArrayList<>(claimVo);
+                    claimItemVo.add(item.getTextbookIdCN());
+                    claimItemVo.add(item.getIssn());
+                    claimItemVo.add(item.getApplicantNumber() + "");
+                    claimItemVo.add(item.getIssueNumber() + "");
+
+                    int mergeClaimItem = 0;
+                    if (recordMap.containsKey(item.getId())) {
+                        List<DistributeRecordVo> issues = recordMap.get(item.getId());
+                        for (DistributeRecordVo issue : issues) {
+                            mergeClaimItem++;
+                            claimItemIssueVo = new ArrayList<>(claimItemVo);
+                            LocalDateTime localDateTime = issue.getIssueDate().toInstant()
+                                    .atZone(ZoneId.systemDefault())
+                                    .toLocalDateTime();
+                            claimItemIssueVo.add(localDateTime.format(formatter));
+                            claimItemIssueVo.add(issue.getIssueUser());
+                            claimItemIssueVo.add(issue.getOrderNumber());
+                            claimItemIssueVo.add(issue.getIssueNumber() + "");
+
+                            Row dataRow = sheet.createRow(rowNumber++);
+                            for (int j = 0; j < claimItemIssueVo.size(); j++) {
+                                String content = claimItemIssueVo.get(j);
+                                Cell cell = dataRow.createCell(j);
+                                cell.setCellValue(content);
+                                cell.setCellStyle(cellStyle);
+                            }
+                        }
+                        // 合并申领项
+                        if (mergeClaimItem > 1) {
+                            for (int k = 7; k < 11; k++) {
+                                sheet.addMergedRegion(new CellRangeAddress(rowNumber - mergeClaimItem, rowNumber - 1, k, k));
+                            }
+                        }
+                    } else {
+                        Row dataRow = sheet.createRow(rowNumber++);
+                        for (int j = 0; j < claimItemVo.size(); j++) {
+                            String content = claimItemVo.get(j);
+                            Cell cell = dataRow.createCell(j);
+                            cell.setCellValue(content);
+                            cell.setCellStyle(cellStyle);
+                        }
+                    }
+                }
+
+                // 合并申领
+                if (mergeClaim > 1) {
+                    for (int k = 0; k < 7; k++) {
+                        sheet.addMergedRegion(new CellRangeAddress(rowNumber - mergeClaim, rowNumber - 1, k, k));
+                    }
+                }
+            } else {
+                Row dataRow = sheet.createRow(rowNumber++);
+                for (int j = 0; j < claimVo.size(); j++) {
+                    String content = claimVo.get(j);
+                    Cell cell = dataRow.createCell(j);
+                    cell.setCellValue(content);
+                    cell.setCellStyle(cellStyle);
+                }
+            }
         }
 
-        ByteArrayOutputStream bot = new ByteArrayOutputStream();
-        EasyExcel.write(bot, ClaimRecordsExportQueryVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(dataList);
+        // 自动列宽
+        for (int i = 0; i < importConfigs.size(); i++) {
+            sheet.autoSizeColumn(i);
+        }
 
+        ByteArrayOutputStream bot = new ByteArrayOutputStream();
+        workbook.write(bot);
         return bot;
     }
 }

+ 46 - 2
src/main/java/com/xjrsoft/module/textbook/vo/ClaimRecordsExportQueryVo.java

@@ -6,8 +6,12 @@ import com.alibaba.excel.annotation.write.style.ContentStyle;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.util.Date;
+import java.util.List;
+
 @Data
 public class ClaimRecordsExportQueryVo {
+    @ContentStyle(dataFormat = 49)
     @ExcelIgnore
     @ApiModelProperty("主键编号")
     private Long id;
@@ -38,8 +42,8 @@ public class ClaimRecordsExportQueryVo {
     private String applicantUserIdCn;
 
     @ContentStyle(dataFormat = 49)
-    @ExcelIgnore
-    @ApiModelProperty("班级编号")
+    @ExcelProperty("班级名称")
+    @ApiModelProperty("班级名称")
     private String classIdCn;
 
     @ContentStyle(dataFormat = 49)
@@ -61,4 +65,44 @@ public class ClaimRecordsExportQueryVo {
     @ExcelProperty("发放数量")
     @ApiModelProperty("已经发放总数量")
     private Integer issueTatolNumber;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("教材名称")
+    @ApiModelProperty("教材名称")
+    private String textbookIdCN;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("国际标准刊号")
+    @ApiModelProperty("国际标准刊号")
+    private String issn;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("申请数量")
+    @ApiModelProperty("申请数量")
+    private Integer applicantNumber;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("已发放数量")
+    @ApiModelProperty("已发放数量")
+    private Integer issueNumber;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("出库时间")
+    @ApiModelProperty("出库时间")
+    private String issueDate;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("出库人员")
+    @ApiModelProperty("出库人员")
+    private String issueUser;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("出库单号")
+    @ApiModelProperty("出库单号(标识+当前时间(YYYYMMDDHHmmss)+三位序号+当前申领项出库次数(-n))")
+    private String orderNumber;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("单次出库数量")
+    @ApiModelProperty("单次出库数量")
+    private Integer onceIssueNumber;
 }

+ 4 - 0
src/main/java/com/xjrsoft/module/textbook/vo/DistributePageVo.java

@@ -7,6 +7,7 @@ import lombok.Data;
 
 import java.time.LocalDateTime;
 import java.util.Date;
+import java.util.List;
 
 @Data
 public class DistributePageVo {
@@ -61,4 +62,7 @@ public class DistributePageVo {
 
     @ApiModelProperty("创建时间")
     private LocalDateTime createDate;
+
+    @ApiModelProperty("申领子项集合")
+    List<WfTextbookClaimItemVo> wfTextbookClaimItemVoList;
 }

+ 16 - 1
src/main/java/com/xjrsoft/module/textbook/vo/DistributeRecordVo.java

@@ -13,7 +13,16 @@ import java.util.Date;
  */
 @Data
 public class DistributeRecordVo {
-
+    /**
+     * 教材申领编号
+     */
+    @ApiModelProperty("教材申领编号")
+    private Long wfTextbookClaimId;
+    /**
+     * 教材申领子项编号
+     */
+    @ApiModelProperty("教材申领子项编号")
+    private Long wfTextbookClaimItemId;
     /**
      * 出库时间
      */
@@ -32,6 +41,12 @@ public class DistributeRecordVo {
     @ApiModelProperty("教材管理编号")
     private String textbookIdCn;
 
+    /**
+     * 国际标准刊号
+     */
+    @ApiModelProperty("国际标准刊号")
+    private String issn;
+
     /**
      * 出库单号(标识+当前时间(YYYYMMDDHHmmss)+三位序号+当前申领项出库次数(-n))
      */

+ 11 - 5
src/main/java/com/xjrsoft/module/textbook/vo/WfTextbookClaimItemVo.java

@@ -1,8 +1,12 @@
 package com.xjrsoft.module.textbook.vo;
 
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ContentStyle;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.util.List;
+
 /**
  * @title: 教材申领项表单出参
  * @Author szs
@@ -17,11 +21,6 @@ public class WfTextbookClaimItemVo {
      */
     @ApiModelProperty("主键编号")
     private Long id;
-    /**
-     * 序号
-     */
-    @ApiModelProperty("序号")
-    private Integer sortCode;
     /**
      * 教材申领编号
      */
@@ -37,6 +36,11 @@ public class WfTextbookClaimItemVo {
      */
     @ApiModelProperty("教材管理编号")
     private String textbookIdCN;
+    /**
+     * 国际标准刊号
+     */
+    @ApiModelProperty("国际标准刊号")
+    private String issn;
     /**
      * 申请数量
      */
@@ -48,4 +52,6 @@ public class WfTextbookClaimItemVo {
     @ApiModelProperty("已发放数量")
     private Integer issueNumber;
 
+    @ApiModelProperty("当前申领子项领取情况")
+    List<DistributeRecordVo> distributeRecordVos;
 }

Datei-Diff unterdrückt, da er zu groß ist
+ 5 - 1
src/main/resources/sqlScript/20250603sql.sql


+ 5 - 0
src/main/resources/sqlScript/20250612sql.sql

@@ -0,0 +1,5 @@
+alter table textbook_discount_alter_record
+    add old_warehouse_num int null comment '旧的入库数量' after new_price;
+
+alter table textbook_discount_alter_record
+    add new_warehouse_num int null comment '新的入库数量' after old_warehouse_num;

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.