This commit is contained in:
jjLv 2025-07-25 15:34:59 +08:00
parent f55583ce19
commit 95fd6aa42e
12 changed files with 116 additions and 32 deletions

View File

@ -160,6 +160,7 @@ dependencies {
implementation 'com.google.guava:guava:31.1-android' // Android
implementation 'com.github.NewHuLe:AppUpdate:v1.7'
implementation 'org.bouncycastle:bcprov-jdk15to18:1.77'
}
//X-Library依赖
apply from: 'x-library.gradle'

View File

@ -32,7 +32,6 @@ import com.bonus.canteen.adapter.initialization.entity.ListBean;
import com.bonus.canteen.core.BaseActivity;
import com.bonus.canteen.db.AppDatabase;
import com.bonus.canteen.db.entity.base.DeviceInfo;
import com.bonus.canteen.face.util.FaceServer;
import com.bonus.canteen.service.data.DownLoadDataService;
import com.bonus.canteen.service.data.entity.ResponseVo;
import com.bonus.canteen.utils.MemoryUtils;
@ -125,8 +124,6 @@ public class InitializationActivity extends BaseActivity<InitializationMainBindi
finish();
}, 3000);
}
//初始化人脸库
FaceServer.getInstance().loadFace(InitializationActivity.this);
}
@SuppressLint("UnspecifiedRegisterReceiverFlag")

View File

