src/main/java/com/ruoyi/CodeGenerator.java
@@ -19,11 +19,11 @@ // æ¼ç¤ºä¾åï¼æ§è¡ main æ¹æ³æ§å¶å°è¾å ¥æ¨¡å表åå车èªå¨çæå¯¹åºé¡¹ç®ç®å½ä¸ public class CodeGenerator { public static String database_url = "jdbc:mysql://localhost:3306/product-inventory-management-new"; public static String database_url = "jdbc:mysql://1.15.17.182:9999/product-inventory-management-new"; public static String database_username = "root"; public static String database_password= "123456"; public static String database_password= "xd@123456.."; public static String author = "è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸"; public static String model = "purchase"; // 模å public static String model = "staff"; // 模å public static String setParent = "com.ruoyi."+ model; // å è·¯å¾ public static String tablePrefix = ""; // è®¾ç½®è¿æ»¤è¡¨åç¼ public static void main(String[] args) { src/main/java/com/ruoyi/staff/controller/PersonalAttendanceLocationConfigController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,43 @@ package com.ruoyi.staff.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.framework.web.domain.R; import com.ruoyi.staff.dto.PersonalAttendanceRecordsDto; import com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig; import com.ruoyi.staff.pojo.PersonalAttendanceRecords; import com.ruoyi.staff.service.PersonalAttendanceLocationConfigService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** * <p> * 人åæå¡è§åé ç½® å端æ§å¶å¨ * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-02-11 09:41:34 */ @RestController @RequestMapping("/personalAttendanceLocationConfig") @Api(tags = "人åæå¡è§åé ç½®") public class PersonalAttendanceLocationConfigController { @Autowired private PersonalAttendanceLocationConfigService personalAttendanceLocationConfigService; @ApiOperation("æ°å¢/ä¿®æ¹äººåæå¡è§åé ç½®") @PostMapping("/add") public R add(@RequestBody PersonalAttendanceLocationConfig personalAttendanceLocationConfig){ return R.ok(personalAttendanceLocationConfigService.saveOrUpdate(personalAttendanceLocationConfig)); } @ApiOperation("å页æ¥è¯¢æå¡ç¾å°") @GetMapping("/listPage") public R listPage(Page page){ return R.ok(personalAttendanceLocationConfigService.page(page)); } } src/main/java/com/ruoyi/staff/controller/PersonalAttendanceRecordsController.java
@@ -6,6 +6,7 @@ import com.ruoyi.staff.pojo.PersonalAttendanceRecords; import com.ruoyi.staff.service.PersonalAttendanceRecordsService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -21,30 +22,30 @@ */ @RestController @RequestMapping("/personalAttendanceRecords") @Api(tags = "æå¡ç¾å°") @Api(tags = "人åæå¡ç¾å°") public class PersonalAttendanceRecordsController { @Resource private PersonalAttendanceRecordsService personalAttendanceRecordsService; // æ°å¢ @ApiOperation("æ°å¢æå¡ç¾å°") @PostMapping("") public AjaxResult add(@RequestBody PersonalAttendanceRecords personalAttendanceRecord){ return AjaxResult.success(personalAttendanceRecordsService.add(personalAttendanceRecord)); public AjaxResult add(@RequestBody PersonalAttendanceRecordsDto personalAttendanceRecordsDto){ return AjaxResult.success(personalAttendanceRecordsService.add(personalAttendanceRecordsDto)); } // å表æ¥è¯¢ @ApiOperation("å页æ¥è¯¢æå¡ç¾å°") @GetMapping("/listPage") public AjaxResult listPage(Page page, PersonalAttendanceRecordsDto personalAttendanceRecordsDto){ return AjaxResult.success(personalAttendanceRecordsService.listPage(page, personalAttendanceRecordsDto)); } // 仿¥è夿°æ® @ApiOperation("è·åå½å人çèå¤ç¸å ³æ°æ®") @GetMapping("/today") public AjaxResult todayInfo(PersonalAttendanceRecordsDto personalAttendanceRecordsDto){ return AjaxResult.success(personalAttendanceRecordsService.todayInfo(personalAttendanceRecordsDto)); } // å¯¼åº @ApiOperation("å¯¼åºæå¡ç¾å°") @PostMapping("/export") public void export(HttpServletResponse response, PersonalAttendanceRecordsDto personalAttendanceRecordsDto) { personalAttendanceRecordsService.export(response, personalAttendanceRecordsDto); src/main/java/com/ruoyi/staff/dto/PersonalAttendanceRecordsDto.java
@@ -1,10 +1,17 @@ package com.ruoyi.staff.dto; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import com.ruoyi.staff.pojo.PersonalAttendanceRecords; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; @Data @ExcelIgnoreUnannotated public class PersonalAttendanceRecordsDto extends PersonalAttendanceRecords { @Excel(name = "å§å", sort = 3) private String staffName; @@ -16,4 +23,20 @@ private String deptName; private Long deptId; //æå¡çç»åº¦ private Double longitude; //æå¡ç纬度 private Double latitude; //æ åä¸çæ¶é´ @JsonFormat(pattern = "HH:mm") @DateTimeFormat(pattern = "HH:mm") private LocalDateTime startAt; //æ åä¸çæ¶é´ @JsonFormat(pattern = "HH:mm") @DateTimeFormat(pattern = "HH:mm") private LocalDateTime endAt; } src/main/java/com/ruoyi/staff/mapper/PersonalAttendanceLocationConfigMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,18 @@ package com.ruoyi.staff.mapper; import com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; /** * <p> * 人åæå¡è§åé ç½® Mapper æ¥å£ * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-02-11 09:41:34 */ @Mapper public interface PersonalAttendanceLocationConfigMapper extends BaseMapper<PersonalAttendanceLocationConfig> { } src/main/java/com/ruoyi/staff/pojo/PersonalAttendanceLocationConfig.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,59 @@ package com.ruoyi.staff.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import java.io.Serializable; import java.time.LocalDateTime; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; import org.springframework.format.annotation.DateTimeFormat; /** * <p> * 人åæå¡è§åé ç½® * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-02-11 09:41:34 */ @Getter @Setter @TableName("personal_attendance_location_config") @ApiModel(value = "PersonalAttendanceLocationConfig对象", description = "人åæå¡è§åé ç½®") public class PersonalAttendanceLocationConfig implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.AUTO) private Integer id; @ApiModelProperty("é¨é¨id") private Integer sysDeptId; @ApiModelProperty("å°ç¹åç§°") private String locationName; @ApiModelProperty("ç»åº¦") private Double longitude; @ApiModelProperty("纬度") private Double latitude; @ApiModelProperty("æå¡èå´") private Double radius; @ApiModelProperty("ä¸çæ¶é´") @JsonFormat(pattern = "HH:mm") @DateTimeFormat(pattern = "HH:mm") private LocalDateTime startAt; @ApiModelProperty("ä¸çæ¶é´") @JsonFormat(pattern = "HH:mm") @DateTimeFormat(pattern = "HH:mm") private LocalDateTime endAt; } src/main/java/com/ruoyi/staff/service/PersonalAttendanceLocationConfigService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,16 @@ package com.ruoyi.staff.service; import com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig; import com.baomidou.mybatisplus.extension.service.IService; /** * <p> * 人åæå¡è§åé ç½® æå¡ç±» * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-02-11 09:41:34 */ public interface PersonalAttendanceLocationConfigService extends IService<PersonalAttendanceLocationConfig> { } src/main/java/com/ruoyi/staff/service/PersonalAttendanceRecordsService.java
@@ -21,7 +21,7 @@ public interface PersonalAttendanceRecordsService extends IService<PersonalAttendanceRecords> { IPage<PersonalAttendanceRecordsDto> listPage(Page page, PersonalAttendanceRecordsDto personalAttendanceRecordsDto); int add(PersonalAttendanceRecords personalAttendanceRecords); int add(PersonalAttendanceRecordsDto personalAttendanceRecordsDto); PersonalAttendanceRecordsDto todayInfo(PersonalAttendanceRecordsDto personalAttendanceRecordsDto); src/main/java/com/ruoyi/staff/service/impl/PersonalAttendanceLocationConfigServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,25 @@ package com.ruoyi.staff.service.impl; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.exception.base.BaseException; import com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig; import com.ruoyi.staff.mapper.PersonalAttendanceLocationConfigMapper; import com.ruoyi.staff.service.PersonalAttendanceLocationConfigService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * <p> * 人åæå¡è§åé ç½® æå¡å®ç°ç±» * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-02-11 09:41:34 */ @Service public class PersonalAttendanceLocationConfigServiceImpl extends ServiceImpl<PersonalAttendanceLocationConfigMapper, PersonalAttendanceLocationConfig> implements PersonalAttendanceLocationConfigService { } 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,13 +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; @@ -41,6 +45,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; @@ -49,7 +54,7 @@ private StaffOnJobMapper staffOnJobMapper; @Autowired private PersonalAttendanceRecordsTask personalAttendanceRecordsTask; private PersonalAttendanceLocationConfigMapper personalAttendanceLocationConfigMapper; @Autowired private ISysDictDataService dictDataService; @@ -58,37 +63,52 @@ 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()); StaffOnJob staffOnJob = staffOnJobMapper.selectOne(staffQueryWrapper); if (staffOnJob == null) { throw new BaseException("å½åç¨æ·æ²¡æå¯¹åºçå工信æ¯"); } // å½åæ¶é´ LocalDateTime currentDateTime = LocalDateTime.now(); // 妿æå¡æ¶é´è¶ è¿èå¤ä¸çæ¶é´ä¸è½æå¡ /*夿æå¡ä½ç½®æ¯å¦å¨è§åèå´å */ 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)); } /*夿æå¡æ¶é´*/ LocalDateTime endAt = locationConfig.getEndAt(); //ä¸çæ¶é´ // è·åèå¤ä¸çæ¶é´ç¹ String[] timeConfigs = getAttendanceTimeConfig(); String timeConfig = timeConfigs[1]; String[] timeParts = timeConfig.split(":"); int standardHour = Integer.parseInt(timeParts[0]); int standardMinute = Integer.parseInt(timeParts[1]); int standardHour = endAt.getHour(); int standardMinute = endAt.getMinute(); // å½åæ¶é´ int actualHour = currentDateTime.getHour(); int actualMinute = currentDateTime.getMinute(); // 夿æå¡æ¶é´æ¯å¦æäºå½åæ¶é´ if (actualHour > standardHour || (actualHour == standardHour && actualMinute > standardMinute)) { throw new BaseException("æå¡æ¶é´ä¸è½æäºä¸çæ¶é´"); throw new BaseException(String.format("æå¡å¤±è´¥ï¼æå¡æ¶é´ä¸è½æäºä¸çæ¶é´ï¼%02d:%02dï¼", standardHour, standardMinute)); } // æ ¹æ®åå·¥IDåå½åæ¥ææ¥è¯¢æå¡è®°å½ QueryWrapper<PersonalAttendanceRecords> attendanceQueryWrapper = new QueryWrapper<>(); attendanceQueryWrapper.eq("staff_on_job_id", staffOnJob.getId()) @@ -97,10 +117,11 @@ // æ ¹æ®åå ¸è®¾ç½®çè夿¶é´å¤æè¿å°æ©é 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); @@ -117,7 +138,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("æ¨å·²ç»æè¿å¡äº,æ éé夿å¡!!!"); @@ -125,46 +146,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 æ£å¸¸ 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]; // è§£ææ åæ¶é´ String[] timeParts = timeConfig.split(":"); int standardHour = Integer.parseInt(timeParts[0]); int standardMinute = Integer.parseInt(timeParts[1]); LocalDateTime startAt = locationConfig.getStartAt();//ä¸çæ¶é´ LocalDateTime endAt = locationConfig.getEndAt();//ä¸çæ¶é´ LocalDateTime timeConfig = isStart ? startAt : endAt; // è§£æå°æ¶ååé int standardHour = timeConfig.getHour(); int standardMinute = timeConfig.getMinute(); // è·åå®é æ¶é´çæ¶å int actualHour = actualTime.getHour(); int actualMinute = actualTime.getMinute(); // å¤æç¶æ if (isStart) { // ä¸çæå¡ï¼è¶ è¿æ åæ¶é´ç®è¿å° @@ -180,9 +177,7 @@ return 2; // æ©é } } return 0; // æ£å¸¸ } catch (Exception e) { // 妿è·åé 置失败ï¼é»è®¤è¿åæ£å¸¸ç¶æ log.warn("è·åè夿¶é´é 置失败ï¼ä½¿ç¨é»è®¤ç¶æï¼" + e.getMessage()); @@ -240,7 +235,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; } src/main/java/com/ruoyi/staff/utils/LocationUtils.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,37 @@ package com.ruoyi.staff.utils; // å·¥å ·ç±»ï¼è®¡ç®ä¸¤ä¸ªç»çº¬åº¦ä¹é´çè·ç¦»ï¼çé¢è·ç¦»ï¼ public class LocationUtils { private static final double EARTH_RADIUS = 6371000; // å°çåå¾ï¼åä½ç±³ /** * 计ç®ä¸¤ä¸ªç»çº¬åº¦ä¹é´çè·ç¦»ï¼ç±³ï¼ * @param lat1 第ä¸ä¸ªç¹çº¬åº¦ * @param lon1 第ä¸ä¸ªç¹ç»åº¦ * @param lat2 第äºä¸ªç¹çº¬åº¦ * @param lon2 第äºä¸ªç¹ç»åº¦ * @return è·ç¦»ï¼ç±³ï¼ */ public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) { // 转弧度 double radLat1 = Math.toRadians(lat1); double radLon1 = Math.toRadians(lon1); double radLat2 = Math.toRadians(lat2); double radLon2 = Math.toRadians(lon2); // å·®å¼ double deltaLat = radLat1 - radLat2; double deltaLon = radLon1 - radLon2; // çé¢è·ç¦»å ¬å¼ double distance = 2 * Math.asin(Math.sqrt( Math.pow(Math.sin(deltaLat / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(deltaLon / 2), 2) )); distance = distance * EARTH_RADIUS; // ä¿ç两ä½å°æ° distance = Math.round(distance * 100) / 100.0; return distance; } } src/main/resources/mapper/staff/PersonalAttendanceLocationConfigMapper.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,17 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.staff.mapper.PersonalAttendanceLocationConfigMapper"> <!-- éç¨æ¥è¯¢æ å°ç»æ --> <resultMap id="BaseResultMap" type="com.ruoyi.staff.pojo.PersonalAttendanceLocationConfig"> <id column="id" property="id" /> <result column="sys_dept_id" property="sysDeptId" /> <result column="location_name" property="locationName" /> <result column="longitude" property="longitude" /> <result column="latitude" property="latitude" /> <result column="radius" property="radius" /> <result column="start_at" property="startAt" /> <result column="end_at" property="endAt" /> </resultMap> </mapper>