|
|
@@ -1,14 +1,35 @@
|
|
|
package cn.iocoder.yudao.module.system.service.usercharacteristic;
|
|
|
|
|
|
+import cn.hutool.core.lang.Assert;
|
|
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
|
+import cn.iocoder.yudao.framework.common.util.io.FileDriveLetterUtils;
|
|
|
+import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileUploadReqVO;
|
|
|
+import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO;
|
|
|
+import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
|
|
+import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient;
|
|
|
+import cn.iocoder.yudao.module.infra.framework.file.core.client.local.LocalFileClientConfig;
|
|
|
+import cn.iocoder.yudao.module.infra.service.file.FileConfigService;
|
|
|
+import cn.iocoder.yudao.module.infra.service.file.FileService;
|
|
|
import cn.iocoder.yudao.module.system.controller.admin.usercharacteristic.vo.UserCharacteristicPageReqVO;
|
|
|
+import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
|
|
import cn.iocoder.yudao.module.system.dal.dataobject.user.UserCharacteristicDO;
|
|
|
import cn.iocoder.yudao.module.system.dal.mysql.user.UserCharacteristicMapper;
|
|
|
+import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.machinezoo.sourceafis.FingerprintTemplate;
|
|
|
import jakarta.annotation.Resource;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
+import java.io.IOException;
|
|
|
+import java.net.URI;
|
|
|
+import java.net.URISyntaxException;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Paths;
|
|
|
import java.util.List;
|
|
|
|
|
|
/**
|
|
|
@@ -22,6 +43,15 @@ public class UserCharacteristicServiceImpl extends ServiceImpl<UserCharacteristi
|
|
|
|
|
|
@Resource
|
|
|
private UserCharacteristicMapper userCharacteristicMapper;
|
|
|
+ @Resource
|
|
|
+ private AdminUserService adminUserService;
|
|
|
+ @Resource
|
|
|
+ private FileService fileService;
|
|
|
+ @Resource
|
|
|
+ private FileConfigService fileConfigService;
|
|
|
+
|
|
|
+ @Value("${local-file.finger-path}")
|
|
|
+ private String fingerPath;
|
|
|
|
|
|
@Override
|
|
|
public void deleteUserCharacteristicListByIds(List<Long> ids) {
|
|
|
@@ -40,4 +70,112 @@ public class UserCharacteristicServiceImpl extends ServiceImpl<UserCharacteristi
|
|
|
return userCharacteristicMapper.selectPage(pageReqVO);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public Boolean insertUserFingerprintDat(MultipartFile file, String userName, String sysAttrValue) throws Exception {
|
|
|
+ Assert.notBlank(userName, "请告知我这是哪个用户的指纹!");
|
|
|
+ Assert.isTrue(file.getSize() > 0, "指纹信息不能为空!");
|
|
|
+ AdminUserDO user = adminUserService.getOne(Wrappers.<AdminUserDO>lambdaQuery()
|
|
|
+ .eq(AdminUserDO::getUsername, userName));
|
|
|
+ Assert.isFalse(user == null, "系统中无该用户!");
|
|
|
+ Long userId = user.getId();
|
|
|
+ if (StringUtils.isNotBlank(sysAttrValue)) {
|
|
|
+ // 检查人员指纹上限
|
|
|
+ long count = count(Wrappers.<UserCharacteristicDO>lambdaQuery()
|
|
|
+ .eq(UserCharacteristicDO::getType, "1")
|
|
|
+ .eq(UserCharacteristicDO::getUserId, userId));
|
|
|
+ int i = Integer.parseInt(sysAttrValue);
|
|
|
+ Assert.isFalse(count >= i, "该人员的指纹录入已上限,最大" + i + "条!");
|
|
|
+ }
|
|
|
+ FileClient fileClient = fileConfigService.getFileClientByName("生物识别存储器");
|
|
|
+ FileConfigDO fileConfig = fileConfigService.getFileConfig(fileClient.getId());
|
|
|
+ LocalFileClientConfig config = (LocalFileClientConfig) fileConfig.getConfig();
|
|
|
+ String basePath = config.getBasePath();
|
|
|
+ // 上传文件
|
|
|
+ FileUploadReqVO fileUploadReqVO = new FileUploadReqVO();
|
|
|
+ fileUploadReqVO.setFile(file);
|
|
|
+ fileUploadReqVO.setDirectory(fingerPath + "/" + userId);
|
|
|
+ FileDO fileDO = fileService.uploadLocalFile(fileUploadReqVO);
|
|
|
+
|
|
|
+ // 开始生成dat文件
|
|
|
+ String imagePath = fileDO.getPath();
|
|
|
+ String imageUrl = fileDO.getUrl();
|
|
|
+ String datPath = null;
|
|
|
+ try {
|
|
|
+ // 盘符
|
|
|
+ String driveLetter = FileDriveLetterUtils.getDriveLetter();
|
|
|
+ // 时间戳
|
|
|
+ byte[] fingerprintData = extractFingerprintTemplate(driveLetter + basePath + "/" + fileDO.getPath());
|
|
|
+ // 保存到文件
|
|
|
+ datPath = driveLetter + basePath + "/" + getDirectoryPath(fileDO.getPath()) + extractFileName(fileDO.getPath()) + ".dat";
|
|
|
+ Files.write(Paths.get(datPath), fingerprintData);
|
|
|
+ System.out.println("指纹特征值已保存!");
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ Assert.isFalse(true, "该文件指纹无法识别,请重新录入!");
|
|
|
+ }
|
|
|
+ UserCharacteristicDO sysUserCharacteristic = new UserCharacteristicDO();
|
|
|
+ sysUserCharacteristic.setUserId(userId);
|
|
|
+ sysUserCharacteristic.setType("1");
|
|
|
+ sysUserCharacteristic.setContent(datPath);
|
|
|
+ sysUserCharacteristic.setOrderNum(0);
|
|
|
+ sysUserCharacteristic.setImageUrl(imageUrl);
|
|
|
+ sysUserCharacteristic.setImagePath(imagePath);
|
|
|
+ save(sysUserCharacteristic);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static byte[] extractFingerprintTemplate(String imagePath) throws IOException {
|
|
|
+ // 读取图像文件(灰度图像 PNG, BMP, JPEG 等)
|
|
|
+ byte[] imageBytes = Files.readAllBytes(Paths.get(imagePath));
|
|
|
+ try {
|
|
|
+ // 提取特征值
|
|
|
+ FingerprintTemplate template = new FingerprintTemplate()
|
|
|
+ .dpi(500) // 指定 DPI (重要,通常为 500)
|
|
|
+ .create(imageBytes);
|
|
|
+ // 导出为 byte[] 保存特征值
|
|
|
+ return template.serialize().getBytes();
|
|
|
+ } catch (Exception e) {
|
|
|
+ Assert.isFalse(true, "该文件指纹无法识别,请重新录入!");
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从URL中提取文件名主体部分(不含扩展名)
|
|
|
+ * @param urlStr 目标URL字符串
|
|
|
+ * @return 提取的文件名主体,例如"光猪_1751351611494"
|
|
|
+ * @throws URISyntaxException URL格式无效时抛出
|
|
|
+ */
|
|
|
+ public static String extractFileName(String urlStr) throws URISyntaxException {
|
|
|
+ // 解析URL获取路径
|
|
|
+ URI uri = new URI(urlStr);
|
|
|
+ String path = uri.getPath();
|
|
|
+
|
|
|
+ // 分割路径并获取最后一个有效段
|
|
|
+ String[] segments = path.split("/");
|
|
|
+ String fileName;
|
|
|
+ if (segments.length > 0 && !segments[segments.length - 1].isEmpty()) {
|
|
|
+ fileName = segments[segments.length - 1];
|
|
|
+ } else {
|
|
|
+ // 处理以斜杠结尾的特殊情况(视为前一个段)
|
|
|
+ fileName = segments.length >= 2 ? segments[segments.length - 2] : "";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 去除扩展名
|
|
|
+ int dotIndex = fileName.lastIndexOf('.');
|
|
|
+ return (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String getDirectoryPath(String path) {
|
|
|
+ if (path == null || path.isEmpty()) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ int lastSlashIndex = path.lastIndexOf('/');
|
|
|
+ if (lastSlashIndex == -1) {
|
|
|
+ // 无斜杠时返回空(或根据需求调整)
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ return path.substring(0, lastSlashIndex + 1); // 包含斜杠
|
|
|
+ }
|
|
|
+
|
|
|
}
|