From f9c24cdd04de07001f078ea093b724e647ac35b2 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期五, 13 二月 2026 11:10:42 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_New' into dev_New
---
src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceRecordsServiceImpl.java | 124 +++++++++++++++++++++--------------------
1 files changed, 63 insertions(+), 61 deletions(-)
diff --git a/src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceRecordsServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceRecordsServiceImpl.java
index bcc3d5d..b323a22 100644
--- a/src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceRecordsServiceImpl.java
+++ b/src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceRecordsServiceImpl.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.base.BaseException;
@@ -12,12 +13,16 @@
import com.ruoyi.project.system.service.ISysDictDataService;
import com.ruoyi.staff.dto.PersonalAttendanceRecordsDto;
import com.ruoyi.staff.dto.StaffOnJobDto;
+import com.ruoyi.staff.mapper.PersonalAttendanceLocationConfigMapper;
import com.ruoyi.staff.mapper.StaffOnJobMapper;
+import com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig;
import com.ruoyi.staff.pojo.PersonalAttendanceRecords;
import com.ruoyi.staff.mapper.PersonalAttendanceRecordsMapper;
import com.ruoyi.staff.pojo.StaffOnJob;
import com.ruoyi.staff.service.PersonalAttendanceRecordsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.staff.task.PersonalAttendanceRecordsTask;
+import com.ruoyi.staff.utils.LocationUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -28,6 +33,7 @@
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
+import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
@@ -40,6 +46,7 @@
* @since 2026-02-09 01:20:07
*/
@Service
+@Transactional(rollbackFor = Exception.class)
public class PersonalAttendanceRecordsServiceImpl extends ServiceImpl<PersonalAttendanceRecordsMapper, PersonalAttendanceRecords> implements PersonalAttendanceRecordsService {
@Autowired
private PersonalAttendanceRecordsMapper personalAttendanceRecordsMapper;
@@ -48,55 +55,64 @@
private StaffOnJobMapper staffOnJobMapper;
@Autowired
+ private PersonalAttendanceLocationConfigMapper personalAttendanceLocationConfigMapper;
+
+ @Autowired
private ISysDictDataService dictDataService;
@Autowired
private SysDeptMapper sysDeptMapper;
@Override
- @Transactional(rollbackFor = Exception.class)
- public int add(PersonalAttendanceRecords personalAttendanceRecords) {
+ public int add(PersonalAttendanceRecordsDto personalAttendanceRecordsDto) {
// 褰撳墠鏃堕棿
LocalDate currentDate = LocalDate.now();
-
- // 棣栧厛鏍规嵁鐢ㄦ埛ID鏌ヨ鍛樺伐淇℃伅
+ LocalDateTime currentDateTime = LocalDateTime.now();
+ /*鏌ヨ鍛樺伐淇℃伅*/
QueryWrapper<StaffOnJob> staffQueryWrapper = new QueryWrapper<>();
staffQueryWrapper.eq("staff_no", SecurityUtils.getUsername());
+ staffQueryWrapper.eq("staff_state", 1);//鍦ㄨ亴
StaffOnJob staffOnJob = staffOnJobMapper.selectOne(staffQueryWrapper);
if (staffOnJob == null) {
throw new BaseException("褰撳墠鐢ㄦ埛娌℃湁瀵瑰簲鐨勫憳宸ヤ俊鎭�");
}
-
- // 褰撳墠鏃堕棿
- LocalDateTime currentDateTime = LocalDateTime.now();
-
- // 濡傛灉鎵撳崱鏃堕棿瓒呰繃鑰冨嫟涓嬬彮鏃堕棿涓嶈兘鎵撳崱
- // 鑾峰彇鑰冨嫟涓嬬彮鏃堕棿鐐�
- String[] timeConfigs = getAttendanceTimeConfig();
- String timeConfig = timeConfigs[1];
- String[] timeParts = timeConfig.split(":");
- int standardHour = Integer.parseInt(timeParts[0]);
- int standardMinute = Integer.parseInt(timeParts[1]);
- // 褰撳墠鏃堕棿
- int actualHour = currentDateTime.getHour();
- int actualMinute = currentDateTime.getMinute();
- // 鍒ゆ柇鎵撳崱鏃堕棿鏄惁鏅氫簬褰撳墠鏃堕棿
- if (actualHour > standardHour || (actualHour == standardHour && actualMinute > standardMinute)) {
- throw new BaseException("鎵撳崱鏃堕棿涓嶈兘鏅氫簬涓嬬彮鏃堕棿");
+ /*鍒ゆ柇鎵撳崱浣嶇疆鏄惁鍦ㄨ鍒欒寖鍥村唴*/
+ List<PersonalAttendanceLocationConfig> personalAttendanceLocationConfigs = personalAttendanceLocationConfigMapper.selectList(Wrappers.<PersonalAttendanceLocationConfig>lambdaQuery()
+ .eq(PersonalAttendanceLocationConfig::getSysDeptId, staffOnJob.getSysDeptId())
+ .orderByDesc(PersonalAttendanceLocationConfig::getId));
+ if (personalAttendanceLocationConfigs == null || personalAttendanceLocationConfigs.isEmpty()) {
+ throw new BaseException("褰撳墠閮ㄩ棬娌℃湁璁剧疆鎵撳崱瑙勫垯");
}
-
+ Double punchLongitude = personalAttendanceRecordsDto.getLongitude(); //鎵撳崱鐨勭粡搴�
+ Double punchLatitude = personalAttendanceRecordsDto.getLatitude(); // 鎵撳崱鐨勭含搴�
+ if (punchLongitude == null || punchLatitude == null) {
+ throw new BaseException("鎵撳崱澶辫触锛氭湭鑾峰彇鍒版偍鐨勪綅缃俊鎭紝璇峰紑鍚畾浣嶆潈闄�");
+ }
+ //璁$畻鎵撳崱浣嶇疆涓庤�冨嫟鐐圭殑璺濈
+ PersonalAttendanceLocationConfig locationConfig = personalAttendanceLocationConfigs.get(0);//鑾峰彇鏈�鏂扮殑涓�鏉℃暟鎹�
+ double allowedRadius = locationConfig.getRadius(); // 鍏佽鐨勮寖鍥达紙绫筹級
+ double actualDistance = LocationUtils.calculateDistance(
+ punchLatitude, punchLongitude, // 鍛樺伐鎵撳崱鐨勭粡绾害
+ locationConfig.getLatitude(), locationConfig.getLongitude() // 鑰冨嫟鐐圭殑缁忕含搴�
+ );
+ //鍒ゆ柇鏄惁鍦ㄨ寖鍥村唴
+ if (actualDistance > allowedRadius) {
+ throw new BaseException(String.format("鎵撳崱澶辫触锛氭偍褰撳墠浣嶇疆璺濈鑰冨嫟鐐�%.2f绫筹紝瓒呭嚭鍏佽鑼冨洿锛�%s绫筹級", actualDistance, allowedRadius));
+ }
+ /*鍒ゆ柇鎵撳崱鏃堕棿*/
// 鏍规嵁鍛樺伐ID鍜屽綋鍓嶆棩鏈熸煡璇㈡墦鍗¤褰�
QueryWrapper<PersonalAttendanceRecords> attendanceQueryWrapper = new QueryWrapper<>();
attendanceQueryWrapper.eq("staff_on_job_id", staffOnJob.getId())
.eq("date", currentDate);
PersonalAttendanceRecords attendanceRecord = personalAttendanceRecordsMapper.selectOne(attendanceQueryWrapper);
- // 鏍规嵁瀛楀吀璁剧疆鐨勮�冨嫟鏃堕棿鍒ゆ柇杩熷埌鏃╅��
+ // 鏍规嵁鑰冨嫟鏃堕棿鍒ゆ柇杩熷埌鏃╅��
if (attendanceRecord == null) {
// 涓嶅瓨鍦ㄦ墦鍗¤褰曪紝鍒涘缓鏂拌褰�
+ PersonalAttendanceRecords personalAttendanceRecords = new PersonalAttendanceRecords();
personalAttendanceRecords.setStaffOnJobId(staffOnJob.getId());
personalAttendanceRecords.setDate(currentDate);
personalAttendanceRecords.setWorkStartAt(currentDateTime);
- personalAttendanceRecords.setStatus(determineAttendanceStatus(personalAttendanceRecords, true));
+ personalAttendanceRecords.setStatus(determineAttendanceStatus(personalAttendanceRecords, true,locationConfig));
personalAttendanceRecords.setRemark(personalAttendanceRecords.getRemark());
personalAttendanceRecords.setTenantId(staffOnJob.getTenantId());
return personalAttendanceRecordsMapper.insert(personalAttendanceRecords);
@@ -113,7 +129,7 @@
.divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
attendanceRecord.setWorkHours(workHours);
// 鏇存柊鑰冨嫟鐘舵��
- attendanceRecord.setStatus(determineAttendanceStatus(attendanceRecord, false));
+ attendanceRecord.setStatus(determineAttendanceStatus(attendanceRecord, false,locationConfig));
return personalAttendanceRecordsMapper.updateById(attendanceRecord);
} else {
throw new BaseException("鎮ㄥ凡缁忔墦杩囧崱浜�,鏃犻渶閲嶅鎵撳崱!!!");
@@ -121,46 +137,22 @@
}
}
- // 鑾峰彇鑰冨嫟鏃堕棿閰嶇疆
- private String[] getAttendanceTimeConfig() {
- String[] timeConfigs = new String[2];
- try {
- String dictType = "sys_work_time";
-
- // 鑾峰彇涓婄彮鏃堕棿閰嶇疆锛岄粯璁や负09:00
- String startTimeConfig = dictDataService.selectDictLabel(dictType, "start_at");
- timeConfigs[0] = (startTimeConfig == null || startTimeConfig.trim().isEmpty()) ? "09:00" : startTimeConfig;
-
- // 鑾峰彇涓嬬彮鏃堕棿閰嶇疆锛岄粯璁や负18:00
- String endTimeConfig = dictDataService.selectDictLabel(dictType, "end_at");
- timeConfigs[1] = (endTimeConfig == null || endTimeConfig.trim().isEmpty()) ? "18:00" : endTimeConfig;
-
- return timeConfigs;
- } catch (Exception e) {
- timeConfigs[0] = "09:00"; // 榛樿涓婄彮鏃堕棿
- timeConfigs[1] = "18:00"; // 榛樿涓嬬彮鏃堕棿
- return timeConfigs;
- }
- }
-
// 鏍规嵁瀹為檯鏃堕棿鍜屾槸鍚︿笂鐝椂闂村垽鏂�冨嫟鐘舵��
// 0 姝e父 1 杩熷埌 2 鏃╅�� 3 杩熷埌鏃╅�� 4 缂哄嫟
- private Integer determineAttendanceStatus(PersonalAttendanceRecords attendanceRecord, boolean isStart) {
+ private Integer determineAttendanceStatus(PersonalAttendanceRecords attendanceRecord, boolean isStart,PersonalAttendanceLocationConfig locationConfig) {
+ //鍒ゆ柇鏄笂鐝墦鍗¤繕鏄笅鐝墦鍗�
LocalDateTime actualTime = isStart ? attendanceRecord.getWorkStartAt() : attendanceRecord.getWorkEndAt();
try {
// 鑾峰彇鑰冨嫟鏃堕棿閰嶇疆
- String[] timeConfigs = getAttendanceTimeConfig();
- String timeConfig = isStart ? timeConfigs[0] : timeConfigs[1];
-
- // 瑙f瀽鏍囧噯鏃堕棿
- String[] timeParts = timeConfig.split(":");
- int standardHour = Integer.parseInt(timeParts[0]);
- int standardMinute = Integer.parseInt(timeParts[1]);
-
+ LocalTime startAt = locationConfig.getStartAt();//涓婄彮鏃堕棿
+ LocalTime endAt = locationConfig.getEndAt();//涓嬬彮鏃堕棿
+ LocalTime timeConfig = isStart ? startAt : endAt;
+ // 瑙f瀽灏忔椂鍜屽垎閽�
+ int standardHour = timeConfig.getHour();
+ int standardMinute = timeConfig.getMinute();
// 鑾峰彇瀹為檯鏃堕棿鐨勬椂鍒�
int actualHour = actualTime.getHour();
int actualMinute = actualTime.getMinute();
-
// 鍒ゆ柇鐘舵��
if (isStart) {
// 涓婄彮鎵撳崱锛氳秴杩囨爣鍑嗘椂闂寸畻杩熷埌
@@ -174,11 +166,11 @@
return 3; // 杩熷埌鏃╅��
}
return 2; // 鏃╅��
+ }else if (attendanceRecord.getStatus() == 1) {
+ return 1; // 涓嬬彮鎵撳崱姝e父浣嗘槸涓婄彮杩熷埌
}
}
-
return 0; // 姝e父
-
} catch (Exception e) {
// 濡傛灉鑾峰彇閰嶇疆澶辫触锛岄粯璁よ繑鍥炴甯哥姸鎬�
log.warn("鑾峰彇鑰冨嫟鏃堕棿閰嶇疆澶辫触锛屼娇鐢ㄩ粯璁ょ姸鎬侊細" + e.getMessage());
@@ -192,6 +184,7 @@
if (!admin) {
QueryWrapper<StaffOnJob> staffQueryWrapper = new QueryWrapper<>();
staffQueryWrapper.eq("staff_no", SecurityUtils.getUsername());
+ staffQueryWrapper.eq("staff_state", 1);//鍦ㄨ亴
StaffOnJob staffOnJob = staffOnJobMapper.selectOne(staffQueryWrapper);
if (staffOnJob == null) {
return new Page<>(page.getCurrent(), page.getSize(), 0);
@@ -210,10 +203,11 @@
// 棣栧厛鏍规嵁鐢ㄦ埛ID鏌ヨ鍛樺伐淇℃伅
QueryWrapper<StaffOnJob> staffQueryWrapper = new QueryWrapper<>();
staffQueryWrapper.eq("staff_no", SecurityUtils.getUsername());
+ staffQueryWrapper.eq("staff_state", 1);//鍦ㄨ亴
StaffOnJob staffOnJob = staffOnJobMapper.selectOne(staffQueryWrapper);
if (staffOnJob == null) {
- return null; // 褰撳墠鐢ㄦ埛娌℃湁瀵瑰簲鐨勫憳宸ヤ俊鎭�
+ throw new BaseException("褰撳墠鐢ㄦ埛娌℃湁瀵瑰簲鐨勫憳宸ヤ俊鎭�");
}
// 鏍规嵁鍛樺伐ID鍜屽綋鍓嶆棩鏈熸煡璇㈡墦鍗¤褰�
@@ -236,7 +230,14 @@
resultDto.setDeptId(staffOnJob.getSysDeptId() != null ? staffOnJob.getSysDeptId() : null);
SysDept dept = sysDeptMapper.selectDeptById(staffOnJob.getSysDeptId());
resultDto.setDeptName(dept != null ? dept.getDeptName() : null);
-
+ //鑾峰彇璇ュ憳宸ュ搴旂殑鎵撳崱瑙勫垯
+ List<PersonalAttendanceLocationConfig> personalAttendanceLocationConfigs = personalAttendanceLocationConfigMapper.selectList(Wrappers.<PersonalAttendanceLocationConfig>lambdaQuery()
+ .eq(PersonalAttendanceLocationConfig::getSysDeptId, staffOnJob.getSysDeptId())
+ .orderByDesc(PersonalAttendanceLocationConfig::getId));
+ if (personalAttendanceLocationConfigs.size()>0){
+ resultDto.setStartAt(personalAttendanceLocationConfigs.get(0).getStartAt());
+ resultDto.setEndAt(personalAttendanceLocationConfigs.get(0).getEndAt());
+ }
return resultDto;
}
@@ -246,6 +247,7 @@
if (!admin) {
QueryWrapper<StaffOnJob> staffQueryWrapper = new QueryWrapper<>();
staffQueryWrapper.eq("staff_no", SecurityUtils.getUsername());
+ staffQueryWrapper.eq("staff_state", 1);//鍦ㄨ亴
StaffOnJob staffOnJob = staffOnJobMapper.selectOne(staffQueryWrapper);
if (staffOnJob == null) {
throw new ServiceException("娌℃湁鍛樺伐淇℃伅锛屾棤娉曞鍑鸿�冨嫟璁板綍");
--
Gitblit v1.9.3