添加分布式锁,添加更换考勤机历史考勤打卡记录上传

This commit is contained in:
haozq 2026-01-19 12:44:28 +08:00
parent c5bc8d14c6
commit c558804a8c
6 changed files with 136 additions and 26 deletions

View File

@ -71,7 +71,7 @@ public class ParamSecureHandler implements AsyncHandlerInterceptor {
returnJson(response, "输入值非法!", 500);
return false;
}
System.err.println(JSON.toJSONString(request.getParameterMap()));
// System.err.println(JSON.toJSONString(request.getParameterMap()));
/**
* 获取所有跳转路径参数保留传入下个界面
*/

View File

@ -10,6 +10,7 @@ import com.bonus.common.core.utils.StringUtils;
import com.bonus.urk.service.UserFaceHandleService;
import com.bonus.urk.vo.BmWorkerEinUserVo;
import com.bonus.urk.vo.DeviceVo;
import com.bonus.urk.vo.ResultVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
@ -78,16 +79,21 @@ public class UserFaceHandle {
// fileService.uploadBast64(bast64,"bm_att_person","bm_att_person")
}
//考情机是否绑定工程
String proId=service.getDevPorId(devCode);
ResultVo resultVo=service.getDevPorId(devCode,time);
//
if(StringUtils.isNotEmpty(proId)){
//验证用户是否入场
BmWorkerEinUserVo vo=service.getOnUserInfo(userId,proId);
if(resultVo!=null){
BmWorkerEinUserVo vo;
//已经解绑过的考勤机
if("1".equals(resultVo.getType())){
vo=service.getOnUserInfoRecord(userId,resultVo.getProId());
}else{
vo=service.getOnUserInfo(userId,resultVo.getProId());
}
if(vo==null){
vo=createAttendanceVo(deviceVo,userId,devCode,time,bast64);
vo.setAttDay(attDay);
vo.setAttMonth(month);
service.addWrcUser(vo);
vo=createAttendanceVo(deviceVo,userId,devCode,time,bast64);
vo.setAttDay(attDay);
vo.setAttMonth(month);
service.addWrcUser(vo);
}else {
vo.setAttDay(attDay);
vo.setAttMonth(month);
@ -98,6 +104,7 @@ public class UserFaceHandle {
service.addAttendInfo(vo);
//数据返回
}
}else{
BmWorkerEinUserVo vo=createAttendanceVo(deviceVo,userId,devCode,time,bast64);
service.addWrcUser(vo);
@ -124,10 +131,18 @@ public class UserFaceHandle {
String attDay= YMD_SDF.format(datetime);
String month=MM_SDF.format(datetime);
//考情机是否绑定工程
String proId=service.getDevPorId(devCode);
if(StringUtils.isNotEmpty(proId)){
ResultVo resultVo=service.getDevPorId(devCode,time);
// String proId=service.getDevPorId(devCode);
if(resultVo!=null ){
//验证用户是否入场
BmWorkerEinUserVo vo=service.getOnUserInfo(userId,proId);
BmWorkerEinUserVo vo;
//已经解绑过的考勤机
if("1".equals(resultVo.getType())){
vo=service.getOnUserInfoRecord(userId,resultVo.getProId());
}else{
vo=service.getOnUserInfo(userId,resultVo.getProId());
}
// BmWorkerEinUserVo vo=service.getOnUserInfo(userId,proId);
if(vo==null){
// vo=createAttendanceVo(deviceVo,userId,devCode,time,bast64);
// vo.setAttDay(attDay);

View File

@ -1,6 +1,7 @@
package com.bonus.urk.mapper;
import com.bonus.urk.vo.BmWorkerEinUserVo;
import com.bonus.urk.vo.ResultVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -16,6 +17,8 @@ public interface UserFaceHandleMapper {
*/
BmWorkerEinUserVo getOnUserInfo(@Param("userId") String userId,@Param("proId")String proId);
BmWorkerEinUserVo getOnUserInfoRecord(@Param("userId") String userId,@Param("proId")String proId);
/**
* 新增人员考勤数据
* @param vo
@ -55,5 +58,12 @@ public interface UserFaceHandleMapper {
* @param devCode
* @return
*/
String getDevPorId(@Param("devCode") String devCode);
ResultVo getDevPorId(@Param("devCode") String devCode);
/**
* 查询历史考勤机绑定信息
* @param devCode
* @param time
*/
ResultVo getDevPorIdTime(@Param("devCode")String devCode, @Param("time")String time);
}

View File

@ -5,18 +5,24 @@ import com.bonus.common.core.constant.SecurityConstants;
import com.bonus.common.core.domain.R;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.redis.service.RedisService;
import com.bonus.system.api.RemoteUploadUtilsService;
import com.bonus.system.api.domain.FileVo;
import com.bonus.system.api.model.UploadFileVo;
import com.bonus.urk.mapper.UserFaceHandleMapper;
import com.bonus.urk.minio.UrkMinioService;
import com.bonus.urk.vo.BmWorkerEinUserVo;
import com.bonus.urk.vo.ResultVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
/**
* @author 黑子
@ -33,6 +39,9 @@ public class UserFaceHandleService {
@Resource
private UrkMinioService fileService;
@Autowired
private RedisService redisService;
/**
* 依据用户id 查询施工工程信息
* @param userId
@ -60,14 +69,23 @@ public class UserFaceHandleService {
String id=StringUtils.randomUUID();
vo.setId(id);
vo.setCreateTime(DateUtils.getTime());
Integer num=mapper.getTodayIsExit(vo);
//每日新增一条考勤信息
if(num==null || num ==0){
UploadFileVo uploadFileVo=fileService.upload("bm_att_person",vo.getId(),"考勤照片","attr",vo.getAttPhoto(),null);
if(uploadFileVo!=null){
vo.setImage(uploadFileVo.getPath());
mapper.insertAttPerson(vo);
}
//先去读取锁-如果被锁了则
Object lock= getLock(vo.getUserId());
synchronized (lock) {
boolean loock= (boolean) lock;
if(loock){
Integer num=mapper.getTodayIsExit(vo);
//每日新增一条考勤信息
if(num==null || num ==0){
UploadFileVo uploadFileVo=fileService.upload("bm_att_person",vo.getId(),"考勤照片","attr",vo.getAttPhoto(),null);
if(uploadFileVo!=null){
vo.setImage(uploadFileVo.getPath());
mapper.insertAttPerson(vo);
//移除锁
removeLock(vo.getUserId());
}
}
}
}
if(StringUtils.isEmpty(vo.getImage())){
vo.setImage("不记录");
@ -108,15 +126,50 @@ public class UserFaceHandleService {
}
}
/**
* 获取指定用户ID的专属锁对象
*/
public boolean getLock(String userId) {
//获取数据
Integer value=redisService.getCacheObject("lock_"+userId);
if (value == null || value == 0) {
//添加一个锁占用一分钟避免失效
redisService.setCacheObject("lock_"+userId,1,20L, TimeUnit.SECONDS);
return true;
}
return false;
}
/**
* 手动移除锁对象非必须弱引用会自动回收建议在用户注销等场景手动调用
*/
public void removeLock(String userId) {
if (userId != null) {
redisService.deleteObject("lock_"+userId);
}
}
/**
* 查询考情机绑定的工程
* @param devCode
* @return
*/
public String getDevPorId(String devCode) {
public ResultVo getDevPorId(String devCode, String time) {
try{
return mapper.getDevPorId(devCode);
ResultVo vo= mapper.getDevPorIdTime(devCode,time);
if(vo==null){
return mapper.getDevPorId(devCode);
}
}catch (Exception e){
log.error(e.toString(),e);
}
return null;
}
public BmWorkerEinUserVo getOnUserInfoRecord(String userId, String proId) {
try{
BmWorkerEinUserVo vo=mapper.getOnUserInfoRecord(userId,proId);
if(vo!=null && StringUtils.isNotEmpty(vo.getUserId())){
return vo;
}
}catch (Exception e){
log.error(e.toString(),e);
}

View File

@ -0,0 +1,13 @@
package com.bonus.urk.vo;
import lombok.Data;
@Data
public class ResultVo {
private String devCode;
private String proId;
private String type;
}

View File

@ -32,6 +32,17 @@
LEFT JOIN bm_worker_contract bwc on bwc.worker_id=bwem.worker_id and bwc.is_active=1 and bwem.pro_id = bwc.pro_id
where bwem.worker_id=#{userId} and bwem.pro_id=#{proId}
</select>
<select id="getOnUserInfoRecord" resultType="com.bonus.urk.vo.BmWorkerEinUserVo">
select bwem.worker_id userId,bwem.pro_name proName,bwem.pro_id proId,pw.`name` userName,
bwem.team_name teamName,bwem.team_id teamId,pw.id_number idNumber,
bwem.sub_id subId,bwem.sub_name subName,bwem.post_id postId,bwem.contract_id,bwc.day_rate dailyWage
from bm_worker_ein_pro_record bwem
left join pm_worker pw on pw.id=bwem.worker_id
LEFT JOIN bm_worker_contract bwc on bwc.worker_id=bwem.worker_id and bwc.is_active=1 and bwem.pro_id = bwc.pro_id
where bwem.worker_id=#{userId} and bwem.pro_id=#{proId}
ORDER BY bwem.id desc
limit 1
</select>
<select id="getTodayIsExit" resultType="java.lang.Integer">
select count(1)
from bm_att_person
@ -42,11 +53,19 @@
from bm_att_record_no_ru
where worker_id=#{userId} and is_active=1 and att_day=#{attDay}
</select>
<select id="getDevPorId" resultType="java.lang.String">
select pro_id
<select id="getDevPorId" resultType="com.bonus.urk.vo.ResultVo">
select pro_id proId ,0 type
from pm_att_device
where device_code=#{devCode}
</select>
<select id="getDevPorIdTime" resultType="com.bonus.urk.vo.ResultVo">
select pro_id proId,if(un_bind_time is null,0,1) type
from pm_att_device_bind_record
where dev_code=#{devCode} and #{time} between bind_time AND IFNULL(un_bind_time,now())
limit 1
</select>
<!--考勤机历史绑定记录-->
<insert id="addWrcUser">
insert into bm_att_record_no_ru(