|
@@ -3,18 +3,14 @@ package cn.iocoder.yudao.module.md.service;
|
|
|
import Acs.*;
|
|
|
import Commom.osSelect;
|
|
|
import NetSDKDemo.HCNetSDK;
|
|
|
-import cn.hutool.core.collection.CollUtil;
|
|
|
-import cn.hutool.core.util.StrUtil;
|
|
|
-import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
|
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
|
|
-import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
|
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
|
|
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
|
|
import cn.iocoder.yudao.module.infra.api.config.ConfigApi;
|
|
|
import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
|
|
-import cn.iocoder.yudao.module.md.controller.admin.vo.UserImportExcelVO;
|
|
|
-import cn.iocoder.yudao.module.md.controller.admin.vo.UserImportRespVO;
|
|
|
+import cn.iocoder.yudao.module.md.controller.admin.vo.attendanceImportExcelVO;
|
|
|
+import cn.iocoder.yudao.module.md.controller.admin.vo.attendanceImportRespVO;
|
|
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|
|
-import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
|
|
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO;
|
|
|
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
|
|
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
|
@@ -32,13 +28,11 @@ import org.springframework.web.multipart.MultipartFile;
|
|
|
import javax.annotation.PostConstruct;
|
|
|
import javax.annotation.PreDestroy;
|
|
|
import javax.annotation.Resource;
|
|
|
-import javax.validation.ConstraintViolationException;
|
|
|
import java.io.*;
|
|
|
import java.nio.file.Files;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
import java.util.zip.ZipEntry;
|
|
|
-import java.util.zip.ZipInputStream;
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
|
@@ -234,16 +228,16 @@ public class AcsService {
|
|
|
public String addFaceByUrl(String userId,String faceURL) throws JSONException {
|
|
|
return FaceManage.addFaceByUrl(lUserID, userId,faceURL);
|
|
|
}
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 查询人脸信息
|
|
|
-// *
|
|
|
-// * @param userId 用户ID
|
|
|
-// */
|
|
|
-// public void searchFace(String userId) throws JSONException {
|
|
|
-// FaceManage.searchFaceInfo(lUserID, userId);
|
|
|
-// }
|
|
|
-//
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询人脸信息
|
|
|
+ *
|
|
|
+ * @param userId 用户ID
|
|
|
+ */
|
|
|
+ public void searchFace(String userId) throws JSONException {
|
|
|
+ FaceManage.searchFaceInfo(lUserID, userId);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 删除人脸信息
|
|
|
*
|
|
@@ -272,51 +266,111 @@ public class AcsService {
|
|
|
|
|
|
|
|
|
//lsq
|
|
|
- static final String USER_INIT_PASSWORD_KEY = "system.user.init-password";
|
|
|
@Resource
|
|
|
private FileApi fileApi;
|
|
|
@Resource
|
|
|
private ConfigApi configApi;
|
|
|
+ @Resource
|
|
|
+ private AdminUserService userService;
|
|
|
+
|
|
|
+ //添加单个用户的照片和信息
|
|
|
+
|
|
|
+ //用户添加自己的照片(也可以对考勤机那添加用户信息照片或更新照片)
|
|
|
+ @Transactional(rollbackFor = Exception.class) //
|
|
|
+ public String addSelfImage(MultipartFile image) throws Exception {
|
|
|
+ if (isValidImageName(image.getName()).equals("照片格式正确")) {
|
|
|
+ Long loginId = SecurityFrameworkUtils.getLoginUserId();
|
|
|
+ AdminUserDO user = userService.getUser(loginId);
|
|
|
+ File newFile = new File(image.getName());
|
|
|
+ String photoUrl = fileApi.createFile(Files.readAllBytes(newFile.toPath()));
|
|
|
+ user.setPhotoUrl(photoUrl);
|
|
|
+ String userNumber = user.getUserNumber();
|
|
|
+ String result =getUser(userNumber);
|
|
|
+ if (result!=null) {
|
|
|
+ Gson gson = new Gson();
|
|
|
+ JsonObject jsonObject = gson.fromJson(result, JsonObject.class);
|
|
|
+ JsonArray userInfoArray = jsonObject
|
|
|
+ .getAsJsonObject("UserInfoSearch")
|
|
|
+ .getAsJsonArray("UserInfo");
|
|
|
+ if (userInfoArray!=null) {
|
|
|
+ JsonObject userInfo = userInfoArray.getAsJsonObject();
|
|
|
+ String empNo = userInfo.get("employeeNo").getAsString();
|
|
|
+ if (empNo != null) {
|
|
|
+ addFaceByUrl(userNumber, user.getPhotoUrl());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ //确保在执行完增加用户后执行增加人脸
|
|
|
+ CompletableFuture<Void> userFuture = CompletableFuture.runAsync(() -> {
|
|
|
+ try {
|
|
|
+ addUser(userNumber, user.getNickname());
|
|
|
+ } catch (JSONException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ } catch (UnsupportedEncodingException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ userFuture.thenRun(() -> {
|
|
|
+ try {
|
|
|
+ addFaceByUrl(userNumber, photoUrl);
|
|
|
+ } catch (JSONException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ return "添加用户并且增加照片成功";
|
|
|
+ }
|
|
|
+ return "更新照片成功";
|
|
|
+ }else{
|
|
|
+ return "照片格式有问题";
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- //导入用户信息与图片
|
|
|
+
|
|
|
+
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public String teacherUpdateUserImage(String employeeNo, MultipartFile image) throws Exception {
|
|
|
+ if (isValidImageName(image.getName()).equals("照片格式正确")) {
|
|
|
+ File newFile = new File(image.getName());
|
|
|
+ String photoUrl = fileApi.createFile(Files.readAllBytes(newFile.toPath()));
|
|
|
+ String result =getUser(employeeNo);
|
|
|
+ if (result!=null) {
|
|
|
+ Gson gson = new Gson();
|
|
|
+ JsonObject jsonObject = gson.fromJson(result, JsonObject.class);
|
|
|
+ JsonArray userInfoArray = jsonObject
|
|
|
+ .getAsJsonObject("UserInfoSearch")
|
|
|
+ .getAsJsonArray("UserInfo");
|
|
|
+ if (userInfoArray!=null) {
|
|
|
+ JsonObject userInfo = userInfoArray.getAsJsonObject();
|
|
|
+ String empNo = userInfo.get("employeeNo").getAsString();
|
|
|
+ if (empNo != null) {
|
|
|
+ String msg = addFaceByUrl(employeeNo,photoUrl);
|
|
|
+ if (msg.contains("下发人脸成功") && !msg.contains("但是有异常情况")) {
|
|
|
+ return "更新照片成功";
|
|
|
+ } else {
|
|
|
+ return "更新照片失败,请检查照片大小";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return "该学号的用户不存在";
|
|
|
+ }else{
|
|
|
+ return "照片格式有问题";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //导入用户信息
|
|
|
@Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
|
|
|
- public UserImportRespVO importUserList(List<UserImportExcelVO> importUsers, boolean isUpdateSupport) {
|
|
|
- // 1.1 参数校验
|
|
|
-// if (CollUtil.isEmpty(importUsers)) {
|
|
|
-// throw exception(USER_IMPORT_LIST_IS_EMPTY);
|
|
|
-// }
|
|
|
-// // 1.2 初始化密码不能为空
|
|
|
-// String initPassword = configApi.getConfigValueByKey(USER_INIT_PASSWORD_KEY);
|
|
|
-// if (StrUtil.isEmpty(initPassword)) {
|
|
|
-// throw exception(USER_IMPORT_INIT_PASSWORD);
|
|
|
-// }
|
|
|
-
|
|
|
- // 2. 遍历,逐个创建 or 更新
|
|
|
- UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>())
|
|
|
+ public attendanceImportRespVO importUserList(List<attendanceImportExcelVO> importUsers, boolean isUpdateSupport) {
|
|
|
+
|
|
|
+ attendanceImportRespVO respVO = attendanceImportRespVO.builder().createUsernames(new ArrayList<>())
|
|
|
.updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
|
|
|
importUsers.forEach(importUser -> {
|
|
|
- // 2.1.1 校验字段是否符合要求
|
|
|
-// try {
|
|
|
-// ValidationUtils.validate(BeanUtils.toBean(importUser, UserSaveReqVO.class).setPassword(initPassword));
|
|
|
-// } catch (ConstraintViolationException ex){
|
|
|
-// respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage());
|
|
|
-// return;
|
|
|
-// }
|
|
|
- // 2.1.2 校验,判断是否有不符合的原因
|
|
|
-// try {
|
|
|
-// validateUserForCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(),
|
|
|
-// importUser.getDeptId(), null);
|
|
|
-// } catch (ServiceException ex) {
|
|
|
-// respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage());
|
|
|
-// return;
|
|
|
-// }
|
|
|
-
|
|
|
-// 2.2.1 判断如果不存在,在进行插入
|
|
|
-// AdminUserDO existUser = userMapper.selectByUsername(importUser.getUsername());
|
|
|
-// if (existUser == null) {
|
|
|
- // 异步添加用户信息
|
|
|
-// AdminUserDO user = userService.findUserByUserNumber(importUser.getEmployeeNo());
|
|
|
-// CompletableFuture<Void> addUserFuture = CompletableFuture.runAsync(() -> {
|
|
|
+
|
|
|
try {
|
|
|
String result = getUser(importUser.getEmployeeNo());
|
|
|
if ( result==null) {
|
|
@@ -337,52 +391,35 @@ public class AcsService {
|
|
|
} catch (UnsupportedEncodingException | InterruptedException | JSONException e) {
|
|
|
throw new RuntimeException("添加用户信息失败: " + e.getMessage(), e);
|
|
|
}
|
|
|
-// });
|
|
|
-
|
|
|
-
|
|
|
-// }
|
|
|
-// // 2.2.2 如果存在,判断是否允许更新
|
|
|
-// if (!isUpdateSupport) {
|
|
|
-// respVO.getFailureUsernames().put(importUser.getUsername(), USER_USERNAME_EXISTS.getMsg());
|
|
|
-// return;
|
|
|
-// }
|
|
|
-// AdminUserDO updateUser = BeanUtils.toBean(importUser, AdminUserDO.class);
|
|
|
-// updateUser.setId(existUser.getId());
|
|
|
-// userMapper.updateById(updateUser);
|
|
|
-// respVO.getUpdateUsernames().add(importUser.getUsername());
|
|
|
+
|
|
|
});
|
|
|
return respVO;
|
|
|
}
|
|
|
|
|
|
|
|
|
- @Resource
|
|
|
- private AdminUserService userService;
|
|
|
-
|
|
|
+ //先插入url到user表再从user表找photoUrl(需要先有用户信息)
|
|
|
@Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
|
|
|
- //一定上传了照片的去添加
|
|
|
-// TODO这里还需判断那个人是否在考勤机的用户列表里
|
|
|
public String importImages(MultipartFile file) throws Exception {
|
|
|
// 校验文件类型
|
|
|
if (!file.getOriginalFilename().endsWith(".zip")) {
|
|
|
throw exception(UPLOADED_FOLDER_CANNOT_EMPTY);
|
|
|
}
|
|
|
// 创建临时目录存放解压后的文件
|
|
|
- File tempDir = Files.createTempDirectory("specimen_images").toFile();
|
|
|
+ File tempDir = Files.createTempDirectory("user_images").toFile();
|
|
|
List<String> successUsers =new LinkedList<>();
|
|
|
List<String> failUsers =new LinkedList<>();
|
|
|
+ List<String> nullUsers =new LinkedList<>();
|
|
|
+ List<String> errorImages =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())) {
|
|
|
+ if (isValidImageName(entry.getName()).equals("照片格式正确")) {
|
|
|
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());
|
|
|
// 进行解压
|
|
@@ -393,18 +430,38 @@ public class AcsService {
|
|
|
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());
|
|
|
+ String result =getUser(userNumber);
|
|
|
+ if (result!=null) {
|
|
|
+ Gson gson = new Gson();
|
|
|
+ JsonObject jsonObject = gson.fromJson(result, JsonObject.class);
|
|
|
+
|
|
|
+ JsonArray userInfoArray = jsonObject
|
|
|
+ .getAsJsonObject("UserInfoSearch")
|
|
|
+ .getAsJsonArray("UserInfo");
|
|
|
+ if (userInfoArray!=null) {
|
|
|
+ JsonObject userInfo = userInfoArray.get(0).getAsJsonObject();
|
|
|
+ String empNo = userInfo.get("employeeNo").getAsString();
|
|
|
+ if (empNo != null) {
|
|
|
+ // 上传文件并获取 URL
|
|
|
+ AdminUserDO user = userService.findUserByUserNumber(userNumber);
|
|
|
+ String photoUrl = fileApi.createFile(Files.readAllBytes(newFile.toPath()));
|
|
|
+ user.setPhotoUrl(photoUrl);
|
|
|
+ userService.updateUser((BeanUtils.toBean(user, UserSaveReqVO.class)));
|
|
|
+ //给对应学号的人的照片添加
|
|
|
+ String msg = addFaceByUrl(user.getUserNumber(), photoUrl);
|
|
|
+ if (msg.contains("下发人脸成功") && !msg.contains("但是有异常情况")) {
|
|
|
+ successUsers.add(studentName);
|
|
|
+ } else {
|
|
|
+ failUsers.add(studentName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ nullUsers.add(studentName);
|
|
|
+ }
|
|
|
+ }
|
|
|
}else{
|
|
|
- String userNumber = entry.getName().substring(0, entry.getName().indexOf('-'));
|
|
|
- AdminUserDO user = userService.findUserByUserNumber(userNumber);
|
|
|
- failUsers.add(user.getNickname());
|
|
|
+ errorImages.add(entry.getName());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -416,9 +473,17 @@ public class AcsService {
|
|
|
"}"+
|
|
|
"添加照片失败的用户{"
|
|
|
+failUsers+
|
|
|
+ "}"+
|
|
|
+ "不存在的用户{"+
|
|
|
+ nullUsers+
|
|
|
+ "}"+
|
|
|
+ "照片格式错误{"+
|
|
|
+ errorImages+
|
|
|
"}";
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ //直接导入用户人脸
|
|
|
public String testImages(MultipartFile file) throws Exception {
|
|
|
// 校验文件类型
|
|
|
if (!file.getOriginalFilename().endsWith(".zip")) {
|
|
@@ -429,13 +494,14 @@ public class AcsService {
|
|
|
List<String> successUsers =new LinkedList<>();
|
|
|
List<String> failUsers =new LinkedList<>();
|
|
|
List<String> nullUsers =new LinkedList<>();
|
|
|
+ List<String> errorImages =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())) {
|
|
|
+ if (isValidImageName(entry.getName()).equals("照片格式正确")) {
|
|
|
System.out.println(entry.getName());
|
|
|
//获取去除后缀名的文件名,需要设置成学号
|
|
|
String userNumber = entry.getName().substring(0, entry.getName().lastIndexOf('-'));
|
|
@@ -453,7 +519,7 @@ public class AcsService {
|
|
|
}
|
|
|
}
|
|
|
String result =getUser(userNumber);
|
|
|
- if (result!=null){
|
|
|
+ if (result!=null){//用户不为空,为用户添加人脸
|
|
|
Gson gson = new Gson();
|
|
|
JsonObject jsonObject = gson.fromJson(result, JsonObject.class);
|
|
|
|
|
@@ -476,15 +542,9 @@ public class AcsService {
|
|
|
}
|
|
|
}
|
|
|
}else{
|
|
|
- nullUsers.add(studentName);
|
|
|
+ nullUsers.add(studentName);//添加找不到的用户
|
|
|
}
|
|
|
- continue;
|
|
|
-// }else{
|
|
|
-// String userNumber = entry.getName().substring(0, entry.getName().indexOf('-'));
|
|
|
-// AdminUserDO user = userService.findUserByUserNumber(userNumber);
|
|
|
-// failUsers.add(user.getNickname());
|
|
|
-// continue;
|
|
|
-// }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -497,30 +557,33 @@ public class AcsService {
|
|
|
+failUsers+
|
|
|
"}"+
|
|
|
"不存在的用户{"+
|
|
|
- nullUsers+"}";
|
|
|
+ nullUsers+
|
|
|
+ "}"+
|
|
|
+ "照片格式错误{"+
|
|
|
+ errorImages+
|
|
|
+ "}";
|
|
|
|
|
|
}
|
|
|
|
|
|
// 检查多个图片名称格式
|
|
|
- private boolean isValidImageName(String imageNames) {
|
|
|
- if (imageNames == null) return false;
|
|
|
- String[] names = imageNames.split(",");
|
|
|
- for (String name : names) {
|
|
|
- if (!name.matches(".*\\.(jpg|jpeg|png|gif)$")) {
|
|
|
- return false; // 只要有一个格式不正确就返回 false
|
|
|
- }
|
|
|
+ private String isValidImageName(String imageName) {
|
|
|
+ if (imageName == null || imageName.trim().isEmpty()) {
|
|
|
+ return "照片为空"; // 如果照片名称为空,返回提示信息
|
|
|
}
|
|
|
- return true;
|
|
|
+ if (!imageName.matches(".*\\.(jpg|jpeg|png|gif)$")) {
|
|
|
+ return "照片格式不正确"; // 如果格式不正确,返回错误消息
|
|
|
+ }
|
|
|
+ return "照片格式正确"; // 如果格式正确,返回确认消息
|
|
|
}
|
|
|
|
|
|
|
|
|
- private UserImportRespVO importRespVO;
|
|
|
+ private attendanceImportRespVO importRespVO;
|
|
|
private String imageImportResult;
|
|
|
@Transactional(rollbackFor = Exception.class) // 事务管理
|
|
|
public String importData(MultipartFile excelFile, MultipartFile imageFile, boolean updateSupport) throws Exception {
|
|
|
// 1. 导入用户信息
|
|
|
if (excelFile!=null){
|
|
|
- List<UserImportExcelVO> list = ExcelUtils.read(excelFile, UserImportExcelVO.class);
|
|
|
+ List<attendanceImportExcelVO> list = ExcelUtils.read(excelFile, attendanceImportExcelVO.class);
|
|
|
importRespVO = importUserList(list, updateSupport);
|
|
|
System.out.println("用户信息导入结果: " + importRespVO);
|
|
|
}else {
|
|
@@ -538,4 +601,28 @@ public class AcsService {
|
|
|
imageImportResult;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+ @Transactional(rollbackFor = Exception.class) // 事务管理
|
|
|
+ public String testData(MultipartFile excelFile, MultipartFile imageFile, boolean updateSupport) throws Exception {
|
|
|
+ // 1. 导入用户信息
|
|
|
+ if (excelFile!=null){
|
|
|
+ List<attendanceImportExcelVO> list = ExcelUtils.read(excelFile, attendanceImportExcelVO.class);
|
|
|
+ importRespVO = importUserList(list, updateSupport);
|
|
|
+ System.out.println("用户信息导入结果: " + importRespVO);
|
|
|
+ }else {
|
|
|
+ importRespVO=null;
|
|
|
+ }
|
|
|
+ // 2. 导入图片
|
|
|
+ if (imageFile!=null){
|
|
|
+ imageImportResult = importImages(imageFile);
|
|
|
+ System.out.println("图片导入结果: " + imageImportResult);
|
|
|
+ }else {
|
|
|
+ imageImportResult="为传入照片信息";
|
|
|
+ }
|
|
|
+
|
|
|
+ return importRespVO+
|
|
|
+ imageImportResult;
|
|
|
+ }
|
|
|
+
|
|
|
}
|