人脸使用组件
This commit is contained in:
parent
7cd61b935c
commit
4c9ddf7251
|
|
@ -0,0 +1,26 @@
|
|||
package com.bonus.bmw.config;
|
||||
|
||||
import com.bonus.bmw.utils.FaceFeatureExtractorUtil;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class FaceServiceInitializer implements ApplicationRunner {
|
||||
|
||||
private final FaceServiceProperties properties;
|
||||
|
||||
public FaceServiceInitializer(FaceServiceProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
@Override
|
||||
public void run(ApplicationArguments args) {
|
||||
// 在 Spring 启动完成后,注入值到静态工具类
|
||||
if (properties.getBaseUrl() != null) {
|
||||
FaceFeatureExtractorUtil.setBaseUrl(properties.getBaseUrl());
|
||||
}
|
||||
if (properties.getFaceUrl() != null) {
|
||||
FaceFeatureExtractorUtil.setFaceUrl(properties.getFaceUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.bonus.bmw.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "face.service")
|
||||
@Data
|
||||
public class FaceServiceProperties {
|
||||
private String baseUrl;
|
||||
private String faceUrl;
|
||||
}
|
||||
|
|
@ -24,9 +24,7 @@ import com.bonus.common.security.annotation.RequiresPermissionsOrInnerAuth;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
|
@ -34,7 +32,6 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
|
||||
|
|
@ -862,11 +859,8 @@ public class PmProjectController extends BaseController {
|
|||
String fileName = URLEncoder.encode("三表一册", "UTF-8").replaceAll("\\+", "%20");
|
||||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
||||
|
||||
// 3. 创建全局Workbook(复用,用于多Sheet)
|
||||
// Workbook wb = new SXSSFWorkbook(); // SXSSFWorkbook:大数据量导出(避免OOM)
|
||||
XSSFWorkbook wb = new XSSFWorkbook();
|
||||
try {
|
||||
// 4. 为每个Sheet创建ExcelUtil并添加到Workbook
|
||||
// 4.1 Sheet1:农民工花名册
|
||||
ExportProMonthTableRoster eptr = new ExportProMonthTableRoster();
|
||||
Map<String, Object> map1 = new HashMap<>();
|
||||
|
|
@ -877,7 +871,7 @@ public class PmProjectController extends BaseController {
|
|||
itemMap.put("subName", vo.getSubName());
|
||||
itemMap.put("teamName", vo.getTeamName());
|
||||
itemMap.put("userName", vo.getUserName());
|
||||
itemMap.put("sex", vo.getSex());
|
||||
itemMap.put("sex", "1".equals(vo.getSex()) ? "男" : "女");
|
||||
itemMap.put("workName", vo.getWorkName());
|
||||
itemMap.put("unitAndCode", vo.getUnitAndCode());
|
||||
itemMap.put("period", vo.getPeriod());
|
||||
|
|
@ -886,7 +880,7 @@ public class PmProjectController extends BaseController {
|
|||
itemMap.put("phone", vo.getPhone());
|
||||
itemMap.put("inTime", vo.getInTime());
|
||||
itemMap.put("outTime", vo.getOutTime());
|
||||
itemMap.put("onDuty", vo.getOnDuty());
|
||||
itemMap.put("onDuty", "1".equals(vo.getOnDuty()) ? "在岗" : "离岗");
|
||||
itemMap.put("remark", vo.getRemark());
|
||||
mapList1.add(itemMap);
|
||||
}
|
||||
|
|
@ -981,9 +975,6 @@ public class PmProjectController extends BaseController {
|
|||
map4.put("proName",userWagePayVo.getProName());
|
||||
euwp.createSheet(wb,map4);
|
||||
|
||||
|
||||
|
||||
|
||||
// 5. 将Workbook写入响应流
|
||||
wb.write(response.getOutputStream());
|
||||
response.flushBuffer(); // 强制刷新流
|
||||
|
|
|
|||
|
|
@ -2,11 +2,12 @@ package com.bonus.bmw.controller;
|
|||
|
||||
import com.bonus.bmw.domain.dto.PmWorkerDto;
|
||||
import com.bonus.bmw.domain.dto.WebFileDto;
|
||||
import com.bonus.bmw.domain.face.FaceResult;
|
||||
import com.bonus.bmw.domain.vo.PmWorker;
|
||||
import com.bonus.bmw.domain.vo.PmWorkerImport;
|
||||
import com.bonus.bmw.service.PmWorkerService;
|
||||
import com.bonus.bmw.utils.FaceFeatureExtractorUtil;
|
||||
import com.bonus.common.core.utils.encryption.Sm4Utils;
|
||||
import com.bonus.common.core.utils.face.ArcFaceHelper;
|
||||
import com.bonus.common.core.utils.json.FastJsonHelper;
|
||||
import com.bonus.common.core.utils.poi.ExcelUtil;
|
||||
import com.bonus.common.core.web.controller.BaseController;
|
||||
|
|
@ -24,7 +25,6 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -188,42 +188,26 @@ public class PmWorkerController extends BaseController {
|
|||
@PostMapping("/faceDetection")
|
||||
@SysLog(title = "人脸照片合格检测", businessType = OperaType.UPDATE, logType = 0, module = "施工人员->出入场管理->人员入场管理", details = "人脸照片合格检测")
|
||||
public AjaxResult faceDetection(@RequestParam(value = "file") MultipartFile file) {
|
||||
if (file == null || file.isEmpty()) {
|
||||
return AjaxResult.error("文件为空:" );
|
||||
if (file == null || file.isEmpty()) {
|
||||
return AjaxResult.error("文件为空" );
|
||||
}
|
||||
File fileData = null;
|
||||
try {
|
||||
fileData = FaceFeatureExtractorUtil.multipartToFile(file);
|
||||
FaceResult faceResult = FaceFeatureExtractorUtil.extractFeature(fileData);
|
||||
if (200 == faceResult.getCode()){
|
||||
return AjaxResult.success(faceResult.getMsg());
|
||||
}else{
|
||||
return AjaxResult.error(faceResult.getMsg());
|
||||
}
|
||||
// 创建临时文件
|
||||
File tempFile = null;
|
||||
try {
|
||||
// 获取文件后缀
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
String suffix = "";
|
||||
if (originalFilename != null && originalFilename.contains(".")) {
|
||||
suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
|
||||
}
|
||||
// 创建临时文件
|
||||
tempFile = Files.createTempFile("temp-image-", suffix).toFile();
|
||||
tempFile.deleteOnExit(); // JVM退出时自动删除
|
||||
// 将 MultipartFile 写入临时文件
|
||||
file.transferTo(tempFile);
|
||||
ArcFaceHelper arcFaceHelper = new ArcFaceHelper();
|
||||
// 调用原方法,传入临时文件的路径
|
||||
String faceFeatures;
|
||||
try {
|
||||
faceFeatures = arcFaceHelper.getIsFaceImage(tempFile.getAbsolutePath());
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("人脸照片识别有问题");
|
||||
}
|
||||
String[] split = faceFeatures.split(",");
|
||||
if ("200".equals(split[0])){
|
||||
return AjaxResult.success(split[1]);
|
||||
}else{
|
||||
return AjaxResult.error(split[1]);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// 处理异常(如磁盘满、权限不足等)
|
||||
e.printStackTrace();
|
||||
return AjaxResult.error("人脸检测失败:"+e.getMessage());
|
||||
} catch (IOException e) {
|
||||
logger.error("人脸检测失败:", e);
|
||||
return AjaxResult.error("人脸检测失败:"+e.getMessage());
|
||||
} finally {
|
||||
if (fileData != null && fileData.exists()) {
|
||||
boolean delete = fileData.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -238,46 +222,22 @@ public class PmWorkerController extends BaseController {
|
|||
if (base64file == null || base64file.isEmpty()) {
|
||||
return AjaxResult.error("文件为空");
|
||||
}
|
||||
File tempFile = null;
|
||||
File fileData = null;
|
||||
try {
|
||||
// 解码base64数据
|
||||
String base64Data = base64file;
|
||||
if (base64file.startsWith("data:image")) {
|
||||
// 如果是data URL格式,提取base64部分
|
||||
base64Data = base64file.substring(base64file.indexOf(",") + 1);
|
||||
}
|
||||
// 确定文件扩展名(简单处理,可根据实际需求调整)
|
||||
String suffix = ".jpg"; // 默认jpg格式
|
||||
if (base64file.contains("png")) {
|
||||
suffix = ".png";
|
||||
} else if (base64file.contains("jpeg")) {
|
||||
suffix = ".jpeg";
|
||||
}
|
||||
// 创建临时文件
|
||||
tempFile = Files.createTempFile("temp-image-", suffix).toFile();
|
||||
tempFile.deleteOnExit(); // JVM退出时自动删除
|
||||
// 将base64数据写入临时文件
|
||||
byte[] imageBytes = java.util.Base64.getDecoder().decode(base64Data);
|
||||
java.nio.file.Files.write(tempFile.toPath(), imageBytes);
|
||||
|
||||
ArcFaceHelper arcFaceHelper = new ArcFaceHelper();
|
||||
// 调用原方法,传入临时文件的路径
|
||||
String faceFeatures = null;
|
||||
try {
|
||||
faceFeatures = arcFaceHelper.getIsFaceImage(tempFile.getAbsolutePath());
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("人脸照片识别有问题");
|
||||
}
|
||||
String[] split = faceFeatures.split(",");
|
||||
if ("200".equals(split[0])){
|
||||
return AjaxResult.success(split[1]);
|
||||
fileData =FaceFeatureExtractorUtil.base64ToFile(base64file, "face_detection");;
|
||||
FaceResult faceResult = FaceFeatureExtractorUtil.extractFeature(fileData);
|
||||
if (200 == faceResult.getCode()){
|
||||
return AjaxResult.success(faceResult.getMsg());
|
||||
}else{
|
||||
return AjaxResult.error(split[1]);
|
||||
return AjaxResult.error(faceResult.getMsg());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// 处理异常(如磁盘满、权限不足等)
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
logger.error("人脸检测失败:", e);
|
||||
return AjaxResult.error("人脸检测失败:"+e.getMessage());
|
||||
} finally {
|
||||
if (fileData != null && fileData.exists()) {
|
||||
boolean delete = fileData.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -187,7 +187,6 @@ public class RepairCardApplyController extends BaseController {
|
|||
*/
|
||||
@PostMapping("/updateRepairCardApply")
|
||||
public AjaxResult updateRepairCardApply(@RequestParam(value = "file", required = false) MultipartFile[] files, @RequestParam(value = "fileMsg", required = false) String fileMsg, @RequestParam(value = "params") String params) {
|
||||
|
||||
try {
|
||||
params= Sm4Utils.decrypt(params);
|
||||
fileMsg= Sm4Utils.decrypt(fileMsg);
|
||||
|
|
|
|||
|
|
@ -103,4 +103,6 @@ public class PmWorkerDto {
|
|||
*/
|
||||
private String lightStatus;
|
||||
|
||||
private String workerName;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
package com.bonus.bmw.domain.face;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FaceResult {
|
||||
private int code;
|
||||
private String msg;
|
||||
private Object data;
|
||||
public FaceResult(int code, String msg, Object o) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.data = o;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.bonus.bmw.domain.face;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class GroupInfo {
|
||||
private Long id;
|
||||
private String name;
|
||||
private String createTime;
|
||||
|
||||
public GroupInfo(Long id, String name, String createTime) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.createTime = createTime;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.bonus.bmw.domain.face;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UserInfo {
|
||||
private Long id;
|
||||
private String name;
|
||||
private Long groupId;
|
||||
|
||||
public UserInfo(Long id, String name, Long groupId) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.groupId = groupId;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,8 +11,6 @@ public interface AppRecognitionService {
|
|||
|
||||
String uploadFaceRecognition(MultipartFile facePhoto, FaceRecognitionBean bean);
|
||||
|
||||
String uploadFaceRecognition(String facePhoto, FaceRecognitionBean bean);
|
||||
|
||||
AjaxResult getFaceRecognition(MultipartFile facePhoto, String proId);
|
||||
|
||||
AjaxResult bankCardRecognition(BankCardBean bean);
|
||||
|
|
|
|||
|
|
@ -1,21 +1,19 @@
|
|||
package com.bonus.bmw.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.bonus.bmw.domain.dto.BankCardBean;
|
||||
import com.bonus.bmw.domain.dto.BmWorkerEinUserVo;
|
||||
import com.bonus.bmw.domain.dto.IdCardBean;
|
||||
import com.bonus.bmw.domain.face.FaceResult;
|
||||
import com.bonus.bmw.domain.face.UserInfo;
|
||||
import com.bonus.bmw.domain.po.FaceRecognitionBean;
|
||||
import com.bonus.bmw.mapper.AppRecognitionMapper;
|
||||
import com.bonus.bmw.service.AppRecognitionService;
|
||||
import com.bonus.bmw.utils.BaiduRecognitionUtils;
|
||||
import com.bonus.bmw.utils.FaceStatusCodeReturn;
|
||||
import com.bonus.bmw.utils.FaceFeatureExtractorUtil;
|
||||
import com.bonus.common.core.constant.Constants;
|
||||
import com.bonus.common.core.utils.DateUtils;
|
||||
import com.bonus.common.core.utils.StringUtils;
|
||||
import com.bonus.common.core.utils.json.FastJsonHelper;
|
||||
import com.bonus.common.core.web.domain.AjaxResult;
|
||||
import com.bonus.system.api.model.UploadFileVo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -30,8 +28,8 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -49,8 +47,8 @@ public class AppRecognitionServiceImpl implements AppRecognitionService {
|
|||
@Autowired
|
||||
private FileUploadUtils fileUploadUtils;
|
||||
|
||||
@Value("${face.path}")
|
||||
public String faceUrl;
|
||||
@Value("${face.groupId}")
|
||||
private Long groupId;
|
||||
|
||||
/**
|
||||
* 人脸识别-人脸照片采集入库
|
||||
|
|
@ -61,128 +59,41 @@ public class AppRecognitionServiceImpl implements AppRecognitionService {
|
|||
@Override
|
||||
public String uploadFaceRecognition(MultipartFile facePhoto, FaceRecognitionBean bean) {
|
||||
try {
|
||||
// 最多尝试两次,避免无限循环 ,删除无需重复
|
||||
int maxRetries = 1;
|
||||
if(!"delete".equals(bean.getOptMode())){
|
||||
// 1. 获取文件字节数组
|
||||
byte[] bytes = facePhoto.getBytes();
|
||||
// 2. 使用 Base64 编码
|
||||
String fileBase64 = Base64.getEncoder().encodeToString(bytes);
|
||||
// 根据文件类型添加相应的前缀
|
||||
String originalFilename = facePhoto.getOriginalFilename();
|
||||
if (originalFilename != null && originalFilename.toLowerCase().endsWith(".png")) {
|
||||
bean.setImg("data:image/png;base64," + fileBase64);
|
||||
} else {
|
||||
bean.setImg("data:image/jpeg;base64," + fileBase64);
|
||||
}
|
||||
maxRetries = 2;
|
||||
FaceResult faceResult = FaceFeatureExtractorUtil.updateUserByIdNumber(bean.getIdNumber(), groupId, FaceFeatureExtractorUtil.multipartToFile(facePhoto));
|
||||
if(faceResult.getCode() == 200) {
|
||||
// 解析 data 数组
|
||||
return "人脸入库成功";
|
||||
}else{
|
||||
bean.setImg("data:image/jpeg;base64,fddsdafretrthwuwtrewyewtrweet");
|
||||
}
|
||||
for (int i = 0; i < maxRetries; i++) {
|
||||
String body = HttpUtil.post(faceUrl + "/updatedb",
|
||||
FastJsonHelper.beanToJsonStr(bean));
|
||||
log.error(body);
|
||||
JSONObject jsonObject = FastJsonHelper.jsonStrToJsonObj(body);
|
||||
String code = jsonObject.getString("code");
|
||||
if(StringUtils.isEmpty(code)){
|
||||
log.error("公司人脸识别大傻逼,code不放一起");
|
||||
code = jsonObject.getJSONObject("detail").getString("code");
|
||||
}
|
||||
if ("30019".equals(code) && i == 0) {
|
||||
// 第一次遇到30019错误时,设置replace模式再试一次
|
||||
bean.setOptMode("replace");
|
||||
} else {
|
||||
// 其他情况直接返回结果
|
||||
return "30002".equals(code) ? FaceStatusCodeReturn.faceStatusCodeReturn(30002)
|
||||
: FaceStatusCodeReturn.faceStatusCodeReturn(Integer.parseInt(code));
|
||||
}
|
||||
return faceResult.getMsg();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("上传文件失败", e);
|
||||
return "公司内部人脸识别服务处理异常";
|
||||
return "人脸识别服务处理异常";
|
||||
}
|
||||
return "公司内部人脸识别服务处理异常";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 人脸识别-人脸照片采集入库
|
||||
* @param facePhoto url
|
||||
* @param bean
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String uploadFaceRecognition(String facePhoto, FaceRecognitionBean bean) {
|
||||
try {
|
||||
// 最多尝试两次,避免无限循环 ,删除无需重复
|
||||
int maxRetries = 1;
|
||||
if(!"delete".equals(bean.getOptMode())){
|
||||
log.error("进人脸服务器的人脸图片:{}", facePhoto);
|
||||
bean.setImg("data:image/png;base64,"+facePhoto);
|
||||
maxRetries = 2;
|
||||
}else{
|
||||
bean.setImg("data:image/png;base64,fddsdafretrthwuwtrewyewtrweet");
|
||||
}
|
||||
for (int i = 0; i < maxRetries; i++) {
|
||||
String body = HttpUtil.post(faceUrl + "/updatedb",
|
||||
FastJsonHelper.beanToJsonStr(bean));
|
||||
log.error(body);
|
||||
JSONObject jsonObject = FastJsonHelper.jsonStrToJsonObj(body);
|
||||
String code = jsonObject.getString("code");
|
||||
if(StringUtils.isEmpty(code)){
|
||||
log.error("公司人脸识别大傻逼,code不放一起");
|
||||
code = jsonObject.getJSONObject("detail").getString("code");
|
||||
}
|
||||
if ("30019".equals(code) && i == 0) {
|
||||
// 第一次遇到30019错误时,设置replace模式再试一次
|
||||
bean.setOptMode("replace");
|
||||
} else {
|
||||
// 其他情况直接返回结果
|
||||
return "30002".equals(code) ? FaceStatusCodeReturn.faceStatusCodeReturn(30002)
|
||||
: FaceStatusCodeReturn.faceStatusCodeReturn(Integer.parseInt(code));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("上传文件失败", e);
|
||||
return "公司内部人脸识别服务处理异常";
|
||||
}
|
||||
return "公司内部人脸识别服务处理异常";
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult getFaceRecognition(MultipartFile facePhoto, String proId) {
|
||||
try {
|
||||
// 1. 获取文件字节数组
|
||||
byte[] bytes = facePhoto.getBytes();
|
||||
// 2. 使用 Base64 编码
|
||||
String fileBase64 = Base64.getEncoder().encodeToString(bytes);
|
||||
// 根据文件类型添加相应的前缀
|
||||
String originalFilename = facePhoto.getOriginalFilename();
|
||||
if (originalFilename != null && originalFilename.toLowerCase().endsWith(".png")) {
|
||||
fileBase64 = "data:image/png;base64," + fileBase64;
|
||||
} else {
|
||||
fileBase64 = "data:image/jpeg;base64," + fileBase64;
|
||||
}
|
||||
String body = HttpUtil.post(faceUrl + "/facerecognition",
|
||||
FastJsonHelper.beanToJsonStr(new FaceRecognitionBean(fileBase64)));
|
||||
log.info("人脸识别响应内容: {}", body);
|
||||
JSONObject jsonObject = FastJsonHelper.jsonStrToJsonObj(body);
|
||||
String code = jsonObject.getString("code");
|
||||
File file = FaceFeatureExtractorUtil.multipartToFile(facePhoto);
|
||||
FaceResult faceResult = FaceFeatureExtractorUtil.faceRecognition(groupId, file);
|
||||
BmWorkerEinUserVo sysFile = new BmWorkerEinUserVo();
|
||||
if(!"30000".equals(code)){
|
||||
sysFile.setFaceResult(false);
|
||||
sysFile.setFaceRemark(body);
|
||||
if(faceResult.getCode() == 200) {
|
||||
// 解析 data 数组
|
||||
UserInfo obj = (UserInfo) faceResult.getData();
|
||||
if (obj != null) {
|
||||
String idNumber = obj.getName();
|
||||
// 1. 获取用户信息
|
||||
sysFile = mapper.getOnUserInfoByIdNumber(idNumber,proId);
|
||||
sysFile.setFaceResult(true);
|
||||
sysFile.setImage(faceResult.getMsg());
|
||||
return AjaxResult.success(sysFile);
|
||||
}else {
|
||||
return AjaxResult.error("人脸接口返回异常");
|
||||
}
|
||||
}else{
|
||||
String data = jsonObject.getString("data");
|
||||
JSONArray jsonArray = FastJsonHelper.jsonArrStrToJsonArr(data);
|
||||
String idNumber = (String) jsonArray.get(0);
|
||||
// 1. 获取用户信息
|
||||
sysFile = mapper.getOnUserInfoByIdNumber(idNumber,proId);
|
||||
sysFile.setFaceResult(true);
|
||||
return AjaxResult.error(faceResult.getMsg());
|
||||
}
|
||||
return !"30000".equals(code) ? AjaxResult.error(FaceStatusCodeReturn.faceStatusCodeReturn(Integer.parseInt(code)))
|
||||
: AjaxResult.success(sysFile);
|
||||
} catch (Exception e) {
|
||||
log.error("上传文件失败", e);
|
||||
return AjaxResult.error("未找到人脸信息");
|
||||
|
|
@ -295,8 +206,4 @@ public class AppRecognitionServiceImpl implements AppRecognitionService {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@ package com.bonus.bmw.service.impl;
|
|||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.bonus.bmw.domain.dto.PmWorkerDto;
|
||||
import com.bonus.bmw.domain.face.FaceResult;
|
||||
import com.bonus.bmw.domain.po.FaceRecognitionBean;
|
||||
import com.bonus.bmw.domain.vo.*;
|
||||
import com.bonus.bmw.mapper.*;
|
||||
import com.bonus.bmw.service.AppRecognitionService;
|
||||
import com.bonus.bmw.service.AppService;
|
||||
import com.bonus.bmw.service.UrkSendService;
|
||||
import com.bonus.bmw.utils.FaceFeatureExtractorUtil;
|
||||
import com.bonus.common.core.constant.Constants;
|
||||
import com.bonus.common.core.utils.StringUtils;
|
||||
import com.bonus.common.core.web.domain.AjaxResult;
|
||||
|
|
@ -18,6 +19,7 @@ import com.bonus.system.api.model.UploadFileVo;
|
|||
import com.github.pagehelper.util.StringUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
|
|
@ -43,15 +45,15 @@ public class AppServiceImpl implements AppService {
|
|||
@Autowired
|
||||
private PmWorkerMapper pmWorkerMapper;
|
||||
|
||||
@Value("${face.groupId}")
|
||||
private Long groupId;
|
||||
|
||||
/**
|
||||
* 引入urk服务 调用考勤机服务
|
||||
*/
|
||||
@Autowired
|
||||
private UrkSendService urkSendService;
|
||||
|
||||
@Resource
|
||||
private AppRecognitionService appRecognitionService;
|
||||
|
||||
@Resource
|
||||
private BmWorkerWageCardMapper wageCardMapper;
|
||||
@Autowired
|
||||
|
|
@ -148,12 +150,10 @@ public class AppServiceImpl implements AppService {
|
|||
//下发人脸到考勤机
|
||||
urkSendService.sendUserToDevice(record.getId(), record.getProId(), record.getSubId(), record.getTeamId(),"0");
|
||||
//下发人脸到人脸库
|
||||
FaceRecognitionBean faceRecognitionBean = new FaceRecognitionBean();
|
||||
faceRecognitionBean.setUniqueKey(record.getIdNumber());
|
||||
faceRecognitionBean.setOptMode("add");
|
||||
UploadFileVo fileBast64 = fileUploadUtils.getFileBast64(record.getPhotoIds(), "", Constants.FILE_UPLOAD_WORKER, "");
|
||||
if (fileBast64 != null) {
|
||||
sb.append(appRecognitionService.uploadFaceRecognition(fileBast64.getBast64(), faceRecognitionBean));
|
||||
FaceResult faceResult = FaceFeatureExtractorUtil.updateUserByIdNumberBase64(record.getIdNumber(), groupId,fileBast64.getBast64());
|
||||
sb.append(faceResult.getMsg());
|
||||
}
|
||||
}
|
||||
//入场相关数据添加
|
||||
|
|
@ -229,11 +229,10 @@ public class AppServiceImpl implements AppService {
|
|||
}
|
||||
//下发人脸到人脸库
|
||||
FaceRecognitionBean faceRecognitionBean = new FaceRecognitionBean();
|
||||
faceRecognitionBean.setUniqueKey(record.getIdNumber());
|
||||
faceRecognitionBean.setOptMode("add");
|
||||
UploadFileVo fileBast64 = fileUploadUtils.getFileBast64(record.getPhotoIds(), "", Constants.FILE_UPLOAD_WORKER, "");
|
||||
if (fileBast64 != null) {
|
||||
sb.append(appRecognitionService.uploadFaceRecognition(fileBast64.getBast64(), faceRecognitionBean));
|
||||
FaceResult faceResult = FaceFeatureExtractorUtil.updateUserByIdNumberBase64(record.getIdNumber(), groupId,fileBast64.getBast64());
|
||||
sb.append(faceResult.getMsg());
|
||||
}
|
||||
}
|
||||
if(record.getEinStatus() == 1){
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package com.bonus.bmw.service.impl;
|
|||
|
||||
import com.bonus.bmw.domain.dto.PmWorkerDto;
|
||||
import com.bonus.bmw.domain.dto.WebFileDto;
|
||||
import com.bonus.bmw.domain.po.FaceRecognitionBean;
|
||||
import com.bonus.bmw.domain.vo.MapBeanVo;
|
||||
import com.bonus.bmw.domain.vo.PmWorker;
|
||||
import com.bonus.bmw.mapper.PmWorkerExitMapper;
|
||||
|
|
@ -96,15 +95,6 @@ public class PmWorkerExitServiceImpl implements PmWorkerExitService {
|
|||
}
|
||||
}
|
||||
|
||||
private void delAppFace(Integer workerId) {
|
||||
String idNumber = mapper.getIdNumberByWorkerId(workerId);
|
||||
//下发人脸到人脸库
|
||||
FaceRecognitionBean faceRecognitionBean = new FaceRecognitionBean();
|
||||
faceRecognitionBean.setUniqueKey(idNumber);
|
||||
faceRecognitionBean.setOptMode("delete");
|
||||
appRecognitionService.uploadFaceRecognition("", faceRecognitionBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult updateWorkerBatchExit(List<PmWorkerDto> list) throws Exception {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@ package com.bonus.bmw.service.impl;
|
|||
import cn.hutool.core.date.DateUtil;
|
||||
import com.bonus.bmw.domain.dto.PmWorkerDto;
|
||||
import com.bonus.bmw.domain.dto.WebFileDto;
|
||||
import com.bonus.bmw.domain.po.FaceRecognitionBean;
|
||||
import com.bonus.bmw.domain.face.FaceResult;
|
||||
import com.bonus.bmw.domain.po.MapBeanPo;
|
||||
import com.bonus.bmw.domain.vo.*;
|
||||
import com.bonus.bmw.mapper.PmWorkerMapper;
|
||||
import com.bonus.bmw.service.*;
|
||||
import com.bonus.bmw.utils.FaceFeatureExtractorUtil;
|
||||
import com.bonus.common.core.constant.Constants;
|
||||
import com.bonus.common.core.exception.ServiceException;
|
||||
import com.bonus.common.core.utils.StringUtils;
|
||||
|
|
@ -20,16 +21,21 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Validator;
|
||||
import java.io.File;
|
||||
import java.time.LocalDate;
|
||||
import java.time.Period;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
|
|
@ -58,6 +64,9 @@ public class PmWorkerServiceImpl implements PmWorkerService{
|
|||
@Autowired
|
||||
protected Validator validator;
|
||||
|
||||
@Value("${face.groupId}")
|
||||
private Long groupId;
|
||||
|
||||
/**
|
||||
* 引入urk服务 调用考勤机服务
|
||||
*/
|
||||
|
|
@ -140,13 +149,21 @@ public class PmWorkerServiceImpl implements PmWorkerService{
|
|||
}
|
||||
//下发人脸到人脸库
|
||||
if(!uploadFileVos.isEmpty()){
|
||||
FaceRecognitionBean faceRecognitionBean = new FaceRecognitionBean();
|
||||
faceRecognitionBean.setUniqueKey(record.getIdNumber());
|
||||
faceRecognitionBean.setOptMode("add");
|
||||
if(isBase64){
|
||||
sb.append(appRecognitionService.uploadFaceRecognition(record.getFacePhotoBase64(), faceRecognitionBean));
|
||||
FaceResult faceResult = FaceFeatureExtractorUtil.updateUserByIdNumberBase64(record.getIdNumber(), groupId, record.getFacePhotoBase64());
|
||||
sb.append(faceResult.getMsg());
|
||||
}else{
|
||||
sb.append(appRecognitionService.uploadFaceRecognition(facePhoto, faceRecognitionBean));
|
||||
File file = null;
|
||||
try {
|
||||
file = FaceFeatureExtractorUtil.multipartToFile(facePhoto);
|
||||
FaceResult faceResult = FaceFeatureExtractorUtil.updateUserByIdNumber(record.getIdNumber(), groupId, file);
|
||||
sb.append(faceResult.getMsg());
|
||||
} finally {
|
||||
if (file != null && file.exists()) {
|
||||
boolean delete = file.delete();
|
||||
// 或使用 Hutool: FileUtil.del(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -452,20 +469,27 @@ public class PmWorkerServiceImpl implements PmWorkerService{
|
|||
}
|
||||
//下发人脸到人脸库
|
||||
if(!uploadFileVos.isEmpty()){
|
||||
FaceRecognitionBean faceRecognitionBean = new FaceRecognitionBean();
|
||||
faceRecognitionBean.setUniqueKey(record.getIdNumber());
|
||||
faceRecognitionBean.setOptMode("add");
|
||||
if(isBase64){
|
||||
sb.append(appRecognitionService.uploadFaceRecognition(record.getFacePhotoBase64(), faceRecognitionBean));
|
||||
FaceResult faceResult = FaceFeatureExtractorUtil.updateUserByIdNumberBase64(record.getIdNumber(), groupId, record.getFacePhotoBase64());
|
||||
sb.append(faceResult.getMsg());
|
||||
}else{
|
||||
sb.append(appRecognitionService.uploadFaceRecognition(facePhoto, faceRecognitionBean));
|
||||
File file = null;
|
||||
try {
|
||||
file = FaceFeatureExtractorUtil.multipartToFile(facePhoto);
|
||||
FaceResult faceResult = FaceFeatureExtractorUtil.updateUserByIdNumber(record.getIdNumber(), groupId, file);
|
||||
sb.append(faceResult.getMsg());
|
||||
} finally {
|
||||
if (file != null && file.exists()) {
|
||||
boolean delete = file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(record.getEinStatus() == 1){
|
||||
//已经入过场了
|
||||
//是否修改工种
|
||||
if(record.getPostId() != null && record.getPostId() > 0){
|
||||
if(record.getPostId() != null && record.getPostId() > 0 && record.getPostName() != null && !record.getPostName().isEmpty()){
|
||||
mapper.updateWorkerPost(record);
|
||||
}
|
||||
addWorkerWageCardDataAndContract(record,fileMsg);
|
||||
|
|
@ -479,7 +503,6 @@ public class PmWorkerServiceImpl implements PmWorkerService{
|
|||
log.error("人员下发考勤机失败:",e);
|
||||
sb.append("人员下发考勤机失败--");
|
||||
}
|
||||
|
||||
addWorkerEinData(record,fileMsg);
|
||||
}
|
||||
return AjaxResult.success(sb.append("--基础数据更新成功").toString());
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ public class RepairCardApplyServiceImpl implements RepairCardApplyService {
|
|||
|
||||
@Override
|
||||
public AjaxResult updateRepairCardApply(RepairCardApplyDto cardApplyDto, FileBasicMsgDto fileBasicMsgDto) {
|
||||
cardApplyDto.setApplyUser(SecurityUtils.getUsername());
|
||||
cardApplyDto.setApplyUser(SecurityUtils.getLoginUser().getUsername());
|
||||
Integer num = repairCardApplyMapper.updateRepairCardApply(cardApplyDto);
|
||||
if (num > 0) {
|
||||
repairCardApplyMapper.delRepairCardRecord(cardApplyDto);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,558 @@
|
|||
package com.bonus.bmw.utils;
|
||||
|
||||
import cn.hutool.core.exceptions.ExceptionUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.bonus.bmw.domain.face.FaceResult;
|
||||
import com.bonus.bmw.domain.face.GroupInfo;
|
||||
import com.bonus.bmw.domain.face.UserInfo;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 人脸识别算法服务(Python 微服务)工具类
|
||||
* 统一管理 API 地址,使用 Hutool 封装 HTTP 调用
|
||||
*/
|
||||
public class FaceFeatureExtractorUtil {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(FaceFeatureExtractorUtil.class);
|
||||
// ========== 基础配置 ==========
|
||||
private static String BASE_URL = "http://192.168.0.37:18080/api";
|
||||
private static String FACE_URL = "http://192.168.0.37:18000";
|
||||
|
||||
// ========== API 路径常量 ==========
|
||||
private static final String EXTRACT_FEATURE_PATH = "/api/extract_feature";
|
||||
private static final String HEALTH_CHECK_PATH = "/health";
|
||||
|
||||
public static final String GROUP_ADD_PATH = "/groups/add";
|
||||
public static final String GROUP_LIST_PATH = "/groups/list";
|
||||
public static final String USER_ADD_PATH = "/users/add";
|
||||
public static final String USER_UPDATE_PATH = "/users/update";
|
||||
public static final String USER_SEARCH_PATH = "/users/search";
|
||||
public static final String USER_LIST_PATH = "/users/list";
|
||||
|
||||
/**
|
||||
* 设置算法服务的基础 URL
|
||||
*/
|
||||
public static void setBaseUrl(String baseUrl) {
|
||||
if (baseUrl != null && !baseUrl.trim().isEmpty()) {
|
||||
BASE_URL = baseUrl.trim();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置算法服务的人脸 URL
|
||||
*/
|
||||
public static void setFaceUrl(String faceUrl) {
|
||||
if (faceUrl != null && !faceUrl.trim().isEmpty()) {
|
||||
FACE_URL = faceUrl.trim();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 提取人脸特征向量
|
||||
*
|
||||
* @param imageFile 人脸图片文件(jpg/png)
|
||||
* @return ExtractResult 包含成功状态、特征向量、错误信息等
|
||||
*/
|
||||
public static FaceResult extractFeature(File imageFile) {
|
||||
if (imageFile == null || !imageFile.exists()) {
|
||||
return new FaceResult(500, "Image file is null or not exists", null);
|
||||
}
|
||||
try {
|
||||
System.out.println("开始调用算法服务:"+FACE_URL + EXTRACT_FEATURE_PATH);
|
||||
HttpResponse response = HttpRequest.post(FACE_URL + EXTRACT_FEATURE_PATH).form("image", imageFile).timeout(10000) // 10秒超时
|
||||
.execute();
|
||||
int status = response.getStatus();
|
||||
String body = response.body();
|
||||
if (status != 200) {
|
||||
return new FaceResult(status, "HTTP error: " + status, null);
|
||||
}
|
||||
JSONObject json = JSONUtil.parseObj(body);
|
||||
boolean success = json.getBool("success", false);
|
||||
String message = json.getStr("message", "Unknown error");
|
||||
if (!success) {
|
||||
return new FaceResult(500, message, null);
|
||||
}
|
||||
// 解析 1024 维特征
|
||||
List<Double> featureList = json.getJSONArray("feature").toList(Double.class);
|
||||
double[] featureArray = new double[featureList.size()];
|
||||
for (int i = 0; i < featureList.size(); i++) {
|
||||
featureArray[i] = featureList.get(i);
|
||||
}
|
||||
return new FaceResult(200, "人脸验证成功", featureArray);
|
||||
} catch (Exception e) {
|
||||
String errorMsg = "Exception during feature extraction: " + ExceptionUtil.stacktraceToString(e);
|
||||
return new FaceResult(500, errorMsg, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 健康检查
|
||||
*/
|
||||
public static FaceResult healthCheck() {
|
||||
try {
|
||||
HttpResponse response = HttpRequest.get(FACE_URL + HEALTH_CHECK_PATH).timeout(3000).execute();
|
||||
if (response.getStatus() == 200) {
|
||||
JSONObject json = JSONUtil.parseObj(response.body());
|
||||
return "healthy".equals(json.getStr("status")) ? new FaceResult(200, "服务正常", null): new FaceResult(500, "服务异常", null);
|
||||
}
|
||||
return new FaceResult(500, "服务健康检查异常", null);
|
||||
} catch (Exception e) {
|
||||
return new FaceResult(500, "服务健康检查异常", null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建分组
|
||||
*
|
||||
* @param name 分组名称(必填)
|
||||
* @param description 分组描述(可选,可传 null)
|
||||
* @return 返回结果对象,包含 id、name、createTime 等
|
||||
*/
|
||||
public static FaceResult addGroup(String name, String description) {
|
||||
if (name == null || name.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("分组名称不能为空");
|
||||
}
|
||||
// 构建请求体 JSON
|
||||
JSONObject requestBody = JSONUtil.createObj().set("name", name).set("description", description); // Hutool 会自动忽略 null 值(不会序列化)
|
||||
try {
|
||||
HttpResponse response = HttpRequest.post(BASE_URL + GROUP_ADD_PATH).body(requestBody.toString()) // 发送 JSON 字符串
|
||||
.contentType("application/json") // 设置 Content-Type
|
||||
.timeout(5000) // 超时 5 秒
|
||||
.execute();
|
||||
// 解析响应
|
||||
int status = response.getStatus();
|
||||
String body = response.body();
|
||||
if (status != 200) {
|
||||
return new FaceResult(status, "创建分组-人脸库返回异常", null);
|
||||
}
|
||||
JSONObject respJson = JSONUtil.parseObj(body);
|
||||
int code = respJson.getInt("code", -1);
|
||||
String msg = respJson.getStr("msg", "Unknown");
|
||||
if (code != 200) {
|
||||
return new FaceResult(status, msg, null);
|
||||
}
|
||||
// 提取 data 部分
|
||||
JSONObject data = respJson.getJSONObject("data");
|
||||
Long id = data.getLong("id");
|
||||
String groupName = data.getStr("name");
|
||||
String createTime = data.getStr("createTime");
|
||||
return new FaceResult(status, "success", new GroupInfo(id, groupName, createTime));
|
||||
} catch (Exception e) {
|
||||
return new FaceResult(500, "请求异常: " + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有分组列表
|
||||
*
|
||||
* @return 返回结果对象,包含 id、name、createTime 等
|
||||
*/
|
||||
public static FaceResult getGroupList() {
|
||||
try {
|
||||
// 构建请求体 JSON
|
||||
HttpResponse response = HttpRequest.get(BASE_URL + GROUP_LIST_PATH).timeout(5000).execute();
|
||||
// 解析响应
|
||||
int status = response.getStatus();
|
||||
String body = response.body();
|
||||
if (status != 200) {
|
||||
return new FaceResult(status, "获取分组列表-人脸库返回异常", null);
|
||||
}
|
||||
JSONObject respJson = JSONUtil.parseObj(body);
|
||||
int code = respJson.getInt("code", -1);
|
||||
String msg = respJson.getStr("msg", "Unknown");
|
||||
if (code != 200) {
|
||||
return new FaceResult(status, msg, null);
|
||||
}
|
||||
// 解析 data 数组
|
||||
JSONArray dataArray = respJson.getJSONArray("data");
|
||||
List<GroupInfo> groupList = new ArrayList<>();
|
||||
if (dataArray != null) {
|
||||
for (Object obj : dataArray) {
|
||||
if (obj instanceof JSONObject) {
|
||||
JSONObject item = (JSONObject) obj;
|
||||
Long id = item.getLong("id");
|
||||
String name = item.getStr("name");
|
||||
// 注意:list 接口不返回 createTime,所以只取 id 和 name
|
||||
groupList.add(new GroupInfo(id, name, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
return new FaceResult(status, "success", groupList);
|
||||
} catch (Exception e) {
|
||||
return new FaceResult(500, "请求异常: " + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 【核心方法】新增人员
|
||||
* 支持格式:
|
||||
* @param idNumber 人员主键
|
||||
* @param groupId 分组ID(可为 null)
|
||||
* @param photoFile 图片
|
||||
* @return 添加结果
|
||||
*/
|
||||
public static FaceResult addUser(String idNumber, Long groupId, File photoFile) {
|
||||
if (idNumber == null || idNumber.trim().isEmpty()) {
|
||||
return new FaceResult(500, "人员主键不能为空", null);
|
||||
}
|
||||
if (photoFile == null || !photoFile.exists()) {
|
||||
return new FaceResult(500, "照片文件无效", null);
|
||||
}
|
||||
try {
|
||||
HttpRequest request = HttpRequest.post(BASE_URL + USER_ADD_PATH)
|
||||
.form("name", idNumber)
|
||||
// Hutool 自动处理 multipart
|
||||
.form("photo", photoFile);
|
||||
if (groupId != null) {
|
||||
request.form("groupId", groupId.toString());
|
||||
}
|
||||
|
||||
HttpResponse response = request.timeout(10000).execute();
|
||||
int status = response.getStatus();
|
||||
String body = response.body();
|
||||
if (status != 200) {
|
||||
return new FaceResult(500, "HTTP Error: " + status, null);
|
||||
}
|
||||
JSONObject respJson = JSONUtil.parseObj(body);
|
||||
int code = respJson.getInt("code", -1);
|
||||
String msg = respJson.getStr("msg", "Unknown");
|
||||
if (code != 200) {
|
||||
return new FaceResult(status, msg, null);
|
||||
}
|
||||
JSONObject data = respJson.getJSONObject("data");
|
||||
Long id = data.getLong("id");
|
||||
String savedName = data.getStr("name");
|
||||
Long savedGroupId = data.getLong("groupId", null);
|
||||
UserInfo userInfo = new UserInfo(id, savedName, savedGroupId);
|
||||
return new FaceResult(status, "success", userInfo);
|
||||
} catch (Exception e) {
|
||||
return new FaceResult(500, "请求异常: " + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 【核心方法】通过文件上传更新人员信息
|
||||
*
|
||||
* @param id 人员ID(必填)
|
||||
* @param idNumber 人员主键(必填)
|
||||
* @param groupId 分组ID(可为 null,表示不修改)
|
||||
* @param photoFile 新照片文件(可为 null,表示不修改)
|
||||
* @return 更新结果
|
||||
*/
|
||||
public static FaceResult updateUser(Long id, String idNumber, Long groupId, File photoFile) {
|
||||
if (id == null || id <= 0) {
|
||||
return new FaceResult(500, "人员ID无效", null);
|
||||
}
|
||||
if (idNumber == null || idNumber.trim().isEmpty()) {
|
||||
return new FaceResult(500, "人员主键不能为空", null);
|
||||
}
|
||||
try {
|
||||
HttpRequest request = HttpRequest.post(BASE_URL + USER_UPDATE_PATH +"/"+ id)
|
||||
.form("name", idNumber); // 必填
|
||||
if (groupId != null) {
|
||||
request.form("groupId", groupId.toString());
|
||||
}
|
||||
if (photoFile != null && photoFile.exists()) {
|
||||
request.form("photo", photoFile);
|
||||
}
|
||||
HttpResponse response = request.timeout(10000).execute();
|
||||
int status = response.getStatus();
|
||||
String body = response.body();
|
||||
if (status != 200) {
|
||||
return new FaceResult(status, "HTTP Error: " + status, null);
|
||||
}
|
||||
|
||||
JSONObject respJson = JSONUtil.parseObj(body);
|
||||
int code = respJson.getInt("code", -1);
|
||||
String msg = respJson.getStr("msg", "Unknown");
|
||||
|
||||
if (code != 200) {
|
||||
return new FaceResult(status, msg, null);
|
||||
}
|
||||
// 可根据实际返回结构解析 data,此处简化为只返回成功状态
|
||||
return new FaceResult(status, "success", null);
|
||||
} catch (Exception e) {
|
||||
return new FaceResult(500, "请求异常: " + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于上传一张人脸照片,并在指定分组内检索最相似的人
|
||||
* @param photoFile 人员主键关键词(可为 null 或空,表示不筛选)
|
||||
* @param groupId 分组ID(可为 null,表示不筛选)
|
||||
* @return 查询结果
|
||||
*/
|
||||
public static FaceResult faceRecognition(Long groupId, File photoFile) {
|
||||
if (photoFile == null || !photoFile.exists()) {
|
||||
return new FaceResult(500, "照片文件无效", null);
|
||||
}
|
||||
if (groupId == null || groupId <= 0) {
|
||||
return new FaceResult(500, "分组Id不能为空", null);
|
||||
}
|
||||
try {
|
||||
HttpRequest request = HttpRequest.post(BASE_URL + USER_SEARCH_PATH)
|
||||
.form("photo", photoFile)
|
||||
.form("groupId", groupId);
|
||||
HttpResponse response = request.timeout(10000).execute();
|
||||
int status = response.getStatus();
|
||||
String body = response.body();
|
||||
if (status != 200) {
|
||||
return new FaceResult(status, "HTTP Error: " + status, null);
|
||||
}
|
||||
JSONObject respJson = JSONUtil.parseObj(body);
|
||||
int code = respJson.getInt("code", -1);
|
||||
String msg = respJson.getStr("msg", "Unknown");
|
||||
if (code != 200) {
|
||||
return new FaceResult(status, msg, null);
|
||||
}
|
||||
// 解析 data 数组
|
||||
JSONObject obj = respJson.getJSONObject("data");
|
||||
UserInfo userInfo = null;
|
||||
if (obj != null) {
|
||||
Long id = obj.getLong("id");
|
||||
String userName = obj.getStr("name");
|
||||
Long gid = obj.getLong("groupId", null);
|
||||
userInfo = new UserInfo(id,userName,gid);
|
||||
}
|
||||
// 可根据实际返回结构解析 data,此处简化为只返回成功状态
|
||||
return new FaceResult(status, "检测成功", userInfo);
|
||||
} catch (Exception e) {
|
||||
return new FaceResult(500, "请求异常: " + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过主键去更新人员数据
|
||||
*
|
||||
* @param idNumber 人员主键关键词(可为 null 或空,表示不筛选)
|
||||
* @param groupId 分组ID(可为 null,表示不筛选)
|
||||
* @return 查询结果
|
||||
*/
|
||||
public static FaceResult updateUserByIdNumber(String idNumber, Long groupId, File photoFile) {
|
||||
try {
|
||||
FaceResult faceResult = getFaceUserList(idNumber, groupId);
|
||||
if(faceResult.getCode() !=200){
|
||||
return faceResult;
|
||||
}
|
||||
List<UserInfo> userList = (List<UserInfo>) faceResult.getData();
|
||||
if(userList.isEmpty()){
|
||||
return addUser(idNumber, groupId, photoFile);
|
||||
}else if(userList.size()>1){
|
||||
return new FaceResult(500, "查询到多个人员主键,请去人脸库查找问题", null);
|
||||
}else {
|
||||
return updateUser(userList.get(0).getId(), idNumber, groupId, photoFile);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return new FaceResult(500, "请求异常: " + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取人员列表(支持按人员主键模糊查询、按分组筛选)
|
||||
*
|
||||
* @param idNumber 人员主键关键词(可为 null 或空,表示不筛选)
|
||||
* @param groupId 分组ID(可为 null,表示不筛选)
|
||||
* @return 查询结果
|
||||
*/
|
||||
public static FaceResult getFaceUserList(String idNumber, Long groupId) {
|
||||
try {
|
||||
HttpRequest request = HttpRequest.get(BASE_URL + USER_LIST_PATH);
|
||||
// 动态添加查询参数(仅当值有效时)
|
||||
if (idNumber != null && !idNumber.trim().isEmpty()) {
|
||||
request.form("name", idNumber.trim()); // Hutool GET 也支持 .form() 自动转 query
|
||||
}
|
||||
if (groupId != null && groupId > 0) {
|
||||
request.form("groupId", groupId.toString());
|
||||
}
|
||||
HttpResponse response = request.timeout(5000).execute();
|
||||
int status = response.getStatus();
|
||||
String body = response.body();
|
||||
if (status != 200) {
|
||||
return new FaceResult(status, "HTTP Error: " + status, null);
|
||||
}
|
||||
JSONObject respJson = JSONUtil.parseObj(body);
|
||||
int code = respJson.getInt("code", -1);
|
||||
String msg = respJson.getStr("msg", "Unknown");
|
||||
if (code != 200) {
|
||||
return new FaceResult(status, msg, null);
|
||||
}
|
||||
// 解析 data 数组
|
||||
JSONArray dataArray = respJson.getJSONArray("data");
|
||||
List<UserInfo> userList = new ArrayList<>();
|
||||
if (dataArray != null) {
|
||||
for (Object obj : dataArray) {
|
||||
if (obj instanceof JSONObject) {
|
||||
JSONObject item = (JSONObject) obj;
|
||||
Long id = item.getLong("id");
|
||||
String userName = item.getStr("name");
|
||||
Long gid = item.getLong("groupId", null);
|
||||
userList.add(new UserInfo(id, userName, gid));
|
||||
}
|
||||
}
|
||||
}
|
||||
return new FaceResult(status, "success", userList);
|
||||
} catch (Exception e) {
|
||||
return new FaceResult(500, "请求异常: " + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 【便捷方法】通过 Base64 字符串新增人员
|
||||
* 支持格式:
|
||||
* - 纯 Base64: "/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAg..."
|
||||
* - Data URL: "data:image/jpeg;base64,/9j/4AAQ..."
|
||||
* @param idNumber 人员主键
|
||||
* @param groupId 分组ID(可为 null)
|
||||
* @param base64Image Base64 编码的图片
|
||||
* @return 添加结果
|
||||
*/
|
||||
public static FaceResult addUserWithBase64(String idNumber, Long groupId, String base64Image) {
|
||||
if (base64Image == null || base64Image.trim().isEmpty()) {
|
||||
return new FaceResult(500, "Base64 图片为空", null);
|
||||
}
|
||||
File tempFile = null;
|
||||
try {
|
||||
tempFile = base64ToFile(base64Image, "face_add_");
|
||||
if (tempFile == null) {
|
||||
return new FaceResult(500, "无法创建临时文件", null);
|
||||
}
|
||||
return addUser(idNumber, groupId, tempFile);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return new FaceResult(500, "Base64 格式无效: " + e.getMessage(), null);
|
||||
} catch (IORuntimeException e) {
|
||||
return new FaceResult(500, "写入临时文件失败: " + e.getMessage(), null);
|
||||
} finally {
|
||||
if (tempFile != null && tempFile.exists()) {
|
||||
FileUtil.del(tempFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 【便捷方法】通过 Base64 更新人员信息
|
||||
*
|
||||
* @param id 人员ID
|
||||
* @param idNumber idNumber(必填)
|
||||
* @param groupId 分组ID(可为 null)
|
||||
* @param base64Image Base64 编码的图片(可为 null)
|
||||
* @return 更新结果
|
||||
*/
|
||||
public static FaceResult updateUserWithBase64(Long id, String idNumber, Long groupId, String base64Image) {
|
||||
File tempFile = null;
|
||||
try {
|
||||
if (base64Image != null && !base64Image.trim().isEmpty()) {
|
||||
tempFile = base64ToFile(base64Image, "face_update_");
|
||||
if (tempFile == null) {
|
||||
return new FaceResult(500, "无法创建临时文件", null);
|
||||
}
|
||||
}
|
||||
// 若 base64Image 为空,则 tempFile 为 null,表示不更新照片
|
||||
return updateUser(id, idNumber, groupId, tempFile);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return new FaceResult(500, "Base64 格式无效: " + e.getMessage(), null);
|
||||
} catch (IORuntimeException e) {
|
||||
return new FaceResult(500, "写入临时文件失败: " + e.getMessage(), null);
|
||||
} finally {
|
||||
if (tempFile != null && tempFile.exists()) {
|
||||
FileUtil.del(tempFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过主键去更新人员数据
|
||||
*
|
||||
* @param idNumber 人员主键关键词(可为 null 或空,表示不筛选)
|
||||
* @param groupId 分组ID(可为 null,表示不筛选)
|
||||
* @return 查询结果
|
||||
*/
|
||||
public static FaceResult updateUserByIdNumberBase64(String idNumber, Long groupId, String photoFileBase64) {
|
||||
try {
|
||||
FaceResult faceResult = getFaceUserList(idNumber, groupId);
|
||||
if(faceResult.getCode() !=200){
|
||||
return faceResult;
|
||||
}
|
||||
List<UserInfo> userList = (List<UserInfo>) faceResult.getData();
|
||||
if(userList.isEmpty()){
|
||||
return addUserWithBase64(idNumber, groupId, photoFileBase64);
|
||||
}else if(userList.size()>1){
|
||||
return new FaceResult(500, "查询到多个人员主键,请去人脸库查找问题", null);
|
||||
}else {
|
||||
return updateUserWithBase64(userList.get(0).getId(), idNumber, groupId, photoFileBase64);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return new FaceResult(500, "请求异常: " + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 Base64 编码的图片字符串转换为临时文件
|
||||
*
|
||||
* @param base64Image 支持纯 Base64 或 Data URL 格式(如 data:image/jpeg;base64,...)
|
||||
* @param prefix 临时文件前缀(如 "face_add_", "face_update_"),用于区分用途
|
||||
* @return 临时 File 对象;若输入无效则返回 null
|
||||
* @throws IllegalArgumentException Base64 格式非法
|
||||
* @throws IORuntimeException 写入临时文件失败
|
||||
*/
|
||||
public static File base64ToFile(String base64Image, String prefix) {
|
||||
if (base64Image == null || base64Image.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
String base64Data = base64Image.trim();
|
||||
// 去除 Data URL 前缀
|
||||
Pattern pattern = Pattern.compile("^data:image/(jpeg|jpg|png);base64,(.*)$", Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(base64Data);
|
||||
if (matcher.matches()) {
|
||||
base64Data = matcher.group(2);
|
||||
}
|
||||
// 解码
|
||||
byte[] imageBytes = Base64.getDecoder().decode(base64Data);
|
||||
// 生成唯一文件名
|
||||
String fileName = (prefix != null ? prefix : "temp_") + IdUtil.fastSimpleUUID() + ".jpg";
|
||||
String tempPath = System.getProperty("java.io.tmpdir") + "/" + fileName;
|
||||
|
||||
// 写入临时文件
|
||||
return FileUtil.writeBytes(imageBytes, tempPath);
|
||||
}
|
||||
|
||||
public static File multipartToFile(MultipartFile multipartFile) throws IOException {
|
||||
// 创建临时文件(自动在系统临时目录)
|
||||
File tempFile = File.createTempFile(
|
||||
"upload_",
|
||||
"." + getExtension(multipartFile.getOriginalFilename())
|
||||
);
|
||||
// 将 MultipartFile 写入临时文件
|
||||
multipartFile.transferTo(tempFile);
|
||||
return tempFile;
|
||||
}
|
||||
// 辅助方法:获取文件扩展名
|
||||
private static String getExtension(String fileName) {
|
||||
if (fileName == null || fileName.lastIndexOf(".") == -1) {
|
||||
return ""; // 无扩展名
|
||||
}
|
||||
return fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -28,4 +28,7 @@ jasypt:
|
|||
password: Encrypt
|
||||
#人脸
|
||||
face:
|
||||
path: http://112.29.103.165:1616/faceIdentification
|
||||
service:
|
||||
base-url: http://192.168.0.37:18080/api
|
||||
face-url: http://192.168.0.37:18000
|
||||
groupId: 5
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@
|
|||
SELECT
|
||||
psc.id AS sub_com_id,
|
||||
psc.sub_company_name,
|
||||
SUM(CASE WHEN pp.pro_status = '0' THEN 1 ELSE 0 END) AS buildProNum,
|
||||
SUM(CASE WHEN pp.pro_status = '2' THEN 1 ELSE 0 END) AS preProNum,
|
||||
SUM(CASE WHEN pp.pro_status = '4' THEN 1 ELSE 0 END) AS completedProNum,
|
||||
COUNT(DISTINCT CASE WHEN pp.pro_status = '0' THEN pp.id ELSE null END) AS buildProNum,
|
||||
COUNT(DISTINCT CASE WHEN pp.pro_status = '2' THEN pp.id ELSE null END) AS preProNum,
|
||||
COUNT(DISTINCT CASE WHEN pp.pro_status = '4' THEN pp.id ELSE null END) AS completedProNum,
|
||||
COUNT(DISTINCT bsc.sub_id) AS subNum,
|
||||
COUNT(DISTINCT bstc.team_id) AS teamNum,
|
||||
COUNT(DISTINCT bwem.worker_id) AS einNum,
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@
|
|||
count(1)
|
||||
FROM
|
||||
bm_worker_ein_msg bwem
|
||||
INNER JOIN bm_att_person bap ON bap.worker_id
|
||||
INNER JOIN bm_att_person bap ON bap.worker_id = bwem.worker_id
|
||||
AND bap.pro_id = bwem.pro_id
|
||||
WHERE
|
||||
bwem.worker_id = #{workerId}
|
||||
|
|
|
|||
|
|
@ -435,8 +435,8 @@
|
|||
<if test="teamName != null and teamName != ''">
|
||||
and locate(#{teamName}, bwem.team_name) > 0
|
||||
</if>
|
||||
<if test="name != null and name != ''">
|
||||
and pw.name like concat('%',#{name},'%')
|
||||
<if test="workerName != null and workerName != ''">
|
||||
and pw.name like concat('%',#{workerName},'%')
|
||||
</if>
|
||||
GROUP BY
|
||||
pw.id,bwem.pro_id
|
||||
|
|
|
|||
|
|
@ -1,20 +1,5 @@
|
|||
package com.bonus.job.controller;
|
||||
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.bonus.common.log.annotation.SysLog;
|
||||
import com.bonus.common.log.enums.OperaType;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.bonus.common.core.constant.Constants;
|
||||
import com.bonus.common.core.exception.job.TaskException;
|
||||
import com.bonus.common.core.utils.StringUtils;
|
||||
|
|
@ -22,16 +7,24 @@ import com.bonus.common.core.utils.poi.ExcelUtil;
|
|||
import com.bonus.common.core.web.controller.BaseController;
|
||||
import com.bonus.common.core.web.domain.AjaxResult;
|
||||
import com.bonus.common.core.web.page.TableDataInfo;
|
||||
import com.bonus.common.log.annotation.SysLog;
|
||||
import com.bonus.common.log.enums.OperaType;
|
||||
import com.bonus.common.security.annotation.RequiresPermissions;
|
||||
import com.bonus.common.security.utils.SecurityUtils;
|
||||
import com.bonus.job.domain.SysJob;
|
||||
import com.bonus.job.service.ISysJobService;
|
||||
import com.bonus.job.util.CronUtils;
|
||||
import com.bonus.job.util.ScheduleUtils;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 调度任务信息操作处理
|
||||
*
|
||||
*
|
||||
* @author bonus
|
||||
*/
|
||||
@RestController
|
||||
|
|
@ -165,7 +158,7 @@ public class SysJobController extends BaseController
|
|||
* 定时任务立即执行一次
|
||||
*/
|
||||
@RequiresPermissions("monitor:job:changeStatus")
|
||||
@PostMapping("/run")
|
||||
@PostMapping("/run")
|
||||
@SysLog(title = "定时任务", businessType = OperaType.UPDATE,logType = 0,module = "系统监控->定时任务",details = "定时任务立即执行一次")
|
||||
public AjaxResult run(@RequestBody SysJob job) throws SchedulerException
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
package com.bonus.job.service;
|
||||
|
||||
import java.util.List;
|
||||
import javax.annotation.PostConstruct;
|
||||
import com.bonus.common.core.constant.ScheduleConstants;
|
||||
import com.bonus.common.core.exception.job.TaskException;
|
||||
import com.bonus.job.domain.SysJob;
|
||||
import com.bonus.job.mapper.SysJobMapper;
|
||||
import com.bonus.job.util.CronUtils;
|
||||
import com.bonus.job.util.ScheduleUtils;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.Scheduler;
|
||||
|
|
@ -9,16 +13,13 @@ import org.quartz.SchedulerException;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import com.bonus.common.core.constant.ScheduleConstants;
|
||||
import com.bonus.common.core.exception.job.TaskException;
|
||||
import com.bonus.job.domain.SysJob;
|
||||
import com.bonus.job.mapper.SysJobMapper;
|
||||
import com.bonus.job.util.CronUtils;
|
||||
import com.bonus.job.util.ScheduleUtils;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 定时任务调度信息 服务层
|
||||
*
|
||||
*
|
||||
* @author bonus
|
||||
*/
|
||||
@Service
|
||||
|
|
@ -46,7 +47,7 @@ public class SysJobServiceImpl implements ISysJobService
|
|||
|
||||
/**
|
||||
* 获取quartz调度器的计划任务列表
|
||||
*
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -58,7 +59,7 @@ public class SysJobServiceImpl implements ISysJobService
|
|||
|
||||
/**
|
||||
* 通过调度任务ID查询调度信息
|
||||
*
|
||||
*
|
||||
* @param jobId 调度任务ID
|
||||
* @return 调度任务对象信息
|
||||
*/
|
||||
|
|
@ -70,7 +71,7 @@ public class SysJobServiceImpl implements ISysJobService
|
|||
|
||||
/**
|
||||
* 暂停任务
|
||||
*
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
|
|
@ -90,7 +91,7 @@ public class SysJobServiceImpl implements ISysJobService
|
|||
|
||||
/**
|
||||
* 恢复任务
|
||||
*
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
|
|
@ -110,7 +111,7 @@ public class SysJobServiceImpl implements ISysJobService
|
|||
|
||||
/**
|
||||
* 删除任务后,所对应的trigger也将被删除
|
||||
*
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
|
|
@ -129,7 +130,7 @@ public class SysJobServiceImpl implements ISysJobService
|
|||
|
||||
/**
|
||||
* 批量删除调度信息
|
||||
*
|
||||
*
|
||||
* @param jobIds 需要删除的任务ID
|
||||
* @return 结果
|
||||
*/
|
||||
|
|
@ -146,7 +147,7 @@ public class SysJobServiceImpl implements ISysJobService
|
|||
|
||||
/**
|
||||
* 任务调度状态修改
|
||||
*
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
|
|
@ -168,7 +169,7 @@ public class SysJobServiceImpl implements ISysJobService
|
|||
|
||||
/**
|
||||
* 立即运行任务
|
||||
*
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
|
|
@ -193,7 +194,7 @@ public class SysJobServiceImpl implements ISysJobService
|
|||
|
||||
/**
|
||||
* 新增任务
|
||||
*
|
||||
*
|
||||
* @param job 调度信息 调度信息
|
||||
*/
|
||||
@Override
|
||||
|
|
@ -211,7 +212,7 @@ public class SysJobServiceImpl implements ISysJobService
|
|||
|
||||
/**
|
||||
* 更新任务的时间表达式
|
||||
*
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
|
|
@ -229,7 +230,7 @@ public class SysJobServiceImpl implements ISysJobService
|
|||
|
||||
/**
|
||||
* 更新任务
|
||||
*
|
||||
*
|
||||
* @param job 任务对象
|
||||
* @param jobGroup 任务组名
|
||||
*/
|
||||
|
|
@ -248,7 +249,7 @@ public class SysJobServiceImpl implements ISysJobService
|
|||
|
||||
/**
|
||||
* 校验cron表达式是否有效
|
||||
*
|
||||
*
|
||||
* @param cronExpression 表达式
|
||||
* @return 结果
|
||||
*/
|
||||
|
|
@ -257,4 +258,4 @@ public class SysJobServiceImpl implements ISysJobService
|
|||
{
|
||||
return CronUtils.isValid(cronExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue