package com.evo.common.utils; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.evo.attendance.domain.RzSysParam; import com.evo.attendance.service.IRzSysParamService; import com.evo.personnelMatters.domain.RzHoliday; import com.evo.personnelMatters.service.IRzHolidayService; 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.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * 全局参数获取配置类 * * @ClassName:ParamUtils * @date: 2025年05月23日 16:50 * @author: andy.shi * @contact: 17330188597 * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 */ @Service @Slf4j public class ParamUtils { private static IRzSysParamService paramService; private static ISysDictDataService dictDataService; private static IRzHolidayService rzHolidayService; /** * 早餐 */ public static String BREAKFAST_SCOPE = "早餐"; /** * 午餐 */ public static String LUNCH_SCOPE = "午餐"; /** * 晚餐 */ public static String DINNER_SCOPE = "晚餐"; @Autowired public ParamUtils(IRzSysParamService paramService, ISysDictDataService dictDataService,IRzHolidayService rzHolidayService) { this.paramService = paramService; this.dictDataService = dictDataService; this.rzHolidayService = rzHolidayService; } /*** * 获取餐厅的开放时间 * @return */ public static List getCanteenOpenHour(){ RzSysParam param= paramService.getRzSysParam("餐厅的开放就餐时间", "canteen_open_hour","7,8,11,12,13,17,18,19,20","餐厅的开放就餐时间, 多个时间用,间隔"); return Collections.asList(param.getParamValue().split(",")).stream().filter(StringUtils::isNotEmpty).map(Integer::valueOf).collect(Collectors.toList()); } public static Map> getCanteenLimitHour(){ RzSysParam param= paramService.getRzSysParam("餐厅的开放就餐时间", "canteen_limit_hour","{\""+BREAKFAST_SCOPE+"\":\"6~9\", \""+LUNCH_SCOPE+"\":\"11~14\", \""+DINNER_SCOPE+"\":\"17~20\"}","餐厅的开放就餐时间, 多个时间用,间隔"); JSONObject jsonObject = JSONObject.parseObject(param.getParamValue()); String[] breakfastScope = jsonObject.getString(BREAKFAST_SCOPE).split("~"); String[] lunchScope = jsonObject.getString(LUNCH_SCOPE).split("~"); String[] dinnerScope = jsonObject.getString(DINNER_SCOPE).split("~"); Map> result = Collections.emptyMap(); result.put(BREAKFAST_SCOPE, Collections.asMap("minHour", Integer.valueOf(breakfastScope[0]),"maxHour",Integer.valueOf(breakfastScope[1]))); result.put(LUNCH_SCOPE,Collections.asMap("minHour",Integer.valueOf(lunchScope[0]),"maxHour",Integer.valueOf(lunchScope[1]))); result.put(DINNER_SCOPE,Collections.asMap("minHour",Integer.valueOf(dinnerScope[0]),"maxHour",Integer.valueOf(dinnerScope[1]))); return result; } public static String getLimitSubsidyDay(){ RzSysParam param= paramService.getRzSysParam("月中转正的补助限制日期", "limit_subsidy_day","10","月中转正的补助限制日期; 如value填写的为10. 则10号之前转正有补助, 10号之后转正没有补助"); return param.getParamValue(); } /*** * 不住宿的实习生人员 * @return */ public static List getInternNotAccommodation(){ RzSysParam param= paramService.getRzSysParam("不住宿的实习生人员名单", "intern_not_accommodation","王习,乔克俭","不住宿的实习生人员名单"); return Collections.asList(param.getParamValue().split(",")); } /*** * 不住宿的实习生人员 * @return */ public static List getInternDailyWage(){ RzSysParam param= paramService.getRzSysParam("实习生不住宿的日薪人员名单", "intern_not_accommodation","乔克俭","实习生不住宿的日薪人员名单"); return Collections.asList(param.getParamValue().split(",")); } /*** * 获取全局静态文件地址 * @return */ public static String getGlobalStaticUrl(){ RzSysParam param= paramService.getRzSysParam("静态地址URL", "static_url","http://192.168.5.12:8088","静态文件的url地址"); return param.getParamValue(); } /*** * 获取日薪全勤天数 * @return */ public static String getShortBreakDeductionMinutes(String type){ RzSysParam param= paramService.getRzSysParam("短休的工时扣减(分钟)", "short_break_deduction_minutes","{\"TS\":\"30\",\"ZC\":\"0\"}","短休的工时扣减(分钟)"); JSONObject jsonObject = JSONObject.parseObject(param.getParamValue()); String rulesVal = jsonObject.getString(type); return (StringUtils.isEmpty(rulesVal) ? "0" : rulesVal); } /*** * 获取日薪全勤天数 * @return */ public static String dailyWageGsBasicPrice(){ RzSysParam param= paramService.getRzSysParam("日薪的基本工资", "daily_wage_basic_price","1800","日薪的基本工资"); return param.getParamValue(); } /*** * 获取那些请假类型不包含法休 * @return */ public static List getLeaveTypeNotIncludedFaXiu(){ RzSysParam param= paramService.getRzSysParam("请假类型不包含法休", "leave_type_not_included_fa_xiu","56,57,58","记录请假类型不包含法休, 属性值为字典的假期类型code, 多个参数使用,隔开"); return Collections.asList(param.getParamValue().split(",")); } /*** * 获取那些请假类型不包含法休, 公休(周日) * @return */ public static List getLeaveTypeNotIncludedFaXiuAndPublicHoliday(){ RzSysParam param= paramService.getRzSysParam("请假类型不包含法休和公休", "leave_type_not_included_fa_xiu_and_public_holiday","54","记录请假类型不包含法休和公休, 属性值为字典的假期类型code, 多个参数使用,隔开"); return Collections.asList(param.getParamValue().split(",")); } /*** * 获取那些请假类型需要自动计算请假时长 * @return */ public static List autoCalculationHolidayType(){ RzSysParam param= paramService.getRzSysParam("需要自动计算请假时长的请假类型", "auto_calculation_holiday_type","54,56,57,58,59","需要自动计算请假时长的请假类型, 多个参数使用,隔开"); return Collections.asList(param.getParamValue().split(",")); } /*** * 检查特殊打卡机的规则 * sn 设备号 * rules 规则 * @return */ public static Boolean checkTsDeviceButton(String sn, String rules){ if(StringUtils.isEmpty(rules))return true; RzSysParam param= paramService.getRzSysParam("特殊打卡机的打卡按钮规则", "ts_device_button_rules","{\"ET74336\":\"加班卡,下班卡\"}","特殊打卡机的打卡按钮规则, 使用json格式, 如果打卡机存在多个按钮规则用,分割"); String val = param.getParamValue(); JSONObject jsonObject = JSONObject.parseObject(val); String rulesVal = jsonObject.getString(sn); if(StringUtils.isEmpty(rulesVal)) return false; return Collections.asList(rulesVal.split(",")).contains(rules); } /*** * 获取特殊加班的考勤规则 * sn 设备号 * rules 规则 * @return */ public static JSONObject getDeviceOverTimeRules(String sn){ 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: 餐厅闭厅时间"); JSONObject jsonObject = JSONObject.parseObject(param.getParamValue()); JSONObject rules = jsonObject.getJSONObject(sn); return (ObjectUtils.isEmpty(rules) ? JSONObject.parseObject("{\"maxHour\":4}") : rules); } /*** * 获取特殊加班的考勤规则 * sn 设备号 * rules 规则 * @return */ public static String getYcRulesByButtonName(String type, String buttonName){ if(StringUtils.isEmpty(type) || StringUtils.isEmpty(buttonName)) return null; RzSysParam param= paramService.getRzSysParam("打卡按钮的打卡异常规则", "device_button_yc_rules", "{\"上班\":{" + "\"上班卡(单班制)\":\"function greet() { return new Date('dkDateTime') > new Date('dkDate'+' 08:30:00'); } greet();\"," + "\"上班卡(倒班8时制)\":\"function greet() { return ((new Date('dkDateTime') > new Date('dkDate'+' 08:30:00') && new Date('dkDateTime').getHours() < 12) || (new Date('dkDateTime') > new Date('dkDate'+' 17:00:00') && new Date('dkDateTime').getHours() < 21)); } greet();\"," + "\"上班卡(倒班12时制)\":\"function greet() { return ((new Date('dkDateTime') > new Date('dkDate'+' 08:30:00') && new Date('dkDateTime').getHours() < 12) || (new Date('dkDateTime') > new Date('dkDate'+' 20:30:00') && new Date('dkDateTime').getHours() < 24)); } greet();\"," + "},\"下班\":{" + "\"上班卡(单班制)\":\"function greet() { return new Date('dkDateTime') < new Date('dkDate'+' 17:30:00'); } greet();\"," + "\"上班卡(倒班8时制)\":\"function greet() { return ((new Date('dkDateTime') < new Date('dkDate'+' 17:00:00') && new Date('dkDateTime') > new Date('dkDate'+' 08:30:00')) || (new Date('dkDateTime') < new Date('dkDate'+' 01:30:00') && new Date('dkDateTime') > new Date('dkDate'+' 17:00:00'))); } greet();\"," + "\"上班卡(倒班12时制)\":\"function greet() { return ((new Date('dkDateTime') < new Date('dkDate'+' 20:30:00') && new Date('dkDateTime').getHours() > 14) || new Date('dkDateTime') < new Date('dkDate'+' 08:30:00')); } greet();\"," + "}}","特殊加班的考勤规则, minHour:最小加班时长. maxHour: 最大加班时长, endMealTime: 餐厅闭厅时间"); String val = param.getParamValue(); JSONObject jsonObject = JSONObject.parseObject(val); JSONObject typeJson = jsonObject.getJSONObject(type); return typeJson != null ? typeJson.getString(buttonName) : null; } /*** * 获取特殊加班的考勤规则 * sn 设备号 * rules 规则 * @return */ public static Integer getTsWorkHour(String name){ if(StringUtils.isEmpty(name)) return null; RzSysParam param= paramService.getRzSysParam("特殊上班人员", "ts_work_hour","{\"11\":\"丁世强,陈亮,贾中恒,孙小建,刘佳,宋娇娇\"}","特殊上班人员, 上班时长做key, 员工做value, 一个员工存在多个value, 以第一个为准"); String val = param.getParamValue(); if(StringUtils.isEmpty(val)) return null; Map hourMaps = JSONObject.parseObject(val, Map.class); Map.Entry mapVal = hourMaps.entrySet().stream().filter(d-> Collections.asList(d.getValue().split(",")).contains(name)).findFirst().orElse(null); return ObjectUtils.isEmpty(mapVal) ? null : Integer.valueOf(mapVal.getKey()); } /*** * 获取每月的工作天数 * @param monthNum * @return */ public static String getMonthWorkDayNum(Integer year, Integer monthNum){ //获取当前年 RzHoliday rzHoliday = rzHolidayService.selectRzHolidayByYear(year); JSONObject workJson = JSONObject.parseObject(rzHoliday.getWorkInfo()); return workJson.containsKey(String.valueOf(monthNum)) ? workJson.getString(String.valueOf(monthNum)) : "26"; } /*** * 检查日期是否为假期 * @param checkDate * @return true: 是 false: 不是 */ public static Boolean checkHoliday(Date checkDate){ if(checkDate == null){ return false; } return checkHoliday(DateUtils.parseDateToStr("yyyy-MM-dd", checkDate)); } /*** * 检查日期是否为假期 * @param checkDate * @return true: 是 false: 不是 */ public static Boolean checkHoliday(String checkDate){ if(StringUtils.isEmpty(checkDate)){ return false; } //检查格式, 如果格式不匹配, 输出日志, 直接返回true if(!Pattern.compile("").matcher(checkDate).matches()){ log.error("当前检查日期{}, 不符合检查规则", checkDate); return false; } //检查是否为假期 return getHoliddayList(Integer.valueOf(checkDate.substring(0,4)), 0).contains(checkDate); } /*** * 获取假期范围 0 全部 1法休 2 公休 * @param year * @Param holidayType 0 全部 1法休 2 公休 * @return */ public static List getHoliddayList(Integer year, Integer holidayType){ //获取当前年 RzHoliday rzHoliday = rzHolidayService.selectRzHolidayByYear(year); Map holidaysMaps = JSONObject.parseObject(rzHoliday.getHolidayInfo(), Map.class); if(Integer.valueOf(0).equals(holidayType)){ return holidaysMaps.keySet().stream().collect(Collectors.toList()); } return holidaysMaps.entrySet().stream().filter(m -> holidayType.equals(m.getValue())).map(m-> m.getKey()).collect(Collectors.toList()); } /*** * 获取全薪假期 * @return */ public static List getFullPaidLeave(){ RzSysParam param= paramService.getRzSysParam("全薪发放的假期", "full_paid_leave","54,56,57,58,59,60","全薪发放的假期; 54-年休假, 56-婚假,57-产假,58-陪产假,59-丧假,60-工伤假 (55-调休假 这是个特殊的假期, 加班会自动抵扣)"); return Collections.asList(param.getParamValue().split(",")).stream().filter(StringUtils::isNotEmpty).map(Long::valueOf).collect(Collectors.toList()); } /*** * 获取80%假期 * @return */ public static List getEightyPercentVacation(){ RzSysParam param= paramService.getRzSysParam("80%的假期类型", "eighty_percent_vacation","52","80%的假期类型; 52-病假"); return Collections.asList(param.getParamValue().split(",")).stream().filter(StringUtils::isNotEmpty).map(Long::valueOf).collect(Collectors.toList()); } /*** * 获取80%假期 * @param nameAndIdCard 姓名-身份证 * @return */ public static BigDecimal getSpecialExemptionAmount(String nameAndIdCard){ RzSysParam param= paramService.getRzSysParam("特殊年度免征额计算", "special_exemption_amount",JSON.toJSONString(Collections.asMap("60000","李欣-130132199103134105;陈阳-130823200405243013;檀亚茹-130124199008242423;师敏玲-130132198610153189;马君君-130133199005203011;赵芬静-130132200109252589;李亚茹-130132199105122861;侯阔-130124198805202411;贺光建-130528198608083019;宋娇娇-130132198811222865;张子豪-130132200505170016;位晓峰-130132199211012877;周红娟-13013219820321284X;周庆迪-342221199208256085;赵硕岐-130132199210280052;李宏叶-130132198902060021;吴海静-130132198701021966;何亚平-130132198407011943;谷丽博-130132198612102887;楚世光-130105196807301212;杜晓华-130132198402093804;姚少鹏-130132199412151937;常志涛-130726200203256135;何旭然-130132198812093268;曹盼-130185199207201360;王硕-130132198701102934;何春玲-431124198612294526;王旭-130132199007270035;郑杰-130426199310292324;崔炫宇-130429200008068019;王晓田-130132199010252903;刘建斌-130105196908150919;崔佳佩-130132198602261323")),"特殊年度免征额计算, 上年各月均有申报且全年收入不超过6万元 所以今年免征额直接60000了"); Map vm = JSON.parseObject(param.getParamValue(), Map.class); for(Map.Entry entry : vm.entrySet()){ if(Collections.asList(entry.getValue().split(";")).contains(nameAndIdCard)){ return new BigDecimal(entry.getKey()); } } return null; } /*** * 检查日期是否需要记录操作日志信息 * @return true: 是 false: 不是 */ public static Boolean checkLogOperation(){ RzSysParam param= paramService.getRzSysParam("检查是否需要记录操作日志", "check_log_operation","false","检查是否需要考勤信息操作日志, 以点击考勤统计的数据校正为开始, 以点击计算工资为结束"); return Boolean.valueOf(param.getParamValue()); } public static RzSysParam getRzSysParam(String code){ return paramService.getRzSysParam(code); } public static void updateLogOperation(Boolean val){ CompletableFuture.runAsync(() -> { try { RzSysParam rzSysParam = getRzSysParam("check_log_operation"); if(ObjectUtils.isEmpty(rzSysParam)){ rzSysParam = paramService.getRzSysParam("检查是否需要记录操作日志", "check_log_operation","false","检查是否需要考勤信息操作日志, 以点击考勤统计的数据校正为开始, 以点击计算工资为结束"); } if(ObjectUtils.isEmpty(rzSysParam)){ throw new RuntimeException("没有找到日志相关的参数"); } rzSysParam.setParamValue(String.valueOf(val)); paramService.updateRzSysParam(rzSysParam); } catch (Exception e) { e.printStackTrace(); } log.info("更新日志记录参数完成当前状态为:" + (val ? "记录": "不记录")); }); } }