Procházet zdrojové kódy

Merge branch 'pre'

dzx před 1 rokem
rodič
revize
8bfe37243a
21 změnil soubory, kde provedl 534 přidání a 60 odebrání
  1. 8 0
      pom.xml
  2. 1 1
      src/main/java/com/xjrsoft/module/courseTable/service/ICourseTableService.java
  3. 17 4
      src/main/java/com/xjrsoft/module/courseTable/service/impl/CourseTableServiceImpl.java
  4. 77 0
      src/main/java/com/xjrsoft/module/hikvision/controller/OutInController.java
  5. 20 0
      src/main/java/com/xjrsoft/module/hikvision/dto/HikvisionOutinPageDto.java
  6. 6 0
      src/main/java/com/xjrsoft/module/hikvision/mapper/HikvisionDataMapper.java
  7. 16 0
      src/main/java/com/xjrsoft/module/hikvision/service/IHikvisionDataService.java
  8. 25 0
      src/main/java/com/xjrsoft/module/hikvision/service/impl/HikvisionDataServiceImpl.java
  9. 24 33
      src/main/java/com/xjrsoft/module/hikvision/util/FaceImportUtil.java
  10. 87 0
      src/main/java/com/xjrsoft/module/hikvision/vo/HikvisionOutinPageVo.java
  11. 20 1
      src/main/java/com/xjrsoft/module/job/HikvisionLeaveTask.java
  12. 1 1
      src/main/java/com/xjrsoft/module/liteflow/node/StudentLeaveNode.java
  13. 52 17
      src/main/java/com/xjrsoft/module/personnel/controller/FaceManagementController.java
  14. 3 0
      src/main/java/com/xjrsoft/module/schedule/dto/CourseTableAdjustDto.java
  15. 7 0
      src/main/java/com/xjrsoft/module/schedule/entity/CourseTableBak.java
  16. 5 0
      src/main/java/com/xjrsoft/module/student/vo/BaseNewStudentExportVo.java
  17. 4 0
      src/main/java/com/xjrsoft/module/system/service/IFileService.java
  18. 123 0
      src/main/java/com/xjrsoft/module/system/service/impl/FileServiceImpl.java
  19. 24 0
      src/main/java/com/xjrsoft/module/system/vo/ImageVo.java
  20. 10 3
      src/main/resources/mapper/courseTable/CourseTable.xml
  21. 4 0
      src/main/resources/mapper/hikvision/HikvisionDataMapper.xml

+ 8 - 0
pom.xml

@@ -75,6 +75,14 @@
     </properties>
 
     <dependencies>
+        <!-- 引入解决人脸照片方向问题 -->
+        <dependency>
+            <groupId>com.drewnoakes</groupId>
+            <artifactId>metadata-extractor</artifactId>
+            <version>2.16.0</version>
+        </dependency>
+
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter</artifactId>

+ 1 - 1
src/main/java/com/xjrsoft/module/courseTable/service/ICourseTableService.java