@ -18,6 +18,7 @@ import com.bonus.canteen.core.BaseActivity;
import com.bonus.canteen.db.AppDatabase;
import com.bonus.canteen.db.entity.base.LoginInfo;
import com.bonus.canteen.utils.OkHttpService;
import com.bonus.canteen.utils.SM4EncryptUtils;
import com.bonus.canteen.utils.ThreadPoolManager;
import com.bonus.canteen.utils.UrlConfig;
import com.bonus.canteen.utils.WorkConfig;
@ -91,8 +92,8 @@ public class LoginActivity extends BaseActivity<ActivityLoginBinding> {
try {
String url = WorkConfig.getPrefixesUrl() + UrlConfig.LOGIN_URL;
org.json.JSONObject json = new org.json.JSONObject();
json.put("username", userName);
json.put("password", password);
json.put("username", SM4EncryptUtils.sm4Encrypt(userName));
json.put("password", SM4EncryptUtils.sm4Encrypt(password));
json.put("verificationCode", "");
json.put("code", "");
json.put("phoneUuid", "");

View File

@ -39,6 +39,7 @@ import com.bonus.canteen.core.BaseActivity;
import com.bonus.canteen.db.AppDatabase;
import com.bonus.canteen.db.entity.base.DeviceInfo;
import com.bonus.canteen.db.entity.base.LoginInfo;
import com.bonus.canteen.face.util.FaceServer;
import com.bonus.canteen.fragment.BusinessDataFragment;
import com.bonus.canteen.fragment.MachineSaleFragment;
import com.bonus.canteen.fragment.OfflineCheckoutFragment;
@ -86,6 +87,8 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> implements C
registerReceiver(shutdownReceiver, new android.content.IntentFilter(Intent.ACTION_SHUTDOWN));
initView();
initTab();
//初始化人脸库
FaceServer.getInstance().loadFace(MainActivity.this);
}
protected void initView() {
//开启时间显示

View File

@ -296,13 +296,22 @@ public class FaceServer {
float maxSimilar = 0;
isProcessing = true;
FaceRegisterInfo bestMatch = null;
for (FaceRegisterInfo registerInfo : faceRegisterInfoList) {
tempFaceFeature.setFeatureData(registerInfo.getFeatureData());
// 使用并行流加快比对进程
bestMatch = faceRegisterInfoList.parallelStream()
.map(registerInfo -> {
tempFaceFeature.setFeatureData(registerInfo.getFeatureData());
faceEngine.compareFaceFeature(faceFeature, tempFaceFeature, faceSimilar);
return new Object[]{registerInfo, faceSimilar.getScore()};
})
.max((a, b) -> Float.compare((float)a[1], (float)b[1]))
.map(maxObj -> (FaceRegisterInfo)maxObj[0])
.orElse(null);
if (bestMatch != null) {
tempFaceFeature.setFeatureData(bestMatch.getFeatureData());
faceEngine.compareFaceFeature(faceFeature, tempFaceFeature, faceSimilar);
if (faceSimilar.getScore() > maxSimilar) {
maxSimilar = faceSimilar.getScore();
bestMatch = registerInfo;
}
maxSimilar = faceSimilar.getScore();
}
isProcessing = false;
if (bestMatch != null) {

View File

@ -182,7 +182,7 @@ public class OfflineCheckoutFragment extends BaseFragment<ActivityOfflineCheckou
balanceDialog = builder.create();
//取消查询
payCancel.setOnClickListener(v -> {
FaceScanUtil.stopReadMealCard(requireActivity());
ThreadPoolManager.getExecutor().execute(()->FaceScanUtil.stopReadMealCard(requireActivity()));
myPresentation.closeScan();
balanceDialog.dismiss();
balanceDialog = null;
@ -458,7 +458,7 @@ public class OfflineCheckoutFragment extends BaseFragment<ActivityOfflineCheckou
}
private void openPayWay(String type) {
openReadMealCard(type);
ThreadPoolManager.getExecutor().execute(()->openReadMealCard(type));
myPresentation.openScan(type);
}
@ -490,7 +490,7 @@ public class OfflineCheckoutFragment extends BaseFragment<ActivityOfflineCheckou
Log.e(TAG, "Dialog balanceDialog: ");
balanceDialog.dismiss();
balanceDialog = null;
FaceScanUtil.stopReadMealCard(requireActivity());
ThreadPoolManager.getExecutor().execute(()->FaceScanUtil.stopReadMealCard(requireActivity()));
myPresentation.closeScan();
new Handler().postDelayed(() -> openBalanceResultDialog(userInfo, custPhotoFulInfo), 500);
@ -520,7 +520,7 @@ public class OfflineCheckoutFragment extends BaseFragment<ActivityOfflineCheckou
}
private void closePayWay() {
FaceScanUtil.stopReadMealCard(requireActivity());
ThreadPoolManager.getExecutor().execute(()->FaceScanUtil.stopReadMealCard(requireActivity()));
myPresentation.closeScan();
if (alertDialog != null && alertDialog.isShowing()) {
alertDialog.dismiss();
@ -950,7 +950,7 @@ public class OfflineCheckoutFragment extends BaseFragment<ActivityOfflineCheckou
Log.e("Dialog", "balanceDialog: ");
balanceDialog.dismiss();
balanceDialog = null;
FaceScanUtil.stopReadMealCard(requireActivity());
ThreadPoolManager.getExecutor().execute(()->FaceScanUtil.stopReadMealCard(requireActivity()));
myPresentation.closeScan();
ThreadPoolManager.getExecutor().execute(() -> {
UserInfo userInfo = AppDatabase.getDatabase(context).userDao().getUserInfoById(finalUserId1);

View File

@ -252,7 +252,7 @@ public class OperationFragment extends BaseFragment<ActivityCanteenCashierBindin
balanceDialog = builder.create();
//取消查询
payCancel.setOnClickListener(v -> {
FaceScanUtil.stopReadMealCard(requireActivity());
ThreadPoolManager.getExecutor().execute(() -> FaceScanUtil.stopReadMealCard(requireActivity()));
myPresentation.closeScan();
balanceDialog.dismiss();
balanceDialog = null;
@ -771,8 +771,9 @@ public class OperationFragment extends BaseFragment<ActivityCanteenCashierBindin
}
private void openPayWay(String type) {
openReadMealCard(type);
myPresentation.openScan(type);
//TODO 尝试异步
ThreadPoolManager.getExecutor().execute(() -> openReadMealCard(type));
requireActivity().runOnUiThread(() -> myPresentation.openScan(type));
}
public void openReadMealCard(String type) {
@ -803,7 +804,7 @@ public class OperationFragment extends BaseFragment<ActivityCanteenCashierBindin
Log.e(TAG, "Dialog balanceDialog: ");
balanceDialog.dismiss();
balanceDialog = null;
FaceScanUtil.stopReadMealCard(requireActivity());
ThreadPoolManager.getExecutor().execute(() -> FaceScanUtil.stopReadMealCard(requireActivity()));
myPresentation.closeScan();
new Handler().postDelayed(() -> openBalanceResultDialog(userInfo, custPhotoFulInfo), 500);
@ -833,7 +834,7 @@ public class OperationFragment extends BaseFragment<ActivityCanteenCashierBindin
}
private void closePayWay() {
FaceScanUtil.stopReadMealCard(requireActivity());
ThreadPoolManager.getExecutor().execute(() -> FaceScanUtil.stopReadMealCard(requireActivity()));
myPresentation.closeScan();
alertDialog.dismiss();
alertDialog = null;
@ -1358,7 +1359,7 @@ public class OperationFragment extends BaseFragment<ActivityCanteenCashierBindin
Log.e("Dialog", "balanceDialog: ");
balanceDialog.dismiss();
balanceDialog = null;
FaceScanUtil.stopReadMealCard(requireActivity());
ThreadPoolManager.getExecutor().execute(() -> FaceScanUtil.stopReadMealCard(requireActivity()));
myPresentation.closeScan();
ThreadPoolManager.getExecutor().execute(() -> {
UserInfo userInfo = AppDatabase.getDatabase(context).userDao().getUserInfoById(finalUserId1);

View File

@ -186,7 +186,7 @@ public class SupermarketCashierFragment extends BaseFragment<ActivityOfflineChec
balanceDialog = builder.create();
//取消查询
payCancel.setOnClickListener(v -> {
FaceScanUtil.stopReadMealCard(requireActivity());
ThreadPoolManager.getExecutor().execute(()->FaceScanUtil.stopReadMealCard(requireActivity()));
myPresentation.closeScan();
balanceDialog.dismiss();
balanceDialog = null;
@ -462,7 +462,7 @@ public class SupermarketCashierFragment extends BaseFragment<ActivityOfflineChec
}
private void openPayWay(String type) {
openReadMealCard(type);
ThreadPoolManager.getExecutor().execute(()->openReadMealCard(type));
myPresentation.openScan(type);
}
@ -494,7 +494,7 @@ public class SupermarketCashierFragment extends BaseFragment<ActivityOfflineChec
Log.e(TAG, "Dialog balanceDialog: ");
balanceDialog.dismiss();
balanceDialog = null;
FaceScanUtil.stopReadMealCard(requireActivity());
ThreadPoolManager.getExecutor().execute(()->FaceScanUtil.stopReadMealCard(requireActivity()));
myPresentation.closeScan();
new Handler().postDelayed(() -> openBalanceResultDialog(userInfo, custPhotoFulInfo), 500);
@ -524,7 +524,7 @@ public class SupermarketCashierFragment extends BaseFragment<ActivityOfflineChec
}
private void closePayWay() {
FaceScanUtil.stopReadMealCard(requireActivity());
ThreadPoolManager.getExecutor().execute(()->FaceScanUtil.stopReadMealCard(requireActivity()));
myPresentation.closeScan();
if (alertDialog != null && alertDialog.isShowing()) {
alertDialog.dismiss();
@ -932,7 +932,7 @@ public class SupermarketCashierFragment extends BaseFragment<ActivityOfflineChec
Log.e("Dialog", "balanceDialog: ");
balanceDialog.dismiss();
balanceDialog = null;
FaceScanUtil.stopReadMealCard(requireActivity());
ThreadPoolManager.getExecutor().execute(()->FaceScanUtil.stopReadMealCard(requireActivity()));
myPresentation.closeScan();
ThreadPoolManager.getExecutor().execute(() -> {
UserInfo userInfo = AppDatabase.getDatabase(context).userDao().getUserInfoById(finalUserId1);

View File

@ -128,7 +128,8 @@ public class UpdateDown {
String path = url + UrlConfig.GET_APP_VERSION;
JSONObject json = new JSONObject();
json.put("id", versionCode + "");
json.put("type", "1");
json.put("type", "20");
json.put("deviceType", "20");
String jsonString = json.toString();
Log.i("getPersonMessage jsonString", jsonString);
// 定义 JSON MediaType

View File

@ -20,6 +20,10 @@ package com.bonus.canteen.utils;
import android.util.Log;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;
import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.PrimitiveArrayUtil;
@ -31,7 +35,11 @@ import cn.hutool.crypto.symmetric.SM4;
public class SM4EncryptUtils {
private static final DataEncDecProperties properties = getProperties();
public static final String SUFFIX = "##encrypted";
static {
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.addProvider(new BouncyCastleProvider());
}
}
public static DataEncDecProperties getProperties() {
DataEncDecProperties dataEncDecProperties = new DataEncDecProperties();
dataEncDecProperties.setSm4Key("jY7bZz6Pjml+H/WZYfNSNA==");
@ -42,13 +50,12 @@ public class SM4EncryptUtils {
public static String sm4Encrypt(String data) {
try {
return SmUtil.sm4(SecureUtil.decode(properties.getSm4Key())).encryptBase64(data) + "##encrypted";
return data = Sm4Utils.encrypt(data);
} catch (Exception var2) {
Log.e("SM4加密异常:{}", var2.getMessage());
return data;
}
}
public static String sm4Encryptbyconfig(String data) {
try {
return properties.isEncrypted() ? SmUtil.sm4(SecureUtil.decode(properties.getSm4Key())).encryptBase64(data) + "##encrypted" : data;

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2025 xuexiangjys(xuexiangjys@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.bonus.canteen.utils;
import android.util.Log;
import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.SM4;
public class Sm4Utils {
private static final String KEY = "78d1295afa99449b99d6f83820e6965c";
private static final String IV = "f555adf6c01d0ab0761e626a2dae34a2";
public Sm4Utils() {
}
public static String encrypt(String plainText) {
try {
SM4 sm4 = new SM4(Mode.CBC, Padding.PKCS5Padding, HexUtil.decodeHex("78d1295afa99449b99d6f83820e6965c"), HexUtil.decodeHex("f555adf6c01d0ab0761e626a2dae34a2"));
byte[] encryptedData = sm4.encrypt(plainText);
return HexUtil.encodeHexStr(encryptedData);
} catch (Exception var3) {
Log.e("Sm4Utils", "加密失败", var3);
return plainText;
}
}
public static String decrypt(String cipherText) {
try {
SM4 sm4 = new SM4(Mode.CBC, Padding.PKCS5Padding, HexUtil.decodeHex("78d1295afa99449b99d6f83820e6965c"), HexUtil.decodeHex("f555adf6c01d0ab0761e626a2dae34a2"));
byte[] decryptedData = sm4.decrypt(cipherText);
return new String(decryptedData);
} catch (Exception var3) {
return cipherText;
}
}
public static void main(String[] args) {
String plainText = "admin";
System.out.println("原文: " + plainText);
String encryptedText = encrypt(plainText);
System.out.println("加密后: " + encryptedText);
String decryptedText = decrypt(plainText);
System.out.println("解密后: " + decryptedText);
}
}

View File

@ -260,8 +260,8 @@ public class RabbitMqMqttHelper {
} else {
GetBasicDataService service = new GetBasicDataServiceImp();
service.getFacePhoto(json.getString("currentTime"), json.getIntValue(UPDATE_PERSON));
runOnUiThread(() -> FaceServer.getInstance().loadFace(context));
}
runOnUiThread(() -> FaceServer.getInstance().loadFace(context));
});
} else if (json.getIntValue(field) > 0 && desc.equals("人员信息")) {
ThreadPoolManager.getExecutor().execute(() -> {