Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
@ -0,0 +1,89 @@
|
||||
package org.dromara.common.utils.attendance;
|
||||
|
||||
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class FaceUtil {
|
||||
|
||||
private static final String FACE_URL = "http://192.168.110.5:1224";
|
||||
|
||||
/**
|
||||
* 创建人脸记录 post
|
||||
* @param name 姓名
|
||||
* @param card 身份证
|
||||
* @param path 人脸图片HTTP地址(需可公开访问)
|
||||
*/
|
||||
public static void createFaceRecord(String name, String card, String path) {
|
||||
String url = FACE_URL+"/api/faces";
|
||||
|
||||
HashMap<String, Object> param = new HashMap<>() {{
|
||||
put("name", name);
|
||||
put("card", card);
|
||||
put("path", path);
|
||||
}};
|
||||
HttpUtil.post(url, param);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 人脸检测
|
||||
* @param path 图片HTTP地址(需可公开访问)
|
||||
*/
|
||||
public static Map<String, String> faceDetect(String path) {
|
||||
String url = FACE_URL+"/api/faces/detect";
|
||||
|
||||
HashMap<String, Object> param = new HashMap<>() {{
|
||||
put("path", path);
|
||||
put("similarity_threshold", 0.8);
|
||||
}};
|
||||
//转成json
|
||||
|
||||
String post = HttpUtil.post(url, param);
|
||||
Map<String, String> map = new HashMap<>();
|
||||
// 遍历检测到的人脸数据
|
||||
try {
|
||||
// 解析返回的JSON数据
|
||||
JSONObject response = JSON.parseObject(post);
|
||||
JSONObject data = response.getJSONObject("data");
|
||||
JSONArray detectedFaces = data.getJSONArray("detected_faces");
|
||||
|
||||
for (int i = 0; i < detectedFaces.size(); i++) {
|
||||
JSONObject face = detectedFaces.getJSONObject(i);
|
||||
JSONObject matchInfo = face.getJSONObject("match_info");
|
||||
|
||||
// 检查相似度是否大于等于阈值
|
||||
double similarity = matchInfo.getDoubleValue("similarity");
|
||||
double threshold = matchInfo.getDoubleValue("threshold");
|
||||
|
||||
if (similarity >= threshold) {
|
||||
// 提取用户信息
|
||||
JSONObject userInfo = face.getJSONObject("user_info");
|
||||
String name = userInfo.getString("name");
|
||||
String idCard = userInfo.getString("id_card");
|
||||
map.put(idCard, name);
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("人脸检测失败",e);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Map<String, String> map = faceDetect("http://xny.yj-3d.com:9000/xinnengyuan-dev/2025/10/12/9688ce2474ad47e7bf59c641848cdf8f.jpg");
|
||||
// System.out.println(map);
|
||||
// createFaceRecord("石志强","513022111145632652","http://xny.yj-3d.com:9000/xinnengyuan-dev/2025/10/12/9688ce2474ad47e7bf59c641848cdf8f.jpg");
|
||||
}
|
||||
|
||||
}
|
||||
@ -69,6 +69,7 @@ public class BusAttendanceDeviceController extends BaseController {
|
||||
req.setProjectId(one.getProjectId());
|
||||
req.setUserId(userId);
|
||||
req.setPunchTime(localDateTime);
|
||||
req.setSource("1");
|
||||
//打印req
|
||||
log.info("请求参数:{}", req);
|
||||
//base64转MultipartFile
|
||||
|
||||
@ -113,4 +113,9 @@ public class BusAttendance extends BaseEntity {
|
||||
* 代打卡人员Id
|
||||
*/
|
||||
private Long replaceId;
|
||||
|
||||
/**
|
||||
* 来源
|
||||
*/
|
||||
private String source;
|
||||
}
|
||||
|
||||
@ -47,4 +47,10 @@ public class BusAttendancePunchCardByFaceReq implements Serializable {
|
||||
*/
|
||||
private LocalDateTime punchTime;
|
||||
|
||||
|
||||
/**
|
||||
* 来源 (0-app,1-考勤机 )
|
||||
*/
|
||||
private String source;
|
||||
|
||||
}
|
||||
|
||||
@ -391,7 +391,8 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
||||
List<BusAttendance> outAttendances = attendances.stream().filter(attendance ->
|
||||
BusAttendanceCommuterEnum.CLOCKOUT.getValue().equals(attendance.getClockType())).toList();
|
||||
|
||||
if (clockTypeByTime == 1 && CollectionUtils.isEmpty(inAttendances)) {
|
||||
if (clockTypeByTime == 1) {
|
||||
if(CollectionUtils.isEmpty(inAttendances)){
|
||||
BusAttendance attendance = new BusAttendance();
|
||||
// 上班打卡
|
||||
attendance.setClockType(BusAttendanceCommuterEnum.CLOCKIN.getValue());
|
||||
@ -417,6 +418,9 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
||||
attendance.setClockTime(now);
|
||||
attendance.setUserName(constructionUser.getUserName());
|
||||
attendance.setReplaceId(replaceId);
|
||||
if(req.getSource() != null){
|
||||
attendance.setSource(req.getSource());
|
||||
}
|
||||
// 记录打卡坐标
|
||||
attendance.setLat(req.getLat());
|
||||
attendance.setLng(req.getLng());
|
||||
@ -440,14 +444,52 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
||||
//计算工资
|
||||
attendance.setSalary(computeSalary(constructionUser, inAttendances));
|
||||
return this.save(attendance);
|
||||
}
|
||||
//考勤机打卡会有历史记录,需要更新状态
|
||||
if(CollectionUtil.isNotEmpty(outAttendances) && "1".equals(req.getSource())){
|
||||
BusAttendance busAttendance = outAttendances.getFirst();
|
||||
String oldStatus = busAttendance.getClockStatus();
|
||||
//更新打卡时间
|
||||
busAttendance.setClockTime(now);
|
||||
// 判断是否为迟到
|
||||
if (isLate(now, busAttendanceRuleVo)) {
|
||||
busAttendance.setClockStatus(BusAttendanceClockStatusEnum.LATE.getValue());
|
||||
busAttendance.setMinuteCount(getMinutesDifference(now, busAttendanceRuleVo.getClockInTime()));
|
||||
} else {
|
||||
busAttendance.setClockStatus(BusAttendanceClockStatusEnum.NORMAL.getValue());
|
||||
}
|
||||
//只要请假,直接归为请假
|
||||
LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime());
|
||||
if (leaveService.isLeave(localDateTime, userId)) {
|
||||
busAttendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue());
|
||||
}
|
||||
|
||||
busAttendance.setSource(req.getSource());
|
||||
//如果是缺卡需要上传人脸
|
||||
if(oldStatus.equals(BusAttendanceClockStatusEnum.UNCLOCK.getValue())){
|
||||
SysOssVo upload = ossService.upload(file);
|
||||
busAttendance.setFacePic(upload.getOssId().toString());
|
||||
}
|
||||
updateById(busAttendance);
|
||||
}
|
||||
|
||||
|
||||
} else if (clockTypeByTime == 2 || CollectionUtils.isNotEmpty(inAttendances)) {
|
||||
|
||||
if (CollectionUtil.isNotEmpty(outAttendances)) {
|
||||
BusAttendance busAttendance = outAttendances.getFirst();
|
||||
if("1".equals(req.getSource())){
|
||||
busAttendance.setSource(req.getSource());
|
||||
if(busAttendance.getClockStatus().equals(BusAttendanceClockStatusEnum.UNCLOCK.getValue())){
|
||||
SysOssVo upload = ossService.upload(file);
|
||||
busAttendance.setFacePic(upload.getOssId().toString());
|
||||
}
|
||||
}else {
|
||||
if (busAttendance.getClockStatus().equals(BusAttendanceClockStatusEnum.UNCLOCK.getValue())) {
|
||||
throw new ServiceException("下班缺卡记录已生成,不能更新");
|
||||
}
|
||||
}
|
||||
|
||||
//更新打卡时间
|
||||
busAttendance.setClockTime(now);
|
||||
// 判断是否为早退
|
||||
@ -488,6 +530,9 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
||||
attendance.setClockTime(now);
|
||||
attendance.setUserName(constructionUser.getUserName());
|
||||
attendance.setReplaceId(replaceId);
|
||||
if(req.getSource() != null){
|
||||
attendance.setSource(req.getSource());
|
||||
}
|
||||
// 记录打卡坐标
|
||||
attendance.setLat(req.getLat());
|
||||
attendance.setLng(req.getLng());
|
||||
@ -1109,7 +1154,9 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
||||
// 过滤有效考勤记录并按日期分组
|
||||
Map<LocalDate, List<BusAttendanceVo>> dateAttendanceMap = attendanceList.stream()
|
||||
.filter(a -> validStatusList.contains(a.getClockStatus()))
|
||||
.collect(Collectors.groupingBy(BusAttendanceVo::getClockDate));
|
||||
.collect(Collectors.groupingBy(BusAttendanceVo::getClockDate,
|
||||
LinkedHashMap::new,
|
||||
Collectors.toList()));
|
||||
List<AttendanceUserDataDetailVo> workList = new ArrayList<>();
|
||||
for (Map.Entry<LocalDate, List<BusAttendanceVo>> entry : dateAttendanceMap.entrySet()) {
|
||||
LocalDate key = entry.getKey();
|
||||
|
||||
@ -1418,6 +1418,7 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
|
||||
map2.put("lng", project.getLng());
|
||||
map2.put("lat", project.getLat());
|
||||
map2.put("position", project.getPosition());
|
||||
map2.put("plan", project.getPlan());
|
||||
map2.put("projectId", project.getId().toString());
|
||||
map1.put(project.getProjectName(), map2);
|
||||
//当满足条件时删除该元素
|
||||
|
||||
@ -9,6 +9,8 @@ public enum ZxdEnum {
|
||||
HETONGLEIXING("合同外清单","1"),
|
||||
HETONGLEIXINGNEI("合同内清单","2"),
|
||||
PURCHASE_PREFIX("采购合同信息前缀","CCTEG(CWZ)"),
|
||||
SFWJSD_S("决算单","1"),
|
||||
SFWJSD_TZ("决算单调整","2"),
|
||||
FENBAOHETONG_PREFIX("分包合同信息前缀","CCTEG(CSG)");
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user