修改移动考勤-使用百度人脸对比

dev_xd
lj7788@126.com 2025-09-05 17:50:38 +08:00
parent 00d696e516
commit faa20e9972
8 changed files with 180 additions and 28 deletions

View File

@ -0,0 +1,9 @@
baidu:
face:
app-id: 7034646
api-key: L3PiEzO9dMFJDExMTjOxuTtq
secret-key: 40LMey6WC1MYIqLU4m5Qe8K4foFUM1bc
similarity-threshold: 0.8
qps-limit-delay: 1000
max-retry-attempts: 3
retry-delay: 2000

View File

@ -0,0 +1,107 @@
package com.yanzhu.common.core.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
*
*
* @author yanzhu
*/
@Configuration
@ConfigurationProperties(prefix = "baidu.face")
public class BaiduFaceProperties {
/**
* App ID
*/
private String appId = "7034646";
/**
* API Key
*/
private String apiKey = "L3PiEzO9dMFJDExMTjOxuTtq";
/**
* Secret Key
*/
private String secretKey = "40LMey6WC1MYIqLU4m5Qe8K4foFUM1bc";
/**
*
*/
private double similarityThreshold = 0.8;
/**
* QPS -
*/
private int qpsLimitDelay = 1000;
/**
*
*/
private int maxRetryAttempts = 3;
/**
*
*/
private int retryDelay = 2000;
// Getter和Setter方法
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getApiKey() {
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public double getSimilarityThreshold() {
return similarityThreshold;
}
public void setSimilarityThreshold(double similarityThreshold) {
this.similarityThreshold = similarityThreshold;
}
public int getQpsLimitDelay() {
return qpsLimitDelay;
}
public void setQpsLimitDelay(int qpsLimitDelay) {
this.qpsLimitDelay = qpsLimitDelay;
}
public int getMaxRetryAttempts() {
return maxRetryAttempts;
}
public void setMaxRetryAttempts(int maxRetryAttempts) {
this.maxRetryAttempts = maxRetryAttempts;
}
public int getRetryDelay() {
return retryDelay;
}
public void setRetryDelay(int retryDelay) {
this.retryDelay = retryDelay;
}
}

View File

@ -0,0 +1,15 @@
package com.yanzhu.common.core.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
*
*
* @author yanzhu
*/
@Configuration
@ComponentScan(basePackages = "com.yanzhu.common.core")
public class CoreConfig {
}

View File

@ -2,7 +2,12 @@ package com.yanzhu.common.core.utils;
import com.baidu.aip.face.AipFace; import com.baidu.aip.face.AipFace;
import com.baidu.aip.face.MatchRequest; import com.baidu.aip.face.MatchRequest;
import com.yanzhu.common.core.config.BaiduFaceProperties;
import org.json.JSONObject; import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
@ -16,28 +21,42 @@ import java.io.ByteArrayOutputStream;
* *
* @author yanzhu * @author yanzhu
*/ */
@Component
public class BaiduFaceSimilarityUtils { public class BaiduFaceSimilarityUtils {
// 百度人脸识别应用的API Key和Secret Key @Autowired
private static final String APP_ID = "您的AppID"; // 需要设置有效的AppID private BaiduFaceProperties baiduFaceProperties;
private static final String API_KEY = "L3PiEzO9dMFJDExMTjOxuTtq";
private static final String SECRET_KEY = "40LMey6WC1MYIqLU4m5Qe8K4foFUM1bc";
// 初始化AipFace客户端 // 初始化AipFace客户端
private static final AipFace client = new AipFace(APP_ID, API_KEY, SECRET_KEY); private static AipFace client;
// 相似度阈值,大于此值认为是同一个人 // 相似度阈值,大于此值认为是同一个人
private static final double SIMILARITY_THRESHOLD = 0.8; public static double SIMILARITY_THRESHOLD = 0.8;
// QPS限制相关常量 // QPS限制相关常量
private static final int QPS_LIMIT_DELAY = 1000; // 1秒延迟避免QPS限制 private static int QPS_LIMIT_DELAY = 1000; // 1秒延迟避免QPS限制
private static final int MAX_RETRY_ATTEMPTS = 3; // 最大重试次数 private static int MAX_RETRY_ATTEMPTS = 3; // 最大重试次数
private static final int RETRY_DELAY = 2000; // 重试延迟(毫秒) private static int RETRY_DELAY = 2000; // 重试延迟(毫秒)
static { @PostConstruct
public void init() {
// 从配置中获取参数
String appId = baiduFaceProperties.getAppId();
String apiKey = baiduFaceProperties.getApiKey();
String secretKey = baiduFaceProperties.getSecretKey();
// 初始化AipFace客户端
client = new AipFace(appId, apiKey, secretKey);
// 设置网络连接参数 // 设置网络连接参数
client.setConnectionTimeoutInMillis(2000); client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000); client.setSocketTimeoutInMillis(60000);
// 更新静态变量
SIMILARITY_THRESHOLD = baiduFaceProperties.getSimilarityThreshold();
QPS_LIMIT_DELAY = baiduFaceProperties.getQpsLimitDelay();
MAX_RETRY_ATTEMPTS = baiduFaceProperties.getMaxRetryAttempts();
RETRY_DELAY = baiduFaceProperties.getRetryDelay();
} }
/** /**
@ -224,18 +243,6 @@ public class BaiduFaceSimilarityUtils {
} }
} }
/**
* API KeySecret Key
*
* @param appId App ID
* @param apiKey API Key
* @param secretKey Secret Key
*/
public static void setCredentials(String appId, String apiKey, String secretKey) {
// 重新初始化AipFace客户端
// 注意:在实际应用中,应该通过配置文件或环境变量来设置这些密钥
}
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("开始测试人脸相似度算法..."); System.out.println("开始测试人脸相似度算法...");
@ -272,5 +279,4 @@ public class BaiduFaceSimilarityUtils {
System.out.println("\n测试完成。"); System.out.println("\n测试完成。");
} }
} }

View File

@ -3,12 +3,16 @@ package com.yanzhu.common.security.config;
import java.util.TimeZone; import java.util.TimeZone;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/** /**
* *
* *
* @author ruoyi * @author ruoyi
*/ */
@Configuration
@ComponentScan(basePackages = "com.yanzhu.common.core")
public class ApplicationConfig public class ApplicationConfig
{ {
/** /**
@ -19,4 +23,4 @@ public class ApplicationConfig
{ {
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault()); return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
} }
} }

View File

@ -136,7 +136,7 @@ public class ProMobileAttendanceConfigController extends BaseController
double similarity = BaiduFaceSimilarityUtils.calculateFaceSimilarity(userPicture, attImg); double similarity = BaiduFaceSimilarityUtils.calculateFaceSimilarity(userPicture, attImg);
System.out.println("相似度:"+similarity); System.out.println("相似度:"+similarity);
double threshold = 0.8; double threshold = BaiduFaceSimilarityUtils.SIMILARITY_THRESHOLD;
if (similarity >= threshold) { if (similarity >= threshold) {
// 相似度达标,允许考勤 // 相似度达标,允许考勤

View File

@ -381,7 +381,18 @@ Page({
app.toast("考勤成功"); app.toast("考勤成功");
this.returnToPage(); this.returnToPage();
} else { } else {
app.toast("考勤失败: " + res.msg); // 显示确认框,提供更友好的错误提示
wx.showModal({
title: "考勤失败",
content: res.msg || "考勤提交失败,请稍后重试",
showCancel: false, // 只显示确定按钮
confirmColor: "#ff0000", // 深色确认按钮
confirmText: "确定",
success: function (res) {
// 用户点击确定按钮后返回考勤列表页面
this.returnToPage();
}.bind(this),
});
} }
}); });
}, },

View File

@ -66,8 +66,8 @@
<text class="txt-blue"> 考勤人像刷脸</text> <text class="txt-blue"> 考勤人像刷脸</text>
</view> </view>
<view class="content_box_content att-img"> <view class="content_box_content att-img">
<image src="{{faceImage}}" mode="aspectFit" wx:if="{{faceImage}}" /> <image src="{{faceImage}}" mode="aspectFit" bindtap="openCamera" wx:if="{{faceImage}}" />
<view wx:else class="placeholder-text">拍照后显示图片</view> <view wx:else class="placeholder-text" bindtap="openCamera">拍照后显示图片</view>
<button bindtap="openCamera">点击打开摄像头刷脸</button> <button bindtap="openCamera">点击打开摄像头刷脸</button>
</view> </view>
</view> </view>