@@ -33,7 +33,7 @@ public interface ICourseTableService extends IService<CourseTable> {
 
     CourseTableVo getList(CourseTableDto dto);
 
-    List<CourseListVo> getAdjustList(String teacherId, String adjustDate, String classId);
+    List<CourseListVo> getAdjustList(String teacherId, String adjustDate, String classId, String adjustType);
 
     String getPreCheck(String preCheckType, String courseId, String swapCourseId, String swapDate, String subTeacherId);
 

+ 17 - 4
src/main/java/com/xjrsoft/module/courseTable/service/impl/CourseTableServiceImpl.java

@@ -46,6 +46,7 @@ import com.xjrsoft.module.schedule.dto.ClassOptionDto;
 import com.xjrsoft.module.schedule.dto.CourseTableAdjustDto;
 import com.xjrsoft.module.schedule.dto.CourseTableDto;
 import com.xjrsoft.module.schedule.dto.ScheduleWeekExportQueryDto;
+import com.xjrsoft.module.schedule.entity.CourseTableBak;
 import com.xjrsoft.module.schedule.entity.WfCourseAdjust;
 import com.xjrsoft.module.schedule.mapper.CourseTableBakMapper;
 import com.xjrsoft.module.schedule.util.ScheduleUtil;
@@ -284,7 +285,7 @@ public class CourseTableServiceImpl extends ServiceImpl<CourseTableMapper, Cours
      * 调课顶课查询
      */
     @Override
-    public List<CourseListVo> getAdjustList(String teacherId, String adjustDate, String classId) {
+    public List<CourseListVo> getAdjustList(String teacherId, String adjustDate, String classId, String adjustType) {
         CourseTableAdjustDto dto = new CourseTableAdjustDto();
         if (adjustDate != null && !"".equals(adjustDate)) {
             DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
@@ -297,6 +298,7 @@ public class CourseTableServiceImpl extends ServiceImpl<CourseTableMapper, Cours
         if(teacherId != null && !"".equals(teacherId)){
             dto.setTeacherId(Long.parseLong(teacherId));
         }
+        dto.setAdjustType(adjustType);
 
         List<CourseListVo> list = courseTableMapper.getAdjustList(dto);
         for (CourseListVo courseListVo : list) {
@@ -355,7 +357,14 @@ public class CourseTableServiceImpl extends ServiceImpl<CourseTableMapper, Cours
 
                 //调课,将双方课程的日期(schedule_date)、时段(time_period)、节次(time_number)、周(week)、星期几(1-7)(weeks)、星期中文(weeks_cn)对调
                 CourseTable courseTable = courseTableMapper.selectById(courseId);
+                CourseTableBak courseBak = BeanUtil.toBean(courseTable, CourseTableBak.class);
+                courseBak.setWfCourseAdjustId(courseAdjust.getId());
+                courseTableBakMapper.insert(courseBak);
+
                 CourseTable swapCourseTable = courseTableMapper.selectById(exchangeCourseId);
+                CourseTableBak swapCourseBak = BeanUtil.toBean(swapCourseTable, CourseTableBak.class);
+                swapCourseBak.setWfCourseAdjustId(courseAdjust.getId());
+                courseTableBakMapper.insert(swapCourseBak);
 
                 CourseTable courseTableBak = BeanUtil.toBean(courseTable, CourseTable.class);
                 CourseTable swapCourseTableBak = BeanUtil.toBean(swapCourseTable, CourseTable.class);
@@ -378,16 +387,20 @@ public class CourseTableServiceImpl extends ServiceImpl<CourseTableMapper, Cours
                 swapCourseTable.setAdjustType(courseAdjust.getAdjustType());
                 courseTableMapper.updateById(swapCourseTable);
             }
-
             //提交调课接口
             //sendExchange(courseTableBak, swapCourseTableBak, courseAdjust);
-
         } else if (CourseAdjustTypeEnum.courseSubstitute.getCode().equals(courseAdjust.getAdjustType())) {
             String[] courseIds = courseAdjust.getCourseId().split(",");
             for (String courseId : courseIds) {
                 CourseTable courseTable = courseTableMapper.selectById(courseId);
+
+                CourseTableBak courseBak = BeanUtil.toBean(courseTable, CourseTableBak.class);
+                courseBak.setWfCourseAdjustId(courseAdjust.getId());
+                courseTableBakMapper.insert(courseBak);
+
+                String teacherId = courseTable.getTeacherId().replace(courseAdjust.getUserId().toString(), courseAdjust.getExchangeTeacherId().toString());
                 courseTable.setAdjustType(courseAdjust.getAdjustType());
-                courseTable.setTeacherId(courseAdjust.getExchangeTeacherId().toString());
+                courseTable.setTeacherId(teacherId);
                 courseTableMapper.updateById(courseTable);
             }
 

+ 77 - 0
src/main/java/com/xjrsoft/module/hikvision/controller/OutInController.java

@@ -0,0 +1,77 @@
+package com.xjrsoft.module.hikvision.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.xjrsoft.common.model.result.RT;
+import com.xjrsoft.common.page.PageOutput;
+import com.xjrsoft.module.hikvision.dto.HikvisionOutinPageDto;
+import com.xjrsoft.module.hikvision.service.IHikvisionDataService;
+import com.xjrsoft.module.hikvision.util.ApiUtil;
+import com.xjrsoft.module.hikvision.vo.HikvisionOutinPageVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping("/hikvision/outin")
+@Api(value = "/hikvision/outin", tags = "海康出入记录")
+@AllArgsConstructor
+@Slf4j
+public class OutInController {
+
+    private final IHikvisionDataService hkvisionDataService;
+
+    @GetMapping("/page")
+    @ApiOperation(value="海康记录查询(分页)")
+    @SaCheckPermission("outin:detail")
+    public RT<PageOutput<HikvisionOutinPageVo>> page(@Valid HikvisionOutinPageDto dto){
+        ApiUtil apiUtil = new ApiUtil();
+        String apiPath = "/api/acs/v2/door/events";
+
+        JsonObject paramJson = new JsonObject();
+        JsonArray eventList = new JsonArray();
+        eventList.add(196893); // 只获取人脸通过的
+        paramJson.addProperty("pageNo", dto.getLimit());
+        paramJson.addProperty("pageSize", dto.getSize());
+        paramJson.add("eventTypes", eventList);
+        String hikvisionId = hkvisionDataService.getHikvisionIdBySourceId(dto.getUserId().toString());
+
+        JsonArray personIds = new JsonArray();
+        personIds.add(hikvisionId);
+        paramJson.add("personIds", personIds);
+        paramJson.addProperty("sort", "eventTime");
+        paramJson.addProperty("order", "desc");
+
+        String doPost = apiUtil.doPost(apiPath, paramJson.toString(), null);
+        JsonParser parser = new JsonParser();
+        JsonObject data = parser.parse(doPost).getAsJsonObject().get("data").getAsJsonObject();
+        JsonArray list = data.get("list").getAsJsonArray();
+        List<HikvisionOutinPageVo> result = new ArrayList<>();
+        Gson gson = new Gson();
+        for (JsonElement jsonElement : list) {
+            result.add(gson.fromJson(jsonElement.getAsJsonObject(), HikvisionOutinPageVo.class));
+        }
+
+        PageOutput<HikvisionOutinPageVo> output = new PageOutput<>();
+        output.setCurrentPage(dto.getLimit());
+        output.setPageSize(dto.getSize());
+        output.setTotalPage(data.get("totalPage").getAsInt());
+        output.setTotal(data.get("total").getAsInt());
+        output.setList(result);
+        
+        return RT.ok(output);
+    }
+}

+ 20 - 0
src/main/java/com/xjrsoft/module/hikvision/dto/HikvisionOutinPageDto.java

@@ -0,0 +1,20 @@
+package com.xjrsoft.module.hikvision.dto;
+
+import com.xjrsoft.common.page.PageInput;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author dzx
+ * @date 2024年9月19日
+ */
+@Data
+public class HikvisionOutinPageDto extends PageInput {
+
+
+    @ApiModelProperty("用户id")
+    private Long userId;
+
+}

+ 6 - 0
src/main/java/com/xjrsoft/module/hikvision/mapper/HikvisionDataMapper.java

@@ -27,4 +27,10 @@ public interface HikvisionDataMapper extends MPJBaseMapper<HikvisionData> {
      * @return
      */
     String getStudentHikvisionId(Long sourceId);
+
+    /**
+     * 查询学生在海康中的id
+     * @param sourceId
+     */
+    String getHikvisionIdBySourceId(String sourceId);
 }

+ 16 - 0
src/main/java/com/xjrsoft/module/hikvision/service/IHikvisionDataService.java

@@ -0,0 +1,16 @@
+package com.xjrsoft.module.hikvision.service;
+
+import com.github.yulichang.base.MPJBaseService;
+import com.xjrsoft.module.hikvision.entity.HikvisionData;
+/**
+* @title: 海康基础数据对照
+* @Author dzx
+* @Date: 2024年9月19日
+* @Version 1.0
+*/
+
+public interface IHikvisionDataService extends MPJBaseService<HikvisionData> {
+
+    String getHikvisionIdBySourceId(String sourceId);
+
+}

+ 25 - 0
src/main/java/com/xjrsoft/module/hikvision/service/impl/HikvisionDataServiceImpl.java

@@ -0,0 +1,25 @@
+package com.xjrsoft.module.hikvision.service.impl;
+
+import com.github.yulichang.base.MPJBaseServiceImpl;
+import com.xjrsoft.module.hikvision.entity.HikvisionData;
+import com.xjrsoft.module.hikvision.mapper.HikvisionDataMapper;
+import com.xjrsoft.module.hikvision.service.IHikvisionDataService;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+/**
+ * @title: 海康基础数据对照
+ * @Author dzx
+ * @Date: 2024年9月19日
+ * @Version 1.0
+ */
+
+@Service
+@AllArgsConstructor
+public class HikvisionDataServiceImpl extends MPJBaseServiceImpl<HikvisionDataMapper, HikvisionData> implements IHikvisionDataService {
+
+    @Override
+    public String getHikvisionIdBySourceId(String sourceId) {
+        return this.baseMapper.getHikvisionIdBySourceId(sourceId);
+    }
+}

+ 24 - 33
src/main/java/com/xjrsoft/module/hikvision/util/FaceImportUtil.java

@@ -1,21 +1,12 @@
 package com.xjrsoft.module.hikvision.util;
 
-import cn.hutool.core.util.IdUtil;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
-import com.xjrsoft.common.utils.ImageUtil;
-import com.xjrsoft.common.utils.PictureUtil;
 
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.net.URL;
-import java.nio.file.Files;
 import java.util.Base64;
 import java.util.HashMap;
 import java.util.Map;
@@ -128,30 +119,30 @@ public class FaceImportUtil {
                 outputStream.write(buffer, 0, bytesRead);
             }
             byte[] imageBytes = outputStream.toByteArray();
-            //压缩到200k
-            imageBytes = ImageUtil.compressUnderSize(imageBytes, 204800);
-
-            InputStream input = new ByteArrayInputStream(imageBytes);
-            BufferedImage image = ImageIO.read(input);
-            BufferedImage rotatedImage = PictureUtil.rotatePhonePhoto(image, 1);
-
-            imageBytes = PictureUtil.convertBufferedImageToByteArray(rotatedImage);
-
-            //压缩之后,存入本地
-            String[] split = imageUrl.split("\\.");
-            String suffix = split[split.length - 1];
-            String filePath = "/" + IdUtil.getSnowflakeNextId() + "." + suffix;
-            FileOutputStream fos = new FileOutputStream(filePath);
-            fos.write(imageBytes);
-            fos.close();
-            //再读取出来
-            File file = new File(filePath);
-            imageBytes = Files.readAllBytes(file.toPath());
-
-            //删除文件
-            if(file.exists()){
-                file.delete();
-            }
+//            //压缩到200k
+//            imageBytes = ImageUtil.compressUnderSize(imageBytes, 204800);
+//
+//            InputStream input = new ByteArrayInputStream(imageBytes);
+//            BufferedImage image = ImageIO.read(input);
+//            BufferedImage rotatedImage = PictureUtil.rotatePhonePhoto(image, 1);
+//
+//            imageBytes = PictureUtil.convertBufferedImageToByteArray(rotatedImage);
+//
+//            //压缩之后,存入本地
+//            String[] split = imageUrl.split("\\.");
+//            String suffix = split[split.length - 1];
+//            String filePath = "/" + IdUtil.getSnowflakeNextId() + "." + suffix;
+//            FileOutputStream fos = new FileOutputStream(filePath);
+//            fos.write(imageBytes);
+//            fos.close();
+//            //再读取出来
+//            File file = new File(filePath);
+//            imageBytes = Files.readAllBytes(file.toPath());
+//
+//            //删除文件
+//            if(file.exists()){
+//                file.delete();
+//            }
 
             base64String = Base64.getEncoder().encodeToString(imageBytes);
             inputStream.close();

+ 87 - 0
src/main/java/com/xjrsoft/module/hikvision/vo/HikvisionOutinPageVo.java

@@ -0,0 +1,87 @@
+package com.xjrsoft.module.hikvision.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+
+/**
+ * 查询海康门禁点事件返回结果对象
+ * @Author: dzx
+ * @Date: 2024年9月19日
+ */
+@Data
+public class HikvisionOutinPageVo {
+
+
+    @ApiModelProperty("事件ID")
+    private String eventId;
+
+    @ApiModelProperty("事件名称")
+    private String eventName;
+
+    @ApiModelProperty("事件产生时间")
+    private String eventTime;
+
+    @ApiModelProperty("卡号")
+    private String cardNo;
+
+    @ApiModelProperty("人员唯一编码")
+    private String personId;
+
+    @ApiModelProperty("人员名称")
+    private String personName;
+
+    @ApiModelProperty("人员所属组织编码")
+    private String orgIndexCode;
+
+    @ApiModelProperty("人员所属组织名称")
+    private String orgName;
+
+    @ApiModelProperty("门禁点编码")
+    private String doorIndexCode;
+
+    @ApiModelProperty("门禁点名称")
+    private String doorName;
+
+    @ApiModelProperty("门禁点所在区域编码")
+    private String doorRegionIndexCode;
+
+    @ApiModelProperty("抓拍图片地址")
+    private String picUri;
+
+    @ApiModelProperty("图片存储服务的唯一标识")
+    private String svrIndexCode;
+
+    @ApiModelProperty("事件类型")
+    private String eventType;
+
+    @ApiModelProperty("进出类型(1:进 0:出 1:未知)")
+    private Integer inAndOutType;
+
+    @ApiModelProperty("读卡器IndexCode")
+    private String readerDevIndexCode;
+
+    @ApiModelProperty("读卡器名称")
+    private String readerDevName;
+
+    @ApiModelProperty("控制器设备IndexCode")
+    private String devIndexCode;
+
+    @ApiModelProperty("控制器名称")
+    private String devName;
+
+    @ApiModelProperty("身份证图片uri")
+    private String identityCardUri;
+
+    @ApiModelProperty("证件号码")
+    private String certNo;
+
+    @ApiModelProperty("事件入库时间")
+    private String receiveTime;
+
+    @ApiModelProperty("工号")
+    private String jobNo;
+
+    @ApiModelProperty("学号")
+    private String studentId;
+}

+ 20 - 1
src/main/java/com/xjrsoft/module/job/HikvisionLeaveTask.java

@@ -109,7 +109,26 @@ public class HikvisionLeaveTask {
         header.put("tagId", "studentleave");
         //调用接口获取到返回内容,并将其存到数据库中
         String result = apiUtil.doPost(apiPath, paramJson.toString(), null, header);
-        System.out.println(result);
+
+        //删除成功后,重新下载
+        //1、创建任务
+        paramJson = new JsonObject();
+        paramJson.addProperty("taskType", 1);
+        apiPath = "/api/acps/v1/download/configuration/task/add";
+        String doPost = apiUtil.doPost(apiPath, paramJson.toString(), null, null);
+
+        JsonParser jsonParser = new JsonParser();
+        JsonObject resultJson = jsonParser.parse(doPost).getAsJsonObject();
+
+        if("0".equals(resultJson.get("code").getAsString()) && "success".equals(resultJson.get("msg").getAsString())){
+            String taskId = resultJson.get("data").getAsJsonObject().get("taskId").getAsString();
+            //2、下载
+            apiPath = "/api/acps/v1/download/configuration/data/add";
+            paramJson = new JsonObject();
+            paramJson.add("resourceInfos", resourceInfos);
+            paramJson.addProperty("taskId", taskId);
+            apiUtil.doPost(apiPath, paramJson.toString(), null, null);
+        }
     }
 
     JsonArray selectResource(ApiUtil apiUtil){

+ 1 - 1
src/main/java/com/xjrsoft/module/liteflow/node/StudentLeaveNode.java

@@ -25,7 +25,7 @@ public class StudentLeaveNode extends NodeComponent {
         Long formId = Convert.toLong(value);
         if (formId != null) {
             // 数据处理
-            studentLeaveService.hikvisionLeave(formId);
+            // studentLeaveService.hikvisionLeave(formId);
             studentLeaveService.noticeParents(formId);
         }
     }

+ 52 - 17
src/main/java/com/xjrsoft/module/personnel/controller/FaceManagementController.java

@@ -6,10 +6,12 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.yulichang.toolkit.MPJWrappers;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
 import com.xjrsoft.common.enums.DeleteMark;
+import com.xjrsoft.common.exception.MyException;
 import com.xjrsoft.common.model.result.RT;
 import com.xjrsoft.common.page.ConventPage;
 import com.xjrsoft.common.page.PageOutput;
@@ -27,9 +29,12 @@ import com.xjrsoft.module.personnel.service.IStundentFaceProcessService;
 import com.xjrsoft.module.personnel.service.ITeacherFaceProcessService;
 import com.xjrsoft.module.personnel.vo.FaceManagementVo;
 import com.xjrsoft.module.system.service.ICodeRuleService;
+import com.xjrsoft.module.system.service.IFileService;
+import com.xjrsoft.module.system.vo.ImageVo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -42,7 +47,10 @@ import org.springframework.web.multipart.MultipartFile;
 
 import javax.validation.Valid;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 @RestController
 @RequestMapping("/personnel" + "/facemanager")
@@ -53,6 +61,7 @@ public class FaceManagementController {
     private ICodeRuleService codeRuleService;
     private final ITeacherFaceProcessService teacherFaceProcessService;
     private final IStundentFaceProcessService stundentFaceProcessService;
+    private final IFileService fileService;
 
     @GetMapping(value = "/page")
     @ApiOperation(value = "人脸列表(分页)")
@@ -147,16 +156,30 @@ public class FaceManagementController {
     @PostMapping(value = "/add")
     @ApiOperation(value = "新增人脸")
     @SaCheckPermission("facemanager:add")
-    public RT<Boolean> add(AddFaceManagementDto dto, @RequestParam("file") MultipartFile file) {
-        FaceManagement faceManagement = BeanUtil.toBean(dto, FaceManagement.class);
-        try {
-            faceManagement.setRegisterBase64(ImageUtil.ImageHandler(file));
-        } catch (Exception e) {
-            return RT.error(e.getMessage());
+    public RT<Long> add(AddFaceManagementDto dto, @RequestParam("file") MultipartFile file) {
+
+        String filename = file.getOriginalFilename();
+        String suffix = StringUtils.substringAfterLast(filename, StringPool.DOT);
+        String[] imgSuffix = new String[]{"png", "jpg", "jpeg"};
+
+        if (!Arrays.asList(imgSuffix).contains(suffix)) {
+            throw new MyException("图片格式不正确!");
         }
-        boolean isSuccess = faceManagementService.add(faceManagement);
+        Map<String, String> map = new HashMap<String, String>() {
+            {
+                put("jpg", "data:image/jpg;base64,");
+                put("jpeg", "data:image/jpeg;base64,");
+                put("png", "data:image/png;base64,");
+            }
+        };
+
+        ImageVo imageVo = fileService.addRubAndHand(file);
+        dto.setFileId(imageVo.getFolderId());
+        FaceManagement faceManagement = BeanUtil.toBean(dto, FaceManagement.class);
+        faceManagement.setRegisterBase64(map.get(suffix) + imageVo.getBase64());
+        faceManagementService.add(faceManagement);
         codeRuleService.useEncode("FACECODE");
-        return RT.ok(isSuccess);
+        return RT.ok(imageVo.getFolderId());
 
     }
 
@@ -165,16 +188,28 @@ public class FaceManagementController {
     @PostMapping(value = "/update")
     @ApiOperation(value = "修改人脸")
     @SaCheckPermission("facemanager:edit")
-    public RT<Boolean> update(UpdateFaceManagementDto dto, @RequestParam(name = "file",required = false) MultipartFile file) {
-        FaceManagement faceManagement = BeanUtil.toBean(dto, FaceManagement.class);
-        if (file != null) {
-            try {
-                faceManagement.setRegisterBase64(ImageUtil.ImageHandler(file));
-            } catch (Exception e) {
-                return RT.error(e.getMessage());
-            }
+    public RT<Long> update(UpdateFaceManagementDto dto, @RequestParam(name = "file",required = false) MultipartFile file) {
+        String filename = file.getOriginalFilename();
+        String suffix = StringUtils.substringAfterLast(filename, StringPool.DOT);
+        String[] imgSuffix = new String[]{"png", "jpg", "jpeg"};
+
+        if (!Arrays.asList(imgSuffix).contains(suffix)) {
+            throw new MyException("图片格式不正确!");
         }
-        return RT.ok(faceManagementService.update(faceManagement));
+        Map<String, String> map = new HashMap<String, String>() {
+            {
+                put("jpg", "data:image/jpg;base64,");
+                put("jpeg", "data:image/jpeg;base64,");
+                put("png", "data:image/png;base64,");
+            }
+        };
+
+        ImageVo imageVo = fileService.addRubAndHand(file);
+        dto.setFileId(imageVo.getFolderId());
+        FaceManagement faceManagement = BeanUtil.toBean(dto, FaceManagement.class);
+        faceManagement.setRegisterBase64(map.get(suffix) + imageVo.getBase64());
+        faceManagementService.update(faceManagement);
+        return RT.ok(imageVo.getFolderId());
 
     }
 

+ 3 - 0
src/main/java/com/xjrsoft/module/schedule/dto/CourseTableAdjustDto.java

@@ -27,4 +27,7 @@ public class CourseTableAdjustDto implements Serializable {
     @ApiModelProperty("班级id")
     private String classId;
 
+    @ApiModelProperty("调课类型")
+    private String adjustType;
+
 }

+ 7 - 0
src/main/java/com/xjrsoft/module/schedule/entity/CourseTableBak.java

@@ -8,6 +8,7 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 
 /**
@@ -91,6 +92,12 @@ public class CourseTableBak implements Serializable {
     @ApiModelProperty("简约课表的id")
     private String jianyueId;
 
+    @ApiModelProperty("上课日期")
+    private LocalDate scheduleDate;
+
+    @ApiModelProperty("调课顶课(顶课:course_substitute 调课:course_exchange)")
+    private String adjustType;
+
     @ApiModelProperty("调顶课申请的id")
     private Long wfCourseAdjustId;
 }

+ 5 - 0
src/main/java/com/xjrsoft/module/student/vo/BaseNewStudentExportVo.java

@@ -26,6 +26,11 @@ public class BaseNewStudentExportVo {
     @ExcelProperty("学生姓名")
     private String name;
 
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("毕业学校")
+    @ApiModelProperty("毕业学校")
+    private String graduateSchool;
+
     @ContentStyle(dataFormat = 49)
     @ExcelProperty("性别")
     private String genderCn;

+ 4 - 0
src/main/java/com/xjrsoft/module/system/service/IFileService.java

@@ -2,6 +2,8 @@ package com.xjrsoft.module.system.service;
 
 import com.github.yulichang.base.MPJBaseService;
 import com.xjrsoft.module.system.entity.File;
+import com.xjrsoft.module.system.vo.ImageVo;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
 
@@ -20,4 +22,6 @@ public interface IFileService extends MPJBaseService<File> {
     byte[] downloadFileByZip(Long folderId);
 
     byte[] downloadFileByZip(List<Long> folderIds);
+
+    ImageVo addRubAndHand(MultipartFile file);
 }

+ 123 - 0
src/main/java/com/xjrsoft/module/system/service/impl/FileServiceImpl.java

@@ -1,15 +1,32 @@
 package com.xjrsoft.module.system.service.impl;
 
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.drew.imaging.ImageMetadataReader;
+import com.drew.metadata.Directory;
+import com.drew.metadata.Metadata;
+import com.drew.metadata.exif.ExifIFD0Directory;
 import com.github.yulichang.base.MPJBaseServiceImpl;
+import com.xjrsoft.common.exception.MyException;
 import com.xjrsoft.common.utils.FileZipUtil;
+import com.xjrsoft.common.utils.ImageUtil;
+import com.xjrsoft.common.utils.PictureUtil;
+import com.xjrsoft.module.oss.factory.OssFactory;
 import com.xjrsoft.module.system.entity.File;
 import com.xjrsoft.module.system.mapper.FileMapper;
 import com.xjrsoft.module.system.service.IFileService;
+import com.xjrsoft.module.system.vo.ImageVo;
+import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.ResourceLoader;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -18,6 +35,7 @@ import java.net.URLConnection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 /**
  * <p>
@@ -29,6 +47,7 @@ import java.util.Map;
  */
 @Service
 public class FileServiceImpl extends MPJBaseServiceImpl<FileMapper, File> implements IFileService {
+    private static final Long BYTE_SIZE = 1024 * 200L;
 
     @Autowired
     private ResourceLoader resourceLoader;
@@ -111,4 +130,108 @@ public class FileServiceImpl extends MPJBaseServiceImpl<FileMapper, File> implem
         //执行下面这段代码就可以拿到压缩之后的byte数组
         return FileZipUtil.byteAryMap2Zip(byteAryMap);
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public ImageVo addRubAndHand(MultipartFile file) {
+        int anInt = 1;
+        try {
+            // 读取图片的元数据
+            Metadata metadata = ImageMetadataReader.readMetadata(file.getInputStream());
+            Directory exifDirectory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
+            if (exifDirectory != null) {
+                anInt = exifDirectory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
+            }
+        } catch (Exception e) {
+            log.error("读取图片的元数据异常", e);
+        }
+
+        // 处理图片,压缩,调转方向
+        byte[] fileByte = dealPicture(file, anInt);
+
+        // 上传到服务器
+        File savaFile = upLoadPicture(file, fileByte);
+
+        // 将图片转换为base64
+        String base64 = ImageUtil.bytesEncode2Base64(fileByte);
+
+        return new ImageVo(){{
+            setFolderId(savaFile.getFolderId());
+            setBase64(base64);
+        }};
+    }
+
+    private byte[] dealPicture(MultipartFile file, Integer anInt) {
+        byte[] fileByte;
+        try {
+            byte[] imageBytes = file.getBytes();
+            fileByte = ImageUtil.compressUnderSize(imageBytes, BYTE_SIZE);
+            InputStream input = new ByteArrayInputStream(fileByte);
+            BufferedImage image = ImageIO.read(input);
+            BufferedImage rotatedImage = PictureUtil.rotatePhonePhoto(image, anInt);
+
+            fileByte = PictureUtil.convertBufferedImageToByteArray(rotatedImage);
+        } catch (Exception e) {
+            throw new MyException("图片格式不符");
+        }
+
+        if (ObjectUtils.isEmpty(fileByte) || fileByte.length == 0) {
+            throw new MyException("图片格式不符");
+        }
+
+        return fileByte;
+    }
+
+    // 将图片放到服务器上
+    private File upLoadPicture(MultipartFile file, byte[] fileByte) {
+        Long folderId = IdWorker.getId();
+        Long fileId = IdWorker.getId();
+        try {
+            return uploadFile(file, folderId, fileId, fileByte);
+        } catch (Exception e) {
+            throw new MyException("图片服务器异常,稍后重试。");
+        }
+    }
+
+    private File uploadFile(MultipartFile file, Long folderId, Long fileId, byte[] fileByte) throws Exception {
+        String filename = file.getOriginalFilename();
+        String suffix = filename.substring(filename.lastIndexOf("."));// StringUtils.substringAfterLast(filename, StringPool.DOT);
+        //保存到云服务器
+        String filePath;
+        if (fileByte.length <= 0) {
+            throw new RuntimeException("上传文件不能为空");
+        } else {
+            filePath = Objects.requireNonNull(OssFactory.build()).uploadSuffix(fileByte, suffix);
+        }
+//        String filePath = UploadUtil.uploadFile(file);
+
+        File fileEntity = new File();
+        fileEntity.setId(fileId);
+        fileEntity.setFolderId(folderId);
+        fileEntity.setFileName(filename);
+        fileEntity.setFileUrl(filePath);
+        fileEntity.setFileSize(file.getSize());
+        fileEntity.setFileSuffiex(StringPool.DOT + suffix);
+        fileEntity.setFileType(suffix);
+
+//        if (GlobalConstant.imageType.contains(StringUtils.lowerCase(suffix.replace(StringPool.DOT, StringPool.EMPTY)))) {
+//            String thSuffix = StringPool.DOT + ImgUtil.IMAGE_TYPE_JPEG;
+//
+//            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+//            ImgUtil.scale(file.getInputStream(), outputStream, 200, 200, null);
+//
+//            byte[] thBytes = outputStream.toByteArray();
+//
+//            String thUrl = Objects.requireNonNull(OssFactory.build()).uploadSuffix(thBytes, StringPool.DOT + ImgUtil.IMAGE_TYPE_JPEG);
+//            outputStream.close();
+//
+//            fileEntity.setThUrl(thUrl);
+//            fileEntity.setThType(thSuffix);
+//            fileEntity.setThName(file.getOriginalFilename().replace(suffix, StringPool.EMPTY) + "-缩略图");
+//            fileEntity.setThSize(Convert.toLong(thBytes.length));
+//        }
+        this.baseMapper.insert(fileEntity);
+        return fileEntity;
+    }
+
 }

+ 24 - 0
src/main/java/com/xjrsoft/module/system/vo/ImageVo.java

@@ -0,0 +1,24 @@
+package com.xjrsoft.module.system.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @title: DatasourceVo
+ * @Author dzx
+ * @Date: 2024年9月19日
+ * @Version 1.0
+ */
+@Data
+public class ImageVo implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("文件夹id")
+    private Long folderId;
+
+    @ApiModelProperty("图片base64")
+    private String base64;
+
+}

+ 10 - 3
src/main/resources/mapper/courseTable/CourseTable.xml

@@ -46,10 +46,17 @@
         </if>
     </select>
     <select id="getAdjustList" parameterType="com.xjrsoft.module.schedule.dto.CourseTableAdjustDto" resultType="com.xjrsoft.module.schedule.vo.CourseListVo">
-        SELECT t1.time_period,t1.time_number,t1.course_name,t2.name AS class_name,t3.name AS classroom_name,t1.id,t2.id as class_id FROM course_table t1
+        SELECT t1.time_period,t4.short_name as time_number,t1.course_name,t2.name AS class_name,t3.name AS classroom_name,t1.id,t2.id as class_id FROM course_table t1
         LEFT JOIN base_class t2 ON t1.class_id = t2.id
         LEFT JOIN base_classroom t3 ON t1.site_id = t3.id
-        WHERE t1.status = 1 AND t1.teacher_id = #{dto.teacherId}
+        left join class_time t4 on t1.time_number = t4.number and t1.time_period = t4.time_period
+        WHERE t1.status = 1
+        <if test="dto.adjustType != null and dto.adjustType == 'course_exchange'">
+            AND t1.teacher_id = #{dto.teacherId}
+        </if>
+        <if test="dto.adjustType != null and dto.adjustType == 'course_substitute'">
+            AND t1.teacher_id like concat('%', #{dto.teacherId},'%')
+        </if>
         AND t1.weeks = #{dto.week} AND t1.schedule_date = #{dto.adjustDate}
         <if test="dto.classId != null and dto.classId != ''">
             and t1.class_id = #{dto.classId}
@@ -57,7 +64,7 @@
     </select>
     <select id="getClassListByTeacherId" parameterType="com.xjrsoft.module.schedule.dto.ClassOptionDto" resultType="com.xjrsoft.module.schedule.vo.ClassOptionVo">
         SELECT id,name FROM base_class WHERE delete_mark = 0 AND id IN (
-            SELECT DISTINCT class_id FROM course_table WHERE teacher_id = #{dto.userId}
+            SELECT DISTINCT class_id FROM course_table WHERE teacher_id like concat('%', #{dto.userId},'%')
         )
     </select>
 </mapper>

+ 4 - 0
src/main/resources/mapper/hikvision/HikvisionDataMapper.xml

@@ -10,4 +10,8 @@
         SELECT hikvision_id FROM hikvision_data WHERE source_id = #{id} AND table_name = 'base_student'
     </select>
 
+    <select id="getHikvisionIdBySourceId" parameterType="java.lang.String" resultType="java.lang.String">
+        SELECT hikvision_id FROM hikvision_data WHERE source_id = #{id}
+    </select>
+
 </mapper>