Compare commits

..

No commits in common. "2002d2a45b8b88c586b13eb4eb8800e29c05297d" and "99640b1edc1b3df95b7d542e31bc9d23271f9c95" have entirely different histories.

38 changed files with 85 additions and 1182 deletions

View File

@ -76,14 +76,7 @@ public interface PunchTheClockStrategyExchangeProcessor {
return ""; return "";
} }
default String initMessage(Integer result, String meg){
default String initMessage(Integer result, String meg){
//需要返回的对象, 默认失败
return initStaticMessage(result, meg);
}
static String initStaticMessage(Integer result, String meg){
//需要返回的对象, 默认失败 //需要返回的对象, 默认失败
return JSONObject.toJSONString(new RzAttendanceVo(result, meg, null)); return JSONObject.toJSONString(new RzAttendanceVo(result, meg, null));
} }

View File

@ -1,11 +1,9 @@
package com.evo.attendance.service; package com.evo.attendance.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.evo.attendance.domain.RzAttendance;
import com.evo.attendance.domain.vo.RzAttendanceDetailVO; import com.evo.attendance.domain.vo.RzAttendanceDetailVO;
import com.evo.common.core.domain.AjaxResult; import com.evo.common.core.domain.AjaxResult;
import com.evo.ding.domain.DingShiftGroup; import com.evo.attendance.domain.RzAttendance;
import com.evo.system.domain.SysStaff;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -66,8 +64,4 @@ public interface IRzAttendanceService extends IService<RzAttendance>
public void sendAbnormalAttendance(); public void sendAbnormalAttendance();
public void dingDing(String dingUserId, String bizId); public void dingDing(String dingUserId, String bizId);
void addRzOverTime(String result, SysStaff sysStaff, DingShiftGroup dingsShiftGroup, String checkType, Date formatWorkDate, Date formatUserCheckTime, String timeResult, String remark );
public RzAttendance queryNowDayAttendanceByStatisticalIdAndDate(Long staffId, Date date);
} }

View File

@ -1,10 +1,7 @@
package com.evo.attendance.service; package com.evo.attendance.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.evo.attendance.domain.RzSpecialAttendance; import com.evo.attendance.domain.RzSpecialAttendance;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
@ -13,7 +10,7 @@ import java.util.List;
* @author evo * @author evo
* @date 2025-04-15 * @date 2025-04-15
*/ */
public interface IRzSpecialAttendanceService extends IService<RzSpecialAttendance> public interface IRzSpecialAttendanceService
{ {
/** /**
* 查询加班考勤记录 * 查询加班考勤记录
@ -54,6 +51,4 @@ public interface IRzSpecialAttendanceService extends IService<RzSpecialAttendanc
* @return 结果 * @return 结果
*/ */
public int deleteRzSpecialAttendanceById(Long id); public int deleteRzSpecialAttendanceById(Long id);
public RzSpecialAttendance selectRzSpecialAttendanceByUserIdAndDate(Long staffId, Date date);
} }

View File

@ -16,17 +16,13 @@ import com.evo.attendance.service.RzAttendanceDetailService;
import com.evo.common.annotation.DataScope; import com.evo.common.annotation.DataScope;
import com.evo.common.core.domain.AjaxResult; import com.evo.common.core.domain.AjaxResult;
import com.evo.common.core.domain.entity.SysDept; import com.evo.common.core.domain.entity.SysDept;
import com.evo.common.utils.Collections; import com.evo.common.utils.*;
import com.evo.common.utils.DateUtils;
import com.evo.common.utils.SecurityUtils;
import com.evo.common.utils.StringUtils;
import com.evo.ding.DingUtils; import com.evo.ding.DingUtils;
import com.evo.ding.domain.DingShift; import com.evo.ding.domain.DingShift;
import com.evo.ding.domain.DingShiftGroup; import com.evo.ding.domain.DingShiftGroup;
import com.evo.ding.mapper.DingShiftGroupMapper; import com.evo.ding.mapper.DingShiftGroupMapper;
import com.evo.ding.mapper.DingShiftMapper; import com.evo.ding.mapper.DingShiftMapper;
import com.evo.equipment.service.IEqImagesService; import com.evo.equipment.service.IEqImagesService;
import com.evo.personnelMatters.service.IRzOverTimeService;
import com.evo.system.domain.SysStaff; import com.evo.system.domain.SysStaff;
import com.evo.system.mapper.SysDeptMapper; import com.evo.system.mapper.SysDeptMapper;
import com.evo.system.mapper.SysStaffMapper; import com.evo.system.mapper.SysStaffMapper;
@ -59,8 +55,6 @@ public class RzAttendanceServiceImpl extends ServiceImpl<RzAttendanceMapper, RzA
@Resource @Resource
private ISysStaffService sysStaffService; private ISysStaffService sysStaffService;
@Resource @Resource
private IRzOverTimeService rzOverTimeService;
@Resource
private IEqImagesService eqImagesService; private IEqImagesService eqImagesService;
@Resource @Resource
private RzAttendanceDetailService rzAttendanceDetailService; private RzAttendanceDetailService rzAttendanceDetailService;
@ -495,7 +489,7 @@ public class RzAttendanceServiceImpl extends ServiceImpl<RzAttendanceMapper, RzA
try { try {
for (SysStaff sysStaff : sysStaffService.selectSysStaffListAll()){ for (SysStaff sysStaff : sysStaffService.selectSysStaffListAll()){
Date date = DateUtils.addDays(new Date(), -1); Date date = DateUtils.addDays(new Date(), -1);
RzAttendance beforeAttendance = queryNowDayAttendanceByStatisticalIdAndDate(sysStaff.getUserId(), date); RzAttendance beforeAttendance = getBaseMapper().queryNowDayAttendanceByStatisticalIdAndDate(sysStaff.getUserId(), date);
if(beforeAttendance.getWorkStartTime() != null && beforeAttendance.getWorkEndTime() == null){ if(beforeAttendance.getWorkStartTime() != null && beforeAttendance.getWorkEndTime() == null){
sendAbnormalAttendance(sysStaff, beforeAttendance.getWorkStartTime()); sendAbnormalAttendance(sysStaff, beforeAttendance.getWorkStartTime());
@ -530,8 +524,7 @@ public class RzAttendanceServiceImpl extends ServiceImpl<RzAttendanceMapper, RzA
String result = DingUtils.getListRecord(Collections.asList(dingUserId), DateUtils.parseDateToStr("yyyy-MM-dd", new Date())+" 00:00:00", DateUtils.parseDateToStr("yyyy-MM-dd", new Date())+" 23:59:59"); String result = DingUtils.getListRecord(Collections.asList(dingUserId), DateUtils.parseDateToStr("yyyy-MM-dd", new Date())+" 00:00:00", DateUtils.parseDateToStr("yyyy-MM-dd", new Date())+" 23:59:59");
System.out.println("打卡结果===>"+result); System.out.println("打卡结果===>"+result);
JSONObject resultJson = JSON.parseObject(result); JSONObject resultJson = JSON.parseObject(result);
if(Integer.valueOf(0).equals(resultJson.getInteger("errcode"))) if(Integer.valueOf(0).equals(resultJson.getInteger("errcode"))) try {
try {
{ {
JSONArray jsonArray = resultJson.getJSONArray("recordresult"); JSONArray jsonArray = resultJson.getJSONArray("recordresult");
for (int i = 0; i < jsonArray.size(); i++) { for (int i = 0; i < jsonArray.size(); i++) {
@ -545,33 +538,13 @@ public class RzAttendanceServiceImpl extends ServiceImpl<RzAttendanceMapper, RzA
Long planCheckTime = ob.getLong("planCheckTime"); Long planCheckTime = ob.getLong("planCheckTime");
// 格式化先转Date对象再格式化 // 格式化先转Date对象再格式化
String formatPlanCheckTime = DateUtils.parseDateToStr("HH:mm:ss", new Date(planCheckTime)); String formatPlanCheckTime = DateUtils.parseDateToStr("HH:mm:ss", new Date(planCheckTime));
//用户打卡时间
Long userCheckTime = ob.getLong("userCheckTime");
//工作时间 (这里指的是哪一天的卡)
Long workDate = ob.getLong("workDate");
/***
* 打卡结果
* Normal正常
* Early早退
* Late迟到
* SeriousLate严重迟到
* Absenteeism旷工迟到
* NotSigned未打卡
*/
String timeResult = ob.getString("timeResult");
Date formatWorkDate = Date.from(Instant.ofEpochMilli(workDate));
Date formatUserCheckTime = Date.from(Instant.ofEpochMilli(userCheckTime));
DingShiftGroup dingsShiftGroup = dingsShiftGroupMapper.selectByGroupIdAndTypeAndCheckTime(groupId, checkType, formatPlanCheckTime); DingShiftGroup dingsShiftGroup = dingsShiftGroupMapper.selectByGroupIdAndTypeAndCheckTime(groupId, checkType, formatPlanCheckTime);
addRzOverTime(result, sysStaff, dingsShiftGroup, checkType, formatWorkDate, formatUserCheckTime, timeResult, null);
/* DingShiftGroup dingsShiftGroup = dingsShiftGroupMapper.selectByGroupIdAndTypeAndCheckTime(groupId, checkType, formatPlanCheckTime);
if(dingsShiftGroup != null){ if(dingsShiftGroup != null){
//用户打卡时间 //用户打卡时间
Long userCheckTime = ob.getLong("userCheckTime"); Long userCheckTime = ob.getLong("userCheckTime");
//工作时间 (这里指的是哪一天的卡) //工作时间 (这里指的是哪一天的卡)
Long workDate = ob.getLong("workDate"); Long workDate = ob.getLong("workDate");
*//*** /***
* 打卡结果 * 打卡结果
* Normal正常 * Normal正常
* Early早退 * Early早退
@ -579,7 +552,7 @@ public class RzAttendanceServiceImpl extends ServiceImpl<RzAttendanceMapper, RzA
* SeriousLate严重迟到 * SeriousLate严重迟到
* Absenteeism旷工迟到 * Absenteeism旷工迟到
* NotSigned未打卡 * NotSigned未打卡
*//* */
String timeResult = ob.getString("timeResult"); String timeResult = ob.getString("timeResult");
Date formatWorkDate = Date.from(Instant.ofEpochMilli(workDate)); Date formatWorkDate = Date.from(Instant.ofEpochMilli(workDate));
@ -587,9 +560,9 @@ public class RzAttendanceServiceImpl extends ServiceImpl<RzAttendanceMapper, RzA
//通过打卡类型, classId, 和排班打卡时间, 获取工作时长 //通过打卡类型, classId, 和排班打卡时间, 获取工作时长
//通过班次id拿到工作时长 //通过班次id拿到工作时长
DingShift dingsShift = dingsShiftMapper.selectByDingId(dingsShiftGroup.getShiftId()); DingShift dingsShift = dingsShiftMapper.selectOne(new LambdaQueryWrapper<DingShift>().eq(DingShift::getDingId, dingsShiftGroup.getShiftId()));
//通过workDate 获取哪一天的卡 //通过workDate 获取哪一天的卡
RzAttendance attendance = queryNowDayAttendanceByStatisticalIdAndDate(sysStaff.getUserId(),formatWorkDate); RzAttendance attendance = getBaseMapper().queryNowDayAttendanceByStatisticalIdAndDate(sysStaff.getUserId(),formatWorkDate);
//生成打卡记录 //生成打卡记录
rzAttendanceDetailService.addDetail(attendance, ("OnDuty".equals(checkType) ? "上班卡" : "下班卡"), "/", formatUserCheckTime, "钉钉打卡", ""); rzAttendanceDetailService.addDetail(attendance, ("OnDuty".equals(checkType) ? "上班卡" : "下班卡"), "/", formatUserCheckTime, "钉钉打卡", "");
//上班 //上班
@ -626,15 +599,12 @@ public class RzAttendanceServiceImpl extends ServiceImpl<RzAttendanceMapper, RzA
//检查是否开启加班 //检查是否开启加班
if(dingsShift.getOvertimeWork()){ if(dingsShift.getOvertimeWork()){
//如果开启了加班 //如果开启了加班
// BigDecimal hours = new BigDecimal(((userCheckTime - attendance.getWorkStartTime().getTime())/1000/60/60)).subtract(new BigDecimal(dingsShift.getWorkHour())).subtract(BigDecimal.valueOf(1)).subtract(new BigDecimal(String.valueOf(DataUtils.findDefaultValue(dingsShift.getDeductionHour(), 0)))); Long hours = (userCheckTime - attendance.getWorkStartTime().getTime())/1000/60/60;
//使用排班下班时间作为加班开始时间 new BigDecimal(hours).subtract(new BigDecimal(dingsShift.getWorkHour())).subtract(BigDecimal.valueOf(1)).subtract(new BigDecimal(String.valueOf(DataUtils.findDefaultValue(dingsShift.getDeductionHour(), 0))));
rzOverTimeService.overTimeCard(sysStaff, DateUtils.parseDate(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date(planCheckTime)), "yyyy-MM-dd HH:mm:ss"));
//员工打卡时间作为加班下班时间
rzOverTimeService.overTimeOffDutyCard(sysStaff, formatUserCheckTime, "/");
} }
}else{ }else{
log.info("未找到相关考勤班次数据, 疑似加班打卡=====>>>>> {}", result); log.info("未找到相关考勤班次数据, 疑似加班打卡=====>>>>> {}", result);
}*/ }
break; break;
} }
} }
@ -646,64 +616,6 @@ public class RzAttendanceServiceImpl extends ServiceImpl<RzAttendanceMapper, RzA
} }
} }
@Override
public void addRzOverTime(String result, SysStaff sysStaff, DingShiftGroup dingsShiftGroup, String checkType, Date formatWorkDate, Date formatUserCheckTime, String timeResult, String remark){
if(dingsShiftGroup != null){
//通过打卡类型, classId, 和排班打卡时间, 获取工作时长
//通过班次id拿到工作时长
DingShift dingsShift = dingsShiftMapper.selectByDingId(dingsShiftGroup.getShiftId());
//通过workDate 获取哪一天的卡
RzAttendance attendance = queryNowDayAttendanceByStatisticalIdAndDate(sysStaff.getUserId(),formatWorkDate);
//生成打卡记录
rzAttendanceDetailService.addDetail(attendance, ("OnDuty".equals(checkType) ? "上班卡" : "下班卡"), "/", formatUserCheckTime, StringUtils.isEmpty(remark) ? "钉钉打卡" : remark, "");
//上班
if("OnDuty".equals(checkType)){
attendance.setRules("上班卡");
attendance.setWorkStartTime(formatUserCheckTime);
if(!"Normal".equals(timeResult)){
attendance.setYcsFlag("1");
}
}else if("OffDuty".equals(checkType)){
attendance.setWorkEndTime(formatUserCheckTime);
if("Normal".equals(timeResult)){
attendance.setWorkSum(BigDecimal.valueOf(dingsShift.getWorkHour()));
}else{
//早退需要计算工时
Long hours = (attendance.getWorkEndTime().getTime() - attendance.getWorkStartTime().getTime())/1000/60/60;
attendance.setWorkSum(BigDecimal.valueOf(hours));
attendance.setYcxFlag("1");
}
}else{
log.error("钉钉打卡=====>>>>>>>>>>>>>>>>>> 出现未知打卡类型, 当前打卡类型");
//终止继续执行
return;
}
//判断打卡时间, 添加夜班次数 打卡时间在晚上7点以后
if(dingsShift.getWorkHour() == 12 && attendance.getWorkSum().intValue() >= 12 && attendance.getWorkStartTime()!= null && attendance.getWorkStartTime().getHours() > 12){
attendance.setNightNumber(1);
//必须是8小时倒班制or单班制, 并且工作时长>=8小时, 并且 上班打开时间在12点至21点 算作中班 -- 2026-02-04 因1月份张克龙中班考勤问题, 刘杰面谈
}else if(dingsShift.getWorkHour() == 8 && attendance.getWorkSum().intValue() >= 8 && attendance.getWorkStartTime() != null && attendance.getWorkStartTime().getHours() >= 12 && attendance.getWorkStartTime().getHours() < 21){
attendance.setMiddleShiftNumber(1);
}
getBaseMapper().updateRzAttendance(attendance);
//检查是否开启加班
if(dingsShift.getOvertimeWork()){
//使用排班下班时间作为加班开始时间
rzOverTimeService.overTimeCard(sysStaff, DateUtils.parseDate(DateUtils.parseDateToStr("yyyy-MM-dd", formatWorkDate)+" "+ dingsShiftGroup.getCheckTime()));
//员工打卡时间作为加班下班时间
rzOverTimeService.overTimeOffDutyCard(sysStaff, formatUserCheckTime, "/");
}
}else{
log.info("钉钉回调打卡信息=====>>>>> {}", result);
}
}
@Override
public RzAttendance queryNowDayAttendanceByStatisticalIdAndDate(Long staffId, Date date) {
return getBaseMapper().queryNowDayAttendanceByStatisticalIdAndDate(staffId,date);
}
@Async @Async
protected void sendAbnormalAttendance(SysStaff sysStaff, Date date){ protected void sendAbnormalAttendance(SysStaff sysStaff, Date date){

View File

@ -4,7 +4,6 @@ import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.attendance.domain.RzAttendanceStatistical; import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.attendance.domain.RzSpecialAttendance; import com.evo.attendance.domain.RzSpecialAttendance;
import com.evo.attendance.domain.RzSpecialOverTime; import com.evo.attendance.domain.RzSpecialOverTime;
@ -24,7 +23,7 @@ import javax.annotation.Resource;
* @date 2025-04-15 * @date 2025-04-15
*/ */
@Service @Service
public class RzSpecialAttendanceServiceImpl extends ServiceImpl<RzSpecialAttendanceMapper, RzSpecialAttendance> implements IRzSpecialAttendanceService public class RzSpecialAttendanceServiceImpl implements IRzSpecialAttendanceService
{ {
@Resource @Resource
private RzSpecialAttendanceMapper rzSpecialAttendanceMapper; private RzSpecialAttendanceMapper rzSpecialAttendanceMapper;
@ -132,9 +131,4 @@ public class RzSpecialAttendanceServiceImpl extends ServiceImpl<RzSpecialAttenda
rzAttendanceStatistical.setOverTimeHours(rzAttendanceStatistical.getOverTimeHours().subtract(rzSpecialAttendance.getWorkHours())); rzAttendanceStatistical.setOverTimeHours(rzAttendanceStatistical.getOverTimeHours().subtract(rzSpecialAttendance.getWorkHours()));
return rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical); return rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical);
} }
@Override
public RzSpecialAttendance selectRzSpecialAttendanceByUserIdAndDate(Long staffId, Date date) {
return getBaseMapper().selectRzSpecialAttendanceByUserIdAndDate(staffId, date);
}
} }

View File

@ -1,21 +1,23 @@
package com.evo.common.controller; package com.evo.common.controller;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.evo.attendance.processor.impl.KQDeviceExchangeProcessor;
import com.evo.attendance.service.IRzAttendanceService; import com.evo.attendance.service.IRzAttendanceService;
import com.evo.common.core.controller.BaseController; import com.evo.common.core.controller.BaseController;
import com.evo.common.utils.StringUtils;
import com.evo.ding.DingGlobalParams; import com.evo.ding.DingGlobalParams;
import com.evo.ding.DingCallbackCrypto; import com.evo.ding.DingCallbackCrypto;
import com.evo.ding.processor.instance.InstanceChangeExchangeProcessor;
import com.evo.ding.processor.callback.DingCallBackExchangeProcessor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List; import javax.annotation.Resource;
import java.util.Map; import java.util.Map;
/** /**
@ -34,10 +36,7 @@ public class CallbackController extends BaseController {
@Autowired @Autowired
IRzAttendanceService rzAttendanceService; IRzAttendanceService rzAttendanceService;
@Autowired
List<InstanceChangeExchangeProcessor> instanceChangeExchangeProcessorList;
@Autowired
List<DingCallBackExchangeProcessor> dingCallBackExchangeProcessorList;
@PostMapping("/ding/clock") @PostMapping("/ding/clock")
public Map<String, String> dingDingClock(@RequestBody Map<String, Object> params){ public Map<String, String> dingDingClock(@RequestBody Map<String, Object> params){
System.out.println(JSONObject.toJSONString(params)); System.out.println(JSONObject.toJSONString(params));
@ -54,52 +53,34 @@ public class CallbackController extends BaseController {
// 3. 反序列化回调事件json数据 // 3. 反序列化回调事件json数据
JSONObject eventJson = JSON.parseObject(decryptMsg); JSONObject eventJson = JSON.parseObject(decryptMsg);
String eventType = eventJson.getString("EventType"); String eventType = eventJson.getString("EventType");
log.info("发生了:" + eventType + "事件");
for (DingCallBackExchangeProcessor processor : dingCallBackExchangeProcessorList) {
if (processor.accept(eventType)) {
processor.exchange(eventJson);
}
}
// 4. 根据EventType分类处理 // 4. 根据EventType分类处理
// if ("check_url".equals(eventType)) { if ("check_url".equals(eventType)) {
// log.info("打卡回调"); // 测试回调url的正确性
// } else if ("attendance_check_record".equals(eventType)) { //打卡推送 log.info("测试回调url的正确性");
// JSONArray dataList = eventJson.getJSONArray("DataList"); } else if ("attendance_check_record".equals(eventType)) { //打卡推送
// if(dataList!= null && dataList.size() > 0){ JSONArray dataList = eventJson.getJSONArray("DataList");
// JSONObject jsonObject = dataList.getJSONObject(0); if(dataList!= null && dataList.size() > 0){
// String userId = jsonObject.getString("userId"); JSONObject jsonObject = dataList.getJSONObject(0);
// if(StringUtils.isNotEmpty(userId)){ String userId = jsonObject.getString("userId");
// rzAttendanceService.dingDing(userId, jsonObject.getString("bizId")); if(StringUtils.isNotEmpty(userId)){
// } rzAttendanceService.dingDing(userId, jsonObject.getString("bizId"));
// } }
// //审批实例订阅 }
// }else if ("bpms_instance_change".equals(eventType)) { //加班审批订阅
// log.info("审批实例订阅回调"); }else if ("bpms_instance_change".equals(eventType)) {
// for (InstanceChangeExchangeProcessor processor : instanceChangeExchangeProcessorList) {
// if (processor.accept(eventJson.getString("processCode"))) {
// processor.exchange(eventJson); // 处理通讯录用户增加事件
// } }else if ("user_add_org".equals(eventType)) {
// } // 处理通讯录用户增加事件
// // 审批任务订阅 log.info("发生了:" + eventType + "事件");
// }else if ("bpms_task_change".equals(eventType)) {
// log.info("审批任务订阅回调");
// // 处理通讯录用户增加事件 } else {
// }else if ("attendance_approve_status_change".equals(eventType)) { // 添加其他已注册的
// log.info("请假、加班、出差、外出状态变更事件"); log.info("发生了:" + eventType + "事件");
// }
//
//
// // 处理通讯录用户增加事件
// }else if ("user_add_org".equals(eventType)) {
// // 处理通讯录用户增加事件
// log.info("发生了:" + eventType + "事件");
//
//
// } else {
// // 添加其他已注册的
// log.info("发生了:" + eventType + "事件");
// }
// 5. 返回success的加密数据 // 5. 返回success的加密数据
Map<String, String> successMap = callbackCrypto.getEncryptedMap("success"); Map<String, String> successMap = callbackCrypto.getEncryptedMap("success");

View File

@ -215,9 +215,6 @@ public class ParamUtils {
public static JSONObject getDeviceOverTimeRules(String sn){ public static JSONObject getDeviceOverTimeRules(String sn){
if(StringUtils.isEmpty(sn)) return null; if(StringUtils.isEmpty(sn)) return null;
RzSysParam param= paramService.getRzSysParam("特殊加班的考勤规则", "device_over_time_rules","{\"ET74336\":{\"minHour\":2, \"maxHour\":3,\"endMealTime\":\"19:00\"}}","特殊加班的考勤规则, minHour:最小加班时长. maxHour: 最大加班时长, endMealTime: 餐厅闭厅时间"); RzSysParam param= paramService.getRzSysParam("特殊加班的考勤规则", "device_over_time_rules","{\"ET74336\":{\"minHour\":2, \"maxHour\":3,\"endMealTime\":\"19:00\"}}","特殊加班的考勤规则, minHour:最小加班时长. maxHour: 最大加班时长, endMealTime: 餐厅闭厅时间");
if(param == null){
return getDefaultMaxOverTime();
}
JSONObject jsonObject = JSONObject.parseObject(param.getParamValue()); JSONObject jsonObject = JSONObject.parseObject(param.getParamValue());
JSONObject rules = jsonObject.getJSONObject(sn); JSONObject rules = jsonObject.getJSONObject(sn);
return (ObjectUtils.isEmpty(rules) ? getDefaultMaxOverTime(): rules); return (ObjectUtils.isEmpty(rules) ? getDefaultMaxOverTime(): rules);

View File

@ -1,5 +1,6 @@
package com.evo.ding; package com.evo.ding;
import com.aliyun.dingtalkoauth2_1_0.Client;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest; import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse; import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse;
import com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceResponseBody; import com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceResponseBody;
@ -37,23 +38,17 @@ public class DingUtils {
this.redisCache = redisCache; this.redisCache = redisCache;
} }
public static <T> com.aliyun.teaopenapi.Client client(Class<?> t) throws Exception { private static Client createClient() throws Exception {
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config(); com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.protocol = "https"; config.protocol = "https";
config.regionId = "central"; config.regionId = "central";
if(t == com.aliyun.dingtalkoauth2_1_0.Client.class){ return new Client(config);
return new com.aliyun.dingtalkoauth2_1_0.Client(config);
}else if(t == com.aliyun.dingtalkworkflow_1_0.Client.class){
return new com.aliyun.dingtalkworkflow_1_0.Client(config);
}
return null;
} }
public static String getAccessToken() throws Exception { public static String getAccessToken() throws Exception {
String token = redisCache.getCacheObject(ACCESS_TOKEN_KEY); String token = redisCache.getCacheObject(ACCESS_TOKEN_KEY);
if(StringUtils.isEmpty(token)){ if(StringUtils.isEmpty(token)){
com.aliyun.dingtalkoauth2_1_0.Client client = (com.aliyun.dingtalkoauth2_1_0.Client) client(com.aliyun.dingtalkoauth2_1_0.Client.class); Client client = createClient();
GetAccessTokenRequest getAccessTokenRequest = new GetAccessTokenRequest().setAppKey(DingGlobalParams.getClientId()).setAppSecret(DingGlobalParams.getClientSecret()); GetAccessTokenRequest getAccessTokenRequest = new GetAccessTokenRequest().setAppKey(DingGlobalParams.getClientId()).setAppSecret(DingGlobalParams.getClientSecret());
try { try {
GetAccessTokenResponse res = client.getAccessToken(getAccessTokenRequest); GetAccessTokenResponse res = client.getAccessToken(getAccessTokenRequest);
@ -173,58 +168,40 @@ public class DingUtils {
return ""; return "";
} }
public static com.aliyun.dingtalkworkflow_1_0.Client createClient1() throws Exception {
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.protocol = "https";
config.regionId = "central";
return new com.aliyun.dingtalkworkflow_1_0.Client(config);
}
/*** /***
* 获取审批详情 * 获取审批详情
* @param processInstanceId 审批示例id * @param processInstanceId 审批示例id
*/ */
public static GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult getProcessInstanceInfo(String processInstanceId){ public static GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult getProcessInstanceInfo(String processInstanceId) throws Exception {
try {
com.aliyun.dingtalkworkflow_1_0.Client client = (com.aliyun.dingtalkworkflow_1_0.Client) client(com.aliyun.dingtalkworkflow_1_0.Client.class);
com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceHeaders getProcessInstanceHeaders = new com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceHeaders();
getProcessInstanceHeaders.xAcsDingtalkAccessToken = getAccessToken();
com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceRequest getProcessInstanceRequest = new com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceRequest();
getProcessInstanceRequest.setProcessInstanceId(processInstanceId);
try {
return client.getProcessInstanceWithOptions(getProcessInstanceRequest, getProcessInstanceHeaders, new com.aliyun.teautil.models.RuntimeOptions()).getBody().getResult();
} catch (TeaException err) {
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
// err 中含有 code message 属性可帮助开发定位问题
log.error("获取token出现 TeaException 异常, 异常编码{}, 异常原因{}", err.getCode(), err.getMessage());
}
} catch (Exception _err) {
TeaException err = new TeaException(_err.getMessage(), _err);
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
// err 中含有 code message 属性可帮助开发定位问题
log.error("获取token出现 Exception 异常, 异常编码{}, 异常原因{}", err.getCode(), err.getMessage());
}
com.aliyun.dingtalkworkflow_1_0.Client client = DingUtils.createClient1();
com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceHeaders getProcessInstanceHeaders = new com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceHeaders();
getProcessInstanceHeaders.xAcsDingtalkAccessToken = getAccessToken();
com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceRequest getProcessInstanceRequest = new com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceRequest();
getProcessInstanceRequest.setProcessInstanceId(processInstanceId);
try {
return client.getProcessInstanceWithOptions(getProcessInstanceRequest, getProcessInstanceHeaders, new com.aliyun.teautil.models.RuntimeOptions()).getBody().getResult();
} catch (TeaException err) {
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
// err 中含有 code message 属性可帮助开发定位问题
log.error("获取token出现 TeaException 异常, 异常编码{}, 异常原因{}", err.getCode(), err.getMessage());
} }
} catch (Exception e) { } catch (Exception _err) {
log.error("=============>>> 获取审批实例出现异常, 异常原因为: {}", e.getMessage()); TeaException err = new TeaException(_err.getMessage(), _err);
e.printStackTrace(); if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
// err 中含有 code message 属性可帮助开发定位问题
log.error("获取token出现 Exception 异常, 异常编码{}, 异常原因{}", err.getCode(), err.getMessage());
}
} }
return null; return null;
} }
/***
* 获取排班详情
* @param userId
* @param planId
* @return
*/
public static String getPlanInfo(String userId, String planId){
try {
DingTalkClient client = new DefaultDingTalkClient(DingGlobalParams.getBaseUrl()+"attendance/schedule/result/listbyids");
OapiAttendanceScheduleResultListbyidsRequest req = new OapiAttendanceScheduleResultListbyidsRequest();
req.setOpUserId(userId);
req.setScheduleIds(planId);
OapiAttendanceScheduleResultListbyidsResponse rsp = client.execute(req, getAccessToken());
return rsp.getBody();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
} }

View File

@ -1,6 +1,5 @@
package com.evo.ding.domain; package com.evo.ding.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
@ -17,7 +16,6 @@ import java.io.Serializable;
public class DingShift implements Serializable { public class DingShift implements Serializable {
/** 主键 */ /** 主键 */
@TableId
private Long id; private Long id;
/** 班次名称 */ /** 班次名称 */
public String name; public String name;

View File

@ -2,8 +2,6 @@ package com.evo.ding.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evo.ding.domain.DingShift; import com.evo.ding.domain.DingShift;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/** /**
* DingsShiftGroupMapper * DingsShiftGroupMapper
@ -15,5 +13,5 @@ import org.apache.ibatis.annotations.Select;
*/ */
public interface DingShiftMapper extends BaseMapper<DingShift> { public interface DingShiftMapper extends BaseMapper<DingShift> {
public DingShift selectByDingId(@Param("dingId") String dingId);
} }

View File

@ -1,108 +0,0 @@
package com.evo.ding.processor;
import com.evo.attendance.service.IRzAttendanceService;
import com.evo.attendance.service.RzAttendanceDetailService;
import com.evo.common.utils.Collections;
import com.evo.common.utils.spring.SpringUtils;
import com.evo.ding.service.DingShiftGroupService;
import com.evo.ding.service.DingShiftService;
import com.evo.personnelMatters.service.IRzLeaveDetailService;
import com.evo.personnelMatters.service.IRzLeaveService;
import com.evo.personnelMatters.service.IRzOverTimeDetailService;
import com.evo.personnelMatters.service.IRzOverTimeService;
import com.evo.system.domain.SysStaff;
import com.evo.system.service.ISysStaffService;
import java.util.Map;
/**
* 钉钉回调基础类型 DingBaseExchangeProcessor
*
* @author andy.shi
* @ClassName:DingBaseExchangeProcessor
* @date: 2026年03月12日 11:05
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
public interface DingBasicExchangeProcessor {
final Map<String, Object> p = Collections.emptyMap();
//审批状态
String APPROVE_STATUS = "COMPLETED";
String APPROVE_RESULT = "AGREE";
default ISysStaffService getISysStaffService(){
if(!p.containsKey("sysStaffService")){
p.put("sysStaffService", SpringUtils.getBean(ISysStaffService.class));
}
return (ISysStaffService)p.get("sysStaffService");
}
default IRzAttendanceService getIRzAttendanceService(){
if(!p.containsKey("rzAttendanceService")){
p.put("rzAttendanceService", SpringUtils.getBean(IRzAttendanceService.class));
}
return (IRzAttendanceService)p.get("rzAttendanceService");
}
default RzAttendanceDetailService getRzAttendanceDetailService(){
if(!p.containsKey("rzAttendanceDetailService")){
p.put("rzAttendanceDetailService", SpringUtils.getBean(RzAttendanceDetailService.class));
}
return (RzAttendanceDetailService)p.get("rzAttendanceDetailService");
}
default IRzOverTimeService getIRzOverTimeService(){
if(!p.containsKey("rzOverTimeService")){
p.put("rzOverTimeService", SpringUtils.getBean(IRzOverTimeService.class));
}
return (IRzOverTimeService)p.get("rzOverTimeService");
}
default IRzOverTimeDetailService getIRzOverTimeDetailService(){
if(!p.containsKey("rzOverTimeDetailService")){
p.put("rzOverTimeDetailService", SpringUtils.getBean(IRzOverTimeDetailService.class));
}
return (IRzOverTimeDetailService)p.get("rzOverTimeDetailService");
}
default DingShiftService getDingShiftService(){
if(!p.containsKey("dingShiftService")){
p.put("dingShiftService", SpringUtils.getBean(DingShiftService.class));
}
return (DingShiftService)p.get("dingShiftService");
}
default DingShiftGroupService getDingShiftGroupService(){
if(!p.containsKey("dingShiftGroupService")){
p.put("dingShiftGroupService", SpringUtils.getBean(DingShiftGroupService.class));
}
return (DingShiftGroupService)p.get("dingShiftGroupService");
}
default IRzLeaveService getIRzLeaveService(){
if(!p.containsKey("rzLeaveService")){
p.put("rzLeaveService", SpringUtils.getBean(IRzLeaveService.class));
}
return (IRzLeaveService)p.get("rzLeaveService");
}
default IRzLeaveDetailService getIRzLeaveDetailService(){
if(!p.containsKey("rzLeaveDetailService")){
p.put("rzLeaveDetailService", SpringUtils.getBean(IRzLeaveDetailService.class));
}
return (IRzLeaveDetailService)p.get("rzLeaveDetailService");
}
default SysStaff getSysStaffByDingUserId(String dingUserId){
SysStaff sysStaff = getISysStaffService().selectSysStaffByDingUserId(dingUserId);
if(sysStaff == null){
throw new RuntimeException("未查询到用户信息, 用户的DingUserId为:"+dingUserId);
}
return sysStaff;
}
}

View File

@ -1,46 +0,0 @@
package com.evo.ding.processor.approveStatus;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceResponseBody;
import com.evo.ding.processor.DingBasicExchangeProcessor;
import com.evo.system.domain.SysStaff;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
/**
* 请假加班出差外出状态变更事件 回调 InstanceChangeExchangeProcessor
*
* @author andy.shi
* @ClassName:InstanceChangeExchangeProcessor
* @date: 2026年03月09日 15:25
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
public interface AttendanceApproveStatusChangeExchangeProcessor extends DingBasicExchangeProcessor {
Logger logger = LoggerFactory.getLogger(AttendanceApproveStatusChangeExchangeProcessor.class);
//请假
String APPROVE_TYPE_LEAVE = "LEAVE";
//加班
String APPROVE_TYPE_OVERTIME = "OVERTIME";
boolean accept(String approveType, String result, String status);
void exchange(GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult json);
default JSONObject getExtValue(GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult json, String componentType) {
List<GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultFormComponentValues> formComponentValueList = json.getFormComponentValues();
GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultFormComponentValues formComponentValue = formComponentValueList.stream().filter(data -> componentType.equals(data.getComponentType())).findAny().orElse(null);
if(formComponentValue != null){
return JSON.parseObject(formComponentValue.getExtValue());
}
throw new RuntimeException("未查询到相关审批信息, 审批类型为:"+componentType+"; 参数信息为: "+ json.toString());
}
}

View File

@ -1,89 +0,0 @@
package com.evo.ding.processor.approveStatus.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceResponseBody;
import com.evo.common.core.domain.entity.SysDictData;
import com.evo.common.utils.StringUtils;
import com.evo.ding.processor.approveStatus.AttendanceApproveStatusChangeExchangeProcessor;
import com.evo.personnelMatters.domain.RzLeave;
import com.evo.personnelMatters.domain.RzLeaveDetail;
import com.evo.system.domain.SysStaff;
import com.evo.system.service.ISysDictDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
* 请假事件处理 ApproveStatusLeaveExchangeProcessor
*
* @author andy.shi
* @ClassName:ApproveStatusLeaveExchangeProcessor
* @date: 2026年03月12日 13:32
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Slf4j
@Service
public class ApproveStatusLeaveExchangeProcessor implements AttendanceApproveStatusChangeExchangeProcessor {
@Autowired
ISysDictDataService sysDictDataService;
@Override
public boolean accept(String approveType, String result, String status) {
return APPROVE_TYPE_LEAVE.equals(approveType.toUpperCase()) && APPROVE_STATUS.equals(status.toUpperCase()) && APPROVE_RESULT.equals(result.toUpperCase());
}
@Override
public void exchange(GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult json) {
try {
SysStaff sysStaff = getSysStaffByDingUserId(json.getOriginatorUserId());
JSONObject extValueJson = getExtValue(json, "DDHolidayField");
//解析假期类型
JSONObject extension = JSON.parseObject(extValueJson.getString("extension"));
//查询假期类型
String tag = extension.getString("tag");
SysDictData sysDictData = sysDictDataService.selectDictDataListByType("holidays_type").stream().filter(data-> StringUtils.equals(data.getDictLabel(),tag)).findFirst().orElse(null);
if(sysDictData != null){
//假期类型的code
Long dictCode = sysDictData.getDictCode();
JSONArray detailList = extValueJson.getJSONArray("detailList");
Date beginTime = null;
Date endTime = null;
//如果大于1 证明是多天请假, 需要排序
if(detailList.size() > 1){
detailList.sort((a,b)->{
return ((JSONObject) a).getLong("workDate").compareTo(((JSONObject) b).getLong("workDate"));
});
//获取第一天
beginTime = new Date(detailList.getJSONObject(0).getJSONObject("approveInfo").getLong("fromTime"));
//获取最后一天
endTime = new Date(detailList.getJSONObject(detailList.size()-1).getJSONObject("approveInfo").getLong("toTime"));
}else{
//只请一天假
JSONObject approveInfo = detailList.getJSONObject(0).getJSONObject("approveInfo");
beginTime = new Date(approveInfo.getLong("fromTime"));
//获取最后一天
endTime = new Date(approveInfo.getLong("toTime"));
}
RzLeave rzLeave = getIRzLeaveService().selectRzLeaveByUserId(sysStaff.getUserId());
RzLeaveDetail rzLeaveDetail = new RzLeaveDetail();
rzLeaveDetail.setName(sysStaff.getName());
rzLeaveDetail.setLeaveStartTime(beginTime);
rzLeaveDetail.setLeaveEndTime(endTime);
rzLeaveDetail.setLeaveId(rzLeave.getId());
rzLeaveDetail.setType(dictCode);
rzLeaveDetail.setLeaveHour(extValueJson.getInteger("durationInHour"));
rzLeaveDetail.setRemarks("钉钉"+tag);
getIRzLeaveDetailService().insertRzLeaveDetail(rzLeaveDetail);
}
} catch (Exception e) {
log.error("执行钉钉 -[请假审批]-回调出现异常, 异常原因为:{}", e.getMessage());
e.printStackTrace();
}
}
}

View File

@ -1,118 +0,0 @@
package com.evo.ding.processor.approveStatus.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceResponseBody;
import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.attendance.domain.RzSpecialAttendance;
import com.evo.attendance.domain.RzSpecialOverTime;
import com.evo.attendance.mapper.RzAttendanceStatisticalMapper;
import com.evo.attendance.mapper.RzSpecialAttendanceMapper;
import com.evo.attendance.mapper.RzSpecialOverTimeMapper;
import com.evo.attendance.service.IRzAttendanceStatisticalService;
import com.evo.attendance.service.IRzSpecialAttendanceService;
import com.evo.common.core.domain.entity.SysDictData;
import com.evo.common.utils.DataUtils;
import com.evo.common.utils.DateUtils;
import com.evo.common.utils.StringUtils;
import com.evo.ding.processor.approveStatus.AttendanceApproveStatusChangeExchangeProcessor;
import com.evo.personnelMatters.domain.RzLeave;
import com.evo.personnelMatters.domain.RzLeaveDetail;
import com.evo.system.domain.SysStaff;
import com.evo.system.service.ISysDictDataService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
*加班事件处理 ApproveStatusOvertimeExchangeProcessor
*
* @author andy.shi
* @ClassName:ApproveStatusLeaveExchangeProcessor
* @date: 2026年03月12日 13:32
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Slf4j
@Service
public class ApproveStatusOvertimeExchangeProcessor implements AttendanceApproveStatusChangeExchangeProcessor {
@Autowired
IRzSpecialAttendanceService rzSpecialAttendanceService;
@Resource
private RzSpecialOverTimeMapper rzSpecialOverTimeMapper;
@Resource
private RzAttendanceStatisticalMapper rzAttendanceStatisticalMapper;
@Override
public boolean accept(String approveType, String result, String status) {
return APPROVE_TYPE_OVERTIME.equals(approveType.toUpperCase()) && APPROVE_STATUS.equals(status.toUpperCase()) && APPROVE_RESULT.equals(result.toUpperCase());
}
@Override
@Transactional
public void exchange(GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult result) {
try {
SysStaff sysStaff = getSysStaffByDingUserId(result.getOriginatorUserId());
List<GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultFormComponentValues> formComponentValueList = result.getFormComponentValues();
GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultFormComponentValues startComponentValue = formComponentValueList.stream().filter(data -> "开始时间".equals(data.getName())).findAny().orElse(null);
GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultFormComponentValues endValue = formComponentValueList.stream().filter(data -> "结束时间".equals(data.getName())).findAny().orElse(null);
GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultFormComponentValues durationValue = formComponentValueList.stream().filter(data -> "时长".equals(data.getName())).findAny().orElse(null);
if(startComponentValue != null && endValue != null && durationValue != null){
Date startDate = DateUtils.parseDate(startComponentValue.getValue(), "yyyy-MM-dd HH:mm");
Date endDate = DateUtils.parseDate(endValue.getValue(), "yyyy-MM-dd HH:mm");
BigDecimal duration = new BigDecimal(durationValue.getValue());
//获取加班详情数据
RzSpecialAttendance rzSpecialAttendance = rzSpecialAttendanceService.selectRzSpecialAttendanceByUserIdAndDate(sysStaff.getUserId(), startDate);
//如果没有, 则新增
if(rzSpecialAttendance == null){
rzSpecialAttendance = new RzSpecialAttendance();
rzSpecialAttendance.setAttendanceDate(startDate);
rzSpecialAttendance.setStaffId(sysStaff.getUserId());
rzSpecialAttendance.setName(sysStaff.getName());
rzSpecialAttendance.setDeptId(sysStaff.getDeptId());
rzSpecialAttendance.setDelFlag("0");
rzSpecialAttendance.setCreateBy("admin");
rzSpecialAttendance.setCreateTime(new Date());
}
rzSpecialAttendance.setWorkStartTime(startDate);
rzSpecialAttendance.setWorkEndTime(endDate);
rzSpecialAttendance.setWorkHours(duration);
rzSpecialAttendanceService.saveOrUpdate(rzSpecialAttendance);
//获取加班统计数据
RzSpecialOverTime rzSpecialOverTime = rzSpecialOverTimeMapper.selectRzSpecialOverTimeByUserIdAndDate(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate());
if(ObjectUtils.isEmpty(rzSpecialOverTime)){
rzSpecialOverTime = new RzSpecialOverTime();
rzSpecialOverTime.setUserId(sysStaff.getUserId());
rzSpecialOverTime.setName(sysStaff.getName());
rzSpecialOverTime.setDeptId(sysStaff.getDeptId());
rzSpecialOverTime.setDelFlag("0");
rzSpecialOverTime.setOverDate(startDate);
rzSpecialOverTime.setCreateTime(new Date());
rzSpecialOverTime.setCreateBy("admin");
rzSpecialOverTimeMapper.insertRzSpecialOverTime(rzSpecialOverTime);
}
if(DataUtils.DEFAULT_VALUE.compareTo(rzSpecialAttendance.getWorkHours()) != 0){
rzSpecialOverTime.setSickHours(DataUtils.findDefaultValue(rzSpecialOverTime.getSickHours(), new BigDecimal(0)).add(rzSpecialAttendance.getWorkHours()));
rzSpecialOverTimeMapper.updateRzSpecialOverTime(rzSpecialOverTime);
//更新加班统计
RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(rzSpecialAttendance.getStaffId(),rzSpecialAttendance.getAttendanceDate());
rzAttendanceStatistical.setOverTimeHours(DataUtils.findDefaultValue(rzAttendanceStatistical.getOverTimeHours(), new BigDecimal(0)).add(rzSpecialAttendance.getWorkHours()));
rzAttendanceStatisticalMapper.updateRzAttendanceStatistical(rzAttendanceStatistical);
}
}
} catch (Exception e) {
log.error("执行钉钉 -[加班审批]-回调出现异常, 异常原因为:{}", e.getMessage());
e.printStackTrace();
}
}
}

View File

@ -1,27 +0,0 @@
package com.evo.ding.processor.callback;
import com.alibaba.fastjson2.JSONObject;
/**
* 钉钉回调入口 DingCallBackExchangeProcessor
*
* @author andy.shi
* @ClassName:DingCallBackExchanageProcessor
* @date: 2026年03月12日 8:49
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
public interface DingCallBackExchangeProcessor {
//打卡
static final String EVENT_TYPE_CHECK_RECORD = "attendance_check_record";
//审批实例订阅
static final String EVENT_TYPE_INSTANCE_CHANGE = "bpms_instance_change";
//请假加班出差外出状态变更事件
static final String EVENT_TYPE_APPROVE_STATUS_CHANGE = "attendance_approve_status_change";
boolean accept(String eventType);
void exchange(JSONObject json);
}

View File

@ -1,48 +0,0 @@
package com.evo.ding.processor.callback.impl;
import com.alibaba.fastjson2.JSONObject;
import com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceResponseBody;
import com.evo.ding.DingUtils;
import com.evo.ding.processor.approveStatus.AttendanceApproveStatusChangeExchangeProcessor;
import com.evo.ding.processor.instance.InstanceChangeExchangeProcessor;
import com.evo.ding.processor.callback.DingCallBackExchangeProcessor;
import com.evo.system.domain.SysStaff;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 请假加班出差外出状态变更事件 DingCallBackInstanceChangeExchangeProcessor
*
* @author andy.shi
* @ClassName:DingCallBackCheckRecordExchangeProcessor
* @date: 2026年03月12日 9:02
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Slf4j
@Service
public class DingCallBackApproveStatusChangeExchangeProcessor implements DingCallBackExchangeProcessor {
@Autowired
List<AttendanceApproveStatusChangeExchangeProcessor> approveStatusChangeExchangeProcessorList;
@Override
public boolean accept(String eventType) {
return EVENT_TYPE_APPROVE_STATUS_CHANGE.equals(eventType);
}
@Override
public void exchange(JSONObject json) {
log.info("请假、加班、出差、外出状态变更事件 回调 ========================>>>{}", json.toString());
//获取审批示例id
String processInstanceId = json.getString("processInstanceId");
GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult result = DingUtils.getProcessInstanceInfo(processInstanceId);
for (AttendanceApproveStatusChangeExchangeProcessor processor : approveStatusChangeExchangeProcessorList) {
if (processor.accept(json.getString("approveType"), result.getResult(), result.getStatus())) {
processor.exchange(result);
}
}
}
}

View File

@ -1,44 +0,0 @@
package com.evo.ding.processor.callback.impl;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.evo.attendance.service.IRzAttendanceService;
import com.evo.common.utils.StringUtils;
import com.evo.ding.processor.callback.DingCallBackExchangeProcessor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 员工打开回调 DingCallBackCheckRecordExchangeProcessor
*
* @author andy.shi
* @ClassName:DingCallBackCheckRecordExchangeProcessor
* @date: 2026年03月12日 9:02
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Slf4j
@Service
public class DingCallBackCheckRecordExchangeProcessor implements DingCallBackExchangeProcessor {
@Autowired
IRzAttendanceService rzAttendanceService;
@Override
public boolean accept(String eventType) {
return EVENT_TYPE_CHECK_RECORD.equals(eventType);
}
@Override
public void exchange(JSONObject json) {
log.info("钉钉 打卡回调========================>>>{}", json.toString());
JSONArray dataList = json.getJSONArray("DataList");
if(dataList!= null && dataList.size() > 0){
JSONObject jsonObject = dataList.getJSONObject(0);
String userId = jsonObject.getString("userId");
if(StringUtils.isNotEmpty(userId)){
rzAttendanceService.dingDing(userId, jsonObject.getString("bizId"));
}
}
}
}

View File

@ -1,41 +0,0 @@
package com.evo.ding.processor.callback.impl;
import com.alibaba.fastjson2.JSONObject;
import com.evo.ding.processor.instance.InstanceChangeExchangeProcessor;
import com.evo.ding.processor.callback.DingCallBackExchangeProcessor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 审批实例订阅 DingCallBackInstanceChangeExchangeProcessor
*
* @author andy.shi
* @ClassName:DingCallBackCheckRecordExchangeProcessor
* @date: 2026年03月12日 9:02
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Slf4j
@Service
public class DingCallBackInstanceChangeExchangeProcessor implements DingCallBackExchangeProcessor {
@Autowired
List<InstanceChangeExchangeProcessor> instanceChangeExchangeProcessorList;
@Override
public boolean accept(String eventType) {
return EVENT_TYPE_INSTANCE_CHANGE.equals(eventType);
}
@Override
public void exchange(JSONObject json) {
log.info("审批实例订阅回调========================>>>{}", json.toString());
for (InstanceChangeExchangeProcessor processor : instanceChangeExchangeProcessorList) {
if (processor.accept(json.getString("processCode"))) {
processor.exchange(json);
}
}
}
}

View File

@ -1,32 +0,0 @@
package com.evo.ding.processor.instance;
import com.alibaba.fastjson2.JSONObject;
import com.evo.ding.processor.DingBasicExchangeProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 钉钉审批实例回调处理接口 InstanceChangeExchangeProcessor
*
* @author andy.shi
* @ClassName:InstanceChangeExchangeProcessor
* @date: 2026年03月09日 15:25
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
public interface InstanceChangeExchangeProcessor extends DingBasicExchangeProcessor {
Logger logger = LoggerFactory.getLogger(InstanceChangeExchangeProcessor.class);
//补卡
static final String PROCESS_CODE_RECHARGE_CARD = "PROC-19617D02-F632-402E-9ACD-134CC47E462F";
boolean accept(String processCode);
void exchange(JSONObject json);
}

View File

@ -1,77 +0,0 @@
package com.evo.ding.processor.instance.impl;
import com.alibaba.fastjson2.JSONObject;
import com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceResponseBody;
import com.evo.common.utils.DateUtils;
import com.evo.common.utils.StringUtils;
import com.evo.ding.DingUtils;
import com.evo.ding.domain.DingShiftGroup;
import com.evo.ding.processor.instance.InstanceChangeExchangeProcessor;
import com.evo.system.domain.SysStaff;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
/**
* 钉钉补卡接口回调 InstanceChangeRechargeCardExchangeProcessor
*
* @author andy.shi
* @ClassName:InstanceChangeRechargeCardExchangeProcessor
* @date: 2026年03月10日 10:24
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Slf4j
@Service
public class InstanceChangeRechargeCardExchangeProcessor implements InstanceChangeExchangeProcessor {
@Override
public boolean accept(String processCode) {
return InstanceChangeExchangeProcessor.PROCESS_CODE_RECHARGE_CARD.equals(processCode);
}
@Override
public void exchange(JSONObject json) {
//获取审批示例id
String processInstanceId = json.getString("processInstanceId");
GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult result = DingUtils.getProcessInstanceInfo(processInstanceId);
//根据操作人id, 获取user
SysStaff sysStaff = getSysStaffByDingUserId(result.getOriginatorUserId());
if(sysStaff != null){
List<GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultFormComponentValues> resultFormValues = result.getFormComponentValues();
//补卡时间
String bkTime = resultFormValues.stream().filter(data-> "补卡时间".equals(data.getName()) && StringUtils.isNotEmpty(data.getValue())).findFirst().get().getValue();
String extValue = resultFormValues.stream().filter(data-> "补卡时间".equals(data.getName()) && StringUtils.isNotEmpty(data.getExtValue())).findFirst().get().getExtValue();
//补卡类型
String bkType = resultFormValues.stream().filter(data-> "补卡类型".equals(data.getName()) && StringUtils.isNotEmpty(data.getValue())).findFirst().get().getValue();
//补卡原因
String bkYi = resultFormValues.stream().filter(data-> "补卡原因".equals(data.getName()) && StringUtils.isNotEmpty(data.getValue())).findFirst().get().getValue();
//获取补卡班次
String checkType = "上班卡".equals(bkType) ? "OnDuty" : "OffDuty";
DingShiftGroup dingsShiftGroup = null;
try {
if(StringUtils.isNotEmpty(extValue)){
JSONObject js = JSONObject.parseObject(extValue);
String planId = js.getString("planId");
String s = DingUtils.getPlanInfo(result.getOriginatorUserId(), planId);
JSONObject planResult = JSONObject.parseObject(s);
if(Integer.valueOf(0).equals(planResult.getInteger("errcode"))){
JSONObject planResultObject = planResult.getJSONArray("result").getJSONObject(0);
String formatPlanCheckTime = DateUtils.parseDateToStr("HH:mm:ss", new Date(planResultObject.getString("plan_check_time")));
dingsShiftGroup = getDingShiftGroupService().selectByGroupIdAndTypeAndCheckTime(planResultObject.getString("group_id"), checkType, formatPlanCheckTime);
Date date= DateUtils.parseDate(bkTime, "yyyy-MM-dd HH:mm");
//生成补卡记录信息
getIRzAttendanceService().addRzOverTime(json.toString(), sysStaff, dingsShiftGroup, checkType, date, date, "/", "钉钉补卡-"+bkYi);
}
}
} catch (ParseException e) {
log.info("补卡出现错误, 为在本地找到班次数据, 错误信息为:{}, 回调信息为: {}", e.getMessage(), json.toString());
e.printStackTrace();
}
}
}
}

View File

@ -1,17 +0,0 @@
package com.evo.ding.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.evo.ding.domain.DingShiftGroup;
/**
* DingShiftGroupService
*
* @author andy.shi
* @ClassName:DingShiftGroupService
* @date: 2026年03月11日 15:48
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
public interface DingShiftGroupService extends IService<DingShiftGroup> {
DingShiftGroup selectByGroupIdAndTypeAndCheckTime(String groupId, String type, String checkTime);
}

View File

@ -1,17 +0,0 @@
package com.evo.ding.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.evo.ding.domain.DingShift;
/**
* DingsShiftService
*
* @author andy.shi
* @ClassName:DingsShiftService
* @date: 2026年03月11日 15:55
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
public interface DingShiftService extends IService<DingShift> {
public DingShift selectByDingId(String dingId);
}

View File

@ -1,23 +0,0 @@
package com.evo.ding.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.ding.domain.DingShiftGroup;
import com.evo.ding.mapper.DingShiftGroupMapper;
import com.evo.ding.service.DingShiftGroupService;
import org.springframework.stereotype.Service;
/**
* DingShiftGroupServiceImpl
*
* @author andy.shi
* @ClassName:DingShiftGroupServiceImpl
* @date: 2026年03月11日 15:49
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Service
public class DingShiftGroupServiceImpl extends ServiceImpl<DingShiftGroupMapper, DingShiftGroup> implements DingShiftGroupService {
@Override
public DingShiftGroup selectByGroupIdAndTypeAndCheckTime(String groupId, String type, String checkTime) {
return getBaseMapper().selectByGroupIdAndTypeAndCheckTime(groupId, type, checkTime);
}
}

View File

@ -1,26 +0,0 @@
package com.evo.ding.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.ding.domain.DingShift;
import com.evo.ding.domain.DingShiftGroup;
import com.evo.ding.mapper.DingShiftGroupMapper;
import com.evo.ding.mapper.DingShiftMapper;
import com.evo.ding.service.DingShiftGroupService;
import com.evo.ding.service.DingShiftService;
import org.springframework.stereotype.Service;
/**
* DingShiftGroupServiceImpl
*
* @author andy.shi
* @ClassName:DingShiftGroupServiceImpl
* @date: 2026年03月11日 15:49
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Service
public class DingShiftServiceImpl extends ServiceImpl<DingShiftMapper, DingShift> implements DingShiftService {
@Override
public DingShift selectByDingId(String dingId) {
return getBaseMapper().selectByDingId(dingId);
}
}

View File

@ -51,10 +51,4 @@ public interface RzLeaveMapper extends BaseMapper<RzLeave>
* @return * @return
*/ */
public RzLeave queryRzLeaveByDateAndUserId(@Param("userId") Long userId, @Param("date") Date date); public RzLeave queryRzLeaveByDateAndUserId(@Param("userId") Long userId, @Param("date") Date date);
/**
* 根据员工ID和时间查询请假统计
* @return
*/
public RzLeave queryRzLeaveByUserId(@Param("userId") Long userId);
} }

View File

@ -59,12 +59,4 @@ public interface IRzLeaveService
public List<RzLeaveDetail> listLeaveDetails(RzLeave rzLeave); public List<RzLeaveDetail> listLeaveDetails(RzLeave rzLeave);
List<RzLeave> selectRzLeaveListByDate(RzLeave rzLeave); List<RzLeave> selectRzLeaveListByDate(RzLeave rzLeave);
/**
* 根据员工
*
* @param userId 员工id
* @return 请假管理
*/
public RzLeave selectRzLeaveByUserId(Long userId);
} }

View File

@ -1,6 +1,5 @@
package com.evo.personnelMatters.service; package com.evo.personnelMatters.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.evo.common.core.domain.AjaxResult; import com.evo.common.core.domain.AjaxResult;
import com.evo.personnelMatters.domain.RzOverTimeDetail; import com.evo.personnelMatters.domain.RzOverTimeDetail;
@ -12,7 +11,7 @@ import java.util.List;
* @author chenyj * @author chenyj
* @date 2024-09-09 * @date 2024-09-09
*/ */
public interface IRzOverTimeDetailService extends IService<RzOverTimeDetail> public interface IRzOverTimeDetailService
{ {
/** /**
* 查询加班详情 * 查询加班详情

View File

@ -1,13 +1,9 @@
package com.evo.personnelMatters.service; package com.evo.personnelMatters.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.evo.common.core.domain.AjaxResult; import com.evo.common.core.domain.AjaxResult;
import com.evo.personnelMatters.domain.RzOverTime; import com.evo.personnelMatters.domain.RzOverTime;
import com.evo.personnelMatters.domain.RzOverTimeDetail; import com.evo.personnelMatters.domain.RzOverTimeDetail;
import com.evo.system.domain.SysStaff;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
@ -16,7 +12,7 @@ import java.util.List;
* @author chenyj * @author chenyj
* @date 2024-09-03 * @date 2024-09-03
*/ */
public interface IRzOverTimeService extends IService<RzOverTime> public interface IRzOverTimeService
{ {
/** /**
* 查询加班管理 * 查询加班管理
@ -64,10 +60,4 @@ public interface IRzOverTimeService extends IService<RzOverTime>
* @return * @return
*/ */
public List<RzOverTimeDetail> selectRzOverTimeDetailListByUserIdAndMonth(RzOverTime rzOverTime); public List<RzOverTimeDetail> selectRzOverTimeDetailListByUserIdAndMonth(RzOverTime rzOverTime);
public RzOverTime selectRzOverTimeByNameAndMonth(Long userId, Date overTimeMonth);
public String overTimeCard(SysStaff sysStaff, Date overTimeMonth);
public String overTimeOffDutyCard(SysStaff sysStaff , Date date, String sn);
} }

View File

@ -2,7 +2,6 @@ package com.evo.personnelMatters.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.common.annotation.DataScope; import com.evo.common.annotation.DataScope;
import com.evo.common.constant.Constants; import com.evo.common.constant.Constants;
import com.evo.common.core.domain.AjaxResult; import com.evo.common.core.domain.AjaxResult;
@ -30,7 +29,7 @@ import java.util.List;
* @date 2024-08-03 * @date 2024-08-03
*/ */
@Service @Service
public class RzLeaveServiceImpl extends ServiceImpl<RzLeaveMapper, RzLeave> implements IRzLeaveService public class RzLeaveServiceImpl implements IRzLeaveService
{ {
@Resource @Resource
private RzLeaveMapper rzLeaveMapper; private RzLeaveMapper rzLeaveMapper;
@ -161,9 +160,4 @@ public class RzLeaveServiceImpl extends ServiceImpl<RzLeaveMapper, RzLeave> impl
wa.like(StringUtils.isNotBlank(rzLeave.getDeptName()),RzLeave::getDeptName,rzLeave.getDeptName()); wa.like(StringUtils.isNotBlank(rzLeave.getDeptName()),RzLeave::getDeptName,rzLeave.getDeptName());
return rzLeaveMapper.selectList(wa); return rzLeaveMapper.selectList(wa);
} }
@Override
public RzLeave selectRzLeaveByUserId(Long userId) {
return getBaseMapper().queryRzLeaveByUserId(userId);
}
} }

View File

@ -1,6 +1,5 @@
package com.evo.personnelMatters.service.impl; package com.evo.personnelMatters.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.attendance.domain.RzAttendance; import com.evo.attendance.domain.RzAttendance;
import com.evo.attendance.domain.RzAttendanceDetail; import com.evo.attendance.domain.RzAttendanceDetail;
import com.evo.attendance.mapper.RzAttendanceDetailMapper; import com.evo.attendance.mapper.RzAttendanceDetailMapper;
@ -35,7 +34,7 @@ import java.util.List;
* @date 2024-09-09 * @date 2024-09-09
*/ */
@Service @Service
public class RzOverTimeDetailServiceImpl extends ServiceImpl<RzOverTimeDetailMapper, RzOverTimeDetail> implements IRzOverTimeDetailService public class RzOverTimeDetailServiceImpl implements IRzOverTimeDetailService
{ {
@Resource @Resource
private RzOverTimeDetailMapper rzOverTimeDetailMapper; private RzOverTimeDetailMapper rzOverTimeDetailMapper;

View File

@ -1,12 +1,9 @@
package com.evo.personnelMatters.service.impl; package com.evo.personnelMatters.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.attendance.processor.KqUtils;
import com.evo.attendance.processor.PunchTheClockStrategyExchangeProcessor;
import com.evo.common.annotation.DataScope; import com.evo.common.annotation.DataScope;
import com.evo.common.constant.Constants; import com.evo.common.constant.Constants;
import com.evo.common.core.domain.AjaxResult; import com.evo.common.core.domain.AjaxResult;
import com.evo.common.utils.DataUtils;
import com.evo.common.utils.DateUtils; import com.evo.common.utils.DateUtils;
import com.evo.common.utils.SecurityUtils; import com.evo.common.utils.SecurityUtils;
import com.evo.common.utils.StringUtils; import com.evo.common.utils.StringUtils;
@ -18,12 +15,10 @@ import com.evo.personnelMatters.service.IRzOverTimeService;
import com.evo.system.domain.SysStaff; import com.evo.system.domain.SysStaff;
import com.evo.system.mapper.SysDeptMapper; import com.evo.system.mapper.SysDeptMapper;
import com.evo.system.mapper.SysStaffMapper; import com.evo.system.mapper.SysStaffMapper;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
@ -156,77 +151,5 @@ public class RzOverTimeServiceImpl extends ServiceImpl<RzOverTimeMapper, RzOverT
return res_list; return res_list;
} }
@Override
public RzOverTime selectRzOverTimeByNameAndMonth(Long userId, Date overTimeMonth) {
return getBaseMapper().selectRzOverTimeByNameAndMonth(userId, overTimeMonth);
}
@Override
public String overTimeCard(SysStaff sysStaff, Date overTimeMonth) {
//判断打卡月是否统计过加班
RzOverTime rzOverTime = getBaseMapper().selectRzOverTimeByNameAndMonth(sysStaff.getUserId(),overTimeMonth);
if(rzOverTime == null){
rzOverTime = new RzOverTime();
rzOverTime.setUserId(sysStaff.getUserId());
rzOverTime.setOverHours(new BigDecimal("0.0"));
rzOverTime.setDeptId(sysStaff.getDeptId());
rzOverTime.setName(sysStaff.getName());
rzOverTime.setOverTimeMonth(overTimeMonth);
if(getBaseMapper().insert(rzOverTime) < 1){
return PunchTheClockStrategyExchangeProcessor.initStaticMessage(1, "打卡失败");
}
}
RzOverTimeDetail rzOverTimeDetail = new RzOverTimeDetail();
rzOverTimeDetail.setOverTimeId(rzOverTime.getId());
rzOverTimeDetail.setOverTimeStart(overTimeMonth);
rzOverTimeDetail.setName(sysStaff.getName());
rzOverTimeDetail.setDelFlag(Constants.DELETE_FLAG_0);
rzOverTimeDetail.setCreateBy("admin");
rzOverTimeDetail.setCreateTime(DateUtils.getNowDate());
return (rzOverTimeDetailMapper.insert(rzOverTimeDetail) < 1) ? PunchTheClockStrategyExchangeProcessor.initStaticMessage(1, "打卡失败") : PunchTheClockStrategyExchangeProcessor.initStaticMessage(0, "打卡成功");
}
@Override
public String overTimeOffDutyCard(SysStaff sysStaff, Date date, String sn) {
//修改加班打卡记录 根据员工ID和时间查找 统计数据
RzOverTime rzOverTime = getBaseMapper().selectRzOverTimeByNameAndMonth(sysStaff.getUserId(),date);
//如果没有加班汇总, 生成一条新的
if(ObjectUtils.isEmpty(rzOverTime)){
rzOverTime = new RzOverTime();
rzOverTime.setUserId(sysStaff.getUserId());
rzOverTime.setDeptId(sysStaff.getDeptId());
rzOverTime.setName(sysStaff.getName());
rzOverTime.setOverTimeMonth(date);
rzOverTime.setOverHours(DataUtils.DEFAULT_VALUE);
rzOverTime.setDelFlag(Constants.DELETE_FLAG_0);
rzOverTime.setCreateBy("admin");
rzOverTime.setCreateTime(new Date());
getBaseMapper().insert(rzOverTime);
}
//查找加班详情 加班统计ID和加班开始时间
RzOverTimeDetail rzOverTimeDetail = rzOverTimeDetailMapper.queryRzOverTimeDetailByDateAndOverId(rzOverTime.getId(),date);
if(ObjectUtils.isEmpty(rzOverTimeDetail)){
//特殊情况, 会存在过12点的情况, 这时候需要核查下前一天没有下班的加班数据
rzOverTimeDetail = rzOverTimeDetailMapper.queryRzOverTimeDetailByDateAndOverIdAndOverTimeEndIsNull(rzOverTime.getId(), DateUtils.addDays(date,-1));
//如果前一天也为空
if(ObjectUtils.isEmpty(rzOverTimeDetail)){
return PunchTheClockStrategyExchangeProcessor.initStaticMessage(1, "未找到当天的加班信息, 请补卡");
}
}
rzOverTimeDetail.setOverTimeEnd(date);
//计算加班时长 分钟
KqUtils.calculateOverTimeHours(rzOverTimeDetail, sysStaff.getUserId(), sn);
if(rzOverTimeDetailMapper.updateRzOverTimeDetail(rzOverTimeDetail) < 1){
return PunchTheClockStrategyExchangeProcessor.initStaticMessage(1, "打卡失败");
}
//加班修改统计
rzOverTime.setOverHours(rzOverTime.getOverHours().add(rzOverTimeDetail.getOverTimeHours()));
if(getBaseMapper().updateRzOverTime(rzOverTime) < 1){
return PunchTheClockStrategyExchangeProcessor.initStaticMessage(1, "打卡失败");
}
return PunchTheClockStrategyExchangeProcessor.initStaticMessage(0, "打卡成功");
}
} }

View File

@ -8,7 +8,8 @@ import com.evo.common.core.domain.entity.SysDictData;
* *
* @author evo * @author evo
*/ */
public interface ISysDictDataService { public interface ISysDictDataService
{
/** /**
* 根据条件分页查询字典数据 * 根据条件分页查询字典数据
* *
@ -65,11 +66,4 @@ public interface ISysDictDataService {
* @return 结果 * @return 结果
*/ */
public int updateDictData(SysDictData dictData); public int updateDictData(SysDictData dictData);
/**
* 根据条件分页查询字典数据
*
* @return 字典数据集合信息
*/
public List<SysDictData> selectDictDataListByType(String type);
} }

View File

@ -108,18 +108,13 @@ public interface ISysStaffService extends IService<SysStaff>
* @param userId 重新入职员工Id * @param userId 重新入职员工Id
*/ */
AjaxResult reEmployment(Long userId); AjaxResult reEmployment(Long userId);
/*** /***
* 数据导出 * 数据导出
* @param response * @param response
* @param sysStaff * @param sysStaff
*/ */
void exportInfo(HttpServletResponse response, SysStaff sysStaff); void exportInfo(HttpServletResponse response, SysStaff sysStaff);
/**
* 根据钉钉id 查询员工信息
*
* @param dingUserId 钉钉userId
* @return 员工管理
*/
public SysStaff selectSysStaffByDingUserId(String dingUserId);
} }

View File

@ -117,9 +117,4 @@ public class SysDictDataServiceImpl extends ServiceImpl<SysDictDataMapper, SysDi
} }
return row; return row;
} }
@Override
public List<SysDictData> selectDictDataListByType(String type) {
return getBaseMapper().selectDictDataByType(type);
}
} }

View File

@ -838,9 +838,4 @@ public class SysStaffServiceImpl extends ServiceImpl<SysStaffMapper, SysStaff> i
ExcelUtil1<SysStaffVo> util = new ExcelUtil1<SysStaffVo>(SysStaffVo.class); ExcelUtil1<SysStaffVo> util = new ExcelUtil1<SysStaffVo>(SysStaffVo.class);
util.exportExcel(response, res_list, "员工信息"); util.exportExcel(response, res_list, "员工信息");
} }
@Override
public SysStaff selectSysStaffByDingUserId(String dingUserId) {
return getBaseMapper().selectSysStaffByDingUserId(dingUserId);
}
} }

View File

@ -1,86 +0,0 @@
<?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.evo.ding.mapper.DingShiftMapper">
<resultMap type="DingShift" id="DingShiftResult">
<result property="id" column="id" />
<result property="name" column="name" />
<result property="dingId" column="ding_Id" />
<result property="workHour" column="work_Hour" />
<result property="overtimeWork" column="overtime_Work" />
<result property="deductionHour" column="deduction_Hour" />
</resultMap>
<sql id="selectVo">
select id, name, ding_Id, work_Hour, overtime_Work, deduction_Hour from ding_shift
</sql>
<select id="selectByDingId" resultMap="DingShiftResult">
<include refid="selectVo"/>
where ding_id = #{dingId}
</select>
<!-- <select id="selectEqButtonList" parameterType="EqButton" resultMap="EqButtonResult">-->
<!-- <include refid="selectEqButtonVo"/>-->
<!-- <where>-->
<!-- del_flag = '0'-->
<!-- <if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if>-->
<!-- </where>-->
<!-- order by num asc-->
<!-- </select>-->
<!-- <select id="selectEqButtonById" parameterType="Long" resultMap="EqButtonResult">-->
<!-- <include refid="selectEqButtonVo"/>-->
<!-- where id = #{id}-->
<!-- </select>-->
<!-- <insert id="insertEqButton" parameterType="EqButton" useGeneratedKeys="true" keyProperty="id">-->
<!-- insert into eq_button-->
<!-- <trim prefix="(" suffix=")" suffixOverrides=",">-->
<!-- <if test="num != null">num,</if>-->
<!-- <if test="name != null">name,</if>-->
<!-- <if test="image != null">image,</if>-->
<!-- <if test="delFlag != null">del_flag,</if>-->
<!-- <if test="remarks != null">remarks,</if>-->
<!-- <if test="createBy != null">create_by,</if>-->
<!-- <if test="createTime != null">create_time,</if>-->
<!-- <if test="updateBy != null">update_by,</if>-->
<!-- <if test="updateTime != null">update_time,</if>-->
<!-- </trim>-->
<!-- <trim prefix="values (" suffix=")" suffixOverrides=",">-->
<!-- <if test="num != null">#{num},</if>-->
<!-- <if test="name != null">#{name},</if>-->
<!-- <if test="image != null">#{image},</if>-->
<!-- <if test="delFlag != null">#{delFlag},</if>-->
<!-- <if test="remarks != null">#{remarks},</if>-->
<!-- <if test="createBy != null">#{createBy},</if>-->
<!-- <if test="createTime != null">#{createTime},</if>-->
<!-- <if test="updateBy != null">#{updateBy},</if>-->
<!-- <if test="updateTime != null">#{updateTime},</if>-->
<!-- </trim>-->
<!-- </insert>-->
<!-- <update id="updateEqButton" parameterType="EqButton">-->
<!-- update eq_button-->
<!-- <trim prefix="SET" suffixOverrides=",">-->
<!-- <if test="num != null">num = #{num},</if>-->
<!-- <if test="name != null">name = #{name},</if>-->
<!-- <if test="image != null">image = #{image},</if>-->
<!-- <if test="delFlag != null">del_flag = #{delFlag},</if>-->
<!-- <if test="remarks != null">remarks = #{remarks},</if>-->
<!-- <if test="createBy != null">create_by = #{createBy},</if>-->
<!-- <if test="createTime != null">create_time = #{createTime},</if>-->
<!-- <if test="updateBy != null">update_by = #{updateBy},</if>-->
<!-- <if test="updateTime != null">update_time = #{updateTime},</if>-->
<!-- </trim>-->
<!-- where id = #{id}-->
<!-- </update>-->
<!-- &lt;!&ndash; 根据名称查询信息 &ndash;&gt;-->
<!-- <select id="selectEqButtonByName" parameterType="String" resultMap="EqButtonResult">-->
<!-- <include refid="selectEqButtonVo"/>-->
<!-- where del_flag = '0' and name = #{name}-->
<!-- </select>-->
</mapper>

View File

@ -106,7 +106,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
from rz_leave_detail d left join rz_leave l on d.leave_id = l.id from rz_leave_detail d left join rz_leave l on d.leave_id = l.id
where l.user_id = #{userId} where l.user_id = #{userId}
and l.del_flag = '0' and l.del_flag = '0'
and d.del_flag = '0'
and DATE_FORMAT( d.leave_start_time, '%Y%m%d' ) &lt;= DATE_FORMAT(#{date} , '%Y%m%d' ) and DATE_FORMAT( d.leave_start_time, '%Y%m%d' ) &lt;= DATE_FORMAT(#{date} , '%Y%m%d' )
and DATE_FORMAT( d.leave_end_time, '%Y%m%d' ) &gt;= DATE_FORMAT(#{date} , '%Y%m%d' ) and DATE_FORMAT( d.leave_end_time, '%Y%m%d' ) &gt;= DATE_FORMAT(#{date} , '%Y%m%d' )

View File

@ -116,10 +116,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where del_flag = '0' and DATE_FORMAT( leave_date, '%Y%m' ) = DATE_FORMAT( #{date} , '%Y%m' ) and user_id = #{userId} where del_flag = '0' and DATE_FORMAT( leave_date, '%Y%m' ) = DATE_FORMAT( #{date} , '%Y%m' ) and user_id = #{userId}
</select> </select>
<select id="queryRzLeaveByUserId" resultMap="RzLeaveResult">
<include refid="selectRzLeaveVo"/>
where del_flag = '0' and user_id = #{userId} order by create_time desc limit 1
</select>
</mapper> </mapper>