考勤统计新增汇总导入接口

员工信息试用期月份改为试用期结束时间, 并同步调整考勤计算规则, 转正规则等接口
处理隔夜班制手动重新抓取考勤的负工时问题
This commit is contained in:
andy 2026-09-08 10:06:09 +08:00
parent 770d1fa42c
commit dea7389197
11 changed files with 371 additions and 129 deletions

View File

@ -1,5 +1,7 @@
package com.evo.attendance.controller; package com.evo.attendance.controller;
import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.attendance.service.IRzAttendanceStatisticalService;
import com.evo.common.annotation.Log; import com.evo.common.annotation.Log;
import com.evo.common.annotation.RepeatSubmit; import com.evo.common.annotation.RepeatSubmit;
import com.evo.common.constant.HttpStatus; import com.evo.common.constant.HttpStatus;
@ -10,14 +12,14 @@ import com.evo.common.enums.BusinessType;
import com.evo.common.utils.ParamUtils; import com.evo.common.utils.ParamUtils;
import com.evo.common.utils.StringUtils; import com.evo.common.utils.StringUtils;
import com.evo.common.utils.poi.ExcelUtil; import com.evo.common.utils.poi.ExcelUtil;
import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.attendance.service.IRzAttendanceStatisticalService;
import com.evo.finance.service.IRzSalaryStatisticsService; import com.evo.finance.service.IRzSalaryStatisticsService;
import com.evo.system.domain.vo.RzAttendanceStatisticalTemplate;
import com.evo.system.service.ISysStatisticalOperationLogService; import com.evo.system.service.ISysStatisticalOperationLogService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -114,11 +116,17 @@ public class RzAttendanceStatisticalController extends BaseController
@PostMapping("/importData") @PostMapping("/importData")
public AjaxResult importData(MultipartFile file) throws Exception public AjaxResult importData(MultipartFile file) throws Exception
{ {
ExcelUtil<RzAttendanceStatistical> util = new ExcelUtil<RzAttendanceStatistical>(RzAttendanceStatistical.class); ExcelUtil<RzAttendanceStatisticalTemplate> util = new ExcelUtil<RzAttendanceStatisticalTemplate>(RzAttendanceStatisticalTemplate.class);
List<RzAttendanceStatistical> attList = util.importExcel(file.getInputStream()); List<RzAttendanceStatisticalTemplate> attList = util.importExcel(file.getInputStream());
return rzAttendanceStatisticalService.importRzAttendanceStatistical(attList); return rzAttendanceStatisticalService.importRzAttendanceStatistical(attList);
} }
@PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response) {
ExcelUtil<RzAttendanceStatisticalTemplate> util = new ExcelUtil<RzAttendanceStatisticalTemplate>(RzAttendanceStatisticalTemplate.class);
util.importTemplateExcel(response, "考勤统计模版");
}
/** /**
* 获取考勤统计的操作记录 * 获取考勤统计的操作记录
*/ */

View File

@ -63,5 +63,5 @@ public interface RzAttendanceStatisticalMapper extends BaseMapper<RzAttendanceSt
public List<RzAttendanceStatistical> queryStatisticalByMonth(Date month); public List<RzAttendanceStatistical> queryStatisticalByMonth(Date month);
RzAttendanceStatistical selectRzAttendanceStatisticalByIdCardAndMonth(@Param("idCard")String idCard, @Param("month")Date month);
} }

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.evo.attendance.domain.RzAttendanceStatistical; import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.common.core.domain.AjaxResult; import com.evo.common.core.domain.AjaxResult;
import com.evo.system.domain.SysStaff; import com.evo.system.domain.SysStaff;
import com.evo.system.domain.vo.RzAttendanceStatisticalTemplate;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -50,7 +51,7 @@ public interface IRzAttendanceStatisticalService extends IService<RzAttendanceSt
* @param list * @param list
* @return * @return
*/ */
public AjaxResult importRzAttendanceStatistical(List<RzAttendanceStatistical> list); public AjaxResult importRzAttendanceStatistical(List<RzAttendanceStatisticalTemplate> list);
/*** /***
* 生成考勤信息 * 生成考勤信息

View File

@ -614,7 +614,7 @@ public class RzAttendanceServiceImpl extends ServiceImpl<RzAttendanceMapper, RzA
//判断打卡时间, 添加夜班次数 打卡时间在晚上7点以后 //判断打卡时间, 添加夜班次数 打卡时间在晚上7点以后
if(dingsShift.getWorkHour() == 12 && attendance.getWorkSum().intValue() >= 12 && attendance.getWorkStartTime()!= null && attendance.getWorkStartTime().getHours() > 12){ if(dingsShift.getWorkHour() == 12 && attendance.getWorkSum().intValue() >= 12 && attendance.getWorkStartTime()!= null && attendance.getWorkStartTime().getHours() > 12){
attendance.setNightNumber(1); attendance.setNightNumber(1);
//必须是8小时倒班制or单班制, 并且工作时长>=8小时, 并且 上班打开时间在12点至21点 算作中班 -- 2026-02-04 因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){ }else if(dingsShift.getWorkHour() == 8 && attendance.getWorkSum().intValue() >= 8 && attendance.getWorkStartTime() != null && attendance.getWorkStartTime().getHours() >= 12 && attendance.getWorkStartTime().getHours() < 21){
attendance.setMiddleShiftNumber(1); attendance.setMiddleShiftNumber(1);
} }
@ -649,11 +649,30 @@ public class RzAttendanceServiceImpl extends ServiceImpl<RzAttendanceMapper, RzA
try { try {
JSONArray jsonArray = resultJson.getJSONArray("recordresult"); JSONArray jsonArray = resultJson.getJSONArray("recordresult");
JSONObject onDutyObject = (JSONObject) jsonArray.stream().filter(data -> "OnDuty".equals(((JSONObject)data).getString("checkType"))).findFirst().orElse(null); JSONObject onDutyObject = (JSONObject) jsonArray.stream().filter(data -> "OnDuty".equals(((JSONObject)data).getString("checkType"))).findFirst().orElse(null);
Long startTime = null;
if(onDutyObject != null){ if(onDutyObject != null){
startTime = onDutyObject.getLong("workDate");
calculationAddRzOverTime(result, sysStaff, onDutyObject, attendance); calculationAddRzOverTime(result, sysStaff, onDutyObject, attendance);
} }
JSONObject offDutyObject = (JSONObject) jsonArray.stream().filter(data -> "OffDuty".equals(((JSONObject)data).getString("checkType"))).findFirst().orElse(null); JSONObject offDutyObject = (JSONObject) jsonArray.stream().filter(data -> "OffDuty".equals(((JSONObject)data).getString("checkType"))).findFirst().orElse(null);
if(offDutyObject != null){ if(offDutyObject != null){
Long endDate = offDutyObject.getLong("workDate");
//如果出现下班时间, 比上班时间早, 默认为隔夜打卡, 需要获取后一天的下班时间
if(startTime != null && endDate != null && endDate < startTime){
result = DingUtils.getListRecord(Collections.asList(sysStaff.getDingUserId()), DateUtils.parseDateToStr("yyyy-MM-dd", DateUtils.addDays(attendance.getAttendanceDate(), 1))+" 00:00:00", DateUtils.parseDateToStr("yyyy-MM-dd", DateUtils.addDays(attendance.getAttendanceDate(), 1))+" 23:59:59");
resultJson = JSON.parseObject(result);
if(Integer.valueOf(0).equals(resultJson.getInteger("errcode"))){
try {
jsonArray = resultJson.getJSONArray("recordresult");
offDutyObject = (JSONObject) jsonArray.stream().filter(data -> "OffDuty".equals(((JSONObject)data).getString("checkType"))).findFirst().orElse(null);
} catch (Exception e) {
e.printStackTrace();
log.error("重新抓取钉钉考勤获取隔夜打卡结果异常, 异常原因是==>>{}, 打卡结果是=====>>>>> {}", e.getMessage(), result);
}
}
}
calculationAddRzOverTime(result, sysStaff, offDutyObject, attendance); calculationAddRzOverTime(result, sysStaff, offDutyObject, attendance);
} }
} catch (Exception e) { } catch (Exception e) {

View File

@ -1,5 +1,6 @@
package com.evo.attendance.service.impl; package com.evo.attendance.service.impl;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.attendance.domain.RzAttendance; import com.evo.attendance.domain.RzAttendance;
@ -14,13 +15,20 @@ import com.evo.common.annotation.StatisticalOperationLog;
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.core.domain.entity.SysDept; import com.evo.common.core.domain.entity.SysDept;
import com.evo.common.core.domain.model.LoginUser;
import com.evo.common.utils.*; import com.evo.common.utils.*;
import com.evo.common.utils.bean.BeanUtils;
import com.evo.framework.aspectj.StatisticalOperationAspect;
import com.evo.personnelMatters.domain.RzOverTime; import com.evo.personnelMatters.domain.RzOverTime;
import com.evo.personnelMatters.mapper.RzLeaveDetailMapper; import com.evo.personnelMatters.mapper.RzLeaveDetailMapper;
import com.evo.personnelMatters.mapper.RzOverTimeDetailMapper; import com.evo.personnelMatters.mapper.RzOverTimeDetailMapper;
import com.evo.personnelMatters.mapper.RzOverTimeMapper; import com.evo.personnelMatters.mapper.RzOverTimeMapper;
import com.evo.system.domain.SysStaff; import com.evo.system.domain.SysStaff;
import com.evo.system.domain.SysStatisticalOperationLog;
import com.evo.system.domain.vo.RzAttendanceStatisticalTemplate;
import com.evo.system.mapper.SysDeptMapper; import com.evo.system.mapper.SysDeptMapper;
import com.evo.system.mapper.SysStatisticalOperationLogMapper;
import com.evo.system.service.ISysStatisticalOperationLogService;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -58,7 +66,8 @@ public class RzAttendanceStatisticalServiceImpl extends ServiceImpl<RzAttendance
@Resource @Resource
private IRzSysParamService rzSysParamService; //部门 private IRzSysParamService rzSysParamService; //部门
@Resource
private SysStatisticalOperationLogMapper sysStatisticalOperationLogMapper;
/** /**
* 查询考勤统计 * 查询考勤统计
* *
@ -148,16 +157,46 @@ public class RzAttendanceStatisticalServiceImpl extends ServiceImpl<RzAttendance
* @return * @return
*/ */
@Override @Override
public AjaxResult importRzAttendanceStatistical(List<RzAttendanceStatistical> list){ @Transactional(rollbackFor = Exception.class)
public AjaxResult importRzAttendanceStatistical(List<RzAttendanceStatisticalTemplate> list){
if(list == null || list.size() == 0){ if(list == null || list.size() == 0){
return AjaxResult.error("导入数据为空!!"); return AjaxResult.error("导入数据为空!!");
} }
for (RzAttendanceStatistical rzAttendanceStatistical : list) { // 获取当前的用户
getBaseMapper().updateRzAttendanceStatistical(rzAttendanceStatistical); LoginUser loginUser = SecurityUtils.getLoginUser();
for (RzAttendanceStatisticalTemplate template : list) {
RzAttendanceStatistical rzAttendanceStatistical = getBaseMapper().selectRzAttendanceStatisticalByIdCardAndMonth(template.getIdCard(), template.getMonth());
SysStatisticalOperationLog log = getLog(loginUser,rzAttendanceStatistical);
log.setOldInfo(StringUtils.substring(JSON.toJSONString(rzAttendanceStatistical), 0, 2000));
BeanUtils.copyProperties(template,rzAttendanceStatistical);
if(getBaseMapper().updateRzAttendanceStatistical(rzAttendanceStatistical) > 0){
log.setNewInfo(StringUtils.substring(JSON.toJSONString(rzAttendanceStatistical), 0, 2000));
sysStatisticalOperationLogMapper.insert(log);
}
} }
return AjaxResult.success("导入数据成功!!"); return AjaxResult.success("导入数据成功!!");
} }
SysStatisticalOperationLog getLog(LoginUser loginUser, RzAttendanceStatistical rzAttendanceStatistical ){
SysStatisticalOperationLog sysStatisticalOperationLog = new SysStatisticalOperationLog();
if (loginUser != null)
{
sysStatisticalOperationLog.setOperationAccount(loginUser.getUsername());
sysStatisticalOperationLog.setOperationTime(new Date());
}
sysStatisticalOperationLog.setMonth(rzAttendanceStatistical.getMonth());
sysStatisticalOperationLog.setBusinessName(rzAttendanceStatistical.getName());
sysStatisticalOperationLog.setBusinessId(rzAttendanceStatistical.getId());
if(sysStatisticalOperationLog.getBusinessId() == null){
sysStatisticalOperationLog.setNewInfo(StringUtils.substring(JSON.toJSONString(rzAttendanceStatistical), 0, 2000));
}
return sysStatisticalOperationLog;
}
@Override @Override
@Transactional @Transactional
public RzAttendanceStatistical createRzAttendance(SysStaff sysStaff, List<String> dayList, Date date) { public RzAttendanceStatistical createRzAttendance(SysStaff sysStaff, List<String> dayList, Date date) {

View File

@ -587,64 +587,157 @@ public class TestController {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
String str = "郝卫明,8000;" + String str = "贾肖,13920,130184199005264914;" +
"郝亮,1500;" + "康璐,7920,133001197912150221;" +
"柳晓龙,1300;" + "梁彩乐,1420,130132199307211942;" +
"王旭,800;" + "付多利,12920,211022197012194413;" +
"张克龙,1500;" + "张振立,120,132331197101062854;" +
"贾会涛,500;" + "郎夕倩,2420,130124198504292425;" +
"李凯伟,2500;" + "林晓路,3420,130124199309082718;" +
"石泽明,500;" + "葛闯,3420,13068319930903801X;" +
"马明广,500;" + "李启帆,3420,130124199409122430;" +
"宋金娜,800;" + "高影,2920,13012419880927464X;" +
"吴海庆,318;" + "郭旭冉,2420,130132198903011643;" +
"冯翠莎,500;" + "王哲雷,7920,130132198407281687;" +
"赵科飞,1000;" + "李虹亮,2420,130132198907300020;" +
"李进江,431;" + "肖大永,13920,130228197901234815;" +
"李佳铭,1000;" + "陈美宇,6920,130684199105252299;" +
"耿利刚,100;" + "何瑞社,120,132331196610112819;" +
"张雨轩,400;" + "王金斗,17920,130682198104093831;" +
"李永文,1000;" + "康泽松,2420,130132200508260033;" +
"代程翼,900;" + "王晓婷,2420,130132199209052861;" +
"李晓亮,800;" + "张若航,2420,130132200307144116;" +
"李兴酉,800;" + "黄新梅,2420,130125198808301526;" +
"王晓凡,800;" + "李伟腾,4920,130132200002182904;" +
"董献召,354;" + "宋怡然,2420,130129200312292123;" +
"王晓军,300;" + "李泽宇,2420,130132200306101317;" +
"苏冰,2000;" + "庞蒂,2420,210921199507095741;" +
"吴建彬,500;" + "张开源,3420,13013019970707063X;" +
"王怀志,1000;" + "李涵洋,2420,130132200602043174;" +
"张广适,400;" + "刘立业,2920,130104199802160614;" +
"赵兰争,800;" + "张涛,7920,130103197701221216;" +
"齐乐芳,500;" + "刘少磊,2920,130124199908182411;" +
"魏佳蕊,500;" + "苏冰,6420,130522198607120019;" +
"范会雨,424;" + "殷立海,120,13233119680929287X;" +
"康坤兰,500;" + "来雯慧,3920,61042520030206304X;" +
"牛立革,600;" + "薛浩远,2920,130133199803112114;" +
"付佳兴,265;" + "张安玲,7920,130123199005030023;" +
"游梦浩,277;" + "郭江伟,2170,130107199102251514;" +
"魏辰强,500;" + "夏凌侠,8920,13118119851104193X;" +
"吴凯亮,400;" + "赵亚东,7670,130682198406176317;" +
"董亚军,500;" + "王若兵,3220,130132200211203812;" +
"赵雄飞,1000;" + "陈凌志,3920,130732200412172939;" +
"宁世汉,351;" + "陶佳毅,3920,130429200409253581;" +
"张会杰,500;" + "尹双双,3920,410923200402064266;" +
"王光磊,207;" + "邓锋,8220,130103198712091511;" +
"梅丙立,189;" + "张凡,3420,610523199909296314;" +
"李泽宇,200;" + "李德山,18370,130635198110164996;" +
"印子鹏,100;" + "王永鹏,7170,130185198602273714;" +
"李雷升,100;" + "李佳铭,2170,130132200212110052;" +
"杨策,305;" + "陈明修,10870,130602199103150315;" +
"赵芊慧,200;" + "冯春芳,10270,132201199401243521;" +
"朱海斌,100;" + "王亚丝,3220,130124199411152786;" +
"李彦辉,100;" + "赵秀娟,2070,130124198206180927;" +
"李增全,200;" + "胡庆伟,18370,211222197510192032;" +
"靳立节,100"; "王雨晨,3220,130107199807060312;" +
"张学勇,3370,130622200309015814;" +
"刘帅,3920,13108120011122001X;" +
"杨宇荣,6920,370921199912293922;" +
"张蝶,7920,120223199902042706;" +
"程才,7920,511324200004107855;" +
"钟铃,3770,430581200308011526;" +
"李宇萌,4420,130628200111056627;" +
"贾彦冲,3920,130431200010102134;" +
"卢敬烨,3370,130430200310141710;" +
"余红清,4420,411324200302024042;" +
"王浩,6220,130184200002205711;" +
"李春草,3770,230802200404083224;" +
"王雪宇,3920,130825200206212911;" +
"张新怡,2220,131127200012036222;" +
"郝晓娟,2770,130121198911161423;" +
"安宏生,2370,130825200111035713;" +
"史国臣,10920,131122199402103219;" +
"王申,10220,130103199209151518;" +
"赵燕花,12920,130105197903090923;" +
"赵力强,7920,132326197806181115;" +
"张晓龙,9720,130133198801192451;" +
"张向月,9920,130183198510120152;" +
"赵晓,10070,130183199511121733;" +
"赵芬静,2720,130132200109252589;" +
"张荣山,18920,41272419901002155X;" +
"郑杰,2870,130426199310292324;" +
"赵世通,4920,131122200212062255;" +
"尹国峰,9920,130121198512011612;" +
"魏步锋,12920,130103197303040030;" +
"王静文,3920,130124198608060071;" +
"杨文夺,8770,130524199308192511;" +
"田志阳,8920,13012119970707241X;" +
"张敏,27920,130105197401210948;" +
"田迎州,7920,130183199209261030;" +
"田英泽,8070,130132198605080018;" +
"尹运书,320,132331196308112850;" +
"檀亚茹,2670,130124199008242423;" +
"位晓峰,3900,130132199211012877;" +
"苏智鹏,2170,230225199412174536;" +
"王旭得,3220,130132200008060078;" +
"王倩,3420,130683198607126021;" +
"徐胜盼,8870,130182198905185317;" +
"苏硕,7920,130132199302161958;" +
"王晓丛,2670,130132199408014104;" +
"王文超,2570,130133200310292415;" +
"张家乐,4420,13012919991221211X;" +
"姚晓骞,5620,130182198711054888;" +
"张茜,2670,130132198903184106;" +
"秦立志,6520,130503197711180333;" +
"马杰,12920,132926197708050376;" +
"李宏叶,2720,130132198902060021;" +
"李会召,7470,13013219870403317X;" +
"李子权,5070,130130198909182774;" +
"刘皓男,7920,13063419930602001X;" +
"刘建斌,3470,130105196908150919;" +
"刘冉,4420,130125199305200023;" +
"吕松林,3920,130130198912281837;" +
"马君君,3070,130133199005203011;" +
"南正一,18270,222426198009120012;" +
"孔德鹏,8220,130106198610102418;" +
"李中胜,22920,211322199007056791;" +
"李欣,3070,130132199103134105;" +
"李瑞娜,9920,130435198708052322;" +
"李东辉,3920,130533200012241216;" +
"南泽林,4920,130627200109140612;" +
"栗巍,4920,13012320000715544X;" +
"刘杰,2420,130124199810072425;" +
"郝卫明,4045,130105197803021517;" +
"何旭阳,7470,130132199711062870;" +
"曹立洋,5470,130132198905233493;" +
"郭磊,4970,211421199110040412;" +
"陈士田,8920,371325198002112714;" +
"胡毅鹏,27920,130104199101032433;" +
"崔佳佩,2670,130132198602261323;" +
"杜惠斌,37770,372901198910196637;" +
"耿长胜,8170,133022198108151510;" +
"贺光建,4270,130528198608083019;" +
"杜晓华,3970,130132198402093804;" +
"康会雪,3870,13013219900203288X;" +
"段晓滨,4370,131181200110281510;" +
"蔡亚光,18270,130104198201291817;" +
"董辰龙,2220,130528200005250033;" +
"郭亚曼,2670,130429199103228441;" +
"次泽召,7020,130132198906230032;" +
"次江波,5670,13012419870713243X;" +
"韩家明,3220,130132200108222871;" +
"胡鹏,6920,130133198709111612;" +
"高俊鹏,5720,130533199710163512;" +
"范运斌,4170,130928200303095010;" +
"毕敏霞,4270,130107199011101529";
String[] aa = str.split(";"); String[] aa = str.split(";");
for (int i = 0; i < aa.length; i++) { for (int i = 0; i < aa.length; i++) {
String a = aa[i].trim(); String a = aa[i].trim();
String[] ss = a.split(","); String[] ss = a.split(",");
System.out.println("CALL `修改其他补助`('"+ss[0]+"', "+ss[1]+");");
System.out.println("update sys_staff_detail ssd left join sys_staff ss on ss.user_id = ssd.staff_id set ssd.jobs_salary = "+ss[1]+" where ss.id_card = '"+ss[2]+"';");
// System.out.println("CALL `修改其他补助`('"+ss[0]+"', "+ss[1]+");");
// System.out.println("INSERT INTO `evo_cw_dev`.`sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) " + // System.out.println("INSERT INTO `evo_cw_dev`.`sys_dict_data` (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) " +
// "VALUES ( "+(sort++)+", '"+ss[1]+"', '"+ss[0]+"_"+ss[2]+"', 'job_info', NULL, 'default', 'N', '0', 'admin', now(), '', NULL, NULL);"); // "VALUES ( "+(sort++)+", '"+ss[1]+"', '"+ss[0]+"_"+ss[2]+"', 'job_info', NULL, 'default', 'N', '0', 'admin', now(), '', NULL, NULL);");

View File

@ -90,7 +90,7 @@ public interface SalaryCalculationStrategyExchangeProcessor {
* @param rzSalaryDetail * @param rzSalaryDetail
*/ */
default void buildRzSalaryDetail(Boolean isMonth, SysStaff sysStaff, SysStaffDetail detail, RzSalaryDetail rzSalaryDetail, RzAttendanceStatistical attendanceStatistical){ default void buildRzSalaryDetail(Boolean isMonth, SysStaff sysStaff, SysStaffDetail detail, RzSalaryDetail rzSalaryDetail, RzAttendanceStatistical attendanceStatistical){
Date limitDate = DateUtils.addMonths(sysStaff.getEmploymentDate(), Integer.valueOf(String.valueOf(sysStaff.getWorkerTerm()))); Date limitDate = sysStaff.getRegularDate(); //DateUtils.addMonths(sysStaff.getEmploymentDate(), Integer.valueOf(String.valueOf(sysStaff.getWorkerTerm())));
Date limitMonth = null; Date limitMonth = null;
Date month = null; Date month = null;
try { try {

View File

@ -0,0 +1,63 @@
package com.evo.system.domain.vo;
import com.evo.common.annotation.Excel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* @desc:
* @ClassName:RzAttendanceStatisticalTemplate
* @date: 2026年09月01日 14:51
* @company: 茹臣科技
* @author: andy.shi
* @contact: 17330188597
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Data
public class RzAttendanceStatisticalTemplate {
@Excel(name = "* 身份证号")
private String idCard;
/** 所属月份 */
@Excel(name = "所属月份", width = 30, dateFormat = "yyyy-MM")
@JsonFormat(pattern = "yyyy-MM")
private Date month;
/** 应出勤(小时) */
@Excel(name = "应出勤(小时)")
private BigDecimal shouldAttendance;
/** 实出勤(小时) */
@Excel(name = "实出勤(小时)")
private BigDecimal realAttendance;
/** 打卡时长(小时) */
@Excel(name = "打卡时长(小时)")
private BigDecimal essentialAttendance;
/** 加班时长(小时) */
@Excel(name = "加班时长(小时)")
private BigDecimal workOvertimeNumber;
/** 请假时长(小时) */
@Excel(name = "请假时长(小时)")
private BigDecimal absenteeism;
/** 特殊加班(小时) */
@Excel(name = "特殊加班(小时)")
private BigDecimal overTimeHours;
/** 异常次数 */
@Excel(name = "异常次数")
private Long lateNumber;
/** 中班次数 */
@Excel(name = "中班次数")
private Long middleShiftNumber;
/** 夜班次数 */
@Excel(name = "夜班次数")
private Long nightNumber;
}

View File

@ -3,12 +3,9 @@ package com.evo.system.service.impl;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.attendance.domain.vo.RzSalaryVo; import com.evo.attendance.domain.vo.RzSalaryVo;
import com.evo.attendance.service.IRzAttendanceStatisticalService; import com.evo.attendance.service.IRzAttendanceStatisticalService;
import com.evo.common.annotation.DataScope; import com.evo.common.annotation.DataScope;
@ -23,8 +20,6 @@ import com.evo.common.utils.bean.BeanUtils;
import com.evo.common.utils.poi.ExcelUtil1; import com.evo.common.utils.poi.ExcelUtil1;
import com.evo.ding.DingUtils; import com.evo.ding.DingUtils;
import com.evo.equipment.service.IEqSnDetailService; import com.evo.equipment.service.IEqSnDetailService;
import com.evo.finance.domain.RzSalaryDetail;
import com.evo.finance.processor.SalaryCalculationStrategyExchangeProcessor;
import com.evo.finance.service.IRzSalaryDetailService; import com.evo.finance.service.IRzSalaryDetailService;
import com.evo.kingdeeUtils.KingdeeRequestUtils; import com.evo.kingdeeUtils.KingdeeRequestUtils;
import com.evo.kingdeeUtils.kenum.KingdeeParamsEnum; import com.evo.kingdeeUtils.kenum.KingdeeParamsEnum;
@ -42,7 +37,6 @@ import com.evo.system.mapper.SysStaffMapper;
import com.evo.system.service.ISysStaffService; import com.evo.system.service.ISysStaffService;
import com.evo.system.service.RzUploadService; import com.evo.system.service.RzUploadService;
import com.evo.system.utils.SubsidyCalculationUtils; import com.evo.system.utils.SubsidyCalculationUtils;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
@ -171,6 +165,12 @@ public class SysStaffServiceImpl extends ServiceImpl<SysStaffMapper, SysStaff> i
//员工编码 //员工编码
sysStaff.setCode(getCodeByCompanyName()); sysStaff.setCode(getCodeByCompanyName());
sysStaff.setSeniority(0l); sysStaff.setSeniority(0l);
//检查转正日期, 是否初始化为试用期
if(sysStaff.getRegularDate().before(DateUtils.getNowDate())){
sysStaff.setStatus(Constants.JOB_STATIS_1);
}else if(sysStaff.getRegularDate().after(DateUtils.getNowDate())){
sysStaff.setStatus(Constants.JOB_STATIS_0);
}
sysStaff.setStatus(Constants.JOB_STATIS_0); sysStaff.setStatus(Constants.JOB_STATIS_0);
sysStaff.setCreateTime(DateUtils.getNowDate()); sysStaff.setCreateTime(DateUtils.getNowDate());
sysStaff.setCreateBy(SecurityUtils.getUsername()); sysStaff.setCreateBy(SecurityUtils.getUsername());
@ -183,12 +183,12 @@ public class SysStaffServiceImpl extends ServiceImpl<SysStaffMapper, SysStaff> i
if(CollectionUtils.isNotEmpty(sysStaff.getTimeClockList())){ if(CollectionUtils.isNotEmpty(sysStaff.getTimeClockList())){
sysStaff.setTimeClock(sysStaff.getTimeClockList().stream().collect(Collectors.joining(","))); sysStaff.setTimeClock(sysStaff.getTimeClockList().stream().collect(Collectors.joining(",")));
} }
// //新增员工信息到金蝶 //新增员工信息到金蝶
// if(StringUtils.isNotEmpty(sysStaff.getJobCode())){ if(StringUtils.isNotEmpty(sysStaff.getJobCode())){
// sysStaff.setExtended(KingdeeRequestUtils.employeeSave(Collections.asMap("userName", sysStaff.getName(), "userCode", sysStaff.getCode(), "jobCode", sysStaff.getJobCode().split("_")[0],"deptCode", sysStaff.getJobCode().split("_")[1]))); sysStaff.setExtended(KingdeeRequestUtils.employeeSave(Collections.asMap("userName", sysStaff.getName(), "userCode", sysStaff.getCode(), "jobCode", sysStaff.getJobCode().split("_")[0],"deptCode", sysStaff.getJobCode().split("_")[1])));
// }else if(StringUtils.isEmpty(sysStaff.getJobCode())){ }else if(StringUtils.isEmpty(sysStaff.getJobCode())){
// sysStaff.setExtended(KingdeeRequestUtils.employeeSaveEmptyJob(Collections.asMap("userName", sysStaff.getName(), "userCode", sysStaff.getCode()))); sysStaff.setExtended(KingdeeRequestUtils.employeeSaveEmptyJob(Collections.asMap("userName", sysStaff.getName(), "userCode", sysStaff.getCode())));
// } }
int i = getBaseMapper().insertSysStaff(sysStaff); int i = getBaseMapper().insertSysStaff(sysStaff);
if(i < 1){ if(i < 1){
@ -251,6 +251,7 @@ public class SysStaffServiceImpl extends ServiceImpl<SysStaffMapper, SysStaff> i
//员工编码 //员工编码
sysStaff.setCode(getCodeByCompanyName()); sysStaff.setCode(getCodeByCompanyName());
sysStaff.setEmploymentDate(new Date()); sysStaff.setEmploymentDate(new Date());
//TODO
sysStaff.setWorkerTerm(1l); sysStaff.setWorkerTerm(1l);
sysStaff.setSeniority(0l); sysStaff.setSeniority(0l);
sysStaff.setCompanyName("YT"); sysStaff.setCompanyName("YT");
@ -380,6 +381,7 @@ public class SysStaffServiceImpl extends ServiceImpl<SysStaffMapper, SysStaff> i
if(repeat){ if(repeat){
return AjaxResult.error("姓名【"+sysStaff.getName()+"】已存在,所有员工(含离职)不可重名"); return AjaxResult.error("姓名【"+sysStaff.getName()+"】已存在,所有员工(含离职)不可重名");
} }
if(StringUtils.isNotEmpty(sysStaff.getSource()) && sysStaff.getSource().equals(Constants.SOURCE_DING) && StringUtils.isEmpty(sysStaff.getSex())){ if(StringUtils.isNotEmpty(sysStaff.getSource()) && sysStaff.getSource().equals(Constants.SOURCE_DING) && StringUtils.isEmpty(sysStaff.getSex())){
//根据省份证确定性别和年龄 //根据省份证确定性别和年龄
sysStaff.setAge(Long.parseLong(new SimpleDateFormat("yyyy").format(new Date())) - Long.parseLong(sysStaff.getIdCard().substring(6,10))); sysStaff.setAge(Long.parseLong(new SimpleDateFormat("yyyy").format(new Date())) - Long.parseLong(sysStaff.getIdCard().substring(6,10)));
@ -430,6 +432,12 @@ public class SysStaffServiceImpl extends ServiceImpl<SysStaffMapper, SysStaff> i
return AjaxResult.success(); return AjaxResult.success();
} }
} }
//检查转正日期, 是否初始化为试用期
if(sysStaff.getRegularDate().before(DateUtils.getNowDate())){
sysStaff.setStatus(Constants.JOB_STATIS_0);
}
//根据省份证确定性别和年龄 //根据省份证确定性别和年龄
Long year = Long.parseLong(sysStaff.getIdCard().substring(6,10)); Long year = Long.parseLong(sysStaff.getIdCard().substring(6,10));
Long age = Long.parseLong(new SimpleDateFormat("yyyy").format(new Date())) - year; Long age = Long.parseLong(new SimpleDateFormat("yyyy").format(new Date())) - year;
@ -442,54 +450,54 @@ public class SysStaffServiceImpl extends ServiceImpl<SysStaffMapper, SysStaff> i
//根据员工ID查询原来的数据信息 //根据员工ID查询原来的数据信息
SysStaff old_staff = getBaseMapper().selectSysStaffByUserId(sysStaff.getUserId()); SysStaff old_staff = getBaseMapper().selectSysStaffByUserId(sysStaff.getUserId());
//检查是否修改岗位 //检查是否修改岗位
// if(StringUtils.isEmpty(old_staff.getJobCode()) && StringUtils.isNotEmpty(sysStaff.getJobCode()) || if(StringUtils.isEmpty(old_staff.getJobCode()) && StringUtils.isNotEmpty(sysStaff.getJobCode()) ||
// StringUtils.isNotEmpty(old_staff.getJobCode()) && StringUtils.isEmpty(sysStaff.getJobCode()) || StringUtils.isNotEmpty(old_staff.getJobCode()) && StringUtils.isEmpty(sysStaff.getJobCode()) ||
// StringUtils.isNotEmpty(old_staff.getJobCode()) && StringUtils.isNotEmpty(sysStaff.getJobCode()) && !old_staff.getJobCode().equals(sysStaff.getJobCode())) { StringUtils.isNotEmpty(old_staff.getJobCode()) && StringUtils.isNotEmpty(sysStaff.getJobCode()) && !old_staff.getJobCode().equals(sysStaff.getJobCode())) {
// String deptNum = ""; String deptNum = "";
// String positionNum = ""; String positionNum = "";
// if(StringUtils.isNotEmpty(sysStaff.getJobCode())){ if(StringUtils.isNotEmpty(sysStaff.getJobCode())){
// deptNum = sysStaff.getJobCode().split("_")[1]; deptNum = sysStaff.getJobCode().split("_")[1];
// positionNum = sysStaff.getJobCode().split("_")[0]; positionNum = sysStaff.getJobCode().split("_")[0];
// } }
// String oldPositionNum = ""; String oldPositionNum = "";
// if(StringUtils.isNotEmpty(old_staff.getJobCode())){ if(StringUtils.isNotEmpty(old_staff.getJobCode())){
// oldPositionNum = old_staff.getJobCode().split("_")[0]; oldPositionNum = old_staff.getJobCode().split("_")[0];
// } }
// String fstaffId = ""; String fstaffId = "";
// String fid = null; String fid = null;
// JSONObject extended = new JSONObject(); JSONObject extended = new JSONObject();
// if(StringUtils.isNotEmpty(sysStaff.getExtended())){ if(StringUtils.isNotEmpty(sysStaff.getExtended())){
// extended = JSON.parseObject(sysStaff.getExtended()); extended = JSON.parseObject(sysStaff.getExtended());
// fstaffId = extended.getString("FSTAFFID"); fstaffId = extended.getString("FSTAFFID");
// fid = extended.getString("FID"); fid = extended.getString("FID");
// } }
//
//
// //都为空, 不确定金蝶是否存在员工信息 //都为空, 不确定金蝶是否存在员工信息
// if(StringUtils.isEmpty(fid) && StringUtils.isEmpty(fstaffId)){ if(StringUtils.isEmpty(fid) && StringUtils.isEmpty(fstaffId)){
// //查询金蝶的表单 //查询金蝶的表单
// String result = KingdeeRequestUtils.executeBillQuery(Collections.asMap("userCode", sysStaff.getCode()), KingdeeParamsEnum.Employee.DOCUMENT_INQUIRY); String result = KingdeeRequestUtils.executeBillQuery(Collections.asMap("userCode", sysStaff.getCode()), KingdeeParamsEnum.Employee.DOCUMENT_INQUIRY);
// JSONArray resJS = JSON.parseArray(result); JSONArray resJS = JSON.parseArray(result);
// if(resJS.size() > 0){ if(resJS.size() > 0){
// fid = resJS.getJSONArray(0).getString(0); fid = resJS.getJSONArray(0).getString(0);
// extended.put("FID", fid); extended.put("FID", fid);
// } }
// } }
// //如果fid还为空, 则证明金蝶不存在员工信息 //如果fid还为空, 则证明金蝶不存在员工信息
// if(StringUtils.isEmpty(fid)){ if(StringUtils.isEmpty(fid)){
// if(StringUtils.isNotEmpty(sysStaff.getJobCode())){ if(StringUtils.isNotEmpty(sysStaff.getJobCode())){
// sysStaff.setExtended(KingdeeRequestUtils.employeeSave(Collections.asMap("userName", sysStaff.getName(), "userCode", sysStaff.getCode(), "jobCode", sysStaff.getJobCode().split("_")[0],"deptCode", sysStaff.getJobCode().split("_")[1]))); sysStaff.setExtended(KingdeeRequestUtils.employeeSave(Collections.asMap("userName", sysStaff.getName(), "userCode", sysStaff.getCode(), "jobCode", sysStaff.getJobCode().split("_")[0],"deptCode", sysStaff.getJobCode().split("_")[1])));
// }else if(StringUtils.isEmpty(sysStaff.getJobCode())){ }else if(StringUtils.isEmpty(sysStaff.getJobCode())){
// sysStaff.setExtended(KingdeeRequestUtils.employeeSaveEmptyJob(Collections.asMap("userName", sysStaff.getName(), "userCode", sysStaff.getCode()))); sysStaff.setExtended(KingdeeRequestUtils.employeeSaveEmptyJob(Collections.asMap("userName", sysStaff.getName(), "userCode", sysStaff.getCode())));
// } }
// }else{ }else{
// String result = KingdeeRequestUtils.updateJobInfo(Collections.asMap( "userCode", sysStaff.getCode(), "deptCode", deptNum, "jobCode", positionNum, "oldJobCode", oldPositionNum,"FSTAFFID", fstaffId)); String result = KingdeeRequestUtils.updateJobInfo(Collections.asMap( "userCode", sysStaff.getCode(), "deptCode", deptNum, "jobCode", positionNum, "oldJobCode", oldPositionNum,"FSTAFFID", fstaffId));
// if(StringUtils.isNotEmpty(result)){ if(StringUtils.isNotEmpty(result)){
// extended.put("FSTAFFID",JSON.parseObject(result).getString("FSTAFFID")); extended.put("FSTAFFID",JSON.parseObject(result).getString("FSTAFFID"));
// sysStaff.setExtended(extended.toString()); sysStaff.setExtended(extended.toString());
// } }
// } }
// } }
//判断员工更换公司 //判断员工更换公司
if(!old_staff.getCompanyName().equals(sysStaff.getCompanyName())) { if(!old_staff.getCompanyName().equals(sysStaff.getCompanyName())) {
SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(sysStaff.getUserId()); SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(sysStaff.getUserId());
@ -914,7 +922,9 @@ public class SysStaffServiceImpl extends ServiceImpl<SysStaffMapper, SysStaff> i
sysStaff.setRegularDate(calendar.getTime()); sysStaff.setRegularDate(calendar.getTime());
} }
//判断转正日期和今天时间比较 //判断转正日期和今天时间比较
if(DateUtils.addMonths(sysStaff.getEmploymentDate(), Integer.valueOf(String.valueOf(sysStaff.getWorkerTerm()))).getTime() < DateUtils.getNowDate().getTime()){
//if(DateUtils.addMonths(sysStaff.getEmploymentDate(), Integer.valueOf(String.valueOf(sysStaff.getWorkerTerm()))).getTime() < DateUtils.getNowDate().getTime()){
if(sysStaff.getRegularDate().before(DateUtils.getNowDate())){
sysStaff.setStatus("1"); sysStaff.setStatus("1");
} }
getBaseMapper().updateSysStaff(sysStaff); getBaseMapper().updateSysStaff(sysStaff);

View File

@ -41,6 +41,8 @@ public class SubsidyCalculationUtils {
public static SysStaffDetail subsidyCalculation(SysStaff staff, SysStaffDetail staffDetail, List<RzSubsidyInfo> subsidyInfoList, Boolean isCalculationSalary){ public static SysStaffDetail subsidyCalculation(SysStaff staff, SysStaffDetail staffDetail, List<RzSubsidyInfo> subsidyInfoList, Boolean isCalculationSalary){
//正式员工并且有补助信息 //正式员工并且有补助信息
Boolean isOfficial = Constants.JOB_STATIS_1.equals(staff.getStatus()); Boolean isOfficial = Constants.JOB_STATIS_1.equals(staff.getStatus());
//是否为日薪
Boolean isDaily = staffDetail.getDailyWage() != null && staffDetail.getDailyWage().compareTo(BigDecimal.ZERO) > 0;
/*** /***
* 2025-7-15 跟人力在工位面谈, 其中, 夜餐, 夜班, 中班, 入职享有, 不在是转正后享有, 所以调整代码 * 2025-7-15 跟人力在工位面谈, 其中, 夜餐, 夜班, 中班, 入职享有, 不在是转正后享有, 所以调整代码
*/ */
@ -56,7 +58,8 @@ public class SubsidyCalculationUtils {
RzSubsidyInfo rzSubsidyInfo = map.get(Long.valueOf(subsidyId)); RzSubsidyInfo rzSubsidyInfo = map.get(Long.valueOf(subsidyId));
String key = rzSubsidyInfo.getName(); String key = rzSubsidyInfo.getName();
BigDecimal value = rzSubsidyInfo.getValue(); BigDecimal value = rzSubsidyInfo.getValue();
if(ht.equals(subsidyId) && isOfficial && staff.getContractStart() != null && staff.getContractEnd() != null){ //非日薪人员, 不在计算合同补助
if(ht.equals(subsidyId) && isOfficial && staff.getContractStart() != null && staff.getContractEnd() != null && isDaily){
Integer year= DateUtils.getBetweenYear(staff.getContractStart(), staff.getContractEnd(), 1); Integer year= DateUtils.getBetweenYear(staff.getContractStart(), staff.getContractEnd(), 1);
value = value.multiply(new BigDecimal(year)); value = value.multiply(new BigDecimal(year));
isAdd = true; isAdd = true;
@ -77,7 +80,8 @@ public class SubsidyCalculationUtils {
} }
} }
//计算学历补助 //计算学历补助
if(StringUtils.isNotEmpty(staff.getLevel()) && isOfficial){ //非日薪不计算学历补助
if(StringUtils.isNotEmpty(staff.getLevel()) && isOfficial && isDaily){
//查询学历 //查询学历
String label = SpringUtils.getBean(SysDictDataMapper.class).selectDictLabel(Constants.SYS_LEVEL, staff.getLevel()); String label = SpringUtils.getBean(SysDictDataMapper.class).selectDictLabel(Constants.SYS_LEVEL, staff.getLevel());
if(StringUtils.isNotEmpty(label)){ if(StringUtils.isNotEmpty(label)){

View File

@ -138,4 +138,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectRzAttendanceStatisticalVo"/> <include refid="selectRzAttendanceStatisticalVo"/>
where DATE_FORMAT( month, '%Y%m' ) = DATE_FORMAT(#{month} , '%Y%m' ) AND del_flag = '0' where DATE_FORMAT( month, '%Y%m' ) = DATE_FORMAT(#{month} , '%Y%m' ) AND del_flag = '0'
</select> </select>
<select id="selectRzAttendanceStatisticalByIdCardAndMonth" resultMap="RzAttendanceStatisticalResult">
select ras.* from rz_attendance_statistical ras left join sys_staff ss on ss.user_id = ras.staff_id
where ss.id_card=#{idCard} and DATE_FORMAT( ras.month, '%Y%m' ) = DATE_FORMAT(#{month} , '%Y%m' ) AND ras.del_flag = '0'
</select>
</mapper> </mapper>