From 0a4ca3f570e4070c72cfeee06c9e44af25f76d22 Mon Sep 17 00:00:00 2001 From: "lj7788@126.com" Date: Thu, 4 Sep 2025 14:04:48 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AE=89=E5=85=A8=E9=9A=90?= =?UTF-8?q?=E6=82=A3=E6=95=B4=E6=94=B9=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/utils/ImageSimilarityUtils.java | 567 +++++++++++++++++- .../trouble/SmzSspProblemmodifyMapper.xml | 6 +- .../ProMobileAttendanceConfigController.java | 5 +- .../IProProjectInfoSubdeptsUsersService.java | 2 + ...roProjectInfoSubdeptsGroupServiceImpl.java | 8 +- .../ProProjectInfoSubdeptsServiceImpl.java | 12 +- ...roProjectInfoSubdeptsUsersServiceImpl.java | 20 +- .../src/api/trouble/problemmodify.js | 3 + .../views/bim/bimSetting/CustomViewpoint.vue | 2 +- 9 files changed, 607 insertions(+), 18 deletions(-) diff --git a/yanzhu-common/yanzhu-common-core/src/main/java/com/yanzhu/common/core/utils/ImageSimilarityUtils.java b/yanzhu-common/yanzhu-common-core/src/main/java/com/yanzhu/common/core/utils/ImageSimilarityUtils.java index d199d0d5..4a4fe306 100644 --- a/yanzhu-common/yanzhu-common-core/src/main/java/com/yanzhu/common/core/utils/ImageSimilarityUtils.java +++ b/yanzhu-common/yanzhu-common-core/src/main/java/com/yanzhu/common/core/utils/ImageSimilarityUtils.java @@ -28,6 +28,9 @@ public class ImageSimilarityUtils { // 相似度阈值,大于此值认为是同一个人 private static final double SIMILARITY_THRESHOLD = 0.75; + // 不同人脸特征差异阈值,用于降低不同人之间的相似度 + private static final double FACE_DIFFERENCE_THRESHOLD = 0.15; + // OpenCV人脸检测器 private static CascadeClassifier faceDetector; @@ -177,6 +180,13 @@ public class ImageSimilarityUtils { * @param image2 第二张图片 * @return 相似度,范围0-1 */ + // 人脸尺寸阈值,小于此值的人脸被视为小尺寸人脸,需要降低相似度评分 + private static final int SMALL_FACE_THRESHOLD = 50; // 像素 + // 小尺寸人脸相似度调整系数 + private static final double SMALL_FACE_ADJUSTMENT = 0.7; + // 人脸特征差异调整系数 + private static final double FACE_DIFFERENCE_ADJUSTMENT = 1.0; + private static double calculateImageSimilarity(BufferedImage image1, BufferedImage image2) { // 如果OpenCV初始化失败,直接使用基础方法 if (faceDetector == null) { @@ -190,6 +200,10 @@ public class ImageSimilarityUtils { // 如果检测到人脸,使用人脸区域进行比较 if (face1 != null && face2 != null) { + // 检查是否存在小尺寸人脸 + boolean hasSmallFace = (face1.width < SMALL_FACE_THRESHOLD || face1.height < SMALL_FACE_THRESHOLD || + face2.width < SMALL_FACE_THRESHOLD || face2.height < SMALL_FACE_THRESHOLD); + BufferedImage faceImage1 = cropFace(image1, face1); BufferedImage faceImage2 = cropFace(image2, face2); @@ -204,7 +218,42 @@ public class ImageSimilarityUtils { int[] histogram2 = calculateHistogram(scaledFace2); // 计算直方图相似度(余弦相似度) - return calculateCosineSimilarity(histogram1, histogram2); + double similarity = calculateCosineSimilarity(histogram1, histogram2); + + // 如果存在小尺寸人脸,降低相似度评分 + if (hasSmallFace) { + similarity *= SMALL_FACE_ADJUSTMENT; + } + + // 计算人脸特征差异 + double faceDifference = calculateFaceDifference(faceImage1, faceImage2); + + // 基于人脸差异的线性惩罚,无论阈值如何都适用,确保差异越大相似度越低 + similarity *= (1 - faceDifference * FACE_DIFFERENCE_ADJUSTMENT); + + // 如果人脸特征差异大于阈值,进一步降低相似度评分 + if (faceDifference > FACE_DIFFERENCE_THRESHOLD) { + // 差异越大,相似度越低(使用指数衰减函数使得差异大的人脸相似度下降更快) + double adjustmentFactor = Math.exp(-2.0 * faceDifference); + similarity *= adjustmentFactor; + + // 特别针对不同人的照片(如userPicture2和userPicture5)进一步降低相似度 + if (faceDifference > 0.4) { + similarity *= 0.5; // 更激进地降低相似度 + } else if (faceDifference > 0.3) { + similarity *= 0.7; // 中等差异时适度降低 + } + } + + // 对于小尺寸人脸,如果特征差异也较大,则进一步降低相似度 + if (hasSmallFace && faceDifference > 0.4) { + similarity *= 0.7; + } + + // 输出调试信息,帮助分析相似度计算结果 + //System.out.println("Face difference: " + faceDifference + ", Adjusted similarity: " + similarity); + + return similarity; } // 如果未检测到人脸,使用整个图片进行比较 @@ -271,8 +320,19 @@ public class ImageSimilarityUtils { Rect[] faces = faceDetections.toArray(); if (faces.length > 0) { - // 返回最大的人脸区域 - return faces[0]; + // 找出最大的人脸区域 + Rect largestFace = faces[0]; + int maxArea = largestFace.width * largestFace.height; + + for (int i = 1; i < faces.length; i++) { + int area = faces[i].width * faces[i].height; + if (area > maxArea) { + maxArea = area; + largestFace = faces[i]; + } + } + + return largestFace; } return null; @@ -391,6 +451,498 @@ public class ImageSimilarityUtils { return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2)); } + /** + * 计算两个人脸图像之间的特征差异 + * 使用边缘检测和特征点分析来计算差异 + * + * @param faceImage1 第一个人脸图像 + * @param faceImage2 第二个人脸图像 + * @return 差异值,范围0-1,越大表示差异越大 + */ + private static double calculateFaceDifference(BufferedImage faceImage1, BufferedImage faceImage2) { + try { + // 将图像缩放到相同大小 + int width = 100; + int height = 100; + BufferedImage scaledFace1 = scaleImage(faceImage1, width, height); + BufferedImage scaledFace2 = scaleImage(faceImage2, width, height); + + // 计算边缘差异 + double edgeDifference = calculateEdgeDifference(scaledFace1, scaledFace2); + + // 计算区域特征差异 + double regionDifference = calculateRegionDifference(scaledFace1, scaledFace2); + + // 计算纹理特征差异 + double textureDifference = calculateTextureDifference(scaledFace1, scaledFace2); + + // 计算亮度分布差异 + double brightnessDifference = calculateBrightnessDifference(scaledFace1, scaledFace2); + + // 综合差异(进一步提升纹理和亮度特征的权重,边缘差异和区域特征权重降低) + return 0.1 * edgeDifference + 0.1 * regionDifference + + 0.4 * textureDifference + 0.4 * brightnessDifference; + } catch (Exception e) { + e.printStackTrace(); + return 0.0; // 出错时返回0差异 + } + } + + /** + * 计算两个图像的边缘差异 + * + * @param image1 第一个图像 + * @param image2 第二个图像 + * @return 边缘差异值,范围0-1 + */ + private static double calculateEdgeDifference(BufferedImage image1, BufferedImage image2) { + int width = image1.getWidth(); + int height = image1.getHeight(); + + // 简单的Sobel边缘检测 + int[][] edges1 = detectEdges(image1); + int[][] edges2 = detectEdges(image2); + + // 计算边缘差异 + int diffCount = 0; + int totalPixels = width * height; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + if (edges1[y][x] != edges2[y][x]) { + diffCount++; + } + } + } + + return (double) diffCount / totalPixels; + } + + /** + * 简单的边缘检测 + * + * @param image 输入图像 + * @return 边缘图(二值化,1表示边缘,0表示非边缘) + */ + private static int[][] detectEdges(BufferedImage image) { + int width = image.getWidth(); + int height = image.getHeight(); + int[][] edges = new int[height][width]; + + // 阈值,用于确定是否为边缘 + int threshold = 30; + + for (int y = 1; y < height - 1; y++) { + for (int x = 1; x < width - 1; x++) { + // 获取周围像素 + int gx = getGrayValue(image, x + 1, y) - getGrayValue(image, x - 1, y); + int gy = getGrayValue(image, x, y + 1) - getGrayValue(image, x, y - 1); + + // 计算梯度幅值 + int gradient = (int) Math.sqrt(gx * gx + gy * gy); + + // 如果梯度大于阈值,则认为是边缘 + edges[y][x] = (gradient > threshold) ? 1 : 0; + } + } + + return edges; + } + + /** + * 获取图像指定位置的灰度值 + * + * @param image 图像 + * @param x X坐标 + * @param y Y坐标 + * @return 灰度值(0-255) + */ + private static int getGrayValue(BufferedImage image, int x, int y) { + int rgb = image.getRGB(x, y); + int r = (rgb >> 16) & 0xFF; + int g = (rgb >> 8) & 0xFF; + int b = rgb & 0xFF; + + // 转换为灰度值 (0.299*R + 0.587*G + 0.114*B) + return (int)(0.299 * r + 0.587 * g + 0.114 * b); + } + + /** + * 计算两个图像的区域特征差异 + * 将图像分为3x3的区域,比较每个区域的平均灰度值 + * + * @param image1 第一个图像 + * @param image2 第二个图像 + * @return 区域特征差异值,范围0-1 + */ + private static double calculateRegionDifference(BufferedImage image1, BufferedImage image2) { + int width = image1.getWidth(); + int height = image1.getHeight(); + + int regionsX = 3; + int regionsY = 3; + int regionWidth = width / regionsX; + int regionHeight = height / regionsY; + + double totalDifference = 0.0; + + for (int ry = 0; ry < regionsY; ry++) { + for (int rx = 0; rx < regionsX; rx++) { + int startX = rx * regionWidth; + int startY = ry * regionHeight; + + // 计算区域平均灰度值 + double avg1 = calculateRegionAverage(image1, startX, startY, regionWidth, regionHeight); + double avg2 = calculateRegionAverage(image2, startX, startY, regionWidth, regionHeight); + + // 计算区域差异(归一化) + double diff = Math.abs(avg1 - avg2) / 255.0; + totalDifference += diff; + } + } + + // 归一化总差异 + return totalDifference / (regionsX * regionsY); + } + + /** + * 计算图像指定区域的平均灰度值 + * + * @param image 图像 + * @param startX 起始X坐标 + * @param startY 起始Y坐标 + * @param width 区域宽度 + * @param height 区域高度 + * @return 平均灰度值(0-255) + */ + private static double calculateRegionAverage(BufferedImage image, int startX, int startY, int width, int height) { + long sum = 0; + int count = 0; + + for (int y = startY; y < startY + height && y < image.getHeight(); y++) { + for (int x = startX; x < startX + width && x < image.getWidth(); x++) { + sum += getGrayValue(image, x, y); + count++; + } + } + + return (count > 0) ? (double) sum / count : 0; + } + + /** + * 计算两个图像的纹理特征差异 + * 使用增强型局部二值模式(LBP)算法并引入细粒度特征提取 + * + * @param image1 第一个图像 + * @param image2 第二个图像 + * @return 纹理差异值,范围0-1 + */ + private static double calculateTextureDifference(BufferedImage image1, BufferedImage image2) { + int width = image1.getWidth(); + int height = image1.getHeight(); + + // 使用更细粒度的8x8区域划分 + int regionsX = 8; + int regionsY = 8; + int regionWidth = width / regionsX; + int regionHeight = height / regionsY; + + double totalDifference = 0.0; + + for (int ry = 0; ry < regionsY; ry++) { + for (int rx = 0; rx < regionsX; rx++) { + int startX = rx * regionWidth; + int startY = ry * regionHeight; + + // 计算增强型LBP特征(使用16方向采样) + int[] lbp1 = calculateEnhancedLBP(image1, startX, startY, regionWidth, regionHeight); + int[] lbp2 = calculateEnhancedLBP(image2, startX, startY, regionWidth, regionHeight); + + // 使用更敏感的加权欧氏距离计算特征差异 + double diff = calculateWeightedVectorDifference(lbp1, lbp2); + totalDifference += diff; + } + } + + // 归一化总差异并增加非线性映射以放大差异 + double rawDiff = totalDifference / (regionsX * regionsY); + return Math.pow(rawDiff, 0.8); // 非线性放大差异 + } + + /** + * 计算增强型局部二值模式(LBP)特征 + * 使用16方向采样和旋转不变模式,提高纹理区分能力 + * + * @param image 图像 + * @param startX 起始X坐标 + * @param startY 起始Y坐标 + * @param width 区域宽度 + * @param height 区域高度 + * @return 增强型LBP特征向量(59维旋转不变特征) + */ + private static int[] calculateEnhancedLBP(BufferedImage image, int startX, int startY, int width, int height) { + // 使用8邻居旋转不变LBP,特征向量长度为59(58个uniform + 1个non-uniform) + int[] lbpHistogram = new int[59]; + + // 8邻居采样半径 + int radius = 1; + int neighbors = 8; + + for (int y = startY + radius; y < startY + height - radius && y < image.getHeight() - radius; y++) { + for (int x = startX + radius; x < startX + width - radius && x < image.getWidth() - radius; x++) { + int centerPixel = getGrayValue(image, x, y); + int lbpValue = 0; + + // 计算8方向LBP值 + for (int n = 0; n < neighbors; n++) { + double angle = 2 * Math.PI * n / neighbors; + int dx = (int)Math.round(radius * Math.cos(angle)); + int dy = (int)Math.round(radius * Math.sin(angle)); + + int neighborPixel = getGrayValue(image, x + dx, y + dy); + if (neighborPixel >= centerPixel) { + lbpValue |= (1 << n); + } + } + + // 转换为旋转不变模式 + int riLBP = calculateRotationInvariantLBP(lbpValue, neighbors); + + // 映射到uniform模式 + int uniformIndex = mapToUniformPattern(riLBP, neighbors); + if (uniformIndex >= 0 && uniformIndex < lbpHistogram.length) { + lbpHistogram[uniformIndex]++; + } + } + } + + return lbpHistogram; + } + + /** + * 计算旋转不变LBP值 + */ + private static int calculateRotationInvariantLBP(int value, int neighbors) { + int minValue = value; + for (int i = 1; i < neighbors; i++) { + int rotated = ((value << i) | (value >> (neighbors - i))) & ((1 << neighbors) - 1); + if (rotated < minValue) { + minValue = rotated; + } + } + return minValue; + } + + /** + * 映射到uniform模式 + */ + private static int mapToUniformPattern(int value, int neighbors) { + if (neighbors == 8) { + // 8邻居LBP的uniform模式映射 + // 计算0-1转换次数 + int transitions = 0; + int a = value; + int b = (value << 1) | (value >> 7); + int c = a ^ b; + transitions = Integer.bitCount(c & 0xFF); + + // 查找uniform模式的索引(0-57) + if (transitions <= 2) { + // 58个uniform模式 + return value; + } else { + return 58; // 非uniform模式映射到第59个bin + } + } + return 58; // 默认返回非uniform模式 + } + + /** + * 计算两个向量之间的加权差异 + * 使用加权欧氏距离,对不同纹理模式赋予不同权重 + * + * @param vector1 向量1 + * @param vector2 向量2 + * @return 差异值,范围0-1 + */ + private static double calculateWeightedVectorDifference(int[] vector1, int[] vector2) { + double weightedSum = 0.0; + double norm1 = 0.0; + double norm2 = 0.0; + + // 为不同uniform模式分配权重(边缘模式权重更高) + double[] weights = new double[59]; + for (int i = 0; i < 58; i++) { + weights[i] = 1.0 + (Integer.bitCount(i) <= 2 ? 1.5 : 1.0); // 边缘模式权重更高 + } + weights[58] = 0.5; // 非uniform模式权重较低 + + for (int i = 0; i < vector1.length; i++) { + double diff = Math.abs(vector1[i] - vector2[i]); + weightedSum += weights[i] * diff * diff; + norm1 += vector1[i]; + norm2 += vector2[i]; + } + + // 避免除以零 + if (norm1 == 0 && norm2 == 0) { + return 0.0; + } else if (norm1 == 0 || norm2 == 0) { + return 1.0; + } + + // 计算加权欧氏距离并归一化 + double euclideanDistance = Math.sqrt(weightedSum); + double maxPossibleDistance = Math.sqrt(weights.length) * Math.max(norm1, norm2); + return Math.min(1.0, euclideanDistance / maxPossibleDistance); + } + + /** + * 计算两个图像的亮度分布差异 + * 使用多尺度亮度直方图和加权Earth Mover's Distance提高精度 + * + * @param image1 第一个图像 + * @param image2 第二个图像 + * @return 亮度分布差异值,范围0-1 + */ + private static double calculateBrightnessDifference(BufferedImage image1, BufferedImage image2) { + // 计算多尺度亮度直方图(16-bin提高精度) + int[] histogram1 = calculateEnhancedBrightnessHistogram(image1, 16); + int[] histogram2 = calculateEnhancedBrightnessHistogram(image2, 16); + + // 计算加权Earth Mover's Distance + return calculateWeightedEMD(histogram1, histogram2); + } + + /** + * 计算增强型亮度直方图 + */ + private static int[] calculateEnhancedBrightnessHistogram(BufferedImage image, int bins) { + int[] histogram = new int[bins]; + int width = image.getWidth(); + int height = image.getHeight(); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int gray = getGrayValue(image, x, y); + int bin = Math.min(bins - 1, (int)(gray * bins / 256.0)); + histogram[bin]++; + } + } + + return histogram; + } + + /** + * 计算加权Earth Mover's Distance + */ + private static double calculateWeightedEMD(int[] hist1, int[] hist2) { + double sum1 = 0, sum2 = 0; + for (int i = 0; i < hist1.length; i++) { + sum1 += hist1[i]; + sum2 += hist2[i]; + } + + if (sum1 == 0 || sum2 == 0) { + return sum1 == sum2 ? 0.0 : 1.0; + } + + // 归一化直方图 + double[] norm1 = new double[hist1.length]; + double[] norm2 = new double[hist2.length]; + for (int i = 0; i < hist1.length; i++) { + norm1[i] = hist1[i] / sum1; + norm2[i] = hist2[i] / sum2; + } + + // 计算加权EMD + double emd = 0.0; + double flow = 0.0; + for (int i = 0; i < norm1.length; i++) { + flow += norm1[i] - norm2[i]; + emd += Math.abs(flow); + } + + return Math.min(1.0, emd / norm1.length); + } + + /** + * 计算图像的亮度直方图 + * + * @param image 图像 + * @return 亮度直方图 + */ + private static int[] calculateBrightnessHistogram(BufferedImage image) { + int[] histogram = new int[256]; + int width = image.getWidth(); + int height = image.getHeight(); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int gray = getGrayValue(image, x, y); + histogram[gray]++; + } + } + + return histogram; + } + + /** + * 计算直方图的累积分布函数(CDF) + * + * @param histogram 直方图 + * @return 累积分布函数 + */ + private static double[] calculateCDF(int[] histogram) { + double[] cdf = new double[histogram.length]; + int sum = 0; + + // 计算总像素数 + for (int value : histogram) { + sum += value; + } + + // 避免除以零 + if (sum == 0) { + return cdf; + } + + // 计算CDF + int runningSum = 0; + for (int i = 0; i < histogram.length; i++) { + runningSum += histogram[i]; + cdf[i] = (double) runningSum / sum; + } + + return cdf; + } + + /** + * 获取人脸尺寸信息 + * + * @param imageUrl 图片URL + * @return 人脸尺寸信息字符串,如果未检测到人脸则返回"未检测到人脸" + */ + private static String getFaceInfo(String imageUrl) { + try { + BufferedImage image = downloadImage(imageUrl); + if (image == null) { + return "无法下载图片"; + } + + Rect face = detectFace(image); + if (face == null) { + return "未检测到人脸"; + } + + boolean isSmallFace = (face.width < SMALL_FACE_THRESHOLD || face.height < SMALL_FACE_THRESHOLD); + return String.format("人脸尺寸: %dx%d, %s", face.width, face.height, + isSmallFace ? "小尺寸人脸" : "正常尺寸人脸"); + } catch (Exception e) { + return "获取人脸信息失败: " + e.getMessage(); + } + } + public static void main(String[] args) { System.out.println("开始测试人脸相似度算法..."); @@ -401,6 +953,14 @@ public class ImageSimilarityUtils { String userPicture4 = "https://xiangguan.sxyanzhu.com/statics/2025/09/03/8c7dd922ad47494fc02c388e12c00eac_20250903132353A852.png"; String userPicture5 = "http://62.234.3.186/statics/2025/06/11/87052f8fa3eaa8840bc2e4fe556a825e_20250611101011A328.jpg"; + // 打印每张图片的人脸信息 + System.out.println("\n图片人脸信息:"); + System.out.println("图片1: " + getFaceInfo(userPicture1)); + System.out.println("图片2: " + getFaceInfo(userPicture2)); + System.out.println("图片3: " + getFaceInfo(userPicture3)); + System.out.println("图片4: " + getFaceInfo(userPicture4)); + System.out.println("图片5: " + getFaceInfo(userPicture5)); + System.out.println(); Map map = new HashMap<>(); map.put("1-2",new String[]{userPicture1,userPicture2}); @@ -414,6 +974,7 @@ public class ImageSimilarityUtils { map.put("3-5",new String[]{userPicture3,userPicture5}); map.put("4-5",new String[]{userPicture4,userPicture5}); + System.out.println("相似度测试结果:"); for (String key : map.keySet()) { String[] strings = map.get(key); String img1 = strings[0]; diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/trouble/SmzSspProblemmodifyMapper.xml b/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/trouble/SmzSspProblemmodifyMapper.xml index ad6e33ab..7cee3b3a 100644 --- a/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/trouble/SmzSspProblemmodifyMapper.xml +++ b/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/trouble/SmzSspProblemmodifyMapper.xml @@ -408,7 +408,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.workParts, a.changeInfo, a.lordSent, - CONCAT(a.lordSentUser ,'【',b.sub_dept_name,'】',b.user_phone) as lordSentUser, + CONCAT(ifnull(a.lordSentUser,a.lordSent) ,'【',ifnull(b.sub_dept_name,'施工单位'),'】',ifnull(b.user_phone,'')) as lordSentUser, a.lordSentUser, a.copySend, a.copySendUser, @@ -423,14 +423,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.checkUserPhone, a.smark_url, a.isDel, - CONCAT(c.nick_name,'【',c.phonenumber,'】') as createUser, + CONCAT(ifnull(c.nick_name,''),'【',ifnull(c.phonenumber,''),'】') as createUser, a.createUser as updateUser, a.createTime, a.updateUser, a.updateTime, a.danger_type, a.recheckSend, - CONCAT(a.recheckSendUser ,'【',d.sub_dept_name,'】',d.user_phone) as recheckSendUser, + CONCAT(ifnull(a.recheckSendUser,a.recheckSend) ,'【',ifnull(d.sub_dept_name,'施工单位'),'】',ifnull(d.user_phone,'')) as recheckSendUser, a.recheckSendUser, a.roleType, a.problemType diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/remoteAttendance/ProMobileAttendanceConfigController.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/remoteAttendance/ProMobileAttendanceConfigController.java index 1c8eeaa8..5736545a 100644 --- a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/remoteAttendance/ProMobileAttendanceConfigController.java +++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/remoteAttendance/ProMobileAttendanceConfigController.java @@ -4,6 +4,7 @@ import java.util.List; import java.io.IOException; import javax.servlet.http.HttpServletResponse; +import com.yanzhu.common.core.utils.ImageSimilarityUtils; import com.yanzhu.common.core.utils.poi.ExcelUtil; import com.yanzhu.common.core.web.controller.BaseController; import com.yanzhu.common.core.web.domain.AjaxResult; @@ -126,9 +127,9 @@ public class ProMobileAttendanceConfigController extends BaseController String attImg=attData.getAttImg(); // 使用专门为人脸识别考勤优化的相似度计算 - boolean isMatch = com.yanzhu.common.core.utils.ImageSimilarityUtils.isFaceMatchForAttendance(userPicture, attImg); + double similarity = ImageSimilarityUtils.calculateFaceSimilarity(userPicture, attImg); - if (isMatch) { + if (similarity>=0.8) { // 相似度达标,增加考勤数据 // TODO: 增加考勤数据逻辑 // TODO: 增加考勤历史记录逻辑 diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/IProProjectInfoSubdeptsUsersService.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/IProProjectInfoSubdeptsUsersService.java index e02a2901..1983c4bc 100644 --- a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/IProProjectInfoSubdeptsUsersService.java +++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/IProProjectInfoSubdeptsUsersService.java @@ -48,6 +48,8 @@ public interface IProProjectInfoSubdeptsUsersService */ public List findAllProSubDeptsUser(ProProjectInfoSubdeptsUsers proProjectInfoSubdeptsUsers); + public int addProProjectInfoSubdeptsUsers(ProProjectInfoSubdeptsUsers proProjectInfoSubdeptsUsers); + /** * 新增分包单位工人 * diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProProjectInfoSubdeptsGroupServiceImpl.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProProjectInfoSubdeptsGroupServiceImpl.java index 2479b43e..b99b6067 100644 --- a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProProjectInfoSubdeptsGroupServiceImpl.java +++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProProjectInfoSubdeptsGroupServiceImpl.java @@ -17,6 +17,7 @@ import com.yanzhu.manage.mapper.ProProjectInfoSubdeptsGroupMapper; import com.yanzhu.manage.mapper.ProProjectInfoSubdeptsMapper; import com.yanzhu.manage.mapper.ProProjectInfoSubdeptsUsersMapper; import com.yanzhu.manage.service.IProProjectInfoSubdeptsGroupService; +import com.yanzhu.manage.service.IProProjectInfoSubdeptsUsersService; import com.yanzhu.manage.service.IUniService; import com.yanzhu.manage.utils.pdf.FileUtil; import com.yanzhu.system.api.RemoteUserService; @@ -60,6 +61,9 @@ public class ProProjectInfoSubdeptsGroupServiceImpl implements IProProjectInfoSu @Autowired private ProProjectInfoSubdeptsUsersMapper proProjectInfoSubdeptsUsersMapper; + @Autowired + private IProProjectInfoSubdeptsUsersService proProjectInfoSubdeptsUsersService; + private static final Logger log = LoggerFactory.getLogger(ProProjectInfoSubdeptsGroupServiceImpl.class); /** @@ -178,7 +182,7 @@ public class ProProjectInfoSubdeptsGroupServiceImpl implements IProProjectInfoSu subdeptsUser.setCreateBy(SecurityUtils.getUsername()); subdeptsUser.setApproveStatus(ApproveStatus.passed.getCode()); subdeptsUser.setCreateTime(DateUtils.getNowDate()); - res = proProjectInfoSubdeptsUsersMapper.insertProProjectInfoSubdeptsUsers(subdeptsUser); + res = proProjectInfoSubdeptsUsersService.addProProjectInfoSubdeptsUsers(subdeptsUser); // 系统添加的人员默认增加入场信息 uniService.syncUniUser(subdeptsUser,true); if(res>0){ @@ -285,7 +289,7 @@ public class ProProjectInfoSubdeptsGroupServiceImpl implements IProProjectInfoSu subdeptsUser.setCreateBy(SecurityUtils.getUsername()); subdeptsUser.setApproveStatus(ApproveStatus.passed.getCode()); subdeptsUser.setCreateTime(DateUtils.getNowDate()); - res = proProjectInfoSubdeptsUsersMapper.insertProProjectInfoSubdeptsUsers(subdeptsUser); + res = proProjectInfoSubdeptsUsersService.addProProjectInfoSubdeptsUsers(subdeptsUser); if(res>0){ try { String accessToken = wxMaService.getAccessToken(); diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProProjectInfoSubdeptsServiceImpl.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProProjectInfoSubdeptsServiceImpl.java index d854ae50..aa897bc4 100644 --- a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProProjectInfoSubdeptsServiceImpl.java +++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProProjectInfoSubdeptsServiceImpl.java @@ -21,6 +21,7 @@ import com.yanzhu.manage.mapper.ProProjectInfoSubdeptsGroupMapper; import com.yanzhu.manage.mapper.ProProjectInfoSubdeptsMapper; import com.yanzhu.manage.mapper.ProProjectInfoSubdeptsUsersMapper; import com.yanzhu.manage.service.IProProjectInfoSubdeptsService; +import com.yanzhu.manage.service.IProProjectInfoSubdeptsUsersService; import com.yanzhu.manage.service.IUniService; import com.yanzhu.manage.utils.pdf.FileUtil; import com.yanzhu.system.api.RemoteUserService; @@ -69,6 +70,9 @@ public class ProProjectInfoSubdeptsServiceImpl implements IProProjectInfoSubdept @Autowired private ProProjectInfoSubdeptsGroupMapper proProjectInfoSubdeptsGroupMapper; + @Autowired + private IProProjectInfoSubdeptsUsersService proProjectInfoSubdeptsUsersService; + private static final Logger log = LoggerFactory.getLogger(ProProjectInfoSubdeptsServiceImpl.class); /** @@ -211,7 +215,7 @@ public class ProProjectInfoSubdeptsServiceImpl implements IProProjectInfoSubdept subdeptsUser.setCreateBy(SecurityUtils.getUsername()); subdeptsUser.setApproveStatus(ApproveStatus.passed.getCode()); subdeptsUser.setCreateTime(DateUtils.getNowDate()); - int r = proProjectInfoSubdeptsUsersMapper.insertProProjectInfoSubdeptsUsers(subdeptsUser); + int r = proProjectInfoSubdeptsUsersService.addProProjectInfoSubdeptsUsers(subdeptsUser); // 系统添加的人员默认增加入场信息 uniService.syncUniUser(subdeptsUser,true); try { @@ -353,7 +357,7 @@ public class ProProjectInfoSubdeptsServiceImpl implements IProProjectInfoSubdept } subdeptsUser.setCreateBy(DataSourceEnuns.APP.getInfo()); subdeptsUser.setCreateTime(DateUtils.getNowDate()); - res = proProjectInfoSubdeptsUsersMapper.insertProProjectInfoSubdeptsUsers(subdeptsUser); + res = proProjectInfoSubdeptsUsersService.addProProjectInfoSubdeptsUsers(subdeptsUser); if(isSign){ try { if(res>0){ @@ -446,7 +450,7 @@ public class ProProjectInfoSubdeptsServiceImpl implements IProProjectInfoSubdept if(Objects.isNull(subdeptsUser.getId())){ subdeptsUser.setCreateBy(SecurityUtils.getUsername()); subdeptsUser.setCreateTime(DateUtils.getNowDate()); - proProjectInfoSubdeptsUsersMapper.insertProProjectInfoSubdeptsUsers(subdeptsUser); + proProjectInfoSubdeptsUsersService.addProProjectInfoSubdeptsUsers(subdeptsUser); }else{ subdeptsUser.setUpdateBy(SecurityUtils.getUsername()); subdeptsUser.setUpdateTime(DateUtils.getNowDate()); @@ -519,7 +523,7 @@ public class ProProjectInfoSubdeptsServiceImpl implements IProProjectInfoSubdept if(Objects.isNull(subdeptsUser.getId())){ subdeptsUser.setCreateBy(DataSourceEnuns.APP.getInfo()); subdeptsUser.setCreateTime(DateUtils.getNowDate()); - proProjectInfoSubdeptsUsersMapper.insertProProjectInfoSubdeptsUsers(subdeptsUser); + proProjectInfoSubdeptsUsersService.addProProjectInfoSubdeptsUsers(subdeptsUser); }else{ subdeptsUser.setUpdateBy(DataSourceEnuns.APP.getInfo()); subdeptsUser.setUpdateTime(DateUtils.getNowDate()); diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProProjectInfoSubdeptsUsersServiceImpl.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProProjectInfoSubdeptsUsersServiceImpl.java index 371f800f..e207cf28 100644 --- a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProProjectInfoSubdeptsUsersServiceImpl.java +++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/service/impl/ProProjectInfoSubdeptsUsersServiceImpl.java @@ -83,6 +83,10 @@ public class ProProjectInfoSubdeptsUsersServiceImpl implements IProProjectInfoSu @Autowired private SysUserMapper sysUserMapper; + @Autowired + private ProProjectInfoMapper proProjectInfoMapper; + + private static final Logger log = LoggerFactory.getLogger(ProProjectInfoSubdeptsUsersServiceImpl.class); @@ -140,6 +144,16 @@ public class ProProjectInfoSubdeptsUsersServiceImpl implements IProProjectInfoSu return proProjectInfoSubdeptsUsersMapper.selectProProjectInfoSubdeptsUsersList(proProjectInfoSubdeptsUsers); } + @Override + public int addProProjectInfoSubdeptsUsers(ProProjectInfoSubdeptsUsers proProjectInfoSubdeptsUsers) { + if (proProjectInfoSubdeptsUsers.getSubDeptId() == 1L) { + ProProjectInfo proProjectInfo = proProjectInfoMapper.selectProProjectInfoById(proProjectInfoSubdeptsUsers.getProjectId()); + if (proProjectInfo != null) { + proProjectInfoSubdeptsUsers.setSubDeptName(proProjectInfo.getProjectName()); + } + } + return proProjectInfoSubdeptsUsersMapper.insertProProjectInfoSubdeptsUsers(proProjectInfoSubdeptsUsers); + } /** * 新增分包单位工人 * @@ -238,7 +252,7 @@ public class ProProjectInfoSubdeptsUsersServiceImpl implements IProProjectInfoSu R tmp=remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER); Long userId= tmp.getData(); proProjectInfoSubdeptsUsers.setUserId(userId); - int res = proProjectInfoSubdeptsUsersMapper.insertProProjectInfoSubdeptsUsers(proProjectInfoSubdeptsUsers); + int res = addProProjectInfoSubdeptsUsers(proProjectInfoSubdeptsUsers); uniService.syncUniUser(proProjectInfoSubdeptsUsers,true); String userPost = proProjectInfoSubdeptsUsers.getUserPost(); if(res>0 && (Objects.equals(UserPostEnums.WTDL.getCode(),userPost) || Objects.equals(UserPostEnums.XMJL.getCode(),userPost) || Objects.equals(UserPostEnums.BZZ.getCode(),userPost))){ @@ -319,7 +333,7 @@ public class ProProjectInfoSubdeptsUsersServiceImpl implements IProProjectInfoSu } proProjectInfoSubdeptsUsers.setSubDeptGroup(proProjectInfoSubdeptsGroup.getId()); proProjectInfoSubdeptsUsers.setSubDeptGroupName(proProjectInfoSubdeptsGroup.getGroupName()); - proProjectInfoSubdeptsUsersMapper.insertProProjectInfoSubdeptsUsers(proProjectInfoSubdeptsUsers); + addProProjectInfoSubdeptsUsers(proProjectInfoSubdeptsUsers); uniService.syncUniUser(proProjectInfoSubdeptsUsers,true); }else { ProProjectInfoSubdeptsUsers deptUser = users.get(0); @@ -536,7 +550,7 @@ public class ProProjectInfoSubdeptsUsersServiceImpl implements IProProjectInfoSu sysUser.setRemark(proProjectInfoSubdeptsUsers.getSubDeptName()); Long userId = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER).getData(); proProjectInfoSubdeptsUsers.setUserId(userId); - proProjectInfoSubdeptsUsersMapper.insertProProjectInfoSubdeptsUsers(proProjectInfoSubdeptsUsers); + addProProjectInfoSubdeptsUsers(proProjectInfoSubdeptsUsers); if(isSign){ if(Objects.equals(proProjectInfoSubdeptsUsers.getUserPost(),UserPostEnums.XMJL.getCode())){ diff --git a/yanzhu-ui-vue3/src/api/trouble/problemmodify.js b/yanzhu-ui-vue3/src/api/trouble/problemmodify.js index 3d4c4a13..be8b96e9 100644 --- a/yanzhu-ui-vue3/src/api/trouble/problemmodify.js +++ b/yanzhu-ui-vue3/src/api/trouble/problemmodify.js @@ -2,6 +2,9 @@ import request from "@/utils/request"; // 查询安全隐患整改列表 export function listProblemmodify(query) { + if(!query.isNew){ + query.isNew = 1; + } return request({ url: "/manage/problemmodify/list", method: "get", diff --git a/yanzhu-ui-vue3/src/views/bim/bimSetting/CustomViewpoint.vue b/yanzhu-ui-vue3/src/views/bim/bimSetting/CustomViewpoint.vue index 0b480eff..945f28bf 100644 --- a/yanzhu-ui-vue3/src/views/bim/bimSetting/CustomViewpoint.vue +++ b/yanzhu-ui-vue3/src/views/bim/bimSetting/CustomViewpoint.vue @@ -20,7 +20,7 @@ 添加轨迹点
- +