设备打卡
This commit is contained in:
@ -0,0 +1,118 @@
|
|||||||
|
package org.dromara.project.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaIgnore;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.common.core.domain.R;
|
||||||
|
import org.dromara.common.web.core.BaseController;
|
||||||
|
import org.dromara.project.domain.BusAttendanceMachine;
|
||||||
|
import org.dromara.project.domain.dto.attendance.*;
|
||||||
|
import org.dromara.project.service.IBusAttendanceMachineService;
|
||||||
|
import org.dromara.project.service.IBusAttendanceService;
|
||||||
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 考勤
|
||||||
|
*
|
||||||
|
* @author Lion Li
|
||||||
|
* @date 2025-08-05
|
||||||
|
*/
|
||||||
|
@Validated
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RestController
|
||||||
|
@RequestMapping()
|
||||||
|
@Slf4j
|
||||||
|
public class BusAttendanceDeviceController extends BaseController {
|
||||||
|
|
||||||
|
private final IBusAttendanceService busAttendanceService;
|
||||||
|
|
||||||
|
private final IBusAttendanceMachineService busAttendanceMachineService;
|
||||||
|
|
||||||
|
@PostMapping("/api/v1/record/face")
|
||||||
|
@SaIgnore
|
||||||
|
public R<Boolean> punchCardByFace(@RequestBody DeviceDto dto) {
|
||||||
|
//打印接收数据
|
||||||
|
log.info("接收数据:{}", dto);
|
||||||
|
if (dto.getLogs().isEmpty()) {
|
||||||
|
return R.fail("没有数据");
|
||||||
|
}
|
||||||
|
Log first = dto.getLogs().getFirst();
|
||||||
|
|
||||||
|
Long userId = Long.valueOf(first.getUser_id());
|
||||||
|
|
||||||
|
BusAttendanceMachine one = busAttendanceMachineService.lambdaQuery()
|
||||||
|
.eq(BusAttendanceMachine::getSn, dto.getSn())
|
||||||
|
.last("limit 1")
|
||||||
|
.one();
|
||||||
|
if (one == null || one.getProjectId() == null) {
|
||||||
|
return R.fail("考勤机不存在或未关联项目");
|
||||||
|
}
|
||||||
|
|
||||||
|
String recogTime = first.getRecog_time();
|
||||||
|
|
||||||
|
LocalDateTime localDateTime = LocalDateTime.parse(recogTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||||
|
|
||||||
|
BusAttendancePunchCardByFaceReq req = new BusAttendancePunchCardByFaceReq();
|
||||||
|
DeviceLocation location = first.getLocation();
|
||||||
|
req.setLat(location.getLatitude());
|
||||||
|
req.setLng(location.getLongitude());
|
||||||
|
req.setProjectId(one.getProjectId());
|
||||||
|
req.setUserId(userId);
|
||||||
|
req.setPunchTime(localDateTime);
|
||||||
|
//打印req
|
||||||
|
log.info("请求参数:{}", req);
|
||||||
|
//base64转MultipartFile
|
||||||
|
try {
|
||||||
|
// 假设first.getImage()返回base64字符串,且你有一个文件名
|
||||||
|
MultipartFile file = convert(first.getPhoto(), "face.jpg");
|
||||||
|
log.info("开始打卡");
|
||||||
|
return R.ok(busAttendanceService.punchCardByFace(file, req));
|
||||||
|
} catch (IOException e) {
|
||||||
|
return R.fail("文件转换失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static MultipartFile convert(String base64String, String fileName) throws IOException {
|
||||||
|
// 先进行URL解码(如果是URL编码过的数据)
|
||||||
|
try {
|
||||||
|
base64String = java.net.URLDecoder.decode(base64String, "UTF-8");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 如果不是URL编码的数据,直接跳过
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去除base64前缀(如data:image/png;base64,)
|
||||||
|
if (base64String.contains(",")) {
|
||||||
|
base64String = base64String.split(",")[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解码base64字符串
|
||||||
|
byte[] decodedBytes = Base64.getDecoder().decode(base64String);
|
||||||
|
|
||||||
|
// 创建MultipartFile对象
|
||||||
|
return new MockMultipartFile(fileName, fileName, "image/jpeg", decodedBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author lilemy
|
* @author lilemy
|
||||||
@ -41,4 +42,9 @@ public class BusAttendancePunchCardByFaceReq implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打卡时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime punchTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
package org.dromara.project.domain.dto.attendance;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.poi.ss.formula.functions.Count;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DeviceDto {
|
||||||
|
private String sn;
|
||||||
|
private int Count;
|
||||||
|
private List<Log> logs;
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package org.dromara.project.domain.dto.attendance;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DeviceLocation {
|
||||||
|
private String longitude;
|
||||||
|
private String latitude;
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package org.dromara.project.domain.dto.attendance;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Log {
|
||||||
|
private String user_id;
|
||||||
|
private String recog_type;
|
||||||
|
private String recog_time;
|
||||||
|
private String photo;
|
||||||
|
private DeviceLocation location;
|
||||||
|
}
|
||||||
@ -326,7 +326,11 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
|||||||
}
|
}
|
||||||
synchronized (userId.toString().intern()) {
|
synchronized (userId.toString().intern()) {
|
||||||
// 记录当前打卡时间
|
// 记录当前打卡时间
|
||||||
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
if(req.getPunchTime() != null){
|
||||||
|
now = req.getPunchTime();
|
||||||
|
}
|
||||||
|
|
||||||
//打卡范围
|
//打卡范围
|
||||||
if (!checkInRange(req)) {
|
if (!checkInRange(req)) {
|
||||||
@ -617,6 +621,9 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
|||||||
public Boolean checkInRange(BusAttendancePunchCardByFaceReq req) {
|
public Boolean checkInRange(BusAttendancePunchCardByFaceReq req) {
|
||||||
// 获取当前用户
|
// 获取当前用户
|
||||||
Long userId = LoginHelper.getUserId();
|
Long userId = LoginHelper.getUserId();
|
||||||
|
if (req.getUserId() != null) {
|
||||||
|
userId = req.getUserId();
|
||||||
|
}
|
||||||
Long projectId = req.getProjectId();
|
Long projectId = req.getProjectId();
|
||||||
|
|
||||||
SysUserVo sysUserVo = userService.queryById(userId);
|
SysUserVo sysUserVo = userService.queryById(userId);
|
||||||
|
|||||||
Reference in New Issue
Block a user