Bläddra i källkod

3.3.1 自动升级

xiaofei 1 år sedan
förälder
incheckning
5bc7f4cd6d
22 ändrade filer med 527 tillägg och 25 borttagningar
  1. 41 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/upgrade/Mainfest.java
  2. 4 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/upgrade/MainfestApp.java
  3. 4 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/upgrade/MainfestScript.java
  4. 110 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ClientUpgrade.java
  5. 16 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ClientUpgradeMapper.java
  6. 2 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamDetailMapper.java
  7. 21 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ClientUpgradeService.java
  8. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamDetailService.java
  9. 176 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientUpgradeServiceImpl.java
  10. 2 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailServiceImpl.java
  11. 2 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/CreatePrintPdfUtil.java
  12. 4 4
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/pdf/CreatePdfNewUtil.java
  13. 15 0
      distributed-print-business/src/main/resources/mapper/ClientUpgradeMapper.xml
  14. 4 1
      distributed-print-business/src/main/resources/mapper/ExamDetailMapper.xml
  15. 1 0
      distributed-print-business/src/main/resources/mapper/TBTaskPdfMapper.xml
  16. 10 0
      distributed-print/install/mysql/upgrade/3.3.1.sql
  17. 3 2
      distributed-print/src/main/java/com/qmth/distributed/print/api/ExamDetailController.java
  18. 0 10
      distributed-print/src/main/java/com/qmth/distributed/print/api/SysController.java
  19. 68 0
      distributed-print/src/main/java/com/qmth/distributed/print/api/admin/ClientUpgradeController.java
  20. 5 1
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/UploadFileEnum.java
  21. 38 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/clientpackage/ClientPackageEnum.java
  22. 0 0
      teachcloud-mark/src/main/resources/mapper/ClientUpgradeService.xml

+ 41 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/upgrade/Mainfest.java

@@ -0,0 +1,41 @@
+package com.qmth.distributed.print.business.bean.upgrade;
+
+public class Mainfest {
+
+    private String version;
+    private Integer build;
+    private String platform;
+    private Integer supportMin;
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public Integer getBuild() {
+        return build;
+    }
+
+    public void setBuild(Integer build) {
+        this.build = build;
+    }
+
+    public String getPlatform() {
+        return platform;
+    }
+
+    public void setPlatform(String platform) {
+        this.platform = platform;
+    }
+
+    public Integer getSupportMin() {
+        return supportMin;
+    }
+
+    public void setSupportMin(Integer supportMin) {
+        this.supportMin = supportMin;
+    }
+}

+ 4 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/upgrade/MainfestApp.java

@@ -0,0 +1,4 @@
+package com.qmth.distributed.print.business.bean.upgrade;
+
+public class MainfestApp {
+}

+ 4 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/upgrade/MainfestScript.java

@@ -0,0 +1,4 @@
+package com.qmth.distributed.print.business.bean.upgrade;
+
+public class MainfestScript {
+}

+ 110 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ClientUpgrade.java

@@ -0,0 +1,110 @@
+package com.qmth.distributed.print.business.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+
+import java.io.Serializable;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author xf
+ * @since 2024-03-20
+ */
+@TableName("client_upgrade")
+@ApiModel(value = "ClientUpgrade对象", description = "")
+public class ClientUpgrade implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "platform")
+    private String platform;
+
+    @ApiModelProperty(value = "安装包保存地址")
+    private String installPath;
+
+    @ApiModelProperty(value = "版本名称")
+    private String version;
+
+    @ApiModelProperty(value = "版本号,用于客户端比对版本高低")
+    private Integer build;
+
+    @ApiModelProperty(value = "增量升级最低版本号,低于(含)此版本需要下载安装包重新安装")
+    private Integer supportMin;
+
+    @ApiModelProperty(value = "升级包保存地址")
+    private String upgradePath;
+
+    public ClientUpgrade() {
+    }
+
+    public ClientUpgrade(String platform) {
+        this.platform = platform;
+    }
+
+    public String getPlatform() {
+        return platform;
+    }
+
+    public void setPlatform(String platform) {
+        this.platform = platform;
+    }
+
+    public String getInstallPath() {
+        return installPath;
+    }
+
+    public void setInstallPath(String installPath) {
+        this.installPath = installPath;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public Integer getBuild() {
+        return build;
+    }
+
+    public void setBuild(Integer build) {
+        this.build = build;
+    }
+
+    public Integer getSupportMin() {
+        return supportMin;
+    }
+
+    public void setSupportMin(Integer supportMin) {
+        this.supportMin = supportMin;
+    }
+
+    public String getUpgradePath() {
+        return upgradePath;
+    }
+
+    public void setUpgradePath(String upgradePath) {
+        this.upgradePath = upgradePath;
+    }
+
+    @Override
+    public String toString() {
+        return "ClientUpgrade{" +
+                "platform=" + platform +
+                ", installPath=" + installPath +
+                ", version=" + version +
+                ", build=" + build +
+                ", supportMin=" + supportMin +
+                ", upgradePath=" + upgradePath +
+                "}";
+    }
+}

+ 16 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ClientUpgradeMapper.java

@@ -0,0 +1,16 @@
+package com.qmth.distributed.print.business.mapper;
+
+import com.qmth.distributed.print.business.entity.ClientUpgrade;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author xf
+ * @since 2024-03-20
+ */
+public interface ClientUpgradeMapper extends BaseMapper<ClientUpgrade> {
+
+}

+ 2 - 2
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamDetailMapper.java

@@ -9,7 +9,6 @@ import com.qmth.distributed.print.business.bean.result.ExaminationDetailResult;
 import com.qmth.distributed.print.business.bean.result.ExaminationResult;
 import com.qmth.distributed.print.business.bean.result.ExaminationResult;
 import com.qmth.distributed.print.business.bean.result.SummarizedDataResult;
 import com.qmth.distributed.print.business.bean.result.SummarizedDataResult;
 import com.qmth.distributed.print.business.entity.ExamDetail;
 import com.qmth.distributed.print.business.entity.ExamDetail;
-import com.qmth.distributed.print.business.entity.ExamDetailCourse;
 import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
 import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Param;
 
 
@@ -71,7 +70,8 @@ public interface ExamDetailMapper extends BaseMapper<ExamDetail> {
                                                   @Param("dpr") DataPermissionRule dpr);
                                                   @Param("dpr") DataPermissionRule dpr);
 
 
     IPage<ExaminationDetailResult> findDetailPageById(@Param("page") Page<ExaminationDetailResult> page,
     IPage<ExaminationDetailResult> findDetailPageById(@Param("page") Page<ExaminationDetailResult> page,
-                                                      @Param("examDetailId") Long examDetailId);
+                                                      @Param("examDetailId") Long examDetailId,
+                                                      @Param("param") String param);
 
 
     PrintTaskTotalDto taskTotalData(@Param("schoolId") Long schoolId,
     PrintTaskTotalDto taskTotalData(@Param("schoolId") Long schoolId,
                                     @Param("semesterId") Long semesterId,
                                     @Param("semesterId") Long semesterId,

+ 21 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ClientUpgradeService.java

@@ -0,0 +1,21 @@
+package com.qmth.distributed.print.business.service;
+
+import com.qmth.distributed.print.business.entity.ClientUpgrade;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.teachcloud.common.enums.clientpackage.ClientPackageEnum;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author xf
+ * @since 2024-03-20
+ */
+public interface ClientUpgradeService extends IService<ClientUpgrade> {
+
+    void upload(MultipartFile file, String md5, ClientPackageEnum type);
+
+    ClientUpgrade getByPlatform(String platform);
+}

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamDetailService.java

@@ -136,7 +136,7 @@ public interface ExamDetailService extends IService<ExamDetail> {
     IPage<ExaminationDetailResult> findExaminationDetail(Long schoolId, Long semesterId, Long examId, List<Long> printPlanIdList, String courseCode, String paperNumber, String examPlace,
     IPage<ExaminationDetailResult> findExaminationDetail(Long schoolId, Long semesterId, Long examId, List<Long> printPlanIdList, String courseCode, String paperNumber, String examPlace,
                                                          String examRoom, String studentParams, Long startDate, Long endDate, int pageNumber, int pageSize);
                                                          String examRoom, String studentParams, Long startDate, Long endDate, int pageNumber, int pageSize);
 
 
-    IPage<ExaminationDetailResult> findExaminationDetail(Long convertIdToLong, int pageNumber, int pageSize);
+    IPage<ExaminationDetailResult> findExaminationDetail(Long convertIdToLong, String param, int pageNumber, int pageSize);
 
 
     /**
     /**
      * 查询印刷计划下考点数据源
      * 查询印刷计划下考点数据源

+ 176 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientUpgradeServiceImpl.java

@@ -0,0 +1,176 @@
+package com.qmth.distributed.print.business.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.distributed.print.business.bean.upgrade.Mainfest;
+import com.qmth.distributed.print.business.entity.ClientUpgrade;
+import com.qmth.distributed.print.business.mapper.ClientUpgradeMapper;
+import com.qmth.distributed.print.business.service.ClientUpgradeService;
+import com.qmth.teachcloud.common.bean.vo.FilePathVo;
+import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
+import com.qmth.teachcloud.common.enums.UploadFileEnum;
+import com.qmth.teachcloud.common.enums.clientpackage.ClientPackageEnum;
+import com.qmth.teachcloud.common.service.FileUploadService;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Objects;
+import java.util.StringJoiner;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+/**
+ * <p>
+ * 服务实现类
+ * </p>
+ *
+ * @author xf
+ * @since 2024-03-20
+ */
+@Service
+public class ClientUpgradeServiceImpl extends ServiceImpl<ClientUpgradeMapper, ClientUpgrade> implements ClientUpgradeService {
+
+    private static String platform = "WINDOWS";
+    private static String MAIN_FEST_JSON = "mainfest.json";
+
+    @Resource
+    private FileUploadService fileUploadService;
+
+    @Override
+    public void upload(MultipartFile file, String md5, ClientPackageEnum type) {
+        try {
+            String fileName = FilenameUtils.getBaseName(file.getOriginalFilename());
+
+            if (ClientPackageEnum.INSTALL.equals(type) && fileName.endsWith(".exe")) {
+                throw ExceptionResultEnum.ERROR.exception("安装包只能上传后缀为[.exe]的文件");
+            }
+            if (ClientPackageEnum.UPGRADE.equals(type) && fileName.endsWith(".zip")) {
+                throw ExceptionResultEnum.ERROR.exception("升级包只能上传后缀为[.zip]的文件");
+            }
+
+            String fileMd5 = DigestUtils.md5Hex(file.getBytes());
+            if (!Objects.equals(fileMd5, md5)) {
+                throw ExceptionResultEnum.MD5_EQUALS_FALSE.exception();
+            }
+
+            ClientUpgrade clientUpgrade = this.getByPlatform(platform);
+            //安装包
+            if (ClientPackageEnum.INSTALL.equals(type)) {
+                // 上传
+                String filePathName = buildPath(true, UploadFileEnum.UPGRADE.getTitle(), "release", platform) + file.getName();
+                FilePathVo filePathVo = fileUploadService.uploadFile(file.getInputStream(), filePathName, UploadFileEnum.UPGRADE);
+                clientUpgrade.setInstallPath(JSON.toJSONString(filePathVo));
+            } else if (ClientPackageEnum.UPGRADE.equals(type)) {
+                // 读取指定文件内容mainfest.josn
+                String mainfestContent = readMainfest(file.getInputStream());
+                if (StringUtils.isBlank(mainfestContent)) {
+                    throw ExceptionResultEnum.ERROR.exception("读取mainfest.json文件内容失败");
+                }
+                // 解析mainfest.josn内容
+                Mainfest mainfest = JSON.parseObject(mainfestContent, Mainfest.class);
+                String version = mainfest.getVersion();
+                if (StringUtils.isBlank(version)) {
+                    throw ExceptionResultEnum.ERROR.exception("version值必填");
+                }
+                Integer build = mainfest.getBuild();
+                if (build == null) {
+                    throw ExceptionResultEnum.ERROR.exception("build值必填");
+                }
+                Integer supportMin = mainfest.getSupportMin();
+                if (supportMin == null) {
+                    throw ExceptionResultEnum.ERROR.exception("supportMin值必填");
+                }
+                // 上传
+                String filePathName = buildPath(true, UploadFileEnum.UPGRADE.getTitle(), "update", platform, version, String.valueOf(build)) + file.getName();
+                FilePathVo filePathVo = fileUploadService.uploadFile(file.getInputStream(), filePathName, UploadFileEnum.UPGRADE);
+                clientUpgrade.setVersion(version);
+                clientUpgrade.setBuild(build);
+                clientUpgrade.setSupportMin(supportMin);
+                clientUpgrade.setUpgradePath(JSON.toJSONString(filePathVo));
+            } else {
+                throw ExceptionResultEnum.ERROR.exception("请选择正确的包类型");
+            }
+            // 保存或更新
+            this.saveOrUpdate(clientUpgrade);
+            // 升级包
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+        }
+    }
+
+    /**
+     * 升级数据查询
+     *
+     * @param platform 平台类型
+     */
+    @Override
+    public ClientUpgrade getByPlatform(String platform) {
+        QueryWrapper<ClientUpgrade> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(ClientUpgrade::getPlatform, platform);
+        ClientUpgrade clientUpgrade = this.getOne(queryWrapper);
+        if (clientUpgrade == null) {
+            clientUpgrade = new ClientUpgrade(platform);
+        }
+        return clientUpgrade;
+    }
+
+    /**
+     * 读取mainfest.json文件
+     *
+     * @param inputStream 文件流
+     */
+    private static String readMainfest(InputStream inputStream) {
+        String jsonContent = null;
+        try (ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
+            ZipEntry zipEntry;
+
+            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
+                String entryName = zipEntry.getName();
+                if (entryName.equals(MAIN_FEST_JSON)) {
+                    // 读取目标文件的内容
+                    StringBuilder content = new StringBuilder();
+                    byte[] buffer = new byte[1024];
+                    int length;
+                    while ((length = zipInputStream.read(buffer)) > 0) {
+                        content.append(new String(buffer, 0, length));
+                    }
+                    jsonContent = content.toString();
+                    break;
+                }
+                zipInputStream.closeEntry();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return jsonContent;
+    }
+
+    /**
+     * 路径拼接
+     *
+     * @param endSeparator 结尾是否带分隔符
+     * @param paths        路径数组
+     */
+    private String buildPath(boolean endSeparator, String... paths) {
+        StringJoiner stringJoiner = new StringJoiner(File.separator);
+        for (String path : paths) {
+            stringJoiner.add(path);
+        }
+        String path = stringJoiner.toString();
+        if (endSeparator) {
+            path = path + File.separator;
+        }
+        return path;
+    }
+
+}

+ 2 - 2
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailServiceImpl.java

@@ -438,8 +438,8 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
 
 
     @Transactional(rollbackFor = Exception.class)
     @Transactional(rollbackFor = Exception.class)
     @Override
     @Override
-    public IPage<ExaminationDetailResult> findExaminationDetail(Long examDetailId, int pageNumber, int pageSize) {
-        return examDetailMapper.findDetailPageById(new Page<>(pageNumber, pageSize), examDetailId);
+    public IPage<ExaminationDetailResult> findExaminationDetail(Long examDetailId, String param, int pageNumber, int pageSize) {
+        return examDetailMapper.findDetailPageById(new Page<>(pageNumber, pageSize), examDetailId, param);
     }
     }
 
 
     @Transactional(rollbackFor = Exception.class)
     @Transactional(rollbackFor = Exception.class)

+ 2 - 2
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/CreatePrintPdfUtil.java

@@ -320,11 +320,11 @@ public class CreatePrintPdfUtil {
             document.add(blank);
             document.add(blank);
 
 
             // 基础信息表格
             // 基础信息表格
-            PdfPTable basicTable = PdfFillUtils.createTable(new float[]{3, 15, 3, 79});
+            PdfPTable basicTable = PdfFillUtils.createTable(new float[]{1, 23, 3, 73});
             List<Map<String, String>> basicPlate = pdfPackageDto.getBasicPlate();
             List<Map<String, String>> basicPlate = pdfPackageDto.getBasicPlate();
             for (Map<String, String> stringMap : basicPlate) {
             for (Map<String, String> stringMap : basicPlate) {
                 basicTable.addCell(PdfFillUtils.createCell("", PdfFillUtils.textFont14, 50f, Element.ALIGN_JUSTIFIED_ALL, 0f));
                 basicTable.addCell(PdfFillUtils.createCell("", PdfFillUtils.textFont14, 50f, Element.ALIGN_JUSTIFIED_ALL, 0f));
-                basicTable.addCell(PdfFillUtils.createCell(stringMap.get("name"), PdfFillUtils.textFont14, 50f, Element.ALIGN_JUSTIFIED_ALL, 0f));
+                basicTable.addCell(PdfFillUtils.createCell(stringMap.get("name"), PdfFillUtils.textFont14, 50f, Element.ALIGN_RIGHT, 0f));
                 basicTable.addCell(PdfFillUtils.createCell(": ", PdfFillUtils.textFont14, 50f, Element.ALIGN_JUSTIFIED_ALL, 0f));
                 basicTable.addCell(PdfFillUtils.createCell(": ", PdfFillUtils.textFont14, 50f, Element.ALIGN_JUSTIFIED_ALL, 0f));
                 basicTable.addCell(PdfFillUtils.createCell(stringMap.get("value"), PdfFillUtils.textFont14, 50f, Element.ALIGN_LEFT, 0f));
                 basicTable.addCell(PdfFillUtils.createCell(stringMap.get("value"), PdfFillUtils.textFont14, 50f, Element.ALIGN_LEFT, 0f));
             }
             }

+ 4 - 4
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/pdf/CreatePdfNewUtil.java

@@ -262,11 +262,11 @@ public class CreatePdfNewUtil {
                 basicMap.put("value", examDetail.getExamRoom());
                 basicMap.put("value", examDetail.getExamRoom());
                 basicPlate.add(basicMap);
                 basicPlate.add(basicMap);
             } else if ("collegeName".equals(code)) {
             } else if ("collegeName".equals(code)) {
-                Set<String> collegeNames = examStudentList.stream().map(ExamStudent::getCollegeName).collect(Collectors.toSet());
+                Set<String> collegeNames = examStudentList.stream().filter(m -> StringUtils.isNotBlank(m.getCollegeName())).map(ExamStudent::getCollegeName).collect(Collectors.toSet());
                 Map<String, String> basicMap = new HashMap<>();
                 Map<String, String> basicMap = new HashMap<>();
                 basicMap.put("code", code);
                 basicMap.put("code", code);
                 basicMap.put("name", name);
                 basicMap.put("name", name);
-                basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, collegeNames));
+                basicMap.put("value", CollectionUtils.isEmpty(collegeNames) ? "" : String.join(SystemConstant.COMMA_OF_CHINESE, collegeNames));
                 basicPlate.add(basicMap);
                 basicPlate.add(basicMap);
             } else if ("majorName".equals(code)) {
             } else if ("majorName".equals(code)) {
                 Set<String> stringSet = new HashSet<>();
                 Set<String> stringSet = new HashSet<>();
@@ -277,7 +277,7 @@ public class CreatePdfNewUtil {
                 Map<String, String> basicMap = new HashMap<>();
                 Map<String, String> basicMap = new HashMap<>();
                 basicMap.put("code", code);
                 basicMap.put("code", code);
                 basicMap.put("name", name);
                 basicMap.put("name", name);
-                basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, stringSet));
+                basicMap.put("value", CollectionUtils.isEmpty(stringSet) ? "" : String.join(SystemConstant.COMMA_OF_CHINESE, stringSet));
                 basicPlate.add(basicMap);
                 basicPlate.add(basicMap);
             } else if ("clazzName".equals(code)) {
             } else if ("clazzName".equals(code)) {
                 Set<String> stringSet = new HashSet<>();
                 Set<String> stringSet = new HashSet<>();
@@ -292,7 +292,7 @@ public class CreatePdfNewUtil {
                 Map<String, String> basicMap = new HashMap<>();
                 Map<String, String> basicMap = new HashMap<>();
                 basicMap.put("code", code);
                 basicMap.put("code", code);
                 basicMap.put("name", name);
                 basicMap.put("name", name);
-                basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, stringSet));
+                basicMap.put("value", CollectionUtils.isEmpty(stringSet) ? "" : String.join(SystemConstant.COMMA_OF_CHINESE, stringSet));
                 basicPlate.add(basicMap);
                 basicPlate.add(basicMap);
             } else if ("paperCount".equals(code)) {
             } else if ("paperCount".equals(code)) {
                 Map<String, String> basicMap = new HashMap<>();
                 Map<String, String> basicMap = new HashMap<>();

+ 15 - 0
distributed-print-business/src/main/resources/mapper/ClientUpgradeMapper.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qmth.distributed.print.business.mapper.ClientUpgradeMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qmth.distributed.print.business.entity.ClientUpgrade">
+        <id column="id" property="id" />
+        <result column="install_path" property="installPath" />
+        <result column="version" property="version" />
+        <result column="build" property="build" />
+        <result column="support_min" property="supportMin" />
+        <result column="mainfest_path" property="mainfestPath" />
+    </resultMap>
+
+</mapper>

+ 4 - 1
distributed-print-business/src/main/resources/mapper/ExamDetailMapper.xml

@@ -365,9 +365,12 @@
                 LEFT JOIN
                 LEFT JOIN
             basic_semester bs ON bs.id = be.semester_id
             basic_semester bs ON bs.id = be.semester_id
         <where>
         <where>
-            <if test="examDetailId != null and examDetailId > 0">
+            <if test="examDetailId != null">
                 AND det.id = #{examDetailId}
                 AND det.id = #{examDetailId}
             </if>
             </if>
+            <if test="param != null and param != ''">
+                AND (stu.student_name like concat('%', #{param}) or stu.student_code like concat('%', #{param}))
+            </if>
         </where>
         </where>
         order by stu.can_delete desc, stu.student_code
         order by stu.can_delete desc, stu.student_code
     </select>
     </select>

+ 1 - 0
distributed-print-business/src/main/resources/mapper/TBTaskPdfMapper.xml

@@ -72,6 +72,7 @@
                 and ed.exam_end_time &lt;= #{examEndTime}
                 and ed.exam_end_time &lt;= #{examEndTime}
             </if>
             </if>
         </where>
         </where>
+        order by tp.id desc
     </select>
     </select>
 
 
 </mapper>
 </mapper>

+ 10 - 0
distributed-print/install/mysql/upgrade/3.3.1.sql

@@ -656,3 +656,13 @@ ALTER TABLE t_c_final_score MODIFY COLUMN course_name varchar(100) NULL COMMENT
 ALTER TABLE t_c_usual_score DROP KEY t_c_score_normal_unique;
 ALTER TABLE t_c_usual_score DROP KEY t_c_score_normal_unique;
 ALTER TABLE t_c_usual_score ADD CONSTRAINT t_c_usual_score_unique UNIQUE KEY (exam_id,course_code,paper_number,name,student_code);
 ALTER TABLE t_c_usual_score ADD CONSTRAINT t_c_usual_score_unique UNIQUE KEY (exam_id,course_code,paper_number,name,student_code);
 ALTER TABLE t_c_usual_score MODIFY COLUMN course_name varchar(100) NULL COMMENT '课程名称';
 ALTER TABLE t_c_usual_score MODIFY COLUMN course_name varchar(100) NULL COMMENT '课程名称';
+
+CREATE TABLE `client_upgrade` (
+          `platform` VARCHAR(20) NOT NULL COMMENT '系统',
+          `install_path` VARCHAR(200) NULL COMMENT '安装包保存地址',
+          `version` VARCHAR(20) NULL COMMENT '版本名称',
+          `build` VARCHAR(45) NULL COMMENT '版本号,用于客户端比对版本高低',
+          `support_min` VARCHAR(45) NULL COMMENT '增量升级最低版本号,低于(含)此版本需要下载安装包重新安装',
+          `upgrade_path` VARCHAR(200) NULL COMMENT '升级包保存地址',
+          `mainfest_path` VARCHAR(200) NULL COMMENT 'mainfest.json文件保存路径',
+          PRIMARY KEY (`platform`));

+ 3 - 2
distributed-print/src/main/java/com/qmth/distributed/print/api/ExamDetailController.java

@@ -168,10 +168,11 @@ public class ExamDetailController {
     @ApiOperation(value = "考务数据导入-查看明细弹窗")
     @ApiOperation(value = "考务数据导入-查看明细弹窗")
     @RequestMapping(value = "/data_detail_list", method = RequestMethod.POST)
     @RequestMapping(value = "/data_detail_list", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
     @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
-    public Result findExaminationDetailById(@ApiParam(value = "考务场次id", required = true) @RequestParam String examDetailId,
+    public Result findExaminationDetailById(@ApiParam(value = "考场ID", required = true) @RequestParam String examDetailId,
+                                            @ApiParam(value = "姓名/学号") @RequestParam(required = false) String param,
                                             @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
                                             @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
                                             @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
                                             @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
-        return ResultUtil.ok(examDetailService.findExaminationDetail(SystemConstant.convertIdToLong(examDetailId), pageNumber, pageSize));
+        return ResultUtil.ok(examDetailService.findExaminationDetail(SystemConstant.convertIdToLong(examDetailId),param, pageNumber, pageSize));
     }
     }
 
 
     @ApiOperation(value = "考务数据导入-考点模糊查询")
     @ApiOperation(value = "考务数据导入-考点模糊查询")

+ 0 - 10
distributed-print/src/main/java/com/qmth/distributed/print/api/SysController.java

@@ -89,16 +89,6 @@ public class SysController {
 
 
     @Resource
     @Resource
     BasicMajorService basicMajorService;
     BasicMajorService basicMajorService;
-
-    @Resource
-    BasicClazzService basicClazzService;
-
-    @Resource
-    TeachClazzService teachClazzService;
-
-    @Resource
-    BasicStudentService basicStudentService;
-
     @Resource
     @Resource
     BasicCourseService basicCourseService;
     BasicCourseService basicCourseService;
 
 

+ 68 - 0
distributed-print/src/main/java/com/qmth/distributed/print/api/admin/ClientUpgradeController.java

@@ -0,0 +1,68 @@
+package com.qmth.distributed.print.api.admin;
+
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.distributed.print.business.bean.result.EditResult;
+import com.qmth.distributed.print.business.service.ClientUpgradeService;
+import com.qmth.distributed.print.business.service.PrintCommonService;
+import com.qmth.distributed.print.business.service.TeachCourseService;
+import com.qmth.teachcloud.common.annotation.OperationLogDetail;
+import com.qmth.teachcloud.common.bean.params.BasicCourseParams;
+import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.entity.BasicCourse;
+import com.qmth.teachcloud.common.entity.SysUser;
+import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
+import com.qmth.teachcloud.common.enums.clientpackage.ClientPackageEnum;
+import com.qmth.teachcloud.common.enums.log.CustomizedOperationTypeEnum;
+import com.qmth.teachcloud.common.enums.log.LevelEnum;
+import com.qmth.teachcloud.common.enums.log.OperationTypeEnum;
+import com.qmth.teachcloud.common.service.BasicCourseService;
+import com.qmth.teachcloud.common.util.Result;
+import com.qmth.teachcloud.common.util.ResultUtil;
+import com.qmth.teachcloud.common.util.ServletUtil;
+import io.swagger.annotations.*;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * 客户端升级 前端控制器
+ */
+@Api(tags = "超管-客户端升级Controller")
+@RestController
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_SYS + "/client/package")
+@Validated
+public class ClientUpgradeController {
+
+    @Resource
+    private ClientUpgradeService clientUpgradeService;
+
+    @ApiOperation(value = "上传安装包/升级包")
+    @RequestMapping(value = "/upload", method = RequestMethod.POST)
+    public Result query(@ApiParam(value = "上传文件", required = true) @RequestParam(value = "file") MultipartFile file,
+                        @ApiParam(value = "文件MD5", required = true) @RequestParam(value = "md5") String md5,
+                        @ApiParam(value = "上传文件", required = true) @RequestParam(value = "type") ClientPackageEnum type) {
+        clientUpgradeService.upload(file, md5, type);
+        return ResultUtil.ok(true);
+    }
+
+    @ApiOperation(value = "升级信息接口")
+    @RequestMapping(value = "/external", method = RequestMethod.POST)
+    public Result remove(@RequestBody BasicCourse course) {
+        return ResultUtil.ok();
+    }
+
+}
+

+ 5 - 1
teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/UploadFileEnum.java

@@ -59,7 +59,11 @@ public enum UploadFileEnum {
     /**
     /**
      * 扫描端日志文件(path:{uploadType}/{schoolCode}/{deviceCode}/{fileName})
      * 扫描端日志文件(path:{uploadType}/{schoolCode}/{deviceCode}/{fileName})
      */
      */
-    LOG("log", "public", "%s/%s/%s/%s");
+    LOG("log", "public", "%s/%s/%s/%s"),
+    /**
+     * 安装包/升级包
+     */
+    UPGRADE("upgrade", "private", "");
 
 
 
 
     private String title;
     private String title;

+ 38 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/clientpackage/ClientPackageEnum.java

@@ -0,0 +1,38 @@
+package com.qmth.teachcloud.common.enums.clientpackage;
+
+import java.util.Objects;
+
+/**
+ * 客户端包类型
+ */
+public enum ClientPackageEnum {
+
+    INSTALL("安装包"),
+
+    UPGRADE("升级包");
+
+    private String name;
+
+    private ClientPackageEnum(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * 状态转换 toName
+     *
+     * @param name
+     * @return
+     */
+    public static String convertToName(String name) {
+        for (ClientPackageEnum e : ClientPackageEnum.values()) {
+            if (Objects.equals(name, e.getName())) {
+                return e.name();
+            }
+        }
+        return null;
+    }
+}

+ 0 - 0
teachcloud-mark/src/main/resources/mapper/MarkQuestionMapper.xml → teachcloud-mark/src/main/resources/mapper/ClientUpgradeService.xml