Crazy 4 months ago
parent
commit
1e28262c7c

+ 7 - 0
yudao-module-md/pom.xml

@@ -48,5 +48,12 @@
     </dependency>
         <!-- JNA JSON 依赖 -->
 
+        <!-- ZIP文件中文处理 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-compress</artifactId>
+            <version>1.26.1</version>
+        </dependency>
+
     </dependencies>
 </project>

+ 22 - 10
yudao-module-md/yudao-module-md-biz/src/main/java/Acs/UserManage.java

@@ -8,6 +8,7 @@ import org.json.JSONException;
 import org.json.JSONObject;
 
 import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
@@ -194,11 +195,27 @@ public class UserManage {
     //lsq
     public static String getUserInfo(int lUserID , String employeeNo ) throws JSONException {
         HCNetSDK.BYTE_ARRAY ptrByteArray = new HCNetSDK.BYTE_ARRAY(1024);    //数组
+
+        // 创建一个JSON格式的查询条件
+        String strQueryCondition = String.format("{\"employeeNo\":\"%s\"}", employeeNo);
+
         String strInBuffer = "POST /ISAPI/AccessControl/UserInfo/Search?format=json";
-        System.arraycopy(strInBuffer.getBytes(), 0, ptrByteArray.byValue, 0, strInBuffer.length());//字符串拷贝到数组中
+
+        // 构建完整的请求,包括请求头和请求体
+        StringBuffer strBuffer = new StringBuffer();
+        strBuffer.append(strInBuffer); // 请求行
+        strBuffer.append(" HTTP/1.1\r\n"); // 请求头开始
+        strBuffer.append("Host: 172.16.58.105\r\n"); // 假设的主机头
+        strBuffer.append("Content-Type: application/json\r\n"); // 指定内容类型为JSON
+        strBuffer.append("Content-Length: ").append(strQueryCondition.getBytes().length).append("\r\n\r\n"); // 内容长度和请求头结束
+        strBuffer.append(strQueryCondition); // 请求体
+
+        byte[] strBufferBytes = strBuffer.toString().getBytes(StandardCharsets.UTF_8);
+
+        System.arraycopy( strBufferBytes, 0, ptrByteArray.byValue, 0,  strBuffer.length());//字符串拷贝到数组中
         ptrByteArray.write();
 
-        int lHandler = AcsService.hCNetSDK.NET_DVR_StartRemoteConfig(lUserID, HCNetSDK.NET_DVR_JSON_CONFIG, ptrByteArray.getPointer(), strInBuffer.length(), null, null);
+        int lHandler = AcsService.hCNetSDK.NET_DVR_StartRemoteConfig(lUserID, HCNetSDK.NET_DVR_JSON_CONFIG, ptrByteArray.getPointer(),  strBuffer.length(), null, null);
         HCNetSDK.BYTE_ARRAY ptrOutuff;
         if (lHandler < 0) {
             System.out.println("SearchUserInfo NET_DVR_StartRemoteConfig 失败,错误码为" + AcsService.hCNetSDK.NET_DVR_GetLastError());
@@ -207,15 +224,10 @@ public class UserManage {
 
             Map<String, Object> parameter = new HashMap<>();
             parameter.put("searchID", UUID.randomUUID()); // 查询id
-            parameter.put("maxResults", 30); // 最大查询数量
-
-            // 构造UserInfo对象
-            Map<String, String> userInfoParams = new HashMap<>();
-            userInfoParams.put("employeeNo", employeeNo);
+            parameter.put("maxResults",1); // 最大查询数量
+            parameter.put("UserInfo.employeeNo",employeeNo);//查询学号对应的人
 
-            // 将UserInfo对象包装在parameter中
-            parameter.put("UserInfo", userInfoParams);
-            System.out.println("查询条件"+parameter);
+//            System.out.println("查询条件"+parameter);
 
             String template = "{\n" +
                     "  \"UserInfoSearchCond\": {\n" +

+ 2 - 3
yudao-module-md/yudao-module-md-biz/src/main/java/cn/iocoder/yudao/module/md/controller/admin/AcsController.java

@@ -192,7 +192,6 @@ public class AcsController {
 
     }
 
-    // TODO 他的目标是Excel导入标本的同时导入标本的图片,你只需要修改成导入用户的同时导入人脸识别图片,同时下发到机器中。
     @PostMapping("/import-data")
     @Operation(summary = "信息导入以及图片导入")
     @Parameters({
@@ -206,8 +205,8 @@ public class AcsController {
                                                    @RequestParam("imageFile") MultipartFile imageFile,
                                                    @RequestParam(value = "updateSupport", required = false, defaultValue = "true") Boolean updateSupport) {
         try {
-            acsService.importData(excelFile, imageFile, updateSupport);
-            return CommonResult.success("用户信息及图片导入成功");
+            String result = acsService.importData(excelFile, imageFile, updateSupport);
+            return CommonResult.success(result);
         } catch (Exception e) {
             return CommonResult.error(500, "导入过程中发生错误: " + e.getMessage());
         }

+ 108 - 64
yudao-module-md/yudao-module-md-biz/src/main/java/cn/iocoder/yudao/module/md/service/AcsService.java

@@ -19,6 +19,7 @@ import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqV
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
 import com.sun.jna.Native;
+import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
 import org.apache.tomcat.util.http.fileupload.FileUtils;
 import org.json.JSONException;
 import org.springframework.stereotype.Service;
@@ -29,15 +30,9 @@ import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.annotation.Resource;
 import javax.validation.ConstraintViolationException;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.UnsupportedEncodingException;
+import java.io.*;
 import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
+import java.util.*;
 import java.util.concurrent.CompletableFuture;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
@@ -318,7 +313,7 @@ public class AcsService {
 //            if (existUser == null) {
             // 异步添加用户信息
             AdminUserDO user = userService.findUserByUserNumber(importUser.getEmployeeNo());
-            CompletableFuture<Void> addUserFuture = CompletableFuture.runAsync(() -> {
+//            CompletableFuture<Void> addUserFuture = CompletableFuture.runAsync(() -> {
                 try {
                     //用户名称与那users表里的相同
                     if (user.getNickname().equals(importUser.getName())) {
@@ -328,25 +323,8 @@ public class AcsService {
                 } catch (UnsupportedEncodingException | InterruptedException | JSONException e) {
                     throw new RuntimeException("添加用户信息失败: " + e.getMessage(), e);
                 }
-            });
+//            });
 
-            // 在用户信息添加成功后添加人脸,人脸照片通过学号去找
-            addUserFuture.thenRun(() -> {
-                try {
-                    String photoUrl =user.getPhotoUrl();
-                    //照片不为空
-                    if ( photoUrl!=null){
-                        FaceManage.addFaceByUrl(lUserID, user.getUserNumber(), photoUrl);
-                        System.out.println("照片路由"+photoUrl);
-                    }
-                } catch (JSONException e) {
-                    throw new RuntimeException("添加人脸失败: " + e.getMessage(), e);
-                }
-            }).exceptionally(ex -> {
-                // 处理异常
-                System.err.println("发生异常: " + ex.getMessage());
-                return null;
-            });
 
 //            }
 //            // 2.2.2 如果存在,判断是否允许更新
@@ -367,6 +345,8 @@ public class AcsService {
     private AdminUserService userService;
 
     @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
+    //一定上传了照片的去添加
+//    TODO这里还需判断那个人是否在考勤机的用户列表里
     public String importImages(MultipartFile file) throws Exception {
         // 校验文件类型
         if (!file.getOriginalFilename().endsWith(".zip")) {
@@ -374,51 +354,113 @@ public class AcsService {
         }
         // 创建临时目录存放解压后的文件
         File tempDir = Files.createTempDirectory("specimen_images").toFile();
-        try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) {
+        List<String> successUsers =new LinkedList<>();
+        List<String> failUsers =new LinkedList<>();
+        try (InputStream inputStream = file.getInputStream();
+             ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(inputStream)) {
             ZipEntry entry;
-            while ((entry = zipInputStream.getNextEntry()) != null) {
+            while ((entry = zipInputStream.getNextZipEntry()) != null) {
                 if (!entry.isDirectory()) {
-
-                    //获取去除后缀名的文件名,需要设置成学号
-                    String newFileName = entry.getName().substring(0, entry.getName().lastIndexOf('.'));
-                    System.out.println("文件名:"+newFileName);
-
-                    File newFile = new File(tempDir, entry.getName());
-                    // 进行解压
-                    try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile))) {
-                        byte[] buffer = new byte[1024];
-                        int len;
-                        while ((len = zipInputStream.read(buffer)) > 0) {
-                            bos.write(buffer, 0, len);
+                    //看名字
+                    if (isValidImageName(entry.getName())) {
+                        System.out.println(entry.getName());
+                        //获取去除后缀名的文件名,需要设置成学号
+                        String userNumber = entry.getName().substring(0, entry.getName().lastIndexOf('-'));
+                        String studentName = entry.getName().substring(entry.getName().lastIndexOf('-') + 1, entry.getName().lastIndexOf('.'));
+                        System.out.println("学号:" + userNumber);
+                        System.out.println("学生名字:" + studentName);
+
+                        File newFile = new File(tempDir, entry.getName());
+                        // 进行解压
+                        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile))) {
+                            byte[] buffer = new byte[1024];
+                            int len;
+                            while ((len = zipInputStream.read(buffer)) > 0) {
+                                bos.write(buffer, 0, len);
+                            }
                         }
+                        // 上传文件并获取 URL
+                        AdminUserDO user = userService.findUserByUserNumber(userNumber);
+                        String photoUrl = fileApi.createFile(Files.readAllBytes(newFile.toPath()));
+                        user.setPhotoUrl(photoUrl);
+                        userService.updateUser((BeanUtils.toBean(user, UserSaveReqVO.class)));
+                        //给对应学号的人的照片添加
+                        addFaceByUrl( user.getUserNumber(), photoUrl);
+                        successUsers.add(user.getNickname());
+                    }else{
+                        String userNumber = entry.getName().substring(0, entry.getName().indexOf('-'));
+                        AdminUserDO user = userService.findUserByUserNumber(userNumber);
+                        failUsers.add(user.getNickname());
                     }
-                    File[] imageFiles = tempDir.listFiles();
-                    if (imageFiles != null) {
-                        for (File imageFile : imageFiles) {
-                            String imageName = imageFile.getName();
-                            if (!isValidImageName(imageName)) {
-                                // 如果不符合格式,抛出异常或记录日志
-                                System.err.println("无效的图片格式: " + imageName);
-                                continue;
+                }
+            }
+        }
+        // 清理临时文件
+        FileUtils.deleteDirectory(tempDir);
+        return "添加照片成功的用户{"
+                +successUsers+
+                "}"+
+                "添加照片失败的用户{"
+                +failUsers+
+                "}";
+    }
+
+    public String testImages(MultipartFile file) throws Exception {
+        // 校验文件类型
+        if (!file.getOriginalFilename().endsWith(".zip")) {
+            throw exception(UPLOADED_FOLDER_CANNOT_EMPTY);
+        }
+        // 创建临时目录存放解压后的文件
+        File tempDir = Files.createTempDirectory("specimen_images").toFile();
+        List<String> successUsers =new LinkedList<>();
+        List<String> failUsers =new LinkedList<>();
+        try (InputStream inputStream = file.getInputStream();
+             ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(inputStream)) {
+            ZipEntry entry;
+            while ((entry = zipInputStream.getNextZipEntry()) != null) {
+                if (!entry.isDirectory()) {
+                    //看名字
+                    if (isValidImageName(entry.getName())) {
+                        System.out.println(entry.getName());
+                        //获取去除后缀名的文件名,需要设置成学号
+                        String userNumber = entry.getName().substring(0, entry.getName().lastIndexOf('-'));
+                        String studentName = entry.getName().substring(entry.getName().lastIndexOf('-') + 1, entry.getName().lastIndexOf('.'));
+                        System.out.println("学号:" + userNumber);
+                        System.out.println("学生名字:" + studentName);
+
+                        File newFile = new File(tempDir, entry.getName());
+                        // 进行解压
+                        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile))) {
+                            byte[] buffer = new byte[1024];
+                            int len;
+                            while ((len = zipInputStream.read(buffer)) > 0) {
+                                bos.write(buffer, 0, len);
                             }
-                            // 上传文件并获取 URL
-                            AdminUserDO user = userService.findUserByUserNumber(newFileName);
-                            String photoUrl = fileApi.createFile(Files.readAllBytes(newFile.toPath()));
-                            user.setPhotoUrl(photoUrl);
-                            userService.updateUser( (BeanUtils.toBean(user, UserSaveReqVO.class)));
-                            System.out.println("照片路径: " + photoUrl);
-                            //给对应学号的人的照片添加
-                            addFaceByUrl(newFileName,photoUrl);
                         }
+                        // 上传文件并获取 URL
+//                        AdminUserDO user = userService.findUserByUserNumber(userNumber);
+                        String photoUrl = fileApi.createFile(Files.readAllBytes(newFile.toPath()));
+//                        user.setPhotoUrl(photoUrl);
+//                        userService.updateUser((BeanUtils.toBean(user, UserSaveReqVO.class)));
+                        //给对应学号的人的照片添加
+                        addFaceByUrl( userNumber, photoUrl);
+                        successUsers.add(studentName);
+                    }else{
+                        String userNumber = entry.getName().substring(0, entry.getName().indexOf('-'));
+                        AdminUserDO user = userService.findUserByUserNumber(userNumber);
+                        failUsers.add(user.getNickname());
                     }
-                    System.out.println(111111);
                 }
             }
         }
-
         // 清理临时文件
         FileUtils.deleteDirectory(tempDir);
-        return "导入成功";
+        return "添加照片成功的用户{"
+                +successUsers+
+                "}"+
+                "添加照片失败的用户{"
+                +failUsers+
+                "}";
     }
 
     // 检查多个图片名称格式
@@ -433,20 +475,22 @@ public class AcsService {
         return true;
     }
 
+
     @Transactional(rollbackFor = Exception.class) // 事务管理
-    public void importData(MultipartFile excelFile, MultipartFile imageFile, boolean updateSupport) throws Exception {
+    public String importData(MultipartFile excelFile, MultipartFile imageFile, boolean updateSupport) throws Exception {
 
-        // TODO 这里用的字段太少了,下午和晚上要把字段完善,能够导入
         // 1. 导入用户信息
         List<UserImportExcelVO> list = ExcelUtils.read(excelFile, UserImportExcelVO.class);
         UserImportRespVO importRespVO = importUserList(list, updateSupport);
 
         // 2. 导入图片
-        String imageImportResult = importImages(imageFile);
-
+        String imageImportResult = testImages(imageFile);
         // 可以根据需要记录导入结果
         System.out.println("用户信息导入结果: " + importRespVO);
         System.out.println("图片导入结果: " + imageImportResult);
+
+        return  importRespVO+
+                imageImportResult;
     }
 
 }

+ 21 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java

@@ -346,9 +346,29 @@ public class UserController {
     }
 
 
+    //在校生导入
+    @GetMapping("/get-import-StudentTemplate")
+    @Operation(summary = "获得在校生模板")
+    public void importStudentTemplate(HttpServletResponse response) throws IOException {
+        // 手动创建导出 demo
+        List<StudentImportExcelVO> list = Arrays.asList(
+                StudentImportExcelVO.builder().username("zhang").email("yunai@iocoder.cn").mobile("15601691300")
+                        .nickname("张三").sex(SexEnum.MALE.getSex()).grade("2020").major("遥感科学与技术")
+                        .userNumber("33333333").email("").mobile("").supervisor("").supervisorMobile("")
+                        .build(),
+
+                StudentImportExcelVO.builder().username("").email("yunai@iocoder.cn").mobile("15601691300")
+                        .nickname("李四").sex(SexEnum.MALE.getSex()).grade("2020").major("遥感科学与技术")
+                        .userNumber("33333333").email("").mobile("").supervisor("").supervisorMobile("")
+                        .build()
+        );
+        // 输出
+        ExcelUtils.write(response, "用户导入模板.xls", "用户列表", StudentImportExcelVO.class, list);
+    }
+
     //毕业生
     @GetMapping("/get-import-GraduateStudentTemplate")
-    @Operation(summary = "获得导入用户模板")
+    @Operation(summary = "获得毕业生模板")
     public void importGraduateStudentTemplate(HttpServletResponse response) throws IOException {
         // 手动创建导出 demo
         List<graduateStudentImportExcelVO> list = Arrays.asList(

+ 62 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/StudentImportExcelVO.java

@@ -0,0 +1,62 @@
+package cn.iocoder.yudao.module.system.controller.admin.user.vo.user;
+
+import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
+import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
+import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * 用户 Excel 导入 VO
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Accessors(chain = false) // 设置 chain = false,避免用户导入有问题
+public class StudentImportExcelVO {
+    @ExcelProperty("登录名称")
+    private String username;
+
+    @ExcelProperty("登录密码")
+    private String password;
+
+    @ExcelProperty("年级")
+    private String grade;
+
+    @ExcelProperty("学号")
+    private String userNumber;
+
+    @ExcelProperty("姓名")
+    private String nickname;
+
+    @ExcelProperty("专业")
+    private String major;
+
+    @ExcelProperty("导师")
+    private String supervisor;
+
+    @ExcelProperty(value = "用户性别", converter = DictConvert.class)
+    @DictFormat(DictTypeConstants.USER_SEX)
+    private Integer sex;
+
+
+
+    @ExcelProperty("用户邮箱")
+    private String email;
+
+    @ExcelProperty("手机号码")
+    private String mobile;
+
+
+    @ExcelProperty("导师电话")
+    private String supervisorMobile;
+
+    //导入毕业生直接添加身份
+
+
+}

+ 2 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserImportExcelVO.java

@@ -26,7 +26,8 @@ public class UserImportExcelVO {
     @ExcelProperty("用户名称")
     private String nickname;
 
-    @ExcelProperty("部门编号")
+
+    @ExcelProperty("工作间ID")
     private Long deptId;
 
     @ExcelProperty("用户邮箱")