浏览代码

Merge branch 'pre'

dzx 11 月之前
父节点
当前提交
3d9479165b
共有 53 个文件被更改,包括 1904 次插入420 次删除
  1. 6 0
      src/main/java/com/xjrsoft/common/enums/WarehouseModeEnum.java
  2. 13 0
      src/main/java/com/xjrsoft/common/utils/LocalDateTimeUtil.java
  3. 22 0
      src/main/java/com/xjrsoft/common/utils/LocalDateUtil.java
  4. 3 0
      src/main/java/com/xjrsoft/module/base/service/IBaseSemesterService.java
  5. 15 0
      src/main/java/com/xjrsoft/module/base/service/impl/BaseSemesterServiceImpl.java
  6. 2 0
      src/main/java/com/xjrsoft/module/job/JianyuekbBaseDataTask.java
  7. 65 0
      src/main/java/com/xjrsoft/module/job/StudentReportPlanTask.java
  8. 123 0
      src/main/java/com/xjrsoft/module/liteflow/node/StudentResumeSchoolingNode.java
  9. 76 9
      src/main/java/com/xjrsoft/module/schedule/util/DataUtil.java
  10. 14 1
      src/main/java/com/xjrsoft/module/student/controller/StudentReportPlanController.java
  11. 124 35
      src/main/java/com/xjrsoft/module/student/controller/StudentReportRecordController.java
  12. 3 0
      src/main/java/com/xjrsoft/module/student/dto/StudentReportRecordStatisticsDto.java
  13. 3 2
      src/main/java/com/xjrsoft/module/student/entity/StudentReportPlan.java
  14. 3 1
      src/main/java/com/xjrsoft/module/student/mapper/StudentReportPlanMapper.java
  15. 3 0
      src/main/java/com/xjrsoft/module/student/mapper/StudentReportRecordMapper.java
  16. 7 1
      src/main/java/com/xjrsoft/module/student/service/IStudentReportPlanService.java
  17. 70 44
      src/main/java/com/xjrsoft/module/student/service/impl/StudentReportPlanServiceImpl.java
  18. 63 16
      src/main/java/com/xjrsoft/module/student/service/impl/StudentReportRecordServiceImpl.java
  19. 73 0
      src/main/java/com/xjrsoft/module/student/vo/StudentReportRecordExcelVo.java
  20. 30 0
      src/main/java/com/xjrsoft/module/student/vo/StudentReportRecordItemVo.java
  21. 3 0
      src/main/java/com/xjrsoft/module/student/vo/StudentReportRecordPlanPageVo.java
  22. 3 0
      src/main/java/com/xjrsoft/module/student/vo/StudentReportRecordStatisticsListVo.java
  23. 6 3
      src/main/java/com/xjrsoft/module/student/vo/StudentReportRecordStatisticsVo.java
  24. 1 1
      src/main/java/com/xjrsoft/module/textbook/controller/TextbookSubscriptionController.java
  25. 2 2
      src/main/java/com/xjrsoft/module/textbook/controller/TextbookWarehouseRecordController.java
  26. 125 0
      src/main/java/com/xjrsoft/module/textbook/controller/TextbookWarehouseRecordDetailController.java
  27. 53 0
      src/main/java/com/xjrsoft/module/textbook/dto/AddTextbookWarehouseRecordDetailDto.java
  28. 26 0
      src/main/java/com/xjrsoft/module/textbook/dto/TextbookWarehouseRecordDetailPageDto.java
  29. 0 20
      src/main/java/com/xjrsoft/module/textbook/dto/TextbookWarehouseRecordPageDto.java
  30. 32 0
      src/main/java/com/xjrsoft/module/textbook/dto/UpdateTextbookWarehouseRecordDetailDto.java
  31. 5 1
      src/main/java/com/xjrsoft/module/textbook/entity/TextbookSubscription.java
  32. 67 29
      src/main/java/com/xjrsoft/module/textbook/entity/TextbookWarehouseRecord.java
  33. 103 0
      src/main/java/com/xjrsoft/module/textbook/entity/TextbookWarehouseRecordDetail.java
  34. 17 0
      src/main/java/com/xjrsoft/module/textbook/mapper/TextbookWarehouseRecordDetailMapper.java
  35. 17 0
      src/main/java/com/xjrsoft/module/textbook/service/ITextbookWarehouseRecordDetailService.java
  36. 2 3
      src/main/java/com/xjrsoft/module/textbook/service/ITextbookWarehouseRecordService.java
  37. 0 1
      src/main/java/com/xjrsoft/module/textbook/service/IWfTextbookSubscriptionService.java
  38. 134 21
      src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookSubscriptionServiceImpl.java
  39. 25 0
      src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookWarehouseRecordDetailServiceImpl.java
  40. 51 12
      src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookWarehouseRecordServiceImpl.java
  41. 4 4
      src/main/java/com/xjrsoft/module/textbook/service/impl/WfTextbookClaimServiceImpl.java
  42. 5 0
      src/main/java/com/xjrsoft/module/textbook/vo/TextbookSubscriptionPageVo.java
  43. 111 0
      src/main/java/com/xjrsoft/module/textbook/vo/TextbookWarehouseRecordDetailPageVo.java
  44. 54 0
      src/main/java/com/xjrsoft/module/textbook/vo/TextbookWarehouseRecordDetailVo.java
  45. 27 86
      src/main/java/com/xjrsoft/module/textbook/vo/TextbookWarehouseRecordPageVo.java
  46. 1 0
      src/main/resources/mapper/student/BaseStudentMapper.xml
  47. 3 3
      src/main/resources/mapper/student/BaseStudentSchoolRollMapper.xml
  48. 6 1
      src/main/resources/mapper/student/StudentReportPlanMapper.xml
  49. 45 11
      src/main/resources/mapper/student/StudentReportRecordMapper.xml
  50. 100 45
      src/main/resources/sqlScript/20250120_sql.sql
  51. 76 68
      src/test/java/com/xjrsoft/module/job/JianyuekbBaseDataTaskTest.java
  52. 57 0
      src/test/java/com/xjrsoft/module/job/StudentReportPlanTaskTest.java
  53. 25 0
      src/test/java/com/xjrsoft/xjrsoftboot/FreeMarkerGeneratorTest.java

+ 6 - 0
src/main/java/com/xjrsoft/common/enums/WarehouseModeEnum.java

@@ -7,6 +7,12 @@ package com.xjrsoft.common.enums;
  * @Version 1.0
  */
 public enum WarehouseModeEnum {
+    /**
+     * 手动
+     * */
+    WmSubscription("wm_subscription", "征订入库"),
+
+
     /**
      * 手动
      * */

+ 13 - 0
src/main/java/com/xjrsoft/common/utils/LocalDateTimeUtil.java

@@ -134,4 +134,17 @@ public final class LocalDateTimeUtil {
         String[] array = timeStr.split(StringPool.COLON);
         return LocalTime.of(Integer.parseInt(array[0]), Integer.parseInt(array[1]), Integer.parseInt(array[2]));
     }
+
+
+    /**
+     * 检查是否targetDateTime是否在时间段内(包含开始时间和结束时间)
+     * @param targetDateTime 需要检查的时间
+     * @param startDateTime 时间段开始时间
+     * @param endDateTime 时间段结束时间
+     * @return true:包含在该时间段内,false:不包含在该时间段内
+     */
+    public static boolean isDateTimeInRange(LocalDateTime targetDateTime, LocalDateTime startDateTime, LocalDateTime endDateTime) {
+        // 检查目标日期是否在开始日期和结束日期之间(包含边界)
+        return !targetDateTime.isBefore(startDateTime) && !targetDateTime.isAfter(endDateTime);
+    }
 }

+ 22 - 0
src/main/java/com/xjrsoft/common/utils/LocalDateUtil.java

@@ -0,0 +1,22 @@
+package com.xjrsoft.common.utils;
+
+import java.time.LocalDate;
+
+/**
+ * @author dzx
+ * @date 2025/2/11
+ */
+public class LocalDateUtil {
+
+    /**
+     * 检查是否targetDate是否在时间段内(包含开始日期和结束日期)
+     * @param targetDate 需要检查的日期
+     * @param startDate 时间段开始日期
+     * @param endDate 时间段结束日期
+     * @return true:包含在该时间段内,false:不包含在该时间段内
+     */
+    public static boolean isDateInRange(LocalDate targetDate, LocalDate startDate, LocalDate endDate) {
+        // 检查目标日期是否在开始日期和结束日期之间(包含边界)
+        return !targetDate.isBefore(startDate) && !targetDate.isAfter(endDate);
+    }
+}

+ 3 - 0
src/main/java/com/xjrsoft/module/base/service/IBaseSemesterService.java

@@ -14,4 +14,7 @@ import com.xjrsoft.module.base.entity.BaseSemester;
 public interface IBaseSemesterService extends IService<BaseSemester> {
 
     BaseSemester getCurrentSemester();
+
+
+    Long getLastSemester();
 }

+ 15 - 0
src/main/java/com/xjrsoft/module/base/service/impl/BaseSemesterServiceImpl.java

@@ -39,4 +39,19 @@ public class BaseSemesterServiceImpl extends ServiceImpl<BaseSemesterMapper, Bas
         BaseSemester baseSemester = semesterList.get(0);
         return baseSemester;
     }
+
+
+    @Override
+    public Long getLastSemester() {
+        List<BaseSemester> semesterList = this.list(
+                new QueryWrapper<BaseSemester>().lambda()
+                        .eq(BaseSemester::getDeleteMark, DeleteMark.NODELETE.getCode())
+                        .orderByDesc(BaseSemester::getStartDate)
+        );
+        if(semesterList.isEmpty()){
+            return null;
+        }
+        BaseSemester baseSemester = semesterList.get(0);
+        return baseSemester.getId();
+    }
 }

+ 2 - 0
src/main/java/com/xjrsoft/module/job/JianyuekbBaseDataTask.java

@@ -102,6 +102,8 @@ public class JianyuekbBaseDataTask {
             tableName = "base_class";
             dataUtil.insertClass(tableName, grade, teacherMap, currenSemeter, dataMap.get(tableName), classroomMap);
 
+            dataUtil.syncClass(tableName, currenSemeter);
+
             log.info("数据推送完成");
         } catch (Exception e) {
             log.error(e.getMessage(), e);

+ 65 - 0
src/main/java/com/xjrsoft/module/job/StudentReportPlanTask.java

@@ -0,0 +1,65 @@
+package com.xjrsoft.module.job;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.xjrsoft.common.enums.DeleteMark;
+import com.xjrsoft.common.enums.EnabledMark;
+import com.xjrsoft.common.utils.RedisUtil;
+import com.xjrsoft.module.student.entity.StudentReportPlan;
+import com.xjrsoft.module.student.entity.StudentReportPlanClassRelation;
+import com.xjrsoft.module.student.service.IBaseStudentService;
+import com.xjrsoft.module.student.service.IStudentReportPlanService;
+import lombok.extern.slf4j.Slf4j;
+import org.hamcrest.core.Is;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 学生报到相关计划调整
+ * @author dzx
+ * @date 2025年2月10日
+ */
+@Component
+@Slf4j
+public class StudentReportPlanTask {
+
+    @Autowired
+    private IStudentReportPlanService planService;
+
+
+    @Scheduled(cron = "0 */5 * * * ?")
+    public void execute() {
+        doExecute();
+    }
+
+    public void doExecute(){
+        //查询已发布未开始的,自动开始
+        LocalDateTime now = LocalDateTime.now();
+        List<StudentReportPlan> list = planService.getWillBeginData();
+
+        for (StudentReportPlan studentReportPlan : list) {
+            List<StudentReportPlanClassRelation> classRelationList = planService.getStudentReportPlanClassRelationList(studentReportPlan.getId());
+            studentReportPlan.setStudentReportPlanClassRelationList(classRelationList);
+            planService.release(studentReportPlan);
+        }
+
+        //查询已发布已结束的,自动结束
+        List<StudentReportPlan> endList = planService.list(
+                new QueryWrapper<StudentReportPlan>().lambda()
+                        .eq(StudentReportPlan::getDeleteMark, DeleteMark.NODELETE.getCode())
+                        .eq(StudentReportPlan::getStatus, 1)
+                        .eq(StudentReportPlan::getEnabledMark, EnabledMark.ENABLED.getCode())
+                        .eq(StudentReportPlan::getDeleteMark, DeleteMark.NODELETE.getCode())
+                        .le(StudentReportPlan::getEndTime, now)
+        );
+        for (StudentReportPlan studentReportPlan : endList) {
+            studentReportPlan.setStatus(2);
+            planService.updateById(studentReportPlan);
+        }
+    }
+
+}
+

+ 123 - 0
src/main/java/com/xjrsoft/module/liteflow/node/StudentResumeSchoolingNode.java

@@ -0,0 +1,123 @@
+package com.xjrsoft.module.liteflow.node;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.db.Entity;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.xjrsoft.common.enums.ArchivesStatusEnum;
+import com.xjrsoft.common.enums.DeleteMark;
+import com.xjrsoft.common.enums.StudentChangeTypeEnum;
+import com.xjrsoft.common.enums.WorkflowApproveType;
+import com.xjrsoft.common.mybatis.SqlRunnerAdapter;
+import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll;
+import com.xjrsoft.module.student.service.IBaseStudentSchoolRollService;
+import com.xjrsoft.module.student.service.IStudentChangeRecordService;
+import com.xjrsoft.module.workflow.entity.WorkflowRecord;
+import com.xjrsoft.module.workflow.mapper.WorkflowRecordMapper;
+import com.xjrsoft.module.workflow.service.IWorkflowExecuteService;
+import com.yomahub.liteflow.core.NodeComponent;
+import org.apache.commons.lang.StringUtils;
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.support.TransactionSynchronization;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * 学生复学
+ */
+@Component("student_resume_schooling_node")
+public class StudentResumeSchoolingNode extends NodeComponent {
+    @Autowired
+    private IBaseStudentSchoolRollService studentSchoolRollService;
+
+    @Autowired
+    private IWorkflowExecuteService workflowExecuteService;
+
+    @Autowired
+    private WorkflowRecordMapper workflowRecordMapper;
+
+    @Autowired
+    private IStudentChangeRecordService changeRecordService;
+
+
+    @Override
+    public void process() throws Exception {
+        // 获取表单中数据编号
+        Map<String, Object> params = this.getFirstContextBean();
+        Object value = util.getFormDatKey(params, "id");
+        Long formId = Convert.toLong(value);
+        Object processInstanceId = params.get("processInstanceId");
+        if (processInstanceId == null) {
+            return;
+        }
+        String processInstanceIdStr = Convert.toStr(processInstanceId);
+        if (formId != null && StringUtils.isNotEmpty(processInstanceIdStr)) {
+            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
+                @Override
+                public void afterCommit() {
+                    CompletableFuture.runAsync(() -> {
+                        Optional<HistoricProcessInstance> historicProcessInstanceOptional = workflowExecuteService.getHistoricProcessInstance(processInstanceId.toString());
+
+                        if (historicProcessInstanceOptional.isEmpty()) {
+                            return;
+                        }
+                        HistoricProcessInstance historicProcessInstance = historicProcessInstanceOptional.get();
+                        if (!historicProcessInstance.getState().equals(HistoricProcessInstance.STATE_ACTIVE)) {
+                            // 获取流程记录中的非正常结束
+                            LambdaQueryWrapper<WorkflowRecord> workflowRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
+                            workflowRecordLambdaQueryWrapper
+                                    .and(wq -> wq.eq(WorkflowRecord::getWorkflowApproveType, WorkflowApproveType.DISAGREE.getCode())
+                                            .or()
+                                            .eq(WorkflowRecord::getWorkflowApproveType, WorkflowApproveType.WITHDRAW.getCode())
+                                    )
+                                    .eq(WorkflowRecord::getProcessId, processInstanceId)
+                            ;
+                            List<WorkflowRecord> workflowRecordList = workflowRecordMapper.selectList(workflowRecordLambdaQueryWrapper);
+
+                            if (!workflowRecordList.isEmpty()) {
+                                return;
+                            }
+                        }
+
+                        //查询出数据
+                        String tableName = "wf_student_resume_schooling";
+                        Entity where = Entity.create(tableName);
+                        where.set("id", formId);
+                        Map<String, Object> objectMap = SqlRunnerAdapter.db().dynamicSelectOne(tableName, where);
+                        long studentUserId = Long.parseLong(objectMap.get("user_id").toString());
+                        //跟新学籍信息
+                        BaseStudentSchoolRoll schoolRoll = studentSchoolRollService.getOne(
+                                new QueryWrapper<BaseStudentSchoolRoll>().lambda()
+                                        .eq(BaseStudentSchoolRoll::getClassId, Long.parseLong(objectMap.get("class_id").toString()))
+                                        .eq(BaseStudentSchoolRoll::getUserId, studentUserId)
+                                        .eq(BaseStudentSchoolRoll::getDeleteMark, DeleteMark.NODELETE.getCode())
+                        );
+
+                        //记录异动
+                        changeRecordService.insertData(
+                                schoolRoll.getArchivesStatus(),
+                                ArchivesStatusEnum.fromCode(schoolRoll.getArchivesStatus()),
+                                ArchivesStatusEnum.FB2904.getCode(),
+                                ArchivesStatusEnum.FB2904.getValue(),
+                                studentUserId,
+                                Long.parseLong(objectMap.get("create_user_id").toString()),
+                                StudentChangeTypeEnum.ArchivesStatus.getCode(),
+                                2
+                        );
+
+
+
+                        schoolRoll.setArchivesStatus(ArchivesStatusEnum.FB2901.getCode());
+                        studentSchoolRollService.updateById(schoolRoll);
+                    });
+                }
+            });
+        }
+    }
+}

+ 76 - 9
src/main/java/com/xjrsoft/module/schedule/util/DataUtil.java

@@ -83,12 +83,35 @@ public class DataUtil {
         String sql = "SELECT * FROM " + tableName + " WHERE delete_mark = 0 and is_graduate = 1";
         List<Map<String, Object>> dataList = SqlRunnerAdapter.db().selectList(sql);
 
+        long timestamp = System.currentTimeMillis();
+        //生成签名
+        String sign = ScheduleUtil.createSign(timestamp);
+        JsonArray semesterSerialNos = new JsonArray();
+        semesterSerialNos.add(semesterSerialNo);
+        JsonObject paramJson = new JsonObject();
+        paramJson.add("semesterSerialNos", semesterSerialNos);
+        paramJson.addProperty("pageSize", 200);
+        paramJson.addProperty("pageIndex", 1);
+        String url= ScheduleUtil.apiUrl + "Class/page";
+        String doPost = ScheduleUtil.doPost(url, paramJson.toString(), sign, timestamp);
+
+
+        JsonParser parser = new JsonParser();
+        JsonObject jsonObject = parser.parse(doPost).getAsJsonObject();
+        JsonArray jsonArray = jsonObject.get("data").getAsJsonObject().get("dataList").getAsJsonArray();
+        List<String> jianyueIds  = new ArrayList<>();//当前学期已存在的班级
+        for (JsonElement jsonElement : jsonArray) {
+            JsonObject object = jsonElement.getAsJsonObject();
+            jianyueIds.add(object.get("serialNo").getAsString());
+        }
+
+
         Map<String, String> idMap = new HashMap<>();
         JsonParser jsonParser = new JsonParser();
         for (Map<String, Object> baseClassMap : dataList) {
             BaseClass baseClass = SqlRunnerAdapterUtil.convertMapToEntity(baseClassMap, BaseClass.class);
-            String url  = ScheduleUtil.apiUrl + "class/create";
-            JsonObject paramJson = new JsonObject();
+            url  = ScheduleUtil.apiUrl + "class/create";
+            paramJson = new JsonObject();
             if(baseClass.getTeacherId() != null && teacherMap.get(baseClass.getTeacherId().toString()) != null){
                 paramJson.addProperty("teacherSerialNo", teacherMap.get(baseClass.getTeacherId().toString()));
             }
@@ -100,20 +123,20 @@ public class DataUtil {
             if(baseClass.getClassroomId() != null && classroomMap.get(baseClass.getClassroomId().toString()) != null){
                 paramJson.addProperty("classRoomSerialNo", classroomMap.get(baseClass.getClassroomId().toString()));
             }
-            if(ids != null && ids.get(baseClass.getId().toString()) != null){
+            if(ids != null && ids.get(baseClass.getId().toString()) != null && jianyueIds.contains(ids.get(baseClass.getId().toString()))){
                 url  = ScheduleUtil.apiUrl + "class/update";
                 paramJson.addProperty("serialNo", ids.get(baseClass.getId().toString()));
-                long timestamp = System.currentTimeMillis();
+                timestamp = System.currentTimeMillis();
                 //生成签名
-                String sign = ScheduleUtil.createSign(timestamp);
+                sign = ScheduleUtil.createSign(timestamp);
                 ScheduleUtil.doPost(url, paramJson.toString(), sign, timestamp);
                 continue;
             }
 
             //获取时间戳
-            long timestamp = System.currentTimeMillis();
+            timestamp = System.currentTimeMillis();
             //生成签名
-            String sign = ScheduleUtil.createSign(timestamp);
+            sign = ScheduleUtil.createSign(timestamp);
             String result = ScheduleUtil.doPost(url, paramJson.toString(), sign, timestamp);
             if(result == null){
                 continue;
@@ -322,7 +345,7 @@ public class DataUtil {
      * 新增学期
      */
     public Map<String, String> insertSemester(String tableName, Map<String, String> ids) throws Exception {
-        String sql = "select * from " + tableName + " where delete_mark = 0";
+        String sql = "select * from " + tableName + " where delete_mark = 0 order by start_date desc limit 3";
         List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql, BaseSemester.class);
 
         Map<String, String> idMap = new HashMap<>();
@@ -369,7 +392,9 @@ public class DataUtil {
             String result = ScheduleUtil.doPost(url, paramJson.toString(), sign, timestamp);
 
             JsonObject resultJson = jsonParser.parse(result).getAsJsonObject();
-            idMap.put(semester.getId().toString(), resultJson.get("data").getAsString());
+            if(StrUtil.isNotEmpty(resultJson.get("data").getAsString())){
+                idMap.put(semester.getId().toString(), resultJson.get("data").getAsString());
+            }
         }
         //插入记录表
         insertRecord(tableName, idMap);
@@ -777,6 +802,48 @@ public class DataUtil {
 
     }
 
+    public void syncClass(String tableName, String currenSemeter) throws Exception {
+        String sql = "select * from base_class where delete_mark = 0 and is_graduate = 1";
+        List<Map<String, Object>> classList = SqlRunnerAdapter.db().selectList(sql);
+        Map<String, String> classNameIdMap = new HashMap<>();
+        for (Map<String, Object> objectMap : classList) {
+            classNameIdMap.put(objectMap.get("name").toString(), objectMap.get("id").toString());
+        }
+
+        long timestamp = System.currentTimeMillis();
+        String sign = ScheduleUtil.createSign(timestamp);
+        String url  = ScheduleUtil.apiUrl + "Class/page";
+
+        JsonObject pageJson = new JsonObject();
+        JsonArray semesterSerialNos = new JsonArray();
+        semesterSerialNos.add(currenSemeter);
+        JsonObject paramJson = new JsonObject();
+        paramJson.add("semesterSerialNos", semesterSerialNos);
+        pageJson.addProperty("pageSize", 2000);
+        pageJson.addProperty("pageIndex", 1);
+        JsonParser parser = new JsonParser();
+        String doPost = ScheduleUtil.doPost(url, pageJson.toString(), sign, timestamp);
+        JsonArray dataList = parser.parse(doPost).getAsJsonObject().get("data").getAsJsonObject().get("dataList").getAsJsonArray();
+
+        for (JsonElement jsonElement : dataList) {
+            JsonObject object = jsonElement.getAsJsonObject();
+            if(!object.get("semesterSerialNo").getAsString().equals(currenSemeter)){
+                continue;
+            }
+            String name = object.get("name").getAsString();
+            if(!classNameIdMap.containsKey(name)){
+                continue;
+            }
+
+            String insertSql = "INSERT INTO jianyue_data(create_date,table_name,source_id,jianyue_id)" +
+                    " select now(), '" + tableName + "', '" + classNameIdMap.containsKey(name) + "', '" + object.get("serialNo").getAsString() + "'" +
+                    " where NOT EXISTS (" +
+                    " SELECT 1 FROM jianyue_data WHERE jianyue_id = '" + object.get("serialNo").getAsString() + "'" +
+                    " );";
+            SqlRunnerAdapter.db().insert(insertSql);
+        }
+    }
+
 
     /**
      * 插入记录表

+ 14 - 1
src/main/java/com/xjrsoft/module/student/controller/StudentReportPlanController.java

@@ -6,6 +6,7 @@ import cn.hutool.core.bean.BeanUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.xjrsoft.common.enums.DeleteMark;
+import com.xjrsoft.common.enums.EnabledMark;
 import com.xjrsoft.common.exception.MyException;
 import com.xjrsoft.common.model.result.RT;
 import com.xjrsoft.common.page.ConventPage;
@@ -131,6 +132,17 @@ public class StudentReportPlanController {
         }
         //如果发布,需要先验证计划中的班级是否在其他生效的计划内
         if(dto.getStatus() != null && dto.getStatus() == 1){
+            List<StudentReportPlan> list = studentReportPlanService.list(
+                    new QueryWrapper<StudentReportPlan>().lambda()
+                            .ne(StudentReportPlan::getId, reportPlan.getId())
+                            .eq(StudentReportPlan::getEnabledMark, EnabledMark.ENABLED.getCode())
+                            .eq(StudentReportPlan::getDeleteMark, DeleteMark.NODELETE.getCode())
+                            .eq(StudentReportPlan::getStatus, 1)
+                            .ne(StudentReportPlan::getSemesterId, reportPlan.getSemesterId())
+            );
+            if(!list.isEmpty()){
+                throw new MyException("已存在正在进行的计划,无法发布");
+            }
             if(reportPlan.getStudentReportPlanClassRelationList() == null || reportPlan.getStudentReportPlanClassRelationList().isEmpty()){
                 return RT.error("未选择班级,无法进行发布");
             }
@@ -146,7 +158,7 @@ public class StudentReportPlanController {
                 return RT.error("已发布,无法再次发布");
             }
 
-            studentReportPlanService.release(reportPlan);
+//            studentReportPlanService.release(reportPlan);
             reportPlan.setStatus(dto.getStatus());
             reportPlan.setModifyDate(new Date());
             reportPlan.setModifyUserId(StpUtil.getLoginIdAsLong());
@@ -199,6 +211,7 @@ public class StudentReportPlanController {
                         setId(e.getId());
                         setName(e.getName());
                         setParentId(e.getSemesterId());
+                        setStatus(e.getStatus());
                     }}
             );
         }));

+ 124 - 35
src/main/java/com/xjrsoft/module/student/controller/StudentReportRecordController.java

@@ -10,8 +10,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.xjrsoft.common.enums.DeleteMark;
-import com.xjrsoft.common.enums.EnabledMark;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
 import com.xjrsoft.common.enums.EnrollTypeEnum;
 import com.xjrsoft.common.enums.GenderDictionaryEnum;
 import com.xjrsoft.common.enums.RoleCodeEnum;
@@ -20,11 +19,13 @@ import com.xjrsoft.common.model.result.RT;
 import com.xjrsoft.common.page.ConventPage;
 import com.xjrsoft.common.page.PageOutput;
 import com.xjrsoft.common.utils.VoToColumnUtil;
+import com.xjrsoft.module.base.entity.BaseClass;
 import com.xjrsoft.module.base.entity.BaseGrade;
 import com.xjrsoft.module.base.entity.BaseSemester;
 import com.xjrsoft.module.base.service.IBaseClassService;
 import com.xjrsoft.module.base.service.IBaseGradeService;
 import com.xjrsoft.module.base.service.IBaseSemesterService;
+import com.xjrsoft.module.base.vo.BaseClassPageVo;
 import com.xjrsoft.module.databoard.vo.ItemCountVo;
 import com.xjrsoft.module.student.dto.AddStudentReportRecordDto;
 import com.xjrsoft.module.student.dto.StudentReportRecordPageDto;
@@ -32,10 +33,12 @@ import com.xjrsoft.module.student.dto.StudentReportRecordStatisticsDto;
 import com.xjrsoft.module.student.dto.StudentReportSignDto;
 import com.xjrsoft.module.student.dto.UpdateStudentReportRecordDto;
 import com.xjrsoft.module.student.entity.StudentReportPlan;
+import com.xjrsoft.module.student.entity.StudentReportPlanClassRelation;
 import com.xjrsoft.module.student.entity.StudentReportRecord;
 import com.xjrsoft.module.student.service.IStudentReportPlanService;
 import com.xjrsoft.module.student.service.IStudentReportRecordService;
-import com.xjrsoft.module.student.vo.BaseMajorCategorPageVo;
+import com.xjrsoft.module.student.vo.StudentReportRecordExcelVo;
+import com.xjrsoft.module.student.vo.StudentReportRecordItemVo;
 import com.xjrsoft.module.student.vo.StudentReportRecordPageVo;
 import com.xjrsoft.module.student.vo.StudentReportRecordPlanPageVo;
 import com.xjrsoft.module.student.vo.StudentReportRecordStatisticsListVo;
@@ -58,6 +61,7 @@ import javax.validation.Valid;
 import java.io.ByteArrayOutputStream;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.Date;
@@ -198,7 +202,7 @@ public class StudentReportRecordController {
     @SaCheckPermission("studentreportrecord:detail")
     public RT<StudentReportRecordStatisticsVo> classStatistics(@Valid StudentReportRecordStatisticsDto dto){
 
-        if(dto.getTeacherId() == null){
+        if(dto.getTeacherId() == null && dto.getClassId() == null){
             dto.setTeacherId(StpUtil.getLoginIdAsLong());
         }
         if(dto.getBaseSemesterId() == null){
@@ -211,7 +215,7 @@ public class StudentReportRecordController {
                 dto.setBaseSemesterId(semesterList.get(0).getId());
             }
         }
-        if(dto.getGradeId() == null){
+        if(dto.getGradeId() == null && dto.getClassId() == null){
             LambdaQueryWrapper<BaseGrade> queryWrapper = new LambdaQueryWrapper<>();
             queryWrapper
                     .orderByDesc(BaseGrade::getTitle)
@@ -222,7 +226,7 @@ public class StudentReportRecordController {
             }
         }
 
-        Long planId = planService.getEffectivePlanId(dto.getTeacherId());
+        Long planId = planService.getEffectivePlanId(dto.getTeacherId(), dto.getClassId());
         dto.setStudentReportPlanId(planId);
 
         StudentReportRecordStatisticsVo statisticsVo = studentReportRecordService.getClassStatistics(dto);
@@ -244,7 +248,7 @@ public class StudentReportRecordController {
     @ApiOperation(value="领导统计")
     @SaCheckPermission("studentreportrecord:detail")
     public RT<StudentReportRecordStatisticsVo> statistics(@Valid StudentReportRecordStatisticsDto dto){
-        if(dto.getGradeId() == null){
+        if(dto.getGradeId() == null && (dto.getCategory() == null || dto.getCategory() == 1)){
             LambdaQueryWrapper<BaseGrade> queryWrapper = new LambdaQueryWrapper<>();
             queryWrapper
                     .orderByDesc(BaseGrade::getTitle)
@@ -257,6 +261,9 @@ public class StudentReportRecordController {
         if(dto.getEnrollType() == null || dto.getEnrollType().isEmpty()){
             dto.setEnrollType(EnrollTypeEnum.AUTUMN_ENROLLMENT.getCode());
         }
+        if(dto.getCategory() != null && dto.getCategory() == 2 && dto.getBaseSemesterId() == null){
+            dto.setBaseSemesterId(semesterService.getLastSemester());
+        }
         List<StudentReportRecordStatisticsListVo> dataList = studentReportRecordService.getStatisticsDataList(dto);
         StudentReportRecordStatisticsVo statisticsVo = new StudentReportRecordStatisticsVo();
         statisticsVo.setAllCount(dataList.stream().count());
@@ -286,54 +293,81 @@ public class StudentReportRecordController {
                         && StudyStatusEnum.AttendDaySchool.getCode().equals(x.getStduyStatus())
                         && x.getReportTime() != null
         ).count());
-        Map<String, List<StudentReportRecordStatisticsListVo>> graduatedUniversityMap = dataList.stream().filter(x -> x.getReportTime() != null).collect(Collectors.groupingBy(StudentReportRecordStatisticsListVo::getGraduatedUniversity));
-        List<ItemCountVo> graduatedUniversityList = new ArrayList<>();
-        for (String graduatedUniversity : graduatedUniversityMap.keySet()) {
-            graduatedUniversityList.add(
-                    new ItemCountVo(){{
-                        setItem(graduatedUniversity);
-                        setCount(graduatedUniversityMap.get(graduatedUniversity).size());
-                    }}
-            );
+
+        if(dto.getCategory() != null && dto.getCategory() == 1){
+            Map<String, List<StudentReportRecordStatisticsListVo>> graduatedUniversityMap = dataList.stream().filter(x -> x.getReportTime() != null).collect(Collectors.groupingBy(StudentReportRecordStatisticsListVo::getGraduatedUniversity));
+            List<ItemCountVo> graduatedUniversityList = new ArrayList<>();
+            for (String graduatedUniversity : graduatedUniversityMap.keySet()) {
+                graduatedUniversityList.add(
+                        new ItemCountVo(){{
+                            setItem(graduatedUniversity);
+                            setCount(graduatedUniversityMap.get(graduatedUniversity).size());
+                        }}
+                );
+            }
+            statisticsVo.setGraduatedUniversityList(graduatedUniversityList);
         }
-        statisticsVo.setGraduatedUniversityList(graduatedUniversityList);
 
         Map<String, List<StudentReportRecordStatisticsListVo>> classMap = dataList.stream().filter(x -> x.getReportTime() != null).collect(Collectors.groupingBy(StudentReportRecordStatisticsListVo::getClassName));
-        List<ItemCountVo> classList = new ArrayList<>();
+        Map<String, List<StudentReportRecordStatisticsListVo>> classNotMap = dataList.stream().filter(x -> x.getReportTime() == null).collect(Collectors.groupingBy(StudentReportRecordStatisticsListVo::getClassName));
+        List<StudentReportRecordItemVo> classList = new ArrayList<>();
         for (String className : classMap.keySet()) {
             classList.add(
-                    new ItemCountVo(){{
+                    new StudentReportRecordItemVo(){{
                         setItem(className);
                         setCount(classMap.get(className).size());
+                        if(classNotMap.get(className) != null && !(classNotMap.get(className).isEmpty())){
+                            setCount2(classNotMap.get(className).size());
+                        }
                     }}
             );
         }
         statisticsVo.setClassList(classList);
 
         Map<String, List<StudentReportRecordStatisticsListVo>> classTypeMap = dataList.stream().filter(x -> x.getReportTime() != null).collect(Collectors.groupingBy(StudentReportRecordStatisticsListVo::getClassType));
-        List<ItemCountVo> classTypeList = new ArrayList<>();
+        Map<String, List<StudentReportRecordStatisticsListVo>> classTypeNotMap = dataList.stream().filter(x -> x.getReportTime() == null).collect(Collectors.groupingBy(StudentReportRecordStatisticsListVo::getClassType));
+        List<StudentReportRecordItemVo> classTypeList = new ArrayList<>();
         for (String classType : classTypeMap.keySet()) {
             classTypeList.add(
-                    new ItemCountVo(){{
+                    new StudentReportRecordItemVo(){{
                         setItem(classType);
                         setCount(classTypeMap.get(classType).size());
+                        if(classTypeNotMap.get(classType) != null && !(classTypeNotMap.get(classType).isEmpty())){
+                            setCount2(classTypeNotMap.get(classType).size());
+                        }
                     }}
             );
         }
         statisticsVo.setClassTypeList(classTypeList);
 
         Map<String, List<StudentReportRecordStatisticsListVo>> majorMap = dataList.stream().filter(x -> x.getReportTime() != null && x.getMajorName() != null).collect(Collectors.groupingBy(StudentReportRecordStatisticsListVo::getMajorName));
-        List<ItemCountVo> majorList = new ArrayList<>();
+        Map<String, List<StudentReportRecordStatisticsListVo>> majorNotMap = dataList.stream().filter(x -> x.getReportTime() == null && x.getMajorName() != null).collect(Collectors.groupingBy(StudentReportRecordStatisticsListVo::getMajorName));
+        List<StudentReportRecordItemVo> majorList = new ArrayList<>();
         for (String majorName : majorMap.keySet()) {
             majorList.add(
-                    new ItemCountVo(){{
+                    new StudentReportRecordItemVo(){{
                         setItem(majorName);
                         setCount(majorMap.get(majorName).size());
+                        if(majorNotMap.get(majorName) != null && !(majorNotMap.get(majorName).isEmpty())){
+                            setCount2(majorNotMap.get(majorName).size());
+                        }
                     }}
             );
         }
         statisticsVo.setMajorList(majorList);
 
+        Map<String, List<StudentReportRecordStatisticsListVo>> deptMap = dataList.stream().filter(x -> x.getReportTime() != null && x.getDeptName() != null).collect(Collectors.groupingBy(StudentReportRecordStatisticsListVo::getDeptName));
+        List<ItemCountVo> deptList = new ArrayList<>();
+        for (String deptName : deptMap.keySet()) {
+            deptList.add(
+                    new ItemCountVo(){{
+                        setItem(deptName);
+                        setCount(deptMap.get(deptName).size());
+                    }}
+            );
+        }
+        statisticsVo.setDeptList(deptList);
+
         BigDecimal divide = BigDecimal.ZERO;
         if( statisticsVo.getAllCount() != 0){
             divide = BigDecimal.valueOf(statisticsVo.getArrivedCount()).divide(BigDecimal.valueOf(statisticsVo.getAllCount()), 4, RoundingMode.HALF_UP);
@@ -348,20 +382,43 @@ public class StudentReportRecordController {
     @SaCheckPermission("studentreportrecord:detail")
     public RT<PageOutput<StudentReportRecordPlanPageVo>> planPage(@Valid StudentReportRecordPageDto dto){
         List<String> roleList = StpUtil.getRoleList();
-        if(roleList.size() == 2 && roleList.contains(RoleCodeEnum.TEACHER.getCode()) && roleList.contains(RoleCodeEnum.CLASSTE.getCode())){
+        if(roleList.contains(RoleCodeEnum.TEACHER.getCode()) && roleList.contains(RoleCodeEnum.CLASSTE.getCode())){
             Long classId = classService.getIdByTeacherId(StpUtil.getLoginIdAsLong());
-            if(ObjectUtil.isNull(classId)){
+            if(ObjectUtil.isNull(classId) && dto.getClassId() == null){
                 return RT.ok(new PageOutput<>());
             }
-            dto.setClassId(classId);
-            Long planId = planService.getEffectivePlanId(dto.getTeacherId());
-            dto.setStudentReportPlanId(planId);
+            if(dto.getClassId() == null){
+                dto.setClassId(classId);
+            }
+            if(dto.getStudentReportPlanId() == null){
+                Long planId = planService.getEffectivePlanId(dto.getTeacherId(), dto.getClassId());
+                dto.setStudentReportPlanId(planId);
+            }
         }
         Page<StudentReportRecordPlanPageVo> planPage = studentReportRecordService.getPlanPage(new Page<>(dto.getLimit(), dto.getSize()), dto);
         PageOutput<StudentReportRecordPlanPageVo> pageOutput = ConventPage.getPageOutput(planPage, StudentReportRecordPlanPageVo.class);
         return RT.ok(pageOutput);
     }
 
+    @GetMapping(value = "/class-list")
+    @ApiOperation(value="班主任负责班级")
+    @SaCheckPermission("studentreportrecord:detail")
+    public RT<List<BaseClassPageVo>> classList(@Valid StudentReportRecordPageDto dto){
+
+        long teacherId = StpUtil.getLoginIdAsLong();
+        Long planId = planService.getEffectivePlanId(teacherId, null);
+        List<BaseClassPageVo> list = classService.selectJoinList(BaseClassPageVo.class,
+                new MPJLambdaWrapper<BaseClass>()
+                        .select(BaseClass::getId)
+                        .selectAs(BaseClass::getName, BaseClassPageVo::getName)
+                        .innerJoin(StudentReportPlanClassRelation.class, StudentReportPlanClassRelation::getClassId, BaseClass::getId)
+                        .innerJoin(StudentReportPlan.class, StudentReportPlan::getId, StudentReportPlanClassRelation::getStudentReportPlanId)
+                        .eq(StudentReportPlan::getId, planId)
+                        .eq(BaseClass::getTeacherId, teacherId)
+        );
+        return RT.ok(list);
+    }
+
     @PostMapping(value = "/sign")
     @ApiOperation(value="学生报到")
     @SaCheckPermission("studentreportrecord:detail")
@@ -369,12 +426,14 @@ public class StudentReportRecordController {
         StudentReportRecord record = studentReportRecordService.getById(dto.getId());
         StudentReportPlan reportPlan = studentReportPlanService.getById(record.getStudentReportPlanId());
         LocalDateTime now = LocalDateTime.now();
-        if(reportPlan.getStatus() != 1 || (now.isAfter(reportPlan.getStartTime()) && now.isBefore(reportPlan.getEndTime()))){
+        if(reportPlan.getStatus() != 1 || !(now.isAfter(reportPlan.getStartTime()) && now.isBefore(reportPlan.getEndTime()))){
             return RT.error("不在报到时间内,无法报到");
         }
         return RT.ok(studentReportRecordService.sgin(dto));
     }
 
+
+
     @PostMapping(value = "/all-sign")
     @ApiOperation(value="变更已报到")
     @SaCheckPermission("studentreportrecord:detail")
@@ -382,8 +441,8 @@ public class StudentReportRecordController {
         StudentReportRecord record = studentReportRecordService.getById(dtoList.get(0).getId());
         StudentReportPlan reportPlan = studentReportPlanService.getById(record.getStudentReportPlanId());
         LocalDateTime now = LocalDateTime.now();
-        if(reportPlan.getStatus() != 1 || (now.isAfter(reportPlan.getStartTime()) && now.isBefore(reportPlan.getEndTime()))){
-            return RT.error("不在报到时间内,无法报到");
+        if(reportPlan.getStatus() == 0 || now.isBefore(reportPlan.getStartTime()) ){
+            return RT.error("暂未开始,无法报到");
         }
         return RT.ok(studentReportRecordService.allSgin(dtoList));
     }
@@ -392,17 +451,47 @@ public class StudentReportRecordController {
     @PostMapping(value = "/update-stduyStatus")
     @ApiOperation(value="切换就读方式")
     @SaCheckPermission("studentreportrecord:detail")
-    public RT<Boolean> updateStduyStatus(@Valid StudentReportSignDto dto){
+    public RT<Boolean> updateStduyStatus(@Valid @RequestBody StudentReportSignDto dto){
         return RT.ok(studentReportRecordService.updateStduyStatus(dto));
     }
 
-    @PostMapping(value = "/export-querty")
+    @PostMapping(value = "/export-query")
     @ApiOperation(value="导出")
     @SaCheckPermission("studentreportrecord:detail")
-    public ResponseEntity<byte[]> exportQuerty(@Valid StudentReportRecordPageDto dto){
+    public ResponseEntity<byte[]> exportQuerty(@Valid @RequestBody StudentReportRecordPageDto dto){
+        List<StudentReportRecordExcelVo> dataList = new ArrayList<>();
+
+        List<String> roleList = StpUtil.getRoleList();
+        if(roleList.contains(RoleCodeEnum.TEACHER.getCode()) && roleList.contains(RoleCodeEnum.CLASSTE.getCode())){
+            Long classId = classService.getIdByTeacherId(StpUtil.getLoginIdAsLong());
+            if(ObjectUtil.isNull(classId) && dto.getClassId() == null){
+                ByteArrayOutputStream bot = new ByteArrayOutputStream();
+                EasyExcel.write(bot, StudentReportRecordExcelVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(dataList);
+                String fileName = "exportQuerty" + ExcelTypeEnum.XLSX.getValue();
+                return RT.fileStream(bot.toByteArray(), fileName);
+            }
+            if(dto.getClassId() == null){
+                dto.setClassId(classId);
+            }
+        }
         List<StudentReportRecordPlanPageVo> planPageList = studentReportRecordService.getPlanPageList(dto);
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        for (StudentReportRecordPlanPageVo pageVo : planPageList) {
+            StudentReportRecordExcelVo excelVo = BeanUtil.toBean(pageVo, StudentReportRecordExcelVo.class);
+            if(pageVo.getReportTime() != null){
+                excelVo.setReportTime(sdf.format(pageVo.getReportTime()));
+            }
+            excelVo.setIsReport("否");
+            if(pageVo.getIsReport() != null && pageVo.getIsReport() == 1){
+                excelVo.setIsReport("是");
+            }
+
+            dataList.add(excelVo);
+        }
         ByteArrayOutputStream bot = new ByteArrayOutputStream();
-        EasyExcel.write(bot, StudentReportRecordPlanPageVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(planPageList);
+        EasyExcel.write(bot, StudentReportRecordExcelVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(dataList);
         String fileName = "exportQuerty" + ExcelTypeEnum.XLSX.getValue();
         return RT.fileStream(bot.toByteArray(), fileName);
     }

+ 3 - 0
src/main/java/com/xjrsoft/module/student/dto/StudentReportRecordStatisticsDto.java

@@ -34,4 +34,7 @@ public class StudentReportRecordStatisticsDto extends PageInput {
     @JsonIgnore
     @ApiModelProperty("报到计划id")
     private Long studentReportPlanId;
+
+    @ApiModelProperty("统计类别(1:新生报到 2:开学报告 3:试读报到)")
+    private Integer category;
 }

+ 3 - 2
src/main/java/com/xjrsoft/module/student/entity/StudentReportPlan.java

@@ -11,6 +11,7 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.Date;
 import java.util.List;
@@ -96,12 +97,12 @@ public class StudentReportPlan implements Serializable {
     * 数据修改开始时间
     */
     @ApiModelProperty("数据修改开始时间")
-    private Date updateStartTime;
+    private LocalDate updateStartTime;
     /**
     * 数据修改结束时间
     */
     @ApiModelProperty("数据修改结束时间")
-    private Date updateEndTime;
+    private LocalDate updateEndTime;
     /**
     * 状态(0:草稿 1:进行中 2:已结束)
     */

+ 3 - 1
src/main/java/com/xjrsoft/module/student/mapper/StudentReportPlanMapper.java

@@ -23,5 +23,7 @@ public interface StudentReportPlanMapper extends MPJBaseMapper<StudentReportPlan
     Page<StudentReportPlanPageVo> getPage(Page<StudentReportPlanPageVo> page, @Param("dto") StudentReportPlanPageDto dto);
 
 
-    List<BaseClass> validateClass(@Param("id") Long id, @Param("classIds") List<Long> classIds);
+    List<BaseClass> validateClass(@Param("id") Long id, @Param("semesterId") Long semesterId, @Param("classIds") List<Long> classIds);
+
+    List<StudentReportPlan> getWillBeginData();
 }

+ 3 - 0
src/main/java/com/xjrsoft/module/student/mapper/StudentReportRecordMapper.java

@@ -33,4 +33,7 @@ public interface StudentReportRecordMapper extends MPJBaseMapper<StudentReportRe
 
     List<StudentReportRecordPlanPageVo> getPlanPageList(@Param("dto") StudentReportRecordPageDto dto);
 
+
+    List<StudentReportRecordStatisticsListVo> getStatisticsPlanDataList(@Param("dto") StudentReportRecordStatisticsDto dto);
+
 }

+ 7 - 1
src/main/java/com/xjrsoft/module/student/service/IStudentReportPlanService.java

@@ -5,6 +5,7 @@ import com.github.yulichang.base.MPJBaseService;
 import com.xjrsoft.module.base.entity.BaseClass;
 import com.xjrsoft.module.student.dto.StudentReportPlanPageDto;
 import com.xjrsoft.module.student.entity.StudentReportPlan;
+import com.xjrsoft.module.student.entity.StudentReportPlanClassRelation;
 import com.xjrsoft.module.student.vo.StudentReportPlanPageVo;
 
 import java.util.List;
@@ -47,5 +48,10 @@ public interface IStudentReportPlanService extends MPJBaseService<StudentReportP
 
     Boolean release(StudentReportPlan studentReportPlan);
 
-    Long getEffectivePlanId(Long teacherId);
+    Long getEffectivePlanId(Long teacherId, Long classId);
+
+
+    List<StudentReportPlan> getWillBeginData();
+
+    List<StudentReportPlanClassRelation> getStudentReportPlanClassRelationList(Long id);
 }

+ 70 - 44
src/main/java/com/xjrsoft/module/student/service/impl/StudentReportPlanServiceImpl.java

@@ -8,6 +8,7 @@ import com.github.yulichang.base.MPJBaseServiceImpl;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
 import com.xjrsoft.common.enums.DeleteMark;
 import com.xjrsoft.common.enums.EnabledMark;
+import com.xjrsoft.common.exception.MyException;
 import com.xjrsoft.module.base.entity.BaseClass;
 import com.xjrsoft.module.organization.entity.User;
 import com.xjrsoft.module.organization.service.IUserService;
@@ -25,6 +26,7 @@ import com.xjrsoft.module.student.service.IStudentReportRecordService;
 import com.xjrsoft.module.student.vo.BaseStudentUserPageVo;
 import com.xjrsoft.module.student.vo.StudentReportPlanPageVo;
 import lombok.AllArgsConstructor;
+import me.zhyd.oauth.log.Log;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -123,7 +125,8 @@ public class StudentReportPlanServiceImpl extends MPJBaseServiceImpl<StudentRepo
 
     @Override
     public List<BaseClass> validateClass(Long id, List<Long> classIds) {
-        return this.baseMapper.validateClass(id, classIds);
+        StudentReportPlan plan = this.getById(id);
+        return this.baseMapper.validateClass(id, plan.getSemesterId(), classIds);
     }
 
     /**
@@ -135,54 +138,61 @@ public class StudentReportPlanServiceImpl extends MPJBaseServiceImpl<StudentRepo
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Boolean release(StudentReportPlan studentReportPlan) {
-        List<Long> classIds = studentReportPlan.getStudentReportPlanClassRelationList().stream().map(StudentReportPlanClassRelation::getClassId).collect(Collectors.toList());
-        //1、查询选择的学生
-        List<BaseStudentUserPageVo> studentList = studentService.getStudentList(new BaseStudentUserPageDto() {{
-            setClassIds(classIds);
-        }});
-
-        Date createDate = new Date();
-        List<StudentReportRecord> insertList = new ArrayList<>();
-        for (BaseStudentUserPageVo student : studentList) {
-            insertList.add(
-                    new StudentReportRecord(){{
-                        setCreateDate(createDate);
-                        setCreateUserId(StpUtil.getLoginIdAsLong());
-                        setUserId(Long.parseLong(student.getId()));
-                        setBaseSemesterId(studentReportPlan.getSemesterId());
-                        setStudentReportPlanId(studentReportPlan.getId());
-                    }}
-            );
-        }
+        try {
+            List<Long> classIds = studentReportPlan.getStudentReportPlanClassRelationList().stream().map(StudentReportPlanClassRelation::getClassId).collect(Collectors.toList());
+            //1、查询选择的学生
+            List<BaseStudentUserPageVo> studentList = studentService.getStudentList(new BaseStudentUserPageDto() {{
+                setClassIds(classIds);
+            }});
+            if(studentList.isEmpty()){
+                return true;
+            }
 
-        if(!insertList.isEmpty()){
-            reportRecordService.remove(
-                    new QueryWrapper<StudentReportRecord>().lambda()
-                            .eq(StudentReportRecord::getStudentReportPlanId, studentReportPlan.getId())
-            );
-
-            reportRecordService.saveBatch(insertList);
-            Set<String> studentUserIds = studentList.stream().map(BaseStudentUserPageVo::getId).collect(Collectors.toSet());
-            //发布后,将学生的状态改为不正常
-            List<BaseStudent> baseStudents = studentService.list(
-                    new QueryWrapper<BaseStudent>().lambda()
-                            .in(BaseStudent::getUserId, studentUserIds)
-            );
-
-            for (BaseStudent baseStudent : baseStudents) {
-                baseStudent.setIsNormal(0);
+            Date createDate = new Date();
+            List<StudentReportRecord> insertList = new ArrayList<>();
+            for (BaseStudentUserPageVo student : studentList) {
+                insertList.add(
+                        new StudentReportRecord(){{
+                            setCreateDate(createDate);
+                            setCreateUserId(studentReportPlan.getCreateUserId());
+                            setUserId(Long.parseLong(student.getId()));
+                            setBaseSemesterId(studentReportPlan.getSemesterId());
+                            setStudentReportPlanId(studentReportPlan.getId());
+                        }}
+                );
             }
 
-            studentService.updateBatchById(baseStudents);
+            if(!insertList.isEmpty()){
+                reportRecordService.remove(
+                        new QueryWrapper<StudentReportRecord>().lambda()
+                                .eq(StudentReportRecord::getStudentReportPlanId, studentReportPlan.getId())
+                );
+
+                reportRecordService.saveBatch(insertList);
+                Set<String> studentUserIds = studentList.stream().map(BaseStudentUserPageVo::getId).collect(Collectors.toSet());
+                //发布后,将学生的状态改为不正常
+                List<BaseStudent> baseStudents = studentService.list(
+                        new QueryWrapper<BaseStudent>().lambda()
+                                .in(BaseStudent::getUserId, studentUserIds)
+                );
+
+                for (BaseStudent baseStudent : baseStudents) {
+                    baseStudent.setIsNormal(0);
+                }
 
-            //修改用户的状态
-            List<User> userList = userService.listByIds(studentUserIds);
+                studentService.updateBatchById(baseStudents);
 
-            for (User user : userList) {
-                user.setEnabledMark(EnabledMark.DISABLED.getCode());
-            }
+                //修改用户的状态
+                List<User> userList = userService.listByIds(studentUserIds);
 
-            userService.updateBatchById(userList);
+                for (User user : userList) {
+                    user.setEnabledMark(EnabledMark.DISABLED.getCode());
+                }
+
+                userService.updateBatchById(userList);
+            }
+        }catch (Exception e){
+            Log.error(e.getMessage(), e);
         }
         return true;
     }
@@ -193,14 +203,17 @@ public class StudentReportPlanServiceImpl extends MPJBaseServiceImpl<StudentRepo
      * @return 计划id
      */
     @Override
-    public Long getEffectivePlanId(Long teacherId) {
+    public Long getEffectivePlanId(Long teacherId, Long classId) {
         LocalDateTime now = LocalDateTime.now();
         List<StudentReportPlan> list = this.selectJoinList(StudentReportPlan.class,
                 new MPJLambdaWrapper<StudentReportPlan>()
                         .leftJoin(StudentReportPlanClassRelation.class, StudentReportPlanClassRelation::getStudentReportPlanId, StudentReportPlan::getId)
                         .leftJoin(BaseClass.class, BaseClass::getId, StudentReportPlanClassRelation::getClassId)
                         .eq(teacherId != null, BaseClass::getTeacherId, teacherId)
+                        .eq(classId != null, BaseClass::getId, classId)
                         .eq(StudentReportPlan::getEnabledMark, EnabledMark.ENABLED.getCode())
+                        .eq(StudentReportPlan::getDeleteMark, DeleteMark.NODELETE.getCode())
+                        .eq(StudentReportPlan::getStatus, 1)
                         .le(StudentReportPlan::getStartTime, now)
                         .ge(StudentReportPlan::getEndTime, now)
                         .orderByDesc(StudentReportPlan::getId)
@@ -210,4 +223,17 @@ public class StudentReportPlanServiceImpl extends MPJBaseServiceImpl<StudentRepo
         }
         return null;
     }
+
+    @Override
+    public List<StudentReportPlan> getWillBeginData() {
+        return baseMapper.getWillBeginData();
+    }
+
+    @Override
+    public List<StudentReportPlanClassRelation> getStudentReportPlanClassRelationList(Long id) {
+        return relationMapper.selectList(
+                new QueryWrapper<StudentReportPlanClassRelation>().lambda()
+                        .eq(StudentReportPlanClassRelation::getStudentReportPlanId, id)
+        );
+    }
 }

+ 63 - 16
src/main/java/com/xjrsoft/module/student/service/impl/StudentReportRecordServiceImpl.java

@@ -2,12 +2,15 @@ package com.xjrsoft.module.student.service.impl;
 
 import cn.dev33.satoken.stp.StpUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.github.yulichang.base.MPJBaseServiceImpl;
 import com.xjrsoft.common.enums.DeleteMark;
 import com.xjrsoft.common.enums.EnabledMark;
 import com.xjrsoft.common.enums.StudentChangeTypeEnum;
 import com.xjrsoft.common.enums.StudyStatusEnum;
+import com.xjrsoft.common.exception.MyException;
+import com.xjrsoft.common.utils.LocalDateUtil;
 import com.xjrsoft.module.organization.entity.User;
 import com.xjrsoft.module.organization.service.IUserService;
 import com.xjrsoft.module.student.dto.StudentReportRecordPageDto;
@@ -15,11 +18,14 @@ import com.xjrsoft.module.student.dto.StudentReportRecordStatisticsDto;
 import com.xjrsoft.module.student.dto.StudentReportSignDto;
 import com.xjrsoft.module.student.entity.BaseStudent;
 import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll;
+import com.xjrsoft.module.student.entity.StudentReportPlan;
 import com.xjrsoft.module.student.entity.StudentReportRecord;
+import com.xjrsoft.module.student.mapper.StudentReportPlanMapper;
 import com.xjrsoft.module.student.mapper.StudentReportRecordMapper;
 import com.xjrsoft.module.student.service.IBaseStudentSchoolRollService;
 import com.xjrsoft.module.student.service.IBaseStudentService;
 import com.xjrsoft.module.student.service.IStudentChangeRecordService;
+import com.xjrsoft.module.student.service.IStudentReportPlanService;
 import com.xjrsoft.module.student.service.IStudentReportRecordService;
 import com.xjrsoft.module.student.vo.StudentReportRecordPageVo;
 import com.xjrsoft.module.student.vo.StudentReportRecordPlanPageVo;
@@ -29,6 +35,7 @@ import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.time.LocalDate;
 import java.util.Date;
 import java.util.List;
 
@@ -46,6 +53,7 @@ public class StudentReportRecordServiceImpl extends MPJBaseServiceImpl<StudentRe
     private final IUserService userService;
     private final IBaseStudentSchoolRollService rollService;
     private final IStudentChangeRecordService changeRecordService;
+    private final StudentReportPlanMapper planMapper;
     @Override
     public StudentReportRecordStatisticsVo getClassStatistics(StudentReportRecordStatisticsDto dto) {
         return this.baseMapper.getClassStatistics(dto);
@@ -53,7 +61,17 @@ public class StudentReportRecordServiceImpl extends MPJBaseServiceImpl<StudentRe
 
     @Override
     public List<StudentReportRecordStatisticsListVo> getStatisticsDataList(StudentReportRecordStatisticsDto dto) {
-        return this.baseMapper.getStatisticsDataList(dto);
+        List<StudentReportRecordStatisticsListVo> resultList;
+        if(dto.getCategory() != null && dto.getCategory() == 1){
+            resultList = this.baseMapper.getStatisticsDataList(dto);
+        }else if(dto.getCategory() != null && dto.getCategory() == 2){
+            resultList = this.baseMapper.getStatisticsPlanDataList(dto);
+        }else if(dto.getCategory() != null && dto.getCategory() == 3){
+            resultList = this.baseMapper.getStatisticsDataList(dto);
+        }else{
+            resultList = this.baseMapper.getStatisticsDataList(dto);
+        }
+        return resultList;
     }
 
     @Override
@@ -79,21 +97,43 @@ public class StudentReportRecordServiceImpl extends MPJBaseServiceImpl<StudentRe
     public Boolean sgin(StudentReportSignDto dto) {
         StudentReportRecord record = this.getById(dto.getId());
         record.setModifyDate(new Date());
-        record.setUserId(StpUtil.getLoginIdAsLong());
-        record.setReportTime(new Date());
-        this.updateById(record);
-
-        BaseStudent student = studentService.getOne(
-                new QueryWrapper<BaseStudent>().lambda()
-                        .eq(BaseStudent::getUserId, record.getUserId())
-                        .eq(BaseStudent::getDeleteMark, DeleteMark.NODELETE.getCode())
-        );
-        student.setIsNormal(1);
-        studentService.updateById(student);
+        record.setModifyUserId(StpUtil.getLoginIdAsLong());
+        if(record.getReportTime() != null){
+            UpdateWrapper<StudentReportRecord> updateWrapper = new UpdateWrapper<>();
+            updateWrapper.eq("id", dto.getId());
+            updateWrapper.setSql("report_time = null");
+            this.update(record, updateWrapper);
+
+            BaseStudent student = studentService.getOne(
+                    new QueryWrapper<BaseStudent>().lambda()
+                            .eq(BaseStudent::getUserId, record.getUserId())
+                            .eq(BaseStudent::getDeleteMark, DeleteMark.NODELETE.getCode())
+            );
+            student.setIsNormal(0);
+            studentService.updateById(student);
+
+            User user = userService.getById(record.getUserId());
+            user.setEnabledMark(EnabledMark.DISABLED.getCode());
+            userService.updateById(user);
+
+
+        }else{
+            record.setReportTime(new Date());
+            this.updateById(record);
+
+            BaseStudent student = studentService.getOne(
+                    new QueryWrapper<BaseStudent>().lambda()
+                            .eq(BaseStudent::getUserId, record.getUserId())
+                            .eq(BaseStudent::getDeleteMark, DeleteMark.NODELETE.getCode())
+            );
+            student.setIsNormal(1);
+            studentService.updateById(student);
+
+            User user = userService.getById(record.getUserId());
+            user.setEnabledMark(EnabledMark.ENABLED.getCode());
+            userService.updateById(user);
+        }
 
-        User user = userService.getById(record.getUserId());
-        user.setEnabledMark(EnabledMark.ENABLED.getCode());
-        userService.updateById(user);
         return true;
     }
 
@@ -113,7 +153,7 @@ public class StudentReportRecordServiceImpl extends MPJBaseServiceImpl<StudentRe
         for (StudentReportSignDto dto : dtoList) {
             StudentReportRecord record = this.getById(dto.getId());
             record.setModifyDate(new Date());
-            record.setUserId(StpUtil.getLoginIdAsLong());
+            record.setModifyUserId(StpUtil.getLoginIdAsLong());
             record.setReportTime(new Date());
             this.updateById(record);
 
@@ -135,7 +175,14 @@ public class StudentReportRecordServiceImpl extends MPJBaseServiceImpl<StudentRe
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Boolean updateStduyStatus(StudentReportSignDto dto) {
+        LocalDate now = LocalDate.now();
         StudentReportRecord record = this.getById(dto.getId());
+        StudentReportPlan reportPlan = planMapper.selectById(record.getStudentReportPlanId());
+        if(!LocalDateUtil.isDateInRange(now, reportPlan.getUpdateStartTime(), reportPlan.getUpdateEndTime())){
+            throw new MyException("不在修改时间内,无法修改");
+        }
+
+
         BaseStudentSchoolRoll roll = rollService.getOne(
                 new QueryWrapper<BaseStudentSchoolRoll>().lambda()
                         .eq(BaseStudentSchoolRoll::getUserId, record.getUserId())

+ 73 - 0
src/main/java/com/xjrsoft/module/student/vo/StudentReportRecordExcelVo.java

@@ -0,0 +1,73 @@
+package com.xjrsoft.module.student.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+* @title: 学生报到记录表导出出参
+* @Author dzx
+* @Date: 2024-08-28
+* @Version 1.0
+*/
+@Data
+public class StudentReportRecordExcelVo {
+
+
+    @ExcelProperty("年级")
+    @ApiModelProperty("年级")
+    private String gradeName;
+
+
+    @ExcelProperty("班级")
+    @ApiModelProperty("班级")
+    private String className;
+
+    @ExcelProperty("班主任")
+    @ApiModelProperty("班主任")
+    private String teacherName;
+
+    @ExcelProperty("学生姓名")
+    @ApiModelProperty("学生姓名")
+    private String name;
+
+    @ExcelProperty("性别")
+    @ApiModelProperty("性别")
+    private String gender;
+
+    @ExcelProperty("身份证号")
+    @ApiModelProperty("身份证号")
+    private String credentialNumber;
+
+    @ExcelProperty("手机号")
+    @ApiModelProperty("手机号")
+    private String mobile;
+
+    @ExcelProperty("学生来源")
+    @ApiModelProperty("学生来源")
+    private String studentTypeCn;
+
+    @ExcelProperty("就读方式")
+    @ApiModelProperty("就读方式")
+    private String stduyStatusCn;
+
+    @ExcelProperty("学籍状态")
+    @ApiModelProperty("学籍状态")
+    private String archivesStatusCn;
+
+    @ExcelProperty("报到时间")
+    @ApiModelProperty("报到时间")
+    private String reportTime;
+
+    @ExcelProperty("报到状态")
+    @ApiModelProperty("是否已报到(1:是 0:否)")
+    private String isReport;
+
+    @ExcelProperty("家长电话")
+    @ApiModelProperty("家长电话")
+    private String parentMobile;
+
+}

+ 30 - 0
src/main/java/com/xjrsoft/module/student/vo/StudentReportRecordItemVo.java

@@ -0,0 +1,30 @@
+package com.xjrsoft.module.student.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+* @title: 学生报到记录表表单出参
+* @Author dzx
+* @Date: 2024-08-28
+* @Version 1.0
+*/
+@Data
+public class StudentReportRecordItemVo {
+
+    @ApiModelProperty("统计项")
+    private String item;
+    /**
+     * 完成总数
+     */
+    @ApiModelProperty("数量")
+    private Integer count;
+
+    @ApiModelProperty("数量")
+    private Integer count2;
+
+
+
+}

+ 3 - 0
src/main/java/com/xjrsoft/module/student/vo/StudentReportRecordPlanPageVo.java

@@ -74,4 +74,7 @@ public class StudentReportRecordPlanPageVo {
     @ApiModelProperty("报到时间")
     private Date reportTime;
 
+    @ApiModelProperty("家长电话")
+    private String parentMobile;
+
 }

+ 3 - 0
src/main/java/com/xjrsoft/module/student/vo/StudentReportRecordStatisticsListVo.java

@@ -43,4 +43,7 @@ public class StudentReportRecordStatisticsListVo {
     @ApiModelProperty("专业方向")
     private String majorName;
 
+    @ApiModelProperty("专业部名称")
+    private String deptName;
+
 }

+ 6 - 3
src/main/java/com/xjrsoft/module/student/vo/StudentReportRecordStatisticsVo.java

@@ -65,12 +65,15 @@ public class StudentReportRecordStatisticsVo {
     private Long notStayFemaleCount;
 
     @ApiModelProperty("班级报到情况")
-    private List<ItemCountVo> classList;
+    private List<StudentReportRecordItemVo> classList;
 
     @ApiModelProperty("班级类型报到情况")
-    private List<ItemCountVo> classTypeList;
+    private List<StudentReportRecordItemVo> classTypeList;
 
     @ApiModelProperty("专业报到情况")
-    private List<ItemCountVo> majorList;
+    private List<StudentReportRecordItemVo> majorList;
+
+    @ApiModelProperty("专业部报到情况")
+    private List<ItemCountVo> deptList;
 
 }

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

@@ -184,7 +184,7 @@ public class TextbookSubscriptionController {
     }
 
     @PostMapping(value = "/instockroom")
-    @ApiOperation(value="手动填写入库")
+    @ApiOperation(value="征订页面手动填写入库")
     @SaCheckPermission("textbooksubscription:detail")
     public RT<Boolean> instockroom(@Valid @RequestBody  List<TextbookInstockroomDto> dtos){
         return RT.ok(textbookSubscriptionService.instockroom(dtos));

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

@@ -4,6 +4,7 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.hutool.core.bean.BeanUtil;
 import com.alibaba.excel.EasyExcel;
 import com.alibaba.excel.support.ExcelTypeEnum;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.xjrsoft.common.model.result.RT;
 import com.xjrsoft.common.page.ConventPage;
@@ -46,14 +47,13 @@ import java.util.List;
 @AllArgsConstructor
 public class TextbookWarehouseRecordController {
 
-
     private final ITextbookWarehouseRecordService textbookClassWarehouseService;
 
     @GetMapping(value = "/page")
     @ApiOperation(value="教材入库列表(分页)")
     @SaCheckPermission("textbookclasswarehouse:detail")
     public RT<PageOutput<TextbookWarehouseRecordPageVo>> page(@Valid TextbookWarehouseRecordPageDto dto){
-        Page<TextbookWarehouseRecordPageVo> page = textbookClassWarehouseService.getPage(dto);
+        IPage<TextbookWarehouseRecordPageVo> page = textbookClassWarehouseService.getPage(dto);
         PageOutput<TextbookWarehouseRecordPageVo> pageOutput = ConventPage.getPageOutput(page, TextbookWarehouseRecordPageVo.class);
         return RT.ok(pageOutput);
     }

+ 125 - 0
src/main/java/com/xjrsoft/module/textbook/controller/TextbookWarehouseRecordDetailController.java

@@ -0,0 +1,125 @@
+package com.xjrsoft.module.textbook.controller;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.xjrsoft.common.constant.GlobalConstant;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.xjrsoft.common.page.ConventPage;
+import com.xjrsoft.common.page.PageOutput;
+import com.xjrsoft.common.model.result.RT;
+import com.xjrsoft.common.utils.VoToColumnUtil;
+import com.xjrsoft.module.textbook.dto.AddTextbookWarehouseRecordDetailDto;
+import com.xjrsoft.module.textbook.dto.UpdateTextbookWarehouseRecordDetailDto;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.alibaba.excel.EasyExcel;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.IOException;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import org.springframework.http.ResponseEntity;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+
+import com.xjrsoft.module.textbook.dto.TextbookWarehouseRecordDetailPageDto;
+import com.xjrsoft.module.textbook.entity.TextbookWarehouseRecordDetail;
+import com.xjrsoft.module.textbook.service.ITextbookWarehouseRecordDetailService;
+import com.xjrsoft.module.textbook.vo.TextbookWarehouseRecordDetailPageVo;
+
+import com.xjrsoft.module.textbook.vo.TextbookWarehouseRecordDetailVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+* @title: 教材入库记录详细入库记录
+* @Author phoenix
+* @Date: 2025-02-10
+* @Version 1.0
+*/
+@RestController
+@RequestMapping("/textbook" + "/textbookWarehouseRecordDetail")
+@Api(value = "/textbook"  + "/textbookWarehouseRecordDetail",tags = "教材入库记录详细入库记录代码")
+@AllArgsConstructor
+public class TextbookWarehouseRecordDetailController {
+
+
+    private final ITextbookWarehouseRecordDetailService textbookWarehouseRecordDetailService;
+
+    @GetMapping(value = "/page")
+    @ApiOperation(value="教材入库记录详细入库记录列表(分页)")
+    @SaCheckPermission("textbookwarehouserecorddetail:detail")
+    public RT<PageOutput<TextbookWarehouseRecordDetailPageVo>> page(@Valid TextbookWarehouseRecordDetailPageDto dto){
+
+        LambdaQueryWrapper<TextbookWarehouseRecordDetail> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper
+                    .orderByDesc(TextbookWarehouseRecordDetail::getId)
+                .select(TextbookWarehouseRecordDetail.class,x -> VoToColumnUtil.fieldsToColumns(TextbookWarehouseRecordDetailPageVo.class).contains(x.getProperty()));
+        IPage<TextbookWarehouseRecordDetail> page = textbookWarehouseRecordDetailService.page(ConventPage.getPage(dto), queryWrapper);
+        PageOutput<TextbookWarehouseRecordDetailPageVo> pageOutput = ConventPage.getPageOutput(page, TextbookWarehouseRecordDetailPageVo.class);
+        return RT.ok(pageOutput);
+    }
+
+    @GetMapping(value = "/info")
+    @ApiOperation(value="根据id查询教材入库记录详细入库记录信息")
+    @SaCheckPermission("textbookwarehouserecorddetail:detail")
+    public RT<TextbookWarehouseRecordDetailVo> info(@RequestParam Long id){
+        TextbookWarehouseRecordDetail textbookWarehouseRecordDetail = textbookWarehouseRecordDetailService.getById(id);
+        if (textbookWarehouseRecordDetail == null) {
+           return RT.error("找不到此数据!");
+        }
+        return RT.ok(BeanUtil.toBean(textbookWarehouseRecordDetail, TextbookWarehouseRecordDetailVo.class));
+    }
+
+
+    @PostMapping
+    @ApiOperation(value = "新增教材入库记录详细入库记录")
+    @SaCheckPermission("textbookwarehouserecorddetail:add")
+    public RT<Boolean> add(@Valid @RequestBody AddTextbookWarehouseRecordDetailDto dto){
+        TextbookWarehouseRecordDetail textbookWarehouseRecordDetail = BeanUtil.toBean(dto, TextbookWarehouseRecordDetail.class);
+        boolean isSuccess = textbookWarehouseRecordDetailService.save(textbookWarehouseRecordDetail);
+    return RT.ok(isSuccess);
+    }
+
+    @PutMapping
+    @ApiOperation(value = "修改教材入库记录详细入库记录")
+    @SaCheckPermission("textbookwarehouserecorddetail:edit")
+    public RT<Boolean> update(@Valid @RequestBody UpdateTextbookWarehouseRecordDetailDto dto){
+
+        TextbookWarehouseRecordDetail textbookWarehouseRecordDetail = BeanUtil.toBean(dto, TextbookWarehouseRecordDetail.class);
+        return RT.ok(textbookWarehouseRecordDetailService.updateById(textbookWarehouseRecordDetail));
+
+    }
+
+    @DeleteMapping
+    @ApiOperation(value = "删除教材入库记录详细入库记录")
+    @SaCheckPermission("textbookwarehouserecorddetail:delete")
+    public RT<Boolean> delete(@Valid @RequestBody List<Long> ids){
+        return RT.ok(textbookWarehouseRecordDetailService.removeBatchByIds(ids));
+
+    }
+    @PostMapping("/import")
+    @ApiOperation(value = "导入")
+    public RT<Boolean> importData(@RequestParam MultipartFile file) throws IOException {
+        List<TextbookWarehouseRecordDetailPageVo> savedDataList = EasyExcel.read(file.getInputStream()).head(TextbookWarehouseRecordDetailPageVo.class).sheet().doReadSync();
+        Boolean result = textbookWarehouseRecordDetailService.saveBatch(BeanUtil.copyToList(savedDataList, TextbookWarehouseRecordDetail.class));
+        return RT.ok(result);
+    }
+
+    @GetMapping("/export")
+    @ApiOperation(value = "导出")
+    public ResponseEntity<byte[]> exportData(@Valid TextbookWarehouseRecordDetailPageDto dto, @RequestParam(defaultValue = "false") Boolean isTemplate) {
+        List<TextbookWarehouseRecordDetailPageVo> customerList = isTemplate != null && isTemplate ? new ArrayList<>() : ((PageOutput<TextbookWarehouseRecordDetailPageVo>) page(dto).getData()).getList();
+        ByteArrayOutputStream bot = new ByteArrayOutputStream();
+        EasyExcel.write(bot, TextbookWarehouseRecordDetailPageVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(customerList);
+
+        return RT.fileStream(bot.toByteArray(), "TextbookWarehouseRecordDetail" + ExcelTypeEnum.XLSX.getValue());
+    }
+}

+ 53 - 0
src/main/java/com/xjrsoft/module/textbook/dto/AddTextbookWarehouseRecordDetailDto.java

@@ -0,0 +1,53 @@
+package com.xjrsoft.module.textbook.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+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-02-10
+* @Version 1.0
+*/
+@Data
+public class AddTextbookWarehouseRecordDetailDto implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+    * 序号
+    */
+    @ApiModelProperty("序号")
+    private Integer sortCode;
+    /**
+    * 教材入库记录主键id(textbook_warehouse_record)
+    */
+    @ApiModelProperty("教材入库记录主键id(textbook_warehouse_record)")
+    private Long textbookWarehouseRecordId;
+    /**
+    * 入库方式(xjr_dictionary_item[warehouse_mode])
+    */
+    @ApiModelProperty("入库方式(xjr_dictionary_item[warehouse_mode])")
+    private String warehouseMode;
+    /**
+    * 入库数量
+    */
+    @ApiModelProperty("入库数量")
+    private Integer warehouseNumber;
+    /**
+    * 备注
+    */
+    @ApiModelProperty("备注")
+    private String remark;
+
+}

+ 26 - 0
src/main/java/com/xjrsoft/module/textbook/dto/TextbookWarehouseRecordDetailPageDto.java

@@ -0,0 +1,26 @@
+package com.xjrsoft.module.textbook.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.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.Date;
+
+
+/**
+* @title: 教材入库记录详细入库记录分页查询入参
+* @Author phoenix
+* @Date: 2025-02-10
+* @Version 1.0
+*/
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class TextbookWarehouseRecordDetailPageDto extends PageInput {
+
+
+}

+ 0 - 20
src/main/java/com/xjrsoft/module/textbook/dto/TextbookWarehouseRecordPageDto.java

@@ -16,9 +16,6 @@ import lombok.EqualsAndHashCode;
 @EqualsAndHashCode(callSuper = false)
 public class TextbookWarehouseRecordPageDto extends PageInput {
 
-    @ApiModelProperty("教材类型")
-    public String textbookType;
-
     @ApiModelProperty("学期id")
     public Long baseSemesterId;
 
@@ -28,23 +25,6 @@ public class TextbookWarehouseRecordPageDto extends PageInput {
     @ApiModelProperty("课程id")
     public Long courseSubjectId;
 
-    @ApiModelProperty("班级id")
-    public Long classId;
-
     @ApiModelProperty("书名")
     public String bookName;
-
-    @ApiModelProperty("书号")
-    public String issn;
-
-    @ApiModelProperty("规格型号")
-    public String specificationsModels;
-
-    @ApiModelProperty("规划教材")
-    public String isTextbookPlan;
-    /**
-     * 出版社
-     */
-    @ApiModelProperty("出版社")
-    private String publishingHouse;
 }

+ 32 - 0
src/main/java/com/xjrsoft/module/textbook/dto/UpdateTextbookWarehouseRecordDetailDto.java

@@ -0,0 +1,32 @@
+package com.xjrsoft.module.textbook.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-02-10
+* @Version 1.0
+*/
+@Data
+public class UpdateTextbookWarehouseRecordDetailDto extends AddTextbookWarehouseRecordDetailDto {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+    * 主键编号
+    */
+    @ApiModelProperty("主键编号")
+    private Long id;
+}

+ 5 - 1
src/main/java/com/xjrsoft/module/textbook/entity/TextbookSubscription.java

@@ -108,7 +108,11 @@ public class TextbookSubscription implements Serializable {
     */
     @ApiModelProperty("征订状态(0:待发起,1:证订中,2:完成)")
     private Integer status;
-
+    /**
+     * 征订单号(标识+当前时间(YYYYMMDDHHmmss)+三位序号)
+     */
+    @ApiModelProperty("征订单号(标识+当前时间(YYYYMMDDHHmmss)+三位序号)")
+    private String orderNumber;
     /**
     * textbookSubscriptionItem
     */

+ 67 - 29
src/main/java/com/xjrsoft/module/textbook/entity/TextbookWarehouseRecord.java

@@ -2,27 +2,30 @@ package com.xjrsoft.module.textbook.entity;
 
 import com.baomidou.mybatisplus.annotation.FieldFill;
 import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
 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.LocalTime;
+import java.time.LocalDateTime;
 import java.math.BigDecimal;
+import java.util.List;
 import java.util.Date;
 
 
 /**
-* @title: 教材入库
-* @Author szs
-* @Date: 2023-12-26
+* @title: 教材入库记录
+* @Author phoenix
+* @Date: 2025-02-10
 * @Version 1.0
 */
 @Data
 @TableName("textbook_warehouse_record")
-@ApiModel(value = "textbook_warehouse_record", description = "教材入库")
+@ApiModel(value = "textbook_warehouse_record", description = "教材入库记录")
 public class TextbookWarehouseRecord implements Serializable {
 
     private static final long serialVersionUID = 1L;
@@ -76,21 +79,31 @@ public class TextbookWarehouseRecord implements Serializable {
     @ApiModelProperty("序号")
     private Integer sortCode;
     /**
-    * 教材管理编号
+    * 入库方式(xjr_dictionary_item[warehouse_mode])
     */
-    @ApiModelProperty("教材管理编号")
-    private Long textbookId;
+    @ApiModelProperty("入库方式(xjr_dictionary_item[warehouse_mode])")
+    private String warehouseMode;
     /**
-     * 数据编号(根据入库方式,编号来自不同数据表)
-     */
+    * 数据编号(根据入库方式,编号来自不同数据表)
+    */
     @ApiModelProperty("数据编号(根据入库方式,编号来自不同数据表)")
     private Long dataId;
     /**
-     * 数据项项编号(根据入库方式,编号来自不同数据表)
-     */
+    * 数据项项编号(根据入库方式,编号来自不同数据表)
+    */
     @ApiModelProperty("数据项项编号(根据入库方式,编号来自不同数据表)")
     private Long dataItemId;
     /**
+    * 教材管理编号
+    */
+    @ApiModelProperty("教材管理编号")
+    private Long textbookId;
+    /**
+    * 定价(元)
+    */
+    @ApiModelProperty("定价(元)")
+    private BigDecimal price;
+    /**
     * 入库数量
     */
     @ApiModelProperty("入库数量")
@@ -101,19 +114,14 @@ public class TextbookWarehouseRecord implements Serializable {
     @ApiModelProperty("来源")
     private String source;
     /**
-    * 定价(元)
+    * 实际折扣
     */
-    @ApiModelProperty("定价(元)")
-    private BigDecimal price;
-    /**
-    * 折扣
-    */
-    @ApiModelProperty("折扣")
+    @ApiModelProperty("实际折扣")
     private Double discount;
     /**
-    * 小计(元)
+    * 实际价格(元)
     */
-    @ApiModelProperty("小计(元)")
+    @ApiModelProperty("实际价格(元)")
     private BigDecimal subtotal;
     /**
     * 总价(元)
@@ -121,15 +129,45 @@ public class TextbookWarehouseRecord implements Serializable {
     @ApiModelProperty("总价(元)")
     private BigDecimal totalPrice;
     /**
-     * 入库方式
-     */
-    @ApiModelProperty("入库方式")
-    private String warehouseMode;
-    /**
-     * 备注
-     */
+    * 备注
+    */
     @ApiModelProperty("备注")
     private String remark;
+    /**
+    * 入库单号(标识+当前时间(YYYYMMDDHHmmss)+三位序号)
+    */
+    @ApiModelProperty("入库单号(标识+当前时间(YYYYMMDDHHmmss)+三位序号)")
+    private String orderNumber;
+    /**
+    * 退还书店数量
+    */
+    @ApiModelProperty("退还书店数量")
+    private Integer returnBookstoreNumber;
+    /**
+    * 实际入库数量(总入库数量 - 退还书店数量)
+    */
+    @ApiModelProperty("实际入库数量(总入库数量 - 退还书店数量)")
+    private Integer actualWarehouseNumber;
+    /**
+    * 实际入库金额(实际入库数量 * 实际价格)
+    */
+    @ApiModelProperty("实际入库金额(实际入库数量 * 实际价格)")
+    private BigDecimal actualTotalPrice;
+    /**
+    * 已出库数量
+    */
+    @ApiModelProperty("已出库数量")
+    private Integer issuedNumber;
+    /**
+    * 领取后退书数量
+    */
+    @ApiModelProperty("领取后退书数量")
+    private Integer recedeNumber;
+    /**
+    * 剩余库存数量
+    */
+    @ApiModelProperty("剩余库存数量")
+    private Integer remainNumber;
 
 
 }

+ 103 - 0
src/main/java/com/xjrsoft/module/textbook/entity/TextbookWarehouseRecordDetail.java

@@ -0,0 +1,103 @@
+package com.xjrsoft.module.textbook.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.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Date;
+
+
+/**
+* @title: 教材入库记录详细入库记录
+* @Author phoenix
+* @Date: 2025-02-10
+* @Version 1.0
+*/
+@Data
+@TableName("textbook_warehouse_record_detail")
+@ApiModel(value = "textbook_warehouse_record_detail", description = "教材入库记录详细入库记录")
+public class TextbookWarehouseRecordDetail 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;
+    /**
+    * 序号
+    */
+    @ApiModelProperty("序号")
+    private Integer sortCode;
+    /**
+    * 教材入库记录主键id(textbook_warehouse_record)
+    */
+    @ApiModelProperty("教材入库记录主键id(textbook_warehouse_record)")
+    private Long textbookWarehouseRecordId;
+    /**
+    * 入库方式(xjr_dictionary_item[warehouse_mode])
+    */
+    @ApiModelProperty("入库方式(xjr_dictionary_item[warehouse_mode])")
+    private String warehouseMode;
+    /**
+    * 入库数量
+    */
+    @ApiModelProperty("入库数量")
+    private Integer warehouseNumber;
+    /**
+    * 备注
+    */
+    @ApiModelProperty("备注")
+    private String remark;
+
+
+}

+ 17 - 0
src/main/java/com/xjrsoft/module/textbook/mapper/TextbookWarehouseRecordDetailMapper.java

@@ -0,0 +1,17 @@
+package com.xjrsoft.module.textbook.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.github.yulichang.base.MPJBaseMapper;
+import com.xjrsoft.module.textbook.entity.TextbookWarehouseRecordDetail;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @title: 教材入库记录详细入库记录
+* @Author phoenix
+* @Date: 2025-02-10
+* @Version 1.0
+*/
+@Mapper
+public interface TextbookWarehouseRecordDetailMapper extends MPJBaseMapper<TextbookWarehouseRecordDetail> {
+
+}

+ 17 - 0
src/main/java/com/xjrsoft/module/textbook/service/ITextbookWarehouseRecordDetailService.java

@@ -0,0 +1,17 @@
+package com.xjrsoft.module.textbook.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.yulichang.base.MPJBaseService;
+import com.xjrsoft.module.textbook.entity.TextbookWarehouseRecordDetail;
+import lombok.Data;
+import java.util.List;
+
+/**
+* @title: 教材入库记录详细入库记录
+* @Author phoenix
+* @Date: 2025-02-10
+* @Version 1.0
+*/
+
+public interface ITextbookWarehouseRecordDetailService extends MPJBaseService<TextbookWarehouseRecordDetail> {
+}

+ 2 - 3
src/main/java/com/xjrsoft/module/textbook/service/ITextbookWarehouseRecordService.java

@@ -1,8 +1,7 @@
 package com.xjrsoft.module.textbook.service;
 
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.yulichang.base.MPJBaseService;
-import com.xjrsoft.module.textbook.dto.AddTextbookWarehouseRecordDto;
 import com.xjrsoft.module.textbook.dto.TextbookWarehouseRecordExportDto;
 import com.xjrsoft.module.textbook.dto.TextbookWarehouseRecordPageDto;
 import com.xjrsoft.module.textbook.entity.TextbookWarehouseRecord;
@@ -19,7 +18,7 @@ import java.util.List;
 
 public interface ITextbookWarehouseRecordService extends MPJBaseService<TextbookWarehouseRecord> {
 
-    Page<TextbookWarehouseRecordPageVo> getPage(TextbookWarehouseRecordPageDto dto);
+    IPage<TextbookWarehouseRecordPageVo> getPage(TextbookWarehouseRecordPageDto dto);
 
     List<TextbookWarehouseRecordPageVo> getList(TextbookWarehouseRecordExportDto dto);
 

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

@@ -56,6 +56,5 @@ public interface IWfTextbookSubscriptionService extends MPJBaseService<WfTextboo
 
     Boolean instockroom(List<TextbookInstockroomDto> dtos);
 
-
     String excelImport(InputStream inputStream, Long wfTextbookSubscriptionId);
 }

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

@@ -2,6 +2,7 @@ package com.xjrsoft.module.textbook.service.impl;
 
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.excel.EasyExcel;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -37,6 +38,8 @@ import org.springframework.transaction.annotation.Transactional;
 import java.io.InputStream;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.regex.Matcher;
@@ -65,6 +68,8 @@ public class TextbookSubscriptionServiceImpl extends MPJBaseServiceImpl<Textbook
 
     private final TextbookSubscriptionItemHistoryMapper textbookSubscriptionItemHistoryMapper;
 
+    private final TextbookWarehouseRecordDetailMapper textbookWarehouseRecordDetailMapper;
+
     @Override
     public IPage<TextbookSubscriptionPageVo> pageRubAndHand(TextbookSubscriptionPageDto dto) {
         MPJLambdaWrapper<TextbookSubscription> queryWrapper = new MPJLambdaWrapper<>();
@@ -78,8 +83,7 @@ public class TextbookSubscriptionServiceImpl extends MPJBaseServiceImpl<Textbook
                 .eq(StringUtils.isNotBlank(dto.getId()), TextbookSubscription::getId, dto.getId())
                 .orderByDesc(TextbookSubscription::getCreateDate)
         ;
-        IPage<TextbookSubscriptionPageVo> page = this.selectJoinListPage(ConventPage.getPage(dto), TextbookSubscriptionPageVo.class, queryWrapper);
-        return page;
+        return this.selectJoinListPage(ConventPage.getPage(dto), TextbookSubscriptionPageVo.class, queryWrapper);
     }
 
     @Override
@@ -273,7 +277,6 @@ public class TextbookSubscriptionServiceImpl extends MPJBaseServiceImpl<Textbook
                 .select(TextbookSubscriptionItem::getId)
                 .selectAs(TextbookSubscriptionItem::getPrice, SubscriptionItemListDistributeVo::getActulPrice)
                 .select(TextbookSubscriptionItem.class,x -> VoToColumnUtil.fieldsToColumns(SubscriptionItemListDistributeVo.class).contains(x.getProperty()))
-                .innerJoin(TextbookSubscription.class, TextbookSubscription::getId, TextbookSubscriptionItem::getTextbookSubscriptionId)
                 .eq(TextbookSubscriptionItem::getTextbookId, dto.getTextbookId())
                 .gt(TextbookSubscriptionItem::getInStockNum, TextbookSubscriptionItem::getOutStockNum)
                 .orderByAsc(TextbookSubscriptionItem::getCreateDate)
@@ -294,6 +297,35 @@ public class TextbookSubscriptionServiceImpl extends MPJBaseServiceImpl<Textbook
         }
         textbookSubscription.setSum(sum);
         textbookSubscription.setCreateDate(new Date());
+
+        // 处理征订单号
+        StringBuilder sb = new StringBuilder();
+        sb.append("ZD");
+        LocalDateTime now = LocalDateTime.now();
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+        String nowStr = now.format(dateTimeFormatter);
+        sb.append(nowStr);
+        // 根据当前征订编号前缀去数据库找是否已经存在了
+        LambdaQueryWrapper<TextbookSubscription> textbookSubscriptionLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        textbookSubscriptionLambdaQueryWrapper
+                .like(TextbookSubscription::getOrderNumber, sb.toString() + "%")
+                .eq(TextbookSubscription::getDeleteMark, DeleteMark.NODELETE.getCode())
+                .orderByDesc(TextbookSubscription::getOrderNumber)
+                .last("limit 1")
+                ;
+        TextbookSubscription maxOrderNumber = textbookSubscriptionTextbookSubscriptionMapper.selectOne(textbookSubscriptionLambdaQueryWrapper);
+        if(ObjectUtils.isNotEmpty(maxOrderNumber) && ObjectUtils.isNotEmpty(maxOrderNumber.getOrderNumber())){
+            String oldOrderNumber = maxOrderNumber.getOrderNumber();
+            String oldOrder = oldOrderNumber.substring(oldOrderNumber.length() - 3);
+            int oldOrderInteger = Integer.parseInt(oldOrder);
+            oldOrderInteger += 1;
+            String newOrder = String.format("%03d", oldOrderInteger); // 补零并格式化为三位数
+            sb.append(newOrder);
+        }else {
+            sb.append("001");
+        }
+        textbookSubscription.setOrderNumber(sb.toString());
+
         textbookSubscriptionTextbookSubscriptionMapper.insert(textbookSubscription);
 
 //        // 处理征订和班级关联表
@@ -347,6 +379,12 @@ public class TextbookSubscriptionServiceImpl extends MPJBaseServiceImpl<Textbook
             return false;
         }
 
+        TextbookSubscription textbookSubscription = this.getById(dtos.get(0).getTextbookSubscriptionId());
+
+        if (ObjectUtils.isEmpty(textbookSubscription)) {
+            throw new MyException("请选择需要入库的征订记录");
+        }
+
         List<Long> textbookSubscriptionItemIds = new ArrayList<>();
         for (TextbookInstockroomDto dto : dtos) {
             if(ObjectUtils.isNotEmpty(dto.getTextbookSubscriptionItemId())){
@@ -368,11 +406,9 @@ public class TextbookSubscriptionServiceImpl extends MPJBaseServiceImpl<Textbook
                 .eq(TextbookSubscriptionItem::getDeleteMark, DeleteMark.NODELETE.getCode())
         ;
         List<TextbookSubscriptionItem> textbookSubscriptionItemList = textbookSubscriptionTextbookSubscriptionItemMapper.selectJoinList(TextbookSubscriptionItem.class, queryWrapper);
-
         if (textbookSubscriptionItemList.isEmpty()) {
-            throw new MyException("证订信息已经修改,请刷新重试");
+            throw new MyException("证订项已经变更,请刷新重试");
         }
-
         Map<Long, TextbookSubscriptionItem> itemByIdMap = new HashMap<>();
         for (TextbookSubscriptionItem el : textbookSubscriptionItemList) {
             if(ObjectUtils.isNotEmpty(el.getId()) && !itemByIdMap.containsKey(el.getId())){
@@ -380,17 +416,60 @@ public class TextbookSubscriptionServiceImpl extends MPJBaseServiceImpl<Textbook
             }
         }
 
+        // 获取当前征订已经产生的入库记录
+        LambdaQueryWrapper<TextbookWarehouseRecord> textbookWarehouseRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        textbookWarehouseRecordLambdaQueryWrapper
+                .in(TextbookWarehouseRecord::getDataId, textbookSubscription.getId())
+                .eq(TextbookWarehouseRecord::getDeleteMark, DeleteMark.NODELETE.getCode())
+                ;
+        List<TextbookWarehouseRecord> textbookWarehouseRecords = textbookWarehouseRecordMapper.selectList(textbookWarehouseRecordLambdaQueryWrapper);
+        Map<Long, TextbookWarehouseRecord> textbookWarehouseRecordByItemIdMap = new HashMap<>();
+        for (TextbookWarehouseRecord twr : textbookWarehouseRecords) {
+            if(ObjectUtils.isNotEmpty(twr.getDataItemId()) && !textbookWarehouseRecordByItemIdMap.containsKey(twr.getDataItemId())){
+                textbookWarehouseRecordByItemIdMap.put(twr.getDataItemId(), twr);
+            }
+        }
+
+        // 处理入库单号
+        StringBuilder sb = new StringBuilder();
+        sb.append("RK");
+        LocalDateTime now = LocalDateTime.now();
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+        String nowStr = now.format(dateTimeFormatter);
+        sb.append(nowStr);
+        // 根据当前征订编号前缀去数据库找是否已经存在了
+        LambdaQueryWrapper<TextbookWarehouseRecord> maxOrderNumberLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        maxOrderNumberLambdaQueryWrapper
+                .like(TextbookWarehouseRecord::getOrderNumber, sb.toString() + "%")
+                .eq(TextbookWarehouseRecord::getDeleteMark, DeleteMark.NODELETE.getCode())
+                .orderByDesc(TextbookWarehouseRecord::getOrderNumber)
+                .last("limit 1")
+        ;
+        TextbookWarehouseRecord maxOrderNumber = textbookWarehouseRecordMapper.selectOne(maxOrderNumberLambdaQueryWrapper);
+        int oldOrderInteger = 0;
+        if(ObjectUtils.isNotEmpty(maxOrderNumber) && ObjectUtils.isNotEmpty(maxOrderNumber.getOrderNumber())){
+            String oldOrderNumber = maxOrderNumber.getOrderNumber();
+            String oldOrder = oldOrderNumber.substring(oldOrderNumber.length() - 3);
+            oldOrderInteger = Integer.parseInt(oldOrder);
+        }
+
+        // 处理入库细节
         TextbookSubscriptionItem old = null;
+        TextbookSubscriptionItem updateItem;
+        TextbookWarehouseRecord textbookWarehouseRecord;
+        TextbookWarehouseRecord oldTextbookWarehouseRecord = null;
+        TextbookWarehouseRecordDetail textbookWarehouseRecordDetail;
         for (TextbookInstockroomDto dto : dtos) {
             if (ObjectUtils.isNotEmpty(dto.getTextbookSubscriptionItemId())) {
                 old = itemByIdMap.get(dto.getTextbookSubscriptionItemId());
+                oldTextbookWarehouseRecord = textbookWarehouseRecordByItemIdMap.get(dto.getTextbookSubscriptionItemId());
             }
 
             if (ObjectUtils.isEmpty(old)) {
                 continue;
             }
 
-            TextbookSubscriptionItem updateItem = new TextbookSubscriptionItem();
+            updateItem = new TextbookSubscriptionItem();
             updateItem.setId(old.getId());
             updateItem.setDiscount(dto.getDiscount());
             updateItem.setPrice(old.getPrice().multiply(BigDecimal.valueOf(dto.getDiscount() / 10)));
@@ -399,20 +478,54 @@ public class TextbookSubscriptionServiceImpl extends MPJBaseServiceImpl<Textbook
             updateItem.setModifyUserId(StpUtil.getLoginIdAsLong());
             textbookSubscriptionTextbookSubscriptionItemMapper.updateById(updateItem);
 
-            //新增入库记录
-            TextbookWarehouseRecord textbookWarehouseRecord = new TextbookWarehouseRecord();
-            textbookWarehouseRecord.setTextbookId(old.getTextbookId());
-            textbookWarehouseRecord.setDataId(dto.getTextbookSubscriptionId());
-            textbookWarehouseRecord.setDataItemId(dto.getTextbookSubscriptionItemId());
-            textbookWarehouseRecord.setWarehouseNumber(dto.getInNum());
-            textbookWarehouseRecord.setPrice(old.getPrice());
-            textbookWarehouseRecord.setDiscount(dto.getDiscount());
-            textbookWarehouseRecord.setSubtotal(old.getPrice().multiply(BigDecimal.valueOf(dto.getDiscount() / 10)));
-            textbookWarehouseRecord.setTotalPrice(textbookWarehouseRecord.getSubtotal().multiply(BigDecimal.valueOf(dto.getInNum())));
-            textbookWarehouseRecord.setWarehouseMode(WarehouseModeEnum.WmManual.getCode());
-            updateItem.setCreateDate(new Date());
-            updateItem.setCreateUserId(StpUtil.getLoginIdAsLong());
-            textbookWarehouseRecordMapper.insert(textbookWarehouseRecord);
+            // 判断当前征订中的当前教材是否已经有了入库记录
+            // 当前征订项第一次入库
+            long textbookWarehouseRecordId = IdUtil.getSnowflakeNextId();
+            if (ObjectUtils.isEmpty(oldTextbookWarehouseRecord)) {
+                //新增入库记录
+                textbookWarehouseRecord = new TextbookWarehouseRecord();
+                textbookWarehouseRecord.setId(textbookWarehouseRecordId);
+                textbookWarehouseRecord.setTextbookId(old.getTextbookId());
+                textbookWarehouseRecord.setDataId(dto.getTextbookSubscriptionId());
+                textbookWarehouseRecord.setDataItemId(dto.getTextbookSubscriptionItemId());
+                textbookWarehouseRecord.setWarehouseNumber(dto.getInNum());
+                textbookWarehouseRecord.setPrice(old.getPrice());
+                textbookWarehouseRecord.setDiscount(dto.getDiscount());
+                textbookWarehouseRecord.setSubtotal(old.getPrice().multiply(BigDecimal.valueOf(dto.getDiscount() / 10)));
+                textbookWarehouseRecord.setTotalPrice(textbookWarehouseRecord.getSubtotal().multiply(BigDecimal.valueOf(dto.getInNum())));
+                oldOrderInteger += 1;
+                String newOrder = String.format("%03d", oldOrderInteger); // 补零并格式化为三位数
+                sb.append(newOrder);
+                textbookWarehouseRecord.setOrderNumber(sb.toString());
+                textbookWarehouseRecord.setReturnBookstoreNumber(0);
+                textbookWarehouseRecord.setActualWarehouseNumber(textbookWarehouseRecord.getWarehouseNumber() - textbookWarehouseRecord.getReturnBookstoreNumber());
+                textbookWarehouseRecord.setActualTotalPrice(textbookWarehouseRecord.getSubtotal().multiply(BigDecimal.valueOf(textbookWarehouseRecord.getActualWarehouseNumber())));
+                textbookWarehouseRecord.setIssuedNumber(0);
+                textbookWarehouseRecord.setRecedeNumber(0);
+                textbookWarehouseRecord.setRemainNumber(textbookWarehouseRecord.getActualWarehouseNumber());
+                textbookWarehouseRecord.setWarehouseMode(WarehouseModeEnum.WmSubscription.getCode());
+                updateItem.setCreateDate(new Date());
+                updateItem.setCreateUserId(StpUtil.getLoginIdAsLong());
+                textbookWarehouseRecordMapper.insert(textbookWarehouseRecord);
+            }else {
+                textbookWarehouseRecordId = oldTextbookWarehouseRecord.getId();
+                textbookWarehouseRecord = BeanUtil.toBean(oldTextbookWarehouseRecord, TextbookWarehouseRecord.class);
+                textbookWarehouseRecord.setWarehouseNumber(textbookWarehouseRecord.getWarehouseNumber() + dto.getInNum());
+                textbookWarehouseRecord.setTotalPrice(textbookWarehouseRecord.getSubtotal().multiply(BigDecimal.valueOf(textbookWarehouseRecord.getWarehouseNumber())));
+                textbookWarehouseRecord.setActualWarehouseNumber(textbookWarehouseRecord.getActualWarehouseNumber() + dto.getInNum());
+                textbookWarehouseRecord.setActualTotalPrice(textbookWarehouseRecord.getSubtotal().multiply(BigDecimal.valueOf(textbookWarehouseRecord.getActualWarehouseNumber())));
+                textbookWarehouseRecord.setRemainNumber(textbookWarehouseRecord.getRemainNumber() + dto.getInNum());
+                textbookWarehouseRecord.setModifyDate(new Date());
+                textbookWarehouseRecord.setModifyUserId(StpUtil.getLoginIdAsLong());
+                textbookWarehouseRecordMapper.updateById(textbookWarehouseRecord);
+            }
+
+            // 新增教材入库记录详细入库记录
+            textbookWarehouseRecordDetail = new TextbookWarehouseRecordDetail();
+            textbookWarehouseRecordDetail.setTextbookWarehouseRecordId(textbookWarehouseRecordId);
+            textbookWarehouseRecordDetail.setWarehouseMode(WarehouseModeEnum.WmSubscription.getCode());
+            textbookWarehouseRecordDetail.setWarehouseNumber(dto.getInNum());
+            textbookWarehouseRecordDetailMapper.insert(textbookWarehouseRecordDetail);
         }
 
         return true;

+ 25 - 0
src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookWarehouseRecordDetailServiceImpl.java

@@ -0,0 +1,25 @@
+package com.xjrsoft.module.textbook.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.yulichang.base.MPJBaseServiceImpl;
+import com.xjrsoft.module.textbook.entity.TextbookWarehouseRecordDetail;
+import com.xjrsoft.module.textbook.mapper.TextbookWarehouseRecordDetailMapper;
+import com.xjrsoft.module.textbook.service.ITextbookWarehouseRecordDetailService;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+
+/**
+* @title: 教材入库记录详细入库记录
+* @Author phoenix
+* @Date: 2025-02-10
+* @Version 1.0
+*/
+@Service
+@AllArgsConstructor
+public class TextbookWarehouseRecordDetailServiceImpl extends MPJBaseServiceImpl<TextbookWarehouseRecordDetailMapper, TextbookWarehouseRecordDetail> implements ITextbookWarehouseRecordDetailService {
+}

+ 51 - 12
src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookWarehouseRecordServiceImpl.java

@@ -2,22 +2,32 @@ package com.xjrsoft.module.textbook.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.github.yulichang.base.MPJBaseServiceImpl;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
 import com.xjrsoft.common.enums.WarehouseModeEnum;
 import com.xjrsoft.common.exception.MyException;
+import com.xjrsoft.common.page.ConventPage;
+import com.xjrsoft.common.utils.VoToColumnUtil;
+import com.xjrsoft.module.base.entity.BaseCourseSubject;
+import com.xjrsoft.module.base.entity.BaseSemester;
+import com.xjrsoft.module.base.entity.CourseSubjectDetail;
+import com.xjrsoft.module.system.entity.DictionaryDetail;
+import com.xjrsoft.module.teacher.entity.XjrUser;
 import com.xjrsoft.module.textbook.dto.AddTextbookWarehouseRecordDto;
 import com.xjrsoft.module.textbook.dto.TextbookWarehouseRecordExportDto;
 import com.xjrsoft.module.textbook.dto.TextbookWarehouseRecordPageDto;
-import com.xjrsoft.module.textbook.entity.Textbook;
-import com.xjrsoft.module.textbook.entity.TextbookWarehouseRecord;
+import com.xjrsoft.module.textbook.entity.*;
 import com.xjrsoft.module.textbook.mapper.TextbookMapper;
 import com.xjrsoft.module.textbook.mapper.TextbookWarehouseRecordMapper;
 import com.xjrsoft.module.textbook.service.ITextbookWarehouseRecordService;
+import com.xjrsoft.module.textbook.vo.SubscriptionItemListDistributeVo;
+import com.xjrsoft.module.textbook.vo.TextbookSubscriptionPageVo;
 import com.xjrsoft.module.textbook.vo.TextbookWarehouseRecordPageVo;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -37,17 +47,46 @@ public class TextbookWarehouseRecordServiceImpl extends MPJBaseServiceImpl<Textb
     private final TextbookWarehouseRecordMapper textbookWarehouseRecordMapper;
 
     @Override
-    public Page<TextbookWarehouseRecordPageVo> getPage(TextbookWarehouseRecordPageDto dto) {
-//        MPJLambdaWrapper<TextbookWarehouseRecord>;-
-
-//        MPJLambdaWrapper<TextbookWarehouseRecord> textbookWarehouseRecordMPJLambdaWrapper = new MPJLambdaWrapper<>();
-//        textbookWarehouseRecordMPJLambdaWrapper
-//                .leftJoin()
-//                ;
-
-
+    public IPage<TextbookWarehouseRecordPageVo> getPage(TextbookWarehouseRecordPageDto dto) {
+        MPJLambdaWrapper<TextbookWarehouseRecord> textbookWarehouseRecordMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        textbookWarehouseRecordMPJLambdaWrapper
+                .disableSubLogicDel()
+                .select(TextbookWarehouseRecord::getId)
+                .select(Textbook.class,x -> VoToColumnUtil.fieldsToColumns(TextbookWarehouseRecordPageVo.class).contains(x.getProperty()))
+                .select(TextbookWarehouseRecord.class,x -> VoToColumnUtil.fieldsToColumns(TextbookWarehouseRecordPageVo.class).contains(x.getProperty()))
+                .innerJoin(Textbook.class, Textbook::getId, TextbookWarehouseRecord::getTextbookId)
+                .leftJoin(TextbookSubscription.class, TextbookSubscription::getId, TextbookWarehouseRecord::getDataId,
+                        wrapper -> wrapper
+                                .selectAs(BaseSemester::getName, TextbookWarehouseRecordPageVo::getBaseSemesterIdCn)
+                                .leftJoin(BaseSemester.class, BaseSemester::getId, TextbookSubscription::getBaseSemesterId)
+                        )
+                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, TextbookWarehouseRecord::getWarehouseMode,
+                        wrapper -> wrapper
+                                .selectAs(DictionaryDetail::getName, TextbookWarehouseRecordPageVo::getWarehouseModeCn)
+                )
+                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, Textbook::getTextbookType,
+                        wrapper -> wrapper
+                                .selectAs(DictionaryDetail::getName, TextbookWarehouseRecordPageVo::getTextbookTypeCn)
+                )
+                .leftJoin(SubjectGroup.class, SubjectGroup::getId, Textbook::getSubjectGroupId,
+                        wrapper -> wrapper
+                                .selectAs(SubjectGroup::getGroupName, TextbookWarehouseRecordPageVo::getGroupName)
+                )
+                .leftJoin(BaseCourseSubject.class, BaseCourseSubject::getId, Textbook::getCourseSubjectId,
+                        wrapper -> wrapper
+                                .selectAs(BaseCourseSubject::getName, TextbookWarehouseRecordPageVo::getCourseName)
+                )
+                .leftJoin(XjrUser.class, XjrUser::getId, TextbookWarehouseRecord::getCreateUserId,
+                        wrapper -> wrapper
+                                .selectAs(XjrUser::getName, TextbookWarehouseRecordPageVo::getWarehouseUser)
+                )
+                .eq(ObjectUtils.isNotEmpty(dto.getBaseSemesterId()), TextbookSubscription::getBaseSemesterId, dto.getBaseSemesterId())
+                .eq(ObjectUtils.isNotEmpty(dto.getSubjectGroupId()), Textbook::getSubjectGroupId, dto.getSubjectGroupId())
+                .eq(ObjectUtils.isNotEmpty(dto.getCourseSubjectId()), Textbook::getCourseSubjectId, dto.getCourseSubjectId())
+                .like(StringUtils.isNotEmpty(dto.getBookName()), Textbook::getBookName, dto.getBookName())
+                ;
+        return this.selectJoinListPage(ConventPage.getPage(dto), TextbookWarehouseRecordPageVo.class, textbookWarehouseRecordMPJLambdaWrapper);
 //        return textbookWarehouseRecordMapper.getPage(page, dto);
-        return null;
     }
 
     @Override

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

@@ -130,7 +130,7 @@ public class WfTextbookClaimServiceImpl extends MPJBaseServiceImpl<WfTextbookCla
         for (WfTextbookClaimPageVo wfTextbookClaimPageVo : page.getRecords()) {
             //拆分代领取人
             String receiveUserIdStr = wfTextbookClaimPageVo.getReceiveUserId();
-            if (ObjectUtil.isNotNull(receiveUserIdStr) && !receiveUserIdStr.equals("")) {
+            if (ObjectUtil.isNotNull(receiveUserIdStr) && !receiveUserIdStr.isEmpty()) {
                 String[] receiveUserIdStrs = receiveUserIdStr.split(",");
                 List<Long> receiveUserIdList = new ArrayList<>();
                 for (String str : receiveUserIdStrs) {
@@ -140,13 +140,13 @@ public class WfTextbookClaimServiceImpl extends MPJBaseServiceImpl<WfTextbookCla
                 queryWrapper
                         .in(XjrUser::getId, receiveUserIdList);
                 List<XjrUser> xjrUserList = xjrUserMapper.selectList(queryWrapper);
-                if (ObjectUtil.isNotNull(xjrUserList) && xjrUserList.size() > 0) {
+                if (ObjectUtil.isNotNull(xjrUserList) && !xjrUserList.isEmpty()) {
                     StringBuilder sb = new StringBuilder();
                     for (int i = 0; i < xjrUserList.size(); i++) {
                         if(i == 0){
                             sb.append(xjrUserList.get(i).getName());
                         }else{
-                            sb.append("," + xjrUserList.get(i).getName());
+                            sb.append(",").append(xjrUserList.get(i).getName());
                         }
                     }
                     wfTextbookClaimPageVo.setReceiveUserIdCN(sb.toString());
@@ -155,7 +155,7 @@ public class WfTextbookClaimServiceImpl extends MPJBaseServiceImpl<WfTextbookCla
             //加上申领项
             List<WfTextbookClaimItemVo> wfTextbookClaimItemVoList = wfTextbookClaimWfTextbookClaimItemMapper.getListByWfTextbookClaimId(Long.parseLong(wfTextbookClaimPageVo.getId()));
 
-            if (ObjectUtil.isNotNull(wfTextbookClaimItemVoList) && wfTextbookClaimItemVoList.size() > 0) {
+            if (ObjectUtil.isNotNull(wfTextbookClaimItemVoList) && !wfTextbookClaimItemVoList.isEmpty()) {
                 wfTextbookClaimPageVo.setWfTextbookClaimItemList(wfTextbookClaimItemVoList);
             }
         }

+ 5 - 0
src/main/java/com/xjrsoft/module/textbook/vo/TextbookSubscriptionPageVo.java

@@ -63,4 +63,9 @@ public class TextbookSubscriptionPageVo {
     @ExcelProperty("状态(1:待发起 2:征订中 3:待入库 4:已入库)")
     @ApiModelProperty("状态(1:待发起 2:征订中 3:待入库 4:已入库)")
     private Integer status;
+    /**
+     * 征订单号(标识+当前时间(YYYYMMDDHHmmss)+三位序号)
+     */
+    @ApiModelProperty("征订单号(标识+当前时间(YYYYMMDDHHmmss)+三位序号)")
+    private String orderNumber;
 }

+ 111 - 0
src/main/java/com/xjrsoft/module/textbook/vo/TextbookWarehouseRecordDetailPageVo.java

@@ -0,0 +1,111 @@
+package com.xjrsoft.module.textbook.vo;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.write.style.ContentStyle;
+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.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+* @title: 教材入库记录详细入库记录分页列表出参
+* @Author phoenix
+* @Date: 2025-02-10
+* @Version 1.0
+*/
+@Data
+public class TextbookWarehouseRecordDetailPageVo {
+
+    /**
+    * 主键编号
+    */
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("主键编号")
+    @ApiModelProperty("主键编号")
+    private String id;
+    /**
+    * 创建人
+    */
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("创建人")
+    @ApiModelProperty("创建人")
+    private Long createUserId;
+    /**
+    * 创建时间
+    */
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("创建时间")
+    @ApiModelProperty("创建时间")
+    private Date createDate;
+    /**
+    * 修改人
+    */
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("修改人")
+    @ApiModelProperty("修改人")
+    private Long modifyUserId;
+    /**
+    * 修改时间
+    */
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("修改时间")
+    @ApiModelProperty("修改时间")
+    private Date modifyDate;
+    /**
+    * 删除标记
+    */
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("删除标记")
+    @ApiModelProperty("删除标记")
+    private Integer deleteMark;
+    /**
+    * 有效标志
+    */
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("有效标志")
+    @ApiModelProperty("有效标志")
+    private Integer enabledMark;
+    /**
+    * 序号
+    */
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("序号")
+    @ApiModelProperty("序号")
+    private Integer sortCode;
+    /**
+    * 教材入库记录主键id(textbook_warehouse_record)
+    */
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("教材入库记录主键id(textbook_warehouse_record)")
+    @ApiModelProperty("教材入库记录主键id(textbook_warehouse_record)")
+    private Long textbookWarehouseRecordId;
+    /**
+    * 入库方式(xjr_dictionary_item[warehouse_mode])
+    */
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("入库方式(xjr_dictionary_item[warehouse_mode])")
+    @ApiModelProperty("入库方式(xjr_dictionary_item[warehouse_mode])")
+    private String warehouseMode;
+    /**
+    * 入库数量
+    */
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("入库数量")
+    @ApiModelProperty("入库数量")
+    private Integer warehouseNumber;
+    /**
+    * 备注
+    */
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("备注")
+    @ApiModelProperty("备注")
+    private String remark;
+
+}

+ 54 - 0
src/main/java/com/xjrsoft/module/textbook/vo/TextbookWarehouseRecordDetailVo.java

@@ -0,0 +1,54 @@
+package com.xjrsoft.module.textbook.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-02-10
+* @Version 1.0
+*/
+@Data
+public class TextbookWarehouseRecordDetailVo {
+
+    /**
+    * 主键编号
+    */
+    @ApiModelProperty("主键编号")
+    private Long id;
+    /**
+    * 序号
+    */
+    @ApiModelProperty("序号")
+    private Integer sortCode;
+    /**
+    * 教材入库记录主键id(textbook_warehouse_record)
+    */
+    @ApiModelProperty("教材入库记录主键id(textbook_warehouse_record)")
+    private Long textbookWarehouseRecordId;
+    /**
+    * 入库方式(xjr_dictionary_item[warehouse_mode])
+    */
+    @ApiModelProperty("入库方式(xjr_dictionary_item[warehouse_mode])")
+    private String warehouseMode;
+    /**
+    * 入库数量
+    */
+    @ApiModelProperty("入库数量")
+    private Integer warehouseNumber;
+    /**
+    * 备注
+    */
+    @ApiModelProperty("备注")
+    private String remark;
+
+
+
+}

+ 27 - 86
src/main/java/com/xjrsoft/module/textbook/vo/TextbookWarehouseRecordPageVo.java

@@ -17,119 +17,60 @@ import java.util.Date;
 @Data
 public class TextbookWarehouseRecordPageVo {
 
-    /**
-    * 主键编号
-    */
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("主键编号")
+    @ApiModelProperty("学期")
+    public String baseSemesterIdCn;
+
     @ApiModelProperty("主键编号")
     private String id;
 
-    /**
-    * 序号
-    */
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("序号")
-    @ApiModelProperty("序号")
-    private Integer sortCode;
-
-    /**
-     * 来源
-     */
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("书号")
-    @ApiModelProperty("书号")
-    private String issn;
-    /**
-     * 单价(元)
-     */
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("单价(元)")
-    @ApiModelProperty("单价(元)")
-    private BigDecimal Price;
-    /**
-     * 折扣
-     */
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("折扣")
-    @ApiModelProperty("折扣")
-    private Double discount;
-    /**
-    * 书名
-    */
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("书名")
+    @ApiModelProperty("入库方式")
+    private String warehouseModeCn;
+
     @ApiModelProperty("书名")
     private String bookName;
 
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("出版社")
+    @ApiModelProperty("书号")
+    private String issn;
+
     @ApiModelProperty("出版社")
     private String publishingHouse;
 
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("作者(主编)")
     @ApiModelProperty("作者(主编)")
     private String editorInChief;
 
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("学科组")
+    @ApiModelProperty("是否为规划教材")
+    private Integer isTextbookPlan;
+
+    @ApiModelProperty("教材分类(xjr_dictionary_item[textbook_type])")
+    private String textbookTypeCn;
+
     @ApiModelProperty("学科组")
     private String groupName;
 
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("对应课程")
     @ApiModelProperty("对应课程")
     private String courseName;
 
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("类型")
-    @ApiModelProperty("类型")
-    private String textbookTypeCn;
+    @ApiModelProperty("使用类型(单位:学期)")
+    private Integer useType;
 
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("规格型号")
-    @ApiModelProperty("规格型号")
-    private String specificationsModels;
+    @ApiModelProperty("单价(元)")
+    private BigDecimal Price;
+
+    @ApiModelProperty("折扣")
+    private Double discount;
+
+    @ApiModelProperty("小计(元)")
+    private BigDecimal subtotal;
 
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("入库时间")
     @ApiModelProperty("入库时间")
     private Date createDate;
 
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("入库人员")
     @ApiModelProperty("入库人员")
     private String warehouseUser;
 
-    /**
-    * 入库数量
-    */
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("入库数量")
     @ApiModelProperty("入库数量")
     private Integer warehouseNumber;
 
-    /**
-     * 使用年级
-     */
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("使用年级")
-    @ApiModelProperty("使用年级")
-    private String useGrade;
-    /**
-     * 使用年级
-     */
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("学期")
-    @ApiModelProperty("学期")
-    public String baseSemesterIdCn;
-    /**
-     * 使用班级
-     */
-    @ContentStyle(dataFormat = 49)
-    @ExcelProperty("使用班级")
-    @ApiModelProperty("使用班级")
-    private String useClass;
-
+    @ApiModelProperty("总价(元)")
+    private BigDecimal totalPrice;
 }

+ 1 - 0
src/main/resources/mapper/student/BaseStudentMapper.xml

@@ -64,6 +64,7 @@
         LEFT JOIN xjr_dictionary_detail t10 ON t3.learn_status = t10.code AND t10.item_id = 1762024751192084482
         WHERE t1.delete_mark = 0 AND t2.delete_mark = 0
         and t3.archives_status = 'FB2901'
+        and t2.is_normal = 1
         <if test="dto.name != null and dto.name != ''">
             and t1.name like concat('%', #{dto.name},'%')
         </if>

+ 3 - 3
src/main/resources/mapper/student/BaseStudentSchoolRollMapper.xml

@@ -48,7 +48,7 @@
         LEFT JOIN room t15 ON t14.room_id = t15.id
         LEFT JOIN base_office_build t16 ON t15.office_build_id = t16.id
         WHERE t2.delete_mark = 0
-        AND t1.delete_mark = 0
+        AND t1.delete_mark = 0 and t1.is_normal = 1
         AND t3.archives_status = 'FB2901'
         <if test="dto.gradeId != null">
             AND t4.grade_id = #{dto.gradeId}
@@ -137,7 +137,7 @@
         LEFT JOIN xjr_user t5 ON t4.teacher_id = t5.id
         LEFT JOIN base_student_family_member t6 ON t6.user_id = t2.id AND t6.delete_mark = 0 AND t6.is_guardian = 1
         WHERE t2.delete_mark = 0
-        AND t1.delete_mark = 0
+        AND t1.delete_mark = 0 and t1.is_normal = 1
         and t3.archives_status = 'FB2901'
         <if test="dto.gradeId != null">
             and t4.grade_id = #{dto.gradeId}
@@ -170,7 +170,7 @@
         LEFT JOIN xjr_user t5 ON t4.teacher_id = t5.id
         LEFT JOIN base_student_family_member t6 ON t6.user_id = t2.id AND t6.delete_mark = 0 AND t6.is_guardian = 1
         WHERE t2.delete_mark = 0
-        AND t1.delete_mark = 0
+        AND t1.delete_mark = 0 and t1.is_normal = 1
         and t3.archives_status = 'FB2901'
         <if test="dto.gradeId != null">
             and t4.grade_id = #{dto.gradeId}

+ 6 - 1
src/main/resources/mapper/student/StudentReportPlanMapper.xml

@@ -26,10 +26,15 @@
         INNER JOIN student_report_plan_class_relation t2 ON t1.id = t2.class_id
         INNER JOIN student_report_plan t3 ON t2.student_report_plan_id = t3.id
         WHERE t3.delete_mark = 0 AND NOW() BETWEEN t3.start_time AND t3.end_time
-        AND t3.id != #{id}
+        AND t3.id != #{id} and t3.status = 1
         and t1.id in
         <foreach item="classId" index="index" collection="classIds" open="(" close=")" separator=",">
             #{classId}
         </foreach>
     </select>
+
+    <select id="getWillBeginData" resultType="com.xjrsoft.module.student.entity.StudentReportPlan">
+        SELECT * FROM student_report_plan WHERE delete_mark = 0 AND enabled_mark = 1 AND status = 1
+        AND DATE_FORMAT(start_time,'%Y-%m-%d %H:00:00') = DATE_FORMAT(now(),'%Y-%m-%d %H:00:00')
+    </select>
 </mapper>

+ 45 - 11
src/main/resources/mapper/student/StudentReportRecordMapper.xml

@@ -10,19 +10,21 @@
         SELECT COUNT(*) FROM xjr_user a1
         INNER JOIN base_student_school_roll a2 ON a1.id = a2.user_id
         WHERE a1.delete_mark = 0 AND a2.delete_mark = 0
-        AND a2.class_id = t1.id
+        AND a2.class_id = t1.id AND a2.archives_status = 'FB2901'
         ) AS all_count,
         (
         SELECT COUNT(*) FROM xjr_user a1
         INNER JOIN base_student_school_roll a2 ON a1.id = a2.user_id
         WHERE a1.delete_mark = 0 AND a2.delete_mark = 0
         AND a1.gender = 'SB10001' AND a2.class_id = t1.id
+        AND a2.archives_status = 'FB2901'
         ) AS male_count,
         (
         SELECT COUNT(*) FROM xjr_user a1
         INNER JOIN base_student_school_roll a2 ON a1.id = a2.user_id
         WHERE a1.delete_mark = 0 AND a2.delete_mark = 0
         AND a1.gender = 'SB10002' AND a2.class_id = t1.id
+        AND a2.archives_status = 'FB2901'
         ) AS female_count,
         (
         SELECT COUNT(distinct(a1.id)) FROM xjr_user a1
@@ -36,8 +38,18 @@
         ) AS arrived_count
         FROM base_class t1
         INNER JOIN xjr_user t2 ON t1.teacher_id = t2.id
-        WHERE t1.delete_mark = 0 and t1.grade_id = #{dto.gradeId}
-        AND t1.teacher_id = #{dto.teacherId}
+        WHERE t1.delete_mark = 0
+        <if test="dto.teacherId != null">
+            AND t1.teacher_id = #{dto.teacherId}
+        </if>
+        <if test="dto.gradeId != null">
+            and t1.grade_id = #{dto.gradeId}
+        </if>
+        <if test="dto.classId != null">
+            AND t1.id = #{dto.classId}
+        </if>
+
+
     </select>
     <select id="getMobilePage" parameterType="com.xjrsoft.module.student.dto.StudentReportRecordPageDto"
             resultType="com.xjrsoft.module.student.vo.StudentReportRecordPageVo">
@@ -61,7 +73,9 @@
         SELECT t1.id, t1.user_id, t4.name AS grade_name,t5.name AS class_name,t6.name AS teacher_name,
         t3.name,t7.name AS gender,t3.credential_number,t3.mobile,t8.name AS student_type_cn,
         t9.name AS stduy_status_cn,t10.name AS archives_status_cn,
-        t1.report_time,IF(t1.report_time IS NULL, 0, 1) as is_report FROM student_report_record t1
+        t1.report_time,IF(t1.report_time IS NULL, 0, 1) as is_report,
+        (SELECT telephone FROM base_student_family WHERE delete_mark = 0 AND user_id = t1.user_id ORDER BY create_date ASC LIMIT 0,1) as parent_mobile
+        FROM student_report_record t1
         INNER JOIN base_student_school_roll t2 ON t1.user_id = t2.user_id
         INNER JOIN xjr_user t3 ON t3.id = t1.user_id
         LEFT JOIN base_grade t4 ON t2.grade_id = t4.id
@@ -72,7 +86,7 @@
         LEFT JOIN xjr_dictionary_detail t9 ON t2.stduy_status = t9.code
         LEFT JOIN xjr_dictionary_detail t10 ON t2.archives_status = t10.code
         WHERE t1.delete_mark = 0 AND t1.enabled_mark = 1
-        and t1.student_report_plan_id = #{dto.studentReportPlanId}
+            and t1.student_report_plan_id = #{dto.studentReportPlanId}
         <if test="dto.keyword != null and dto.keyword != ''">
             and t1.name like concat('%', #{dto.keyword},'%')
         </if>
@@ -89,7 +103,7 @@
             and t5.name like concat('%', #{dto.className}, '%')
         </if>
         <if test="dto.credentialNumber != null and dto.credentialNumber != ''">
-            and t3.credentialNumber like concat('%', #{dto.credentialNumber}, '%')
+            and t3.credential_number like concat('%', #{dto.credentialNumber}, '%')
         </if>
         <if test="dto.archivesStatus != null and dto.archivesStatus != ''">
             and t2.archives_status = #{dto.archivesStatus}
@@ -114,13 +128,15 @@
         <if test="dto.reportTimeStart != null and dto.reportTimeEnd != null">
             and t1.report_time between #{dto.reportTimeStart} and #{dto.reportTimeEnd}
         </if>
-        ORDER BY t1.report_time IS NULL DESC, t1.report_time DESC
+        ORDER BY t1.report_time IS NULL DESC, t1.report_time DESC,t5.name
     </select>
     <select id="getPlanPageList" parameterType="com.xjrsoft.module.student.dto.StudentReportRecordPageDto" resultType="com.xjrsoft.module.student.vo.StudentReportRecordPlanPageVo">
         SELECT t1.id, t1.user_id, t4.name AS grade_name,t5.name AS class_name,t6.name AS teacher_name,
         t3.name,t7.name AS gender,t3.credential_number,t3.mobile,t8.name AS student_type_cn,
         t9.name AS stduy_status_cn,t10.name AS archives_status_cn,
-        t1.report_time,IF(t1.report_time IS NULL, 0, 1) as is_report FROM student_report_record t1
+        t1.report_time,IF(t1.report_time IS NULL, 0, 1) as is_report,
+        (SELECT telephone FROM base_student_family WHERE delete_mark = 0 AND user_id = t1.user_id ORDER BY create_date ASC LIMIT 0,1) as parent_mobile
+        FROM student_report_record t1
         INNER JOIN base_student_school_roll t2 ON t1.user_id = t2.user_id
         INNER JOIN xjr_user t3 ON t3.id = t1.user_id
         LEFT JOIN base_grade t4 ON t2.grade_id = t4.id
@@ -148,7 +164,7 @@
             and t5.name like concat('%', #{dto.className}, '%')
         </if>
         <if test="dto.credentialNumber != null and dto.credentialNumber != ''">
-            and t3.credentialNumber like concat('%', #{dto.credentialNumber}, '%')
+            and t3.credential_number like concat('%', #{dto.credentialNumber}, '%')
         </if>
         <if test="dto.archivesStatus != null and dto.archivesStatus != ''">
             and t2.archives_status = #{dto.archivesStatus}
@@ -173,12 +189,12 @@
         <if test="dto.reportTimeStart != null and dto.reportTimeEnd != null">
             and t1.report_time between #{dto.reportTimeStart} and #{dto.reportTimeEnd}
         </if>
-        ORDER BY t1.report_time IS NULL DESC, t1.report_time DESC
+        ORDER BY t1.report_time IS NULL DESC, t1.report_time DESC,t5.name
     </select>
     <select id="getStatisticsDataList" parameterType="com.xjrsoft.module.student.dto.StudentReportRecordStatisticsDto"
             resultType="com.xjrsoft.module.student.vo.StudentReportRecordStatisticsListVo">
         SELECT t1.name,t1.credential_number,t2.gender,t4.graduated_university,t4.stduy_status,t5.report_time ,
-        t6.name AS class_name,t8.name as class_type,t7.name AS major_name FROM base_new_student t1
+        t6.name AS class_name,t8.name as class_type,t7.name AS major_name,t9.name as dept_name FROM base_new_student t1
         INNER JOIN xjr_user t2 ON t1.credential_number = t2.credential_number
         INNER JOIN enrollment_plan t3 ON t3.id = t1.enrollment_plan_id
         INNER JOIN base_student_school_roll t4 ON t4.user_id = t2.id
@@ -186,9 +202,27 @@
         INNER JOIN base_class t6 ON t6.id = t4.class_id
         INNER JOIN base_major_set t7 ON t7.id = t6.major_set_id
         left join xjr_dictionary_detail t8 on t6.class_type = t8.code and t8.item_id = 2023000000000000039
+        INNER JOIN xjr_department t9 ON t9.id = t6.org_id
         WHERE t1.delete_mark = 0 AND t2.delete_mark = 0
         AND t3.grade_id = #{dto.gradeId} AND t3.enroll_type = #{dto.enrollType}
         AND (t1.delete_reason IS NULL OR t1.delete_reason = '')
         AND t2.delete_mark = 0
     </select>
+    <select id="getStatisticsPlanDataList" parameterType="com.xjrsoft.module.student.dto.StudentReportRecordStatisticsDto"
+            resultType="com.xjrsoft.module.student.vo.StudentReportRecordStatisticsListVo">
+        SELECT t1.name,t1.credential_number,t1.gender,t4.graduated_university,t4.stduy_status,t5.report_time ,
+        t6.name AS class_name,t8.name AS class_type,t7.name AS major_name,t9.name AS dept_name FROM xjr_user t1
+        INNER JOIN base_student_school_roll t4 ON t4.user_id = t1.id
+        INNER JOIN student_report_record t5 ON t1.id = t5.user_id AND t5.delete_mark = 0
+        INNER JOIN base_class t6 ON t6.id = t4.class_id
+        INNER JOIN base_major_set t7 ON t7.id = t6.major_set_id
+        LEFT JOIN xjr_dictionary_detail t8 ON t6.class_type = t8.code AND t8.item_id = 2023000000000000039
+        INNER JOIN xjr_department t9 ON t9.id = t6.org_id
+        inner join student_report_plan t10 on t5.student_report_plan_id = t10.id
+        WHERE t1.delete_mark = 0 and t10.delete_mark = 0
+        <if test="dto.gradeId != null">
+            and t4.grade_id = #{dto.gradeId}
+        </if>
+        AND t10.semester_id = #{dto.baseSemesterId}
+    </select>
 </mapper>

+ 100 - 45
src/main/resources/sqlScript/20250120_sql.sql

@@ -2,57 +2,55 @@
 -- 2025-01-20 10:36
 -- 需要进行课程管理的班级
 -- ----------------------------
-drop table if exists base_class_admin_course;
-create table `base_class_admin_course`
+DROP TABLE IF EXISTS base_class_admin_course;
+CREATE TABLE `base_class_admin_course`
 (
-    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 '有效标志',
-    sort_code           int           null comment '序号',
-    remark              varchar(1000) null comment '备注',
-
-    class_id         bigint      null comment '班级id(base_class)',
-    base_semester_id bigint      null comment '学期id'
-) engine = innodb
-  default charset = utf8mb4
-  collate = utf8mb4_0900_ai_ci comment ='需要进行课程管理的班级';
+    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 '有效标志',
+    sort_code           INT           NULL COMMENT '序号',
+    remark              VARCHAR(1000) NULL COMMENT '备注',
+
+    class_id         BIGINT      NULL COMMENT '班级id(base_class)',
+    base_semester_id BIGINT      NULL COMMENT '学期id'
+) ENGINE = INNODB
+  DEFAULT CHARSET = utf8mb4
+  COLLATE = utf8mb4_0900_ai_ci COMMENT ='需要进行课程管理的班级';
 
-alter table base_class_course
-    modify class_id bigint null comment '需要进行课程管理的班级id(base_class_admin_course)(原有班级主键id字段)';
+ALTER TABLE base_class_course
+    MODIFY class_id BIGINT NULL COMMENT '需要进行课程管理的班级id(base_class_admin_course)(原有班级主键id字段)';
 
-alter table textbook_subscription_item
-    add use_class_num int default 0 null comment '在本次征订中本征订项的教材使用的班级数量';
+ALTER TABLE textbook_subscription_item
+    ADD use_class_num INT DEFAULT 0 NULL COMMENT '在本次征订中本征订项的教材使用的班级数量';
 
 -- ----------------------------
 -- 2025-01-22 14:36
 -- 教材征订记录详情与班级关联表
 -- ----------------------------
-drop table if exists textbook_subscription_item_class;
-create table `textbook_subscription_item_class`
+DROP TABLE IF EXISTS textbook_subscription_item_class;
+CREATE TABLE `textbook_subscription_item_class`
 (
-    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 '有效标志',
-    sort_code                int           null comment '序号',
-    remark                   varchar(1000) null comment '备注',
-
-    textbook_subscription_item_id bigint        not null comment '教材征订记录详情表id(textbook_subscription)',
-    base_class_id            bigint        not null comment '按班级征订中征订的班级主键(base_class)'
-) engine = innodb
-  default charset = utf8mb4
-  collate = utf8mb4_0900_ai_ci comment ='教材征订记录详情与班级关联表';
-
+    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 '有效标志',
+    sort_code                INT           NULL COMMENT '序号',
+    remark                   VARCHAR(1000) NULL COMMENT '备注',
 
+    textbook_subscription_item_id BIGINT        NOT NULL COMMENT '教材征订记录详情表id(textbook_subscription)',
+    base_class_id            BIGINT        NOT NULL COMMENT '按班级征订中征订的班级主键(base_class)'
+) ENGINE = INNODB
+  DEFAULT CHARSET = utf8mb4
+  COLLATE = utf8mb4_0900_ai_ci COMMENT ='教材征订记录详情与班级关联表';
 
 DROP TABLE IF EXISTS student_change_record;
 CREATE TABLE `student_change_record`  (
@@ -95,8 +93,6 @@ CREATE TABLE `student_report_plan`  (
   PRIMARY KEY (`id`) USING BTREE
 ) ENGINE = INNODB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '学生报到计划';
 
-
-
 -- ---------------------------------------------------------------
 -- 学生报到计划-班级
 -- ---------------------------------------------------------------
@@ -111,6 +107,65 @@ CREATE TABLE `student_report_plan_class_relation`  (
 ALTER TABLE `student_report_record`
   ADD COLUMN `student_report_plan_id` BIGINT NULL   COMMENT '报到计划id' AFTER `base_semester_id`;
 
-alter table textbook_subscription_item
-    add class_ids varchar(1024) null comment '按班级征订当前征订项的的教材使用的班级的主键';
+ALTER TABLE textbook_subscription_item
+    ADD base_class_ids VARCHAR(1024) NULL COMMENT '按班级征订当前征订项的的教材使用的班级的主键';
+
+ALTER TABLE `base_class`
+  ADD INDEX (`major_set_id`);
+
+alter table textbook_subscription
+    add order_number varchar(256) not null comment '征订单号(标识+当前时间(YYYYMMDDHHmmss)+三位序号)';
+
+alter table textbook_warehouse_record
+    add order_number varchar(256) not null comment '入库单号(标识+当前时间(YYYYMMDDHHmmss)+三位序号)';
+
+alter table textbook_warehouse_record
+    alter column warehouse_number set default 0;
+
+alter table textbook_warehouse_record
+    add actual_warehouse_number int default 0 null comment '实际入库数量(总入库数量 - 退还书店数量)';
 
+alter table textbook_warehouse_record
+    add actual_total_price decimal(10, 2) null comment '实际入库金额(实际入库数量 * 实际价格)';
+
+alter table textbook_warehouse_record
+    add return_bookstore_number int default 0 null comment '退还书店数量' after order_number;
+
+alter table textbook_warehouse_record
+    add issued_number int default 0 null comment '已出库数量';
+
+ALTER TABLE `student_report_record`
+  ADD INDEX (`base_semester_id`),
+  ADD INDEX (`student_report_plan_id`);
+
+alter table textbook_warehouse_record
+    add recede_number int default 0 null comment '领取后退书数量';
+
+alter table textbook_warehouse_record
+    add remain_number int default 0 null comment '剩余库存数量';
+
+-- ----------------------------
+-- 2025-02-10 14:36
+-- 教材入库记录详细入库记录
+-- ----------------------------
+drop table if exists textbook_warehouse_record_detail;
+create table `textbook_warehouse_record_detail`
+(
+    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 '有效标志',
+    sort_code        int            null comment '序号',
+
+    textbook_warehouse_record_id bigint         null comment '教材入库记录主键id(textbook_warehouse_record)',
+
+    warehouse_mode   varchar(20)    null comment '入库方式(xjr_dictionary_item[warehouse_mode])',
+    warehouse_number int            null comment '入库数量',
+    remark           varchar(1000)  null comment '备注'
+) engine = innodb
+  default charset = utf8mb4
+  collate = utf8mb4_0900_ai_ci comment ='教材入库记录详细入库记录';

+ 76 - 68
src/test/java/com/xjrsoft/module/job/JianyuekbBaseDataTaskTest.java

@@ -111,60 +111,18 @@ class JianyuekbBaseDataTaskTest {
             sql = "SELECT * FROM base_class WHERE delete_mark = 0" +
                 " and id not in (SELECT source_id FROM jianyue_data WHERE table_name = 'base_class' AND source_id IS NOT NULL)";
 
-            List<Map<String, Object>> dataList = SqlRunnerAdapter.db().selectList(sql, BaseClass.class);
-            String semesterSerialNo = dataUtil.getCurrenSemeter();
-            Map<String, String> idMap = new HashMap<>();
-            JsonParser jsonParser = new JsonParser();
-            for (Map<String, Object> baseClassMap : dataList) {
-                BaseClass baseClass = SqlRunnerAdapterUtil.convertMapToEntity(baseClassMap, BaseClass.class);
-                String url  = ScheduleUtil.apiUrl + "class/create";
-                JsonObject paramJson = new JsonObject();
-                if(baseClass.getTeacherId() != null && teacherMap.get(baseClass.getTeacherId().toString()) != null){
-                    paramJson.addProperty("teacherSerialNo", teacherMap.get(baseClass.getTeacherId().toString()));
-                }
-                paramJson.addProperty("name", baseClass.getName());
-
-                paramJson.addProperty("semesterSerialNo", semesterSerialNo);
-                paramJson.addProperty("eduYearSerialNo", gradeMap.get(baseClass.getOrgId() + "_" + baseClass.getGradeId().toString()));
-                paramJson.addProperty("extendId", baseClass.getId());
-                if(baseClass.getClassroomId() != null && classroomMap.get(baseClass.getClassroomId().toString()) != null){
-                    paramJson.addProperty("classRoomSerialNo", classroomMap.get(baseClass.getClassroomId().toString()));
-                }
-//                if(ids != null && ids.get(baseClass.getId().toString()) != null){
-//                    url  = ScheduleUtil.apiUrl + "class/update";
-//                    paramJson.addProperty("serialNo", ids.get(baseClass.getId().toString()));
-//                    long timestamp = System.currentTimeMillis();
-//                    //生成签名
-//                    String sign = ScheduleUtil.createSign(timestamp);
-//                    ScheduleUtil.doPost(url, paramJson.toString(), sign, timestamp);
-//                    continue;
-//                }
-
-                //获取时间戳
-                long timestamp = System.currentTimeMillis();
-                //生成签名
-                String sign = ScheduleUtil.createSign(timestamp);
-                String result = ScheduleUtil.doPost(url, paramJson.toString(), sign, timestamp);
-                if(result == null){
-                    continue;
-                }
-                JsonObject resultJson = jsonParser.parse(result).getAsJsonObject();
-                idMap.put(baseClass.getId().toString(), resultJson.get("data").getAsString());
-            }
-            dataUtil.insertRecord("base_class", idMap);
+            tableName = "base_class";
+            dataUtil.insertClass(tableName, gradeMap, teacherMap, currenSemeter, dataMap.get(tableName), classroomMap);
         } catch (Exception e) {
         }
     }
 
     @Test
     void test3() throws Exception {
-        long timestamp = System.currentTimeMillis();
-        //生成签名
-        String sign = ScheduleUtil.createSign(timestamp);
+        DataUtil dataUtil = new DataUtil();
+        String currenSemeter = dataUtil.getCurrenSemeter();
 
-        System.out.println(timestamp);
 
-        System.out.println(sign);
     }
 
     @Test
@@ -208,6 +166,55 @@ class JianyuekbBaseDataTaskTest {
         SqlRunnerAdapter.db().dynamicInsertBatch(tableName, insertList);
     }
 
+    @Test
+    void deleteClass() throws Exception {
+        long timestamp = System.currentTimeMillis();
+        String sign = ScheduleUtil.createSign(timestamp);
+        String url  = ScheduleUtil.apiUrl + "Class/page";
+
+        DataUtil dataUtil = new DataUtil();
+        String currenSemeter = dataUtil.getCurrenSemeter();
+        JsonObject pageJson = new JsonObject();
+        JsonArray semesterSerialNos = new JsonArray();
+        semesterSerialNos.add(currenSemeter);
+        JsonObject paramJson = new JsonObject();
+        paramJson.add("semesterSerialNos", semesterSerialNos);
+        pageJson.addProperty("pageSize", 2000);
+        pageJson.addProperty("pageIndex", 1);
+        JsonParser parser = new JsonParser();
+        String doPost = ScheduleUtil.doPost(url, pageJson.toString(), sign, timestamp);
+        JsonArray dataList = parser.parse(doPost).getAsJsonObject().get("data").getAsJsonObject().get("dataList").getAsJsonArray();
+        List<String> ids = new ArrayList<>();
+
+        for (JsonElement jsonElement : dataList) {
+            JsonObject object = jsonElement.getAsJsonObject();
+            if(!object.get("semesterSerialNo").getAsString().equals(currenSemeter)){
+                continue;
+            }
+            ids.add(object.get("serialNo").getAsString());
+        }
+
+//        url  = ScheduleUtil.apiUrl + "Class/del";
+//        timestamp = System.currentTimeMillis();
+//        sign = ScheduleUtil.createSign(timestamp);
+//        int maxNum = 100;
+//        int cishu = ids.size() / maxNum + 1;
+//        if(ids.size() < maxNum){
+//            maxNum = ids.size();
+//        }
+//        for (int i = 0; i < cishu; i++){
+//            JsonArray delArray = new JsonArray();
+//            for (int j = 0 + (i * maxNum);  j < maxNum; j ++){
+//                delArray.add(ids.get(j));
+//            }
+//
+//            String delResult = ScheduleUtil.doPost(url, delArray.toString(), sign, timestamp);
+//
+//            System.out.println(delResult);
+//        }
+
+    }
+
     @Test
     void updateGrade() throws Exception {
         String url  = ScheduleUtil.apiUrl + "EduYear/page";
@@ -394,7 +401,9 @@ class JianyuekbBaseDataTaskTest {
             paramJson.addProperty("semesterSerialNo", currenSemeter);
             paramJson.addProperty("eduYearSerialNo", gradeMap.get(baseClass.getOrgId() + "_" + baseClass.getGradeId().toString()));
             paramJson.addProperty("extendId", baseClass.getId());
-            paramJson.addProperty("classRoomSerialNo", classroomMap.get(baseClass.getClassroomId().toString()));
+            if(baseClass.getClassroomId() != null){
+                paramJson.addProperty("classRoomSerialNo", classroomMap.get(baseClass.getClassroomId().toString()));
+            }
             paramJson.addProperty("serialNo", classMap3.get(baseClass.getId().toString()));
             paramJson.addProperty("teacherSerialNo", teacherMap.get(baseClass.getTeacherId().toString()));
 
@@ -607,13 +616,12 @@ class JianyuekbBaseDataTaskTest {
             jianyueIds.add("'" + object.get("serialNo").getAsString() + "'");
         }
 
-        DataSource datasource = DatasourceUtil.getDataSource(GlobalConstant.DEFAULT_DATASOURCE_KEY);
-        Db use = Db.use(datasource);
+
         String sql = "SELECT * FROM jianyue_data WHERE table_name = 'base_class' and jianyue_id in (" + jianyueIds.toString().replace("[","").replace("]","") + ")";
-        List<JianyueData> classList = use.query(sql, JianyueData.class);
+        List<Map<String, Object>> classList = SqlRunnerAdapter.db().selectList(sql);
         Map<String, String> classJianyueSourceMap = new HashMap<>();
-        for (JianyueData jianyueData : classList) {
-            classJianyueSourceMap.put(jianyueData.getJianyueId(), jianyueData.getSourceId());
+        for (Map<String, Object> jianyueData : classList) {
+            classJianyueSourceMap.put(jianyueData.get("jianyue_id").toString(), jianyueData.get("source_id").toString());
         }
 
         url  = ScheduleUtil.apiUrl + "class/update";
@@ -628,49 +636,49 @@ class JianyuekbBaseDataTaskTest {
         doPost = ScheduleUtil.doPost(url, paramJson.toString(), sign, timestamp);
 
         sql = "SELECT * FROM base_class WHERE delete_mark = 0 and is_graduate = 1";
-        List<BaseClass> dataList = use.query(sql, BaseClass.class);
-        Map<String, BaseClass> classMap = new HashMap<>();
-        for (BaseClass baseClass : dataList) {
-            classMap.put(baseClass.getId().toString(), baseClass);
+        List<Map<String, Object>> dataList = SqlRunnerAdapter.db().selectList(sql);
+        Map<String, Map<String, Object>> classMap = new HashMap<>();
+        for (Map<String, Object> baseClass : dataList) {
+            classMap.put(baseClass.get("id").toString(), baseClass);
         }
 
         sql = "SELECT * FROM jianyue_data WHERE table_name = 'base_classroom'";
-        List<JianyueData> classroomList = use.query(sql, JianyueData.class);
+        List<Map<String, Object>> classroomList = SqlRunnerAdapter.db().selectList(sql);
         Map<String, String> classroomMap = new HashMap<>();
-        for (JianyueData jianyueData : classroomList) {
-            classroomMap.put(jianyueData.getSourceId(), jianyueData.getJianyueId());
+        for (Map<String, Object> jianyueData : classroomList) {
+            classroomMap.put(jianyueData.get("source_id").toString(), jianyueData.get("jianyue_id").toString());
         }
 
         sql = "SELECT * FROM jianyue_data WHERE table_name = 'base_teacher'";
-        List<JianyueData> teacherList = use.query(sql, JianyueData.class);
+        List<Map<String, Object>> teacherList = SqlRunnerAdapter.db().selectList(sql);
         Map<String, String> teacherMap = new HashMap<>();
-        for (JianyueData jianyueData : teacherList) {
-            teacherMap.put(jianyueData.getSourceId(), jianyueData.getJianyueId());
+        for (Map<String, Object> jianyueData : teacherList) {
+            teacherMap.put(jianyueData.get("source_id").toString(), jianyueData.get("jianyue_id").toString());
         }
 
         url  = ScheduleUtil.apiUrl + "class/update";
 
 
         for (String jianyueId : classJianyueSourceMap.keySet()) {
-            BaseClass baseClass = classMap.get(classJianyueSourceMap.get(jianyueId));
+            Map<String, Object> baseClass = classMap.get(classJianyueSourceMap.get(jianyueId));
             if(baseClass == null){
                 continue;
             }
             paramJson = new JsonObject();
-            paramJson.addProperty("name", baseClass.getName());
+            paramJson.addProperty("name", baseClass.get("name").toString());
 
             paramJson.addProperty("semesterSerialNo", currenSemeter);
-            paramJson.addProperty("extendId", baseClass.getId());
-            paramJson.addProperty("classRoomSerialNo", classroomMap.get(baseClass.getClassroomId().toString()));
+            paramJson.addProperty("extendId", baseClass.get("id").toString());
+            paramJson.addProperty("classRoomSerialNo", classroomMap.get(baseClass.get("classroom_id").toString()));
             paramJson.addProperty("serialNo", jianyueId);
-            paramJson.addProperty("teacherSerialNo", teacherMap.get(baseClass.getTeacherId().toString()));
+            paramJson.addProperty("teacherSerialNo", teacherMap.get(baseClass.get("teacher_id").toString()));
 
             timestamp = System.currentTimeMillis();
             //生成签名
             sign = ScheduleUtil.createSign(timestamp);
             String result = ScheduleUtil.doPost(url, paramJson.toString(), sign, timestamp);
 
-            System.out.println(baseClass.getName() + " -> " + result);
+            System.out.println(baseClass.get("name").toString() + " -> " + result);
         }
     }
 }

+ 57 - 0
src/test/java/com/xjrsoft/module/job/StudentReportPlanTaskTest.java

@@ -0,0 +1,57 @@
+package com.xjrsoft.module.job;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.xjrsoft.common.enums.DeleteMark;
+import com.xjrsoft.common.enums.EnabledMark;
+import com.xjrsoft.module.student.entity.StudentReportPlan;
+import com.xjrsoft.module.student.service.IStudentReportPlanService;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+
+/**
+ * @author dzx
+ * @date 2025/2/10
+ */
+
+@SpringBootTest
+class StudentReportPlanTaskTest {
+
+    @Autowired
+    private IStudentReportPlanService planService;
+
+
+    @Test
+    public void execute() {
+        doExecute();
+    }
+
+
+    public void doExecute(){
+        //查询已发布未开始的,自动开始
+        LocalDateTime now = LocalDateTime.now();
+        List<StudentReportPlan> list = planService.getWillBeginData();
+
+        for (StudentReportPlan studentReportPlan : list) {
+            planService.release(planService.getByIdDeep(studentReportPlan.getId()));
+        }
+
+        //查询已发布已结束的,自动结束
+        List<StudentReportPlan> endList = planService.list(
+                new QueryWrapper<StudentReportPlan>().lambda()
+                        .eq(StudentReportPlan::getDeleteMark, DeleteMark.NODELETE.getCode())
+                        .eq(StudentReportPlan::getStatus, 1)
+                        .eq(StudentReportPlan::getEnabledMark, EnabledMark.ENABLED.getCode())
+                        .eq(StudentReportPlan::getDeleteMark, DeleteMark.NODELETE.getCode())
+                        .le(StudentReportPlan::getEndTime, now)
+        );
+        for (StudentReportPlan studentReportPlan : endList) {
+            studentReportPlan.setStatus(2);
+            planService.updateById(studentReportPlan);
+        }
+    }
+}

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

@@ -4360,4 +4360,29 @@ public class FreeMarkerGeneratorTest {
 
         apiGeneratorService.generateCodes(params);
     }
+
+    @Test
+    public void gcTextbookWarehouseRecordDetail() throws IOException {
+        List<TableConfig> tableConfigs = new ArrayList<>();
+        TableConfig mainTable = new TableConfig();
+        mainTable.setTableName("textbook_warehouse_record_detail");//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("textbook");//包名
+        params.setTableConfigs(tableConfigs);
+        params.setPage(true);//是否生成分页接口
+        params.setImport(true);//是否生成导入接口
+        params.setExport(true);//是否生成导出接口
+        params.setOutMainDir(false);//是否生成在主目录,前期测试可设置成false
+        params.setDs(ds);
+
+        IApiGeneratorService apiGeneratorService = new ApiGeneratorServiceImpl();
+
+        apiGeneratorService.generateCodes(params);
+    }
 }