新增考勤操作日志

This commit is contained in:
andy 2025-09-19 15:54:33 +08:00
parent 93087177ab
commit c93c72abdf
21 changed files with 438 additions and 416 deletions

View File

@ -1,6 +1,7 @@
package com.evo.attendance.controller;
import com.evo.common.annotation.Log;
import com.evo.common.annotation.RepeatSubmit;
import com.evo.common.core.controller.BaseController;
import com.evo.common.core.domain.AjaxResult;
import com.evo.common.core.page.TableDataInfo;
@ -9,6 +10,7 @@ import com.evo.common.utils.StringUtils;
import com.evo.common.utils.poi.ExcelUtil;
import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.attendance.service.IRzAttendanceStatisticalService;
import com.evo.system.service.ISysStatisticalOperationLogService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@ -28,6 +30,8 @@ public class RzAttendanceStatisticalController extends BaseController
{
@Resource
private IRzAttendanceStatisticalService rzAttendanceStatisticalService;
@Resource
private ISysStatisticalOperationLogService sysStatisticalOperationLogService;
/**
* 查询考勤统计列表
@ -80,6 +84,7 @@ public class RzAttendanceStatisticalController extends BaseController
*/
@PreAuthorize("@ss.hasPermi('attendance:statistical:correct')")
@RequestMapping(value = "correct")
@RepeatSubmit
public AjaxResult correct(@RequestBody RzAttendanceStatistical rzAttendanceStatistical)
{
if (StringUtils.isNull(rzAttendanceStatistical) || StringUtils.isNull(rzAttendanceStatistical.getMonth())) {
@ -97,4 +102,13 @@ public class RzAttendanceStatisticalController extends BaseController
return rzAttendanceStatisticalService.importRzAttendanceStatistical(attList);
}
/**
* 获取考勤统计的操作记录
*/
@PreAuthorize("@ss.hasPermi('attendance:statistical:oper')")
@GetMapping(value = "/oper/{id}")
public AjaxResult getOper(@PathVariable("id") Long id)
{
return success(sysStatisticalOperationLogService.getOperationByBusinessId(id, RzAttendanceStatistical.class));
}
}

View File

@ -1,7 +1,9 @@
package com.evo.attendance.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.evo.common.annotation.Excel;
import com.evo.common.core.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
@ -25,6 +27,7 @@ public class RzAttendanceStatistical extends BaseEntity
/** 主键 */
@Excel(name = "主键ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/** 员工ID */

View File

@ -145,7 +145,11 @@ public class KQDeviceExchangeProcessor implements PunchTheClockStrategyExchangeP
//如果当前打卡是下班卡, 并且当前员工考勤上班时间为空, 则判定为隔天打下班卡
if(rules.contains("下班") && attendance.getWorkStartTime() == null){
//获取最后一次的上班记录
attendance = rzAttendanceMapper.selectLastRzAttendanceByStaffId(Long.valueOf(userId));
RzAttendance beforeRzAttendance = rzAttendanceMapper.selectLastRzAttendanceByStaffId(Long.valueOf(userId));
//这么写, 是因为存在第一天上班就没打卡,导致获取前一天的数据为空, 导致打卡失败
if(ObjectUtils.isNotEmpty(beforeRzAttendance)){
attendance = beforeRzAttendance;
}
}
//
// RzAttendanceDetail attendanceDetail = new RzAttendanceDetail();

View File

@ -1,5 +1,6 @@
package com.evo.attendance.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.common.core.domain.AjaxResult;
import com.evo.system.domain.SysStaff;
@ -13,7 +14,7 @@ import java.util.List;
* @author chenyj
* @date 2024-09-05
*/
public interface IRzAttendanceStatisticalService
public interface IRzAttendanceStatisticalService extends IService<RzAttendanceStatistical>
{
/**
* 查询考勤统计

View File

@ -68,4 +68,11 @@ public interface IRzSysParamService
* @return
*/
public RzSysParam getRzSysParam(String name, String code, String defVal, String des);
/***
* 获取数据信息
* @param code
* @return
*/
public RzSysParam getRzSysParam(String code);
}

View File

@ -5,11 +5,14 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.attendance.domain.RzAttendance;
import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.attendance.domain.RzSysParam;
import com.evo.attendance.mapper.RzAttendanceMapper;
import com.evo.attendance.mapper.RzAttendanceStatisticalMapper;
import com.evo.attendance.mapper.RzSpecialAttendanceMapper;
import com.evo.attendance.service.IRzAttendanceStatisticalService;
import com.evo.attendance.service.IRzSysParamService;
import com.evo.common.annotation.DataScope;
import com.evo.common.annotation.StatisticalOperationLog;
import com.evo.common.constant.Constants;
import com.evo.common.core.domain.AjaxResult;
import com.evo.common.core.domain.entity.SysDept;
@ -32,6 +35,7 @@ import java.beans.Transient;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
/**
@ -56,6 +60,9 @@ public class RzAttendanceStatisticalServiceImpl extends ServiceImpl<RzAttendance
@Resource
private RzLeaveDetailMapper rzLeaveDetailMapper;
@Resource
private IRzSysParamService rzSysParamService; //部门
/**
* 查询考勤统计
*
@ -91,6 +98,7 @@ public class RzAttendanceStatisticalServiceImpl extends ServiceImpl<RzAttendance
* @return 结果
*/
@Override
@StatisticalOperationLog
public int updateRzAttendanceStatistical(RzAttendanceStatistical rzAttendanceStatistical)
{
rzAttendanceStatistical.setRealAttendance(rzAttendanceStatistical.getEssentialAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber()));
@ -261,6 +269,8 @@ public class RzAttendanceStatisticalServiceImpl extends ServiceImpl<RzAttendance
//更新全部考勤
updateBatchById(list);
//开启日志记录
ParamUtils.updateLogOperation(true);
return AjaxResult.success();
}

View File

@ -6,8 +6,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.common.utils.DateUtils;
import com.evo.common.utils.SecurityUtils;
import com.evo.equipment.constant.Constants;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.evo.attendance.mapper.RzSysParamMapper;
import com.evo.attendance.domain.RzSysParam;
@ -99,10 +102,9 @@ public class RzSysParamServiceImpl extends ServiceImpl<RzSysParamMapper, RzSysPa
}
@Override
public RzSysParam getRzSysParam(String name, String code, String defVal, String des){
RzSysParam param = getOne(new LambdaQueryWrapper<RzSysParam>().eq(RzSysParam::getParamCode, code));
RzSysParam param = getRzSysParam(code);
if(ObjectUtils.isEmpty(param)){
param = new RzSysParam();
param.setParamName(name);
@ -113,4 +115,9 @@ public class RzSysParamServiceImpl extends ServiceImpl<RzSysParamMapper, RzSysPa
}
return param;
}
@Override
@Cacheable(cacheNames = Constants.SYS_RUNNING_PARAMS, key = "#code")
public RzSysParam getRzSysParam(String code){
return getOne(new LambdaQueryWrapper<RzSysParam>().eq(RzSysParam::getParamCode, code));
}
}

View File

@ -0,0 +1,11 @@
package com.evo.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface StatisticalOperationLog {
}

View File

@ -10,12 +10,14 @@ 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;
@ -56,6 +58,7 @@ public class ParamUtils {
this.rzHolidayService = rzHolidayService;
}
/***
* 获取餐厅的开放时间
* @return
@ -316,5 +319,36 @@ public class ParamUtils {
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 ? "记录": "不记录"));
});
}
}

View File

@ -26,5 +26,10 @@ public class Constants
* 加班打卡机
*/
public static final String EQ_DEVICE_OVER_TIME_CODE = "ET74336"; //加班打卡机
public static final String SYS_RUNNING_PARAMS= "system:running:params:";
}

View File

@ -1,6 +1,7 @@
package com.evo.finance.controller;
import com.evo.common.annotation.Log;
import com.evo.common.annotation.RepeatSubmit;
import com.evo.common.constant.Constants;
import com.evo.common.core.controller.BaseController;
import com.evo.common.core.domain.AjaxResult;
@ -72,6 +73,7 @@ public class RzSalaryDetailController extends BaseController
@PreAuthorize("@ss.hasPermi('finance:financeDetail:add')")
@Log(title = "工资详情", businessType = BusinessType.INSERT)
@PostMapping
@RepeatSubmit(interval=70000)
public AjaxResult add(@RequestBody RzSalaryDetail rzSalaryDetail)
{
return rzSalaryDetailService.insertRzSalaryDetail(rzSalaryDetail);

View File

@ -92,7 +92,7 @@ public class DailyWageStrategyExchangeProcessor implements SalaryCalculationStra
//计算补助
subsidy(limitMonth, month, limitDate, sysStaff, detail, rzSalaryDetail, attendanceStatistical);
//计算扣减
deduction("".equals(sysStaff.getClockIn()), detail, rzSalaryDetail, new BigDecimal(ParamUtils.getMonthWorkDayNum(DateUtils.getYear(rzSalaryDetail.getMonth()), DateUtils.getMonth(rzSalaryDetail.getMonth()))).multiply(Constants.DAY_WORK_HOUR), attendanceStatistical.getRealAttendance());
deduction("".equals(sysStaff.getClockIn()), detail, rzSalaryDetail, new BigDecimal(ParamUtils.getMonthWorkDayNum(DateUtils.getYear(rzSalaryDetail.getMonth()), DateUtils.getMonth(rzSalaryDetail.getMonth()))).multiply(Constants.DAY_WORK_HOUR), attendanceStatistical.getEssentialAttendance());
//deduction("".equals(sysStaff.getClockIn()), detail, rzSalaryDetail, new BigDecimal(DateUtils.getMonthDays(rzSalaryDetail.getMonth())).multiply(Constants.DAY_WORK_HOUR), rzAttendanceMapper.selectOne(new QueryWrapper<RzAttendance>().select( " ifnull(sum(work_sum),0) as workSum ").lambda().isNotNull(RzAttendance::getWorkSum).gt(RzAttendance::getWorkSum, 0).eq(RzAttendance::getDelFlag, Constants.DELETE_FLAG_0).eq(RzAttendance::getStaffId, sysStaff.getUserId()).apply(" DATE_FORMAT( attendance_date, '%Y%m' ) = DATE_FORMAT({0} , '%Y%m' )", rzSalaryDetail.getMonth())).getWorkSum());
//deduction(detail, rzSalaryDetail, String.valueOf(DateUtils.getMonthDays(rzSalaryDetail.getMonth())), rzAttendanceMapper.selectCount(new LambdaQueryWrapper<RzAttendance>().isNotNull(RzAttendance::getWorkSum).gt(RzAttendance::getWorkSum, 0).eq(RzAttendance::getDelFlag, Constants.DELETE_FLAG_0).eq(RzAttendance::getStaffId, sysStaff.getUserId()).apply(" DATE_FORMAT( attendance_date, '%Y%m' ) = DATE_FORMAT({0} , '%Y%m' )", rzSalaryDetail.getMonth()).select(RzAttendance::getId)));
//日薪没有缺勤扣款, 上一天就一天

View File

@ -93,7 +93,7 @@ public class MonthlySalaryStrategyExchangeProcessor implements SalaryCalculation
//计算补助
subsidy(limitMonth, month, limitDate, sysStaff, detail, rzSalaryDetail, attendanceStatistical);
//计算扣减
deduction("".equals(sysStaff.getClockIn()), detail, rzSalaryDetail, new BigDecimal(workNum).multiply(Constants.DAY_WORK_HOUR), attendanceStatistical.getRealAttendance());
deduction("".equals(sysStaff.getClockIn()), detail, rzSalaryDetail, new BigDecimal(workNum).multiply(Constants.DAY_WORK_HOUR), attendanceStatistical.getEssentialAttendance());
//deduction(detail, rzSalaryDetail,workNum, rzAttendanceMapper.selectCount(new LambdaQueryWrapper<RzAttendance>().isNotNull(RzAttendance::getWorkSum).gt(RzAttendance::getWorkSum, 0).eq(RzAttendance::getDelFlag, Constants.DELETE_FLAG_0).eq(RzAttendance::getStaffId, sysStaff.getUserId()).apply(" DATE_FORMAT( attendance_date, '%Y%m' ) = DATE_FORMAT({0} , '%Y%m' )", rzSalaryDetail.getMonth()).select(RzAttendance::getId)));
//计算社保
socialSecurity(sysStaff, detail, attendanceStatistical);

View File

@ -1,13 +1,9 @@
package com.evo.finance.service.impl;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.mapper.RzAttendanceMapper;
import com.evo.attendance.mapper.RzAttendanceStatisticalMapper;
import com.evo.attendance.mapper.RzSpecialOverTimeMapper;
import com.evo.common.constant.Constants;
import com.evo.common.core.domain.AjaxResult;
import com.evo.common.core.domain.entity.SysDept;
@ -22,15 +18,12 @@ import com.evo.finance.mapper.RzSalaryDetailMapper;
import com.evo.finance.mapper.RzSalaryStatisticsMapper;
import com.evo.finance.processor.SalaryCalculationStrategyExchangeProcessor;
import com.evo.finance.service.IRzSalaryDetailService;
import com.evo.personnelMatters.mapper.RzHolidayMapper;
import com.evo.restaurant.mapper.RzRestaurantStatisticsMapper;
import com.evo.system.domain.SysStaff;
import com.evo.system.domain.SysStaffDetail;
import com.evo.system.mapper.SysDeptMapper;
import com.evo.system.mapper.SysDictDataMapper;
import com.evo.system.mapper.SysStaffDetailMapper;
import com.evo.system.mapper.SysStaffMapper;
import com.evo.system.service.ISysDictDataService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@ -103,7 +96,7 @@ public class RzSalaryDetailServiceImpl extends ServiceImpl<RzSalaryDetailMapper,
*/
@Override
@Transactional
public AjaxResult insertRzSalaryDetail(RzSalaryDetail rzSalaryDetail)
public synchronized AjaxResult insertRzSalaryDetail(RzSalaryDetail rzSalaryDetail)
{
if(StringUtils.isNull(rzSalaryDetail.getMonth())){
return AjaxResult.error("工资月份为不填项!!");
@ -167,413 +160,14 @@ public class RzSalaryDetailServiceImpl extends ServiceImpl<RzSalaryDetailMapper,
}
}
}
//不为空, 为日薪
// if(sysStaffDetail.getDailyWage() != null){
//
// }else
// //如果都不为空, 则为月薪
// if(sysStaffDetail.getBasicSalary() != null && sysStaffDetail.getJobsSalary()!=null){
// rzSalaryDetail.setMonthSalary(sysStaffDetail.getBasicSalary());
// rzSalaryDetail.setJobSalary(sysStaffDetail.getJobsSalary());
// rzSalaryDetail.setDailyWage(new BigDecimal(0));
// //计算加班工资
// autoCalculationOverTimeWorkSalary(rzSalaryDetail, attendanceStatistical, overTimeMap.get(rzSalaryDetail.getDeptId()));
//
// }
// //计算获得的工资
// SysStaffDetail salaryDetail = calculateSalary(sysStaff,rzSalaryDetail.getMonth(),sbrq);
// rzSalaryDetail.setMonthSalary(salaryDetail.getBasicSalary()); //基本工资
// rzSalaryDetail.setAbsenteeismSalary(salaryDetail.getAbsenteeismSalary()); //请假扣除工资
// rzSalaryDetail.setOvertimeSalary(salaryDetail.getOverWages()); //加班工资
// rzSalaryDetail.setNightSubsidies(salaryDetail.getNightShiftSubsidies()); //夜班补助
// rzSalaryDetail.setDinnerSubsidies(salaryDetail.getDinnerSubsidies()); //夜餐补助
// rzSalaryDetail.setMiddleSubsidies(salaryDetail.getMiddleSubsidies()); //中班补助
//查询员工详情
// SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(sysStaff.getUserId());
// rzSalaryDetail.setFullSubsidies(sysStaffDetail.getFullFrequentlySubsidies()); //全勤奖
// rzSalaryDetail.setLevelSubsidies(sysStaffDetail.getLevelOfEducationSubsidies()); //学历
// rzSalaryDetail.setContractSubsidies(sysStaffDetail.getContractSubsidies()); //合同
// rzSalaryDetail.setSocialSubsidies(sysStaffDetail.getSocialSecuritySubsidies()); //社保
// rzSalaryDetail.setSubsidyOrBonus(sysStaffDetail.getOtherSubsidies().add(sysStaffDetail.getFixedAllowance())); //其他补助
//补助扣除 TODO 福利扣除百分比
// rzSalaryDetail.setAbsenteeismSubsidies(sysStaffDetail.getLevelOfEducationSubsidies().add(sysStaffDetail.getContractSubsidies())
// .add(sysStaffDetail.getSenioritySubsidies()).add(sysStaffDetail.getSocialSecuritySubsidies()).multiply(salaryDetail.getAbsenteeismSubsidies()));
// rzSalaryDetail.setDeductions(sysStaffDetail.getDeductions()); //其他扣款
// //计算工龄,以每月10号社保缴纳计算
// int years = sbrq.getYear() - sysStaff.getEmploymentDate().getYear();
// int months = sbrq.getMonth() - sysStaff.getEmploymentDate().getMonth();
// int days = sbrq.getDate() - sysStaff.getEmploymentDate().getDate();
// if(months < 0){
// years -= 1;
// }
// if(months == 0 && days < 0){
// years -= 1;
// }
// if(years > 10){
// rzSalaryDetail.setSenioritySalary(sysStaffDetail.getSenioritySubsidies().multiply(new BigDecimal("10.0"))); //工龄
// }else{
// rzSalaryDetail.setSenioritySalary(sysStaffDetail.getSenioritySubsidies().multiply(new BigDecimal(years))); //工龄
// }
// //餐费
// RzRestaurantStatistics rzRestaurantStatistics = rzRestaurantStatisticsMapper.selectRzRestaurantStatisticsByUserIdAndDate(sysStaff.getUserId(),rzSalaryDetail.getMonth());
// rzSalaryDetail.setMealFee(rzRestaurantStatistics.getPersonalSumConsumption()); //餐费扣除
// //计算应发工资 合算月工资+学历补助+合同补助+社保补助+工龄工资+全勤奖+加班工资+夜班补助+夜餐补助+其他补助
// BigDecimal sum = rzSalaryDetail.getMonthSalary().add(rzSalaryDetail.getOvertimeSalary()).add(rzSalaryDetail.getNightSubsidies()).add(rzSalaryDetail.getDinnerSubsidies())
// .add(rzSalaryDetail.getFullSubsidies()).add(rzSalaryDetail.getLevelSubsidies()).add(rzSalaryDetail.getContractSubsidies()).add(rzSalaryDetail.getSocialSubsidies())
// .add(rzSalaryDetail.getSenioritySalary()).add(rzSalaryDetail.getSubsidyOrBonus()).subtract(rzSalaryDetail.getAbsenteeismSalary())
// .subtract(rzSalaryDetail.getMealFee()).subtract(rzSalaryDetail.getAbsenteeismSubsidies());
// rzSalaryDetail.setSalary(sum);
// //五险一金
// rzSalaryDetail.setAccumulationFund(sysStaffDetail.getAccumulationFund()); //公积金
// rzSalaryDetail.setUnemploymentInsurance(sysStaffDetail.getUnemploymentInsurance()); //失业保险
// rzSalaryDetail.setMaternityInsurance(sysStaffDetail.getMaternityInsurance()); //生育保险
// rzSalaryDetail.setMedicalInsurance(sysStaffDetail.getMedicalInsurance()); //医疗保险
// rzSalaryDetail.setEndowmentInsurance(sysStaffDetail.getEndowmentInsurance()); //养老保险
// rzSalaryDetail.setEmploymentInjuryInsurance(sysStaffDetail.getEmploymentInjuryInsurance()); //工伤保险
// //税前工资 应发 - 社保
//// rzSalaryDetail.setSalaryBeforeTax(rzSalaryDetail.getSalary().subtract(rzSalaryDetail.getAccumulationFund()).subtract(rzSalaryDetail.getUnemploymentInsurance())
//// .subtract(rzSalaryDetail.getMaternityInsurance()).subtract(rzSalaryDetail.getMedicalInsurance())
//// .subtract(rzSalaryDetail.getEndowmentInsurance()).subtract(rzSalaryDetail.getEmploymentInjuryInsurance()).subtract(salaryDetail.getCountInsurance()));
//
// //获取统计月份
// int curr_month = rzSalaryDetail.getMonth().getMonth();
// //获取工资统计月份,查询上个月的纳税公司 得到年度免征额
// RzSalaryDetail old_rzSalary = rzSalaryDetailMapper.selectRzSalaryDetailByStaffId(sysStaff.getUserId());
// if(curr_month == 12){
// rzSalaryDetail.setAnnualExemptionAmount(new BigDecimal("5000.00"));
// }else{
// //判断员工为 新入职公司纳税主题改变同一主题超一年的同一主题不超一年但跨年的
// if(StringUtils.isNull(old_rzSalary) || !old_rzSalary.getWbFlag().equals(sysStaff.getCompanyName())
// || (rzSalaryDetail.getMonth().getTime() - old_rzSalary.getMonth().getTime())/1000/60/60/24 > 365
// || (old_rzSalary.getMonth().getMonth() < 12 && old_rzSalary.getMonth().getMonth() > rzSalaryDetail.getMonth().getMonth())){
// rzSalaryDetail.setAnnualExemptionAmount(new BigDecimal("5000.00"));
// }else{
// rzSalaryDetail.setAnnualExemptionAmount(new BigDecimal("5000.00").add(old_rzSalary.getAnnualExemptionAmount()));
// }
// }
// // 本年累计已发工资本年累计已发工资+本月税前工资
// rzSalaryDetail.setTotalWages(sysStaffDetail.getTotalWages().add(rzSalaryDetail.getSalaryBeforeTax()));
// // 专项附加扣除六项附加扣除额相加
// rzSalaryDetail.setSpecialDeduction(sysStaffDetail.getChildrenEducation().add(sysStaffDetail.getSupportTheOld()).add(sysStaffDetail.getHousingLoans())
// .add(sysStaffDetail.getHousingRents()).add(sysStaffDetail.getAdultEducation()).add(sysStaffDetail.getTreatmentForSeriousDisease()));
//
// // 判断应纳税所得额额度额度不一样税率不一样
// if (rzSalaryDetail.getTaxableIncome().doubleValue() > 0 && rzSalaryDetail.getTaxableIncome().doubleValue() <= 36000l) {
// // 此阶税率为百分之3速减数为0
// rzSalaryDetail.setTaxRate(new BigDecimal("0.03"));
// // 速算扣除数速算扣除数跟税率同步
// rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("0"));
// } else if (rzSalaryDetail.getTaxableIncome().doubleValue() > 36000l && rzSalaryDetail.getTaxableIncome().doubleValue() <= 144000L) {
// // 此阶税率为百分之3速减数为0
// rzSalaryDetail.setTaxRate(new BigDecimal("0.10"));
// // 速算扣除数速算扣除数跟税率同步
// rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("2520"));
// } else if (rzSalaryDetail.getTaxableIncome().doubleValue() > 144000L && rzSalaryDetail.getTaxableIncome().doubleValue() <= 300000l) {
// // 此阶税率为百分之3速减数为0
// rzSalaryDetail.setTaxRate(new BigDecimal("0.20"));
// // 速算扣除数速算扣除数跟税率同步
// rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("16920"));
// } else if (rzSalaryDetail.getTaxableIncome().doubleValue() > 300000l && rzSalaryDetail.getTaxableIncome().doubleValue() <= 420000l) {
// // 此阶税率为百分之3速减数为0
// rzSalaryDetail.setTaxRate(new BigDecimal("0.25"));
// // 速算扣除数速算扣除数跟税率同步
// rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("31920"));
// } else if (rzSalaryDetail.getTaxableIncome().doubleValue() > 420000l && rzSalaryDetail.getTaxableIncome().doubleValue() <= 660000l) {
// // 此阶税率为百分之3速减数为0
// rzSalaryDetail.setTaxRate(new BigDecimal("0.30"));
// // 速算扣除数速算扣除数跟税率同步
// rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("52920"));
// } else if (rzSalaryDetail.getTaxableIncome().doubleValue() > 660000l && rzSalaryDetail.getTaxableIncome().doubleValue() <= 960000l) {
// // 此阶税率为百分之3速减数为0
// rzSalaryDetail.setTaxRate(new BigDecimal("0.35"));
// // 速算扣除数速算扣除数跟税率同步
// rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("85920"));
// } else if (rzSalaryDetail.getTaxableIncome().doubleValue() > 960000l) {
// // 此阶税率为百分之3速减数为0
// rzSalaryDetail.setTaxRate(new BigDecimal("0.45"));
// // 速算扣除数速算扣除数跟税率同步
// rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("181920"));
// } else {
// // 应纳税所得额小于0(免征额+专项扣除>应发工资时)
// // 此阶税率为百分之0速减数为0
// rzSalaryDetail.setTaxRate(new BigDecimal("0.00"));
// // 速算扣除数速算扣除数跟税率同步
// rzSalaryDetail.setSlowDownTheDeduction(new BigDecimal("0"));
// }
//
// //判断是否外包外包公司员工不做税(月薪50000不上税)
// if("外包".equals(sysStaff.getCompanyName())){
// // 实发工资 = 税前工资
// rzSalaryDetail.setNetPayroll(rzSalaryDetail.getSalaryBeforeTax());
// }else {
// // 应纳税额 (本年累计已发工资-年度免征额-累计专项扣除-本月专项扣除)
// BigDecimal tax = rzSalaryDetail.getTotalWages().subtract(rzSalaryDetail.getSpecialDeduction()).subtract(rzSalaryDetail.getAnnualExemptionAmount());
// if(tax.doubleValue() <= 0.0){
// rzSalaryDetail.setTaxableIncome(new BigDecimal("0.00"));
// }else{
// rzSalaryDetail.setTaxableIncome(tax);
// }
// // 判断税前工资是否大于5000,如果小于则不在计算个税
// if (rzSalaryDetail.getSalaryBeforeTax().doubleValue() > 5000.00){
// // 本月应缴税额(本月应纳税所得额*税率-速减数-本年累计已预缴个税)
// rzSalaryDetail.setTaxPayable(
// rzSalaryDetail.getTaxableIncome().multiply(rzSalaryDetail.getTaxRate()).subtract(rzSalaryDetail.getSlowDownTheDeduction()).subtract(sysStaffDetail.getAggregatePersonalIncomeTax()));
// if (rzSalaryDetail.getTaxPayable().doubleValue() <= 0) {
// rzSalaryDetail.setTaxPayable(new BigDecimal("0.00"));
// }
// } else {
// // 应纳税所得额
// rzSalaryDetail.setTaxableIncome(new BigDecimal("0.00"));
// rzSalaryDetail.setTaxPayable(new BigDecimal("0.00"));
// }
// // 实发工资税前工资-本月应缴个人所得税
// rzSalaryDetail.setNetPayroll(rzSalaryDetail.getSalaryBeforeTax().subtract(rzSalaryDetail.getTaxPayable()));
// // 本年累计已缴税额
// rzSalaryDetail.setAggregatePersonalIncomeTax(sysStaffDetail.getAggregatePersonalIncomeTax().add(rzSalaryDetail.getTaxPayable()));
// }
// rzSalaryDetail.setCreateTime(DateUtils.getNowDate());
// rzSalaryDetail.setDelFlag(Constants.DELETE_FLAG_0);
// rzSalaryDetail.setCreateBy(SecurityUtils.getUsername());
// // 保存工资信息
// i = rzSalaryDetailMapper.insertRzSalaryDetail(rzSalaryDetail);
// if(i < 1){
// return AjaxResult.error();
// }
// //判断统计月缴费公司和上一次是否一个公司
// if(StringUtils.isNull(old_rzSalary) || old_rzSalary.getWbFlag().equals(sysStaff.getCompanyName())){
// // 把本年累计个税
// sysStaffDetail.setAggregatePersonalIncomeTax(rzSalaryDetail.getAggregatePersonalIncomeTax());
// // 把本年累计专项扣除保存到员工信息表中
// sysStaffDetail.setSpecialDeduction(sysStaffDetail.getSpecialDeduction().add(rzSalaryDetail.getSpecialDeduction()));
// // 把本年累计已发工资保存到员工信息表中
// sysStaffDetail.setTotalWages(rzSalaryDetail.getTotalWages());
// i = sysStaffDetailMapper.updateSysStaffDetail(sysStaffDetail);
// if(i < 1){
// return AjaxResult.error();
// }
// }else{
// //删除原来的数据
// sysStaffDetail.setDelFlag(Constants.DELETE_FLAG_1);
// i = sysStaffDetailMapper.updateSysStaffDetail(sysStaffDetail);
// //新建详情数据
// // 把本年累计已缴个税保存到员工信息表中
// sysStaffDetail.setAggregatePersonalIncomeTax(rzSalaryDetail.getTaxPayable());
// // 把本年累计专项扣除保存到员工信息表中
// sysStaffDetail.setSpecialDeduction(rzSalaryDetail.getSpecialDeduction());
// // 把本年累计已发工资保存到员工信息表中
// sysStaffDetail.setTotalWages(rzSalaryDetail.getSalaryBeforeTax());
// sysStaffDetail.setId(null);
// i = sysStaffDetailMapper.insertSysStaffDetail(sysStaffDetail);
// if(i < 1){
// return AjaxResult.error();
// }
// }
// }
//关闭日志记录
ParamUtils.updateLogOperation(false);
return AjaxResult.success();
}
// public void autoCalculationOverTimeWorkSalary(RzSalaryDetail rzSalaryDetail, RzAttendanceStatistical attendanceStatistical, Boolean isOverTime){
// if(!isOverTime){
// rzSalaryDetail.setOvertimeSalary(new BigDecimal(0));
// }else{
// BigDecimal salary = rzSalaryDetail.getJobSalary().add(rzSalaryDetail.getBasicSalary());
// BigDecimal hourlyWage = salary.divide(new BigDecimal(ParamUtils.getMonthWorkDayNum(DateUtils.getMonth(rzSalaryDetail.getMonth()))),2,BigDecimal.ROUND_HALF_UP);
// //计算加班工资
// rzSalaryDetail.setOvertimeSalary(attendanceStatistical.getOverTimeHours().multiply(hourlyWage));
// }
//
// }
/**
* 计算员工的工资信息
* @param sysStaff 员工信息
* @param month 统计月份
* @param date 统计月10日
* @return
*/
private SysStaffDetail calculateSalary(SysStaff sysStaff, Date month,Date date){
//获取统计月份
Calendar calendar = Calendar.getInstance();
calendar.setTime(month);
//获取当前月
Integer monthNum = calendar.getActualMaximum(Calendar.MONTH);
//根据当前月获取字典信息
// String wordDays = sysDictDataService.selectDictValue("sys_work_days", monthNum+"");
//如果没有配置工作时长, 则默认为26天工作日
// if(StringUtils.isEmpty(wordDays)){
// wordDays = "26";
// }
// //计算当月出勤时长
// Integer workHours = Integer.valueOf(wordDays)*8;
//计算是否全勤
// rzHolidayMapper.selectList();
//获取假期信息
//判断假期和特殊上班时间
// List<RzHoliday> h_list = rzHolidayMapper.selectRzHolidayList(null);
return null;
//获取全年天数 - 节假日天数
// int days = calendar.getActualMaximum(Calendar.DAY_OF_YEAR);
// SimpleDateFormat sdfm = new SimpleDateFormat("yyyy-MM");
// SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd");
// //判断假期和特殊上班时间
// List<RzHoliday> h_list = rzHolidayMapper.selectRzHolidayList(null);
// try{
// //获取统计月所在年的开始和结束时间,统计一年的工作日期
// String start = sdfm.format(monthNum).split("-")[0] + "-01-01";
// String end = sdfm.format(monthNum).split("-")[0] + "-12-31";
// days -= DateUtil.isWeeked(sdfd.parse(start),sdfd.parse(end),1);
// for (RzHoliday rzHoliday : h_list) {
// if(rzHoliday.getHoliday().after(sdfd.parse(sdfm.format(monthNum)+"-01")) && rzHoliday.getHoliday().before(sdfd.parse(sdfm.format(monthNum)+"-" + calendar.get(Calendar.DAY_OF_MONTH)))){
// if("1".equals(rzHoliday.getSpecialFlag())){
// days += 1;
// }
// }
// }
// }catch (Exception e){
// e.printStackTrace();
// }
// //记录工资详情
// SysStaffDetail sysStaffDetail = sysStaffDetailMapper.selectSysStaffDetailByStaffId(sysStaff.getUserId());
// //补助扣除比例
// BigDecimal bfb = new BigDecimal("0.00");
// //获取考勤统计
// RzAttendanceStatistical rzAttendanceStatistical = rzAttendanceStatisticalMapper.getRzAttendanceStatisticalByDateAndName(sysStaff.getUserId(), monthNum);
//// //判断入职日期社保缴纳日期以前入职计算补助扣除比例
// if(sysStaff.getEmploymentDate().before(date)){
// //计算请假百分比
// BigDecimal b = rzAttendanceStatistical.getAbsenteeism().divide(new BigDecimal("4"));
// bfb = b.multiply(new BigDecimal(Constants.SUBSIDY_PROPORTION));
// sysStaffDetail.setAbsenteeismSubsidies(bfb);
// }else{
// sysStaffDetail.setAbsenteeismSubsidies(new BigDecimal("1.00"));
// }
// sysStaffDetail.setNightShiftSubsidies(sysStaffDetail.getNightShiftSubsidies().multiply(new BigDecimal(rzAttendanceStatistical.getNightNumber())));
// sysStaffDetail.setDinnerSubsidies(sysStaffDetail.getDinnerSubsidies().multiply(new BigDecimal(rzAttendanceStatistical.getNightNumber())));
//// //是否打卡
// if("".equals(sysStaff.getClockIn())){
// return sysStaffDetail;
// }
// //查询员工考勤月的考勤
// List<RzAttendance> att_list = rzAttendanceMapper.queryMonthAttendanceByStaffId(sysStaff.getUserId(), monthNum);
// //判断是日工资
// if(sysStaffDetail.getDailyWage().doubleValue() > 0) {
// //额薪资日期在工资月下一个月
// calendar.set(Calendar.MONTH,1);
// //全额薪资日期在工资月以前
// if(sysStaff.getWagesRatioDate().before(monthNum)) {
// sysStaffDetail.setBasicSalary(sysStaffDetail.getDailyWage().divide(new BigDecimal("8.0"),2, RoundingMode.HALF_UP)
// .multiply(rzAttendanceStatistical.getRealAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber())));
// }else if(sysStaff.getWagesRatioDate().after(calendar.getTime())) {
// sysStaffDetail.setBasicSalary(sysStaffDetail.getDailyWage().divide(new BigDecimal("8.0"),2, RoundingMode.HALF_UP)
// .multiply(rzAttendanceStatistical.getRealAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber())).multiply(new BigDecimal(Constants.SUBSIDY_PERIOD)));
// }else {
// //根据转正日期查询员工的打卡信息
// BigDecimal att_work = new BigDecimal("0.0");
// for (RzAttendance rzAttendance : att_list) {
// if(rzAttendance.getAttendanceDate().before(sysStaff.getWagesRatioDate())) {
// att_work = att_work.add(rzAttendance.getWorkSum());
// }
// }
// //未转正需要扣除的工资
// BigDecimal work = sysStaffDetail.getDailyWage().divide(new BigDecimal("8.0"),2, RoundingMode.HALF_UP).multiply(att_work).multiply(new BigDecimal(Constants.SUBSIDY_PERIOD_1));
// sysStaffDetail.setBasicSalary(sysStaffDetail.getDailyWage().divide(new BigDecimal("8.0"),2, RoundingMode.HALF_UP)
// .multiply(rzAttendanceStatistical.getRealAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber())).subtract(work));
// }
// sysStaffDetail.setOverWages(sysStaffDetail.getDailyWage().divide(new BigDecimal("8.0"),2, RoundingMode.HALF_UP).multiply(rzAttendanceStatistical.getWorkOvertimeNumber()));
// sysStaffDetail.setAbsenteeismSalary(new BigDecimal("0.00"));
// sysStaffDetail.setMiddleSubsidies(sysStaffDetail.getMiddleSubsidies().multiply(new BigDecimal(rzAttendanceStatistical.getMiddleShiftNumber())));
// }
//判断是小时工
// if(sysStaffDetail.getHoursSalary().doubleValue() > 0) {
// //额薪资日期在工资月下一个月
// calendar.set(Calendar.MONTH,1);
// //全额薪资日期在工资月以前
// if(sysStaff.getWagesRatioDate().before(month)) {
// sysStaffDetail.setBasicSalary(sysStaffDetail.getHoursSalary().multiply(rzAttendanceStatistical.getRealAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber())));
// }else if(sysStaff.getWagesRatioDate().after(calendar.getTime())) {
// sysStaffDetail.setBasicSalary(sysStaffDetail.getHoursSalary().multiply(rzAttendanceStatistical.getRealAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber())).multiply(new BigDecimal(Constants.SUBSIDY_PERIOD)));
// }else {
// //根据转正日期查询员工的打卡信息
// BigDecimal att_work = new BigDecimal("0.0");
// for (RzAttendance rzAttendance : att_list) {
// if(rzAttendance.getAttendanceDate().before(sysStaff.getWagesRatioDate())) {
// att_work = att_work.add(rzAttendance.getWorkSum());
// }
// }
// //未转正需要扣除的工资
// BigDecimal work = sysStaffDetail.getHoursSalary().multiply(att_work).multiply(new BigDecimal(Constants.SUBSIDY_PERIOD_1));
// sysStaffDetail.setBasicSalary(sysStaffDetail.getHoursSalary().multiply(rzAttendanceStatistical.getRealAttendance().add(rzAttendanceStatistical.getWorkOvertimeNumber())).subtract(work));
// }
// sysStaffDetail.setOverWages(sysStaffDetail.getHoursSalary().multiply(rzAttendanceStatistical.getWorkOvertimeNumber()));
// sysStaffDetail.setAbsenteeismSalary(new BigDecimal("0.00"));
// sysStaffDetail.setMiddleSubsidies(sysStaffDetail.getMiddleSubsidies().multiply(new BigDecimal(rzAttendanceStatistical.getMiddleShiftNumber())));
// }
// //判断是月工资
// if(sysStaffDetail.getBasicSalary().doubleValue() > 0 || sysStaffDetail.getJobsSalary().longValue() > 0) {
// //额薪资日期在工资月下一个月
// calendar.set(Calendar.MONTH,1);
// //全额薪资日期在工资月以前
// if(sysStaff.getWagesRatioDate().before(monthNum)) {
// sysStaffDetail.setBasicSalary(sysStaffDetail.getBasicSalary().add(sysStaffDetail.getJobsSalary()));
// }else if(sysStaff.getWagesRatioDate().after(calendar.getTime())) {
// BigDecimal hours = sysStaffDetail.getBasicSalary().add(sysStaffDetail.getJobsSalary()).divide(rzAttendanceStatistical.getShouldAttendance(),2, RoundingMode.HALF_UP);
// sysStaffDetail.setBasicSalary(hours.multiply(rzAttendanceStatistical.getRealAttendance()).multiply(new BigDecimal(Constants.SUBSIDY_PERIOD)));
// }else {
// //根据转正日期查询员工的打卡信息
// BigDecimal att_work = new BigDecimal("0.0");
// for (RzAttendance rzAttendance : att_list) {
// if(rzAttendance.getAttendanceDate().before(sysStaff.getWagesRatioDate())) {
// att_work = att_work.add(rzAttendance.getWorkSum());
// }
// }
// //未转正需要扣除的工资
// BigDecimal work = sysStaffDetail.getBasicSalary().add(sysStaffDetail.getJobsSalary()).divide(rzAttendanceStatistical.getShouldAttendance(),2, RoundingMode.HALF_UP)
// .multiply(att_work).multiply(new BigDecimal(Constants.SUBSIDY_PERIOD_1));
// sysStaffDetail.setBasicSalary(sysStaffDetail.getBasicSalary().add(sysStaffDetail.getJobsSalary()).subtract(work));
// }
// //计算月工资的每小时工资
// BigDecimal evrymoney = sysStaffDetail.getBasicSalary().multiply(new BigDecimal("11.00"))
// .add(sysStaffDetail.getBasicSalary().multiply(new BigDecimal(Constants.SUBSIDY_PERIOD)))
// .divide(new BigDecimal(days).multiply(new BigDecimal("8.00")),2, RoundingMode.HALF_UP);
// sysStaffDetail.setAbsenteeismSalary(evrymoney.multiply(rzAttendanceStatistical.getShouldAttendance().subtract(rzAttendanceStatistical.getRealAttendance())));
//// sysStaffDetail.setMiddleSubsidies(new BigDecimal("0.00"));
// //根据用户获取当前的加班情况
// RzSpecialOverTime rSpecialOverTime = rzSpecialOverTimeMapper.selectRzSpecialOverTimeByUserIdAndDate(sysStaff.getUserId(), monthNum);
// if(StringUtils.isNull(rSpecialOverTime)){
// sysStaffDetail.setOverWages(new BigDecimal("0.00"));
// }else{
// sysStaffDetail.setOverWages(evrymoney.multiply(rSpecialOverTime.getSickHours()));
// }
// }
// //判断员工的上班时长设置保险的补交
// BigDecimal baifenbi = rzAttendanceStatistical.getRealAttendance().divide(rzAttendanceStatistical.getShouldAttendance(),2, RoundingMode.HALF_UP);
// if(baifenbi.compareTo(new BigDecimal("0.20")) > 0 && baifenbi.compareTo(new BigDecimal("0.40")) <= 0){
// sysStaffDetail.setCountInsurance(sysStaffDetail.getCountInsurance().multiply(new BigDecimal("0.70")));
// }else if(baifenbi.compareTo(new BigDecimal("0.40")) > 0 && baifenbi.compareTo(new BigDecimal("0.60")) <= 0){
// sysStaffDetail.setCountInsurance(sysStaffDetail.getCountInsurance().multiply(new BigDecimal("0.50")));
// }else if(baifenbi.compareTo(new BigDecimal("0.60")) > 0){
// sysStaffDetail.setCountInsurance(sysStaffDetail.getCountInsurance());
// }else{
// sysStaffDetail.setCountInsurance(new BigDecimal("0.00"));
// }
// return sysStaffDetail;
}
/**
* 修改工资详情
*

View File

@ -0,0 +1,154 @@
package com.evo.framework.aspectj;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.evo.attendance.domain.RzAttendanceStatistical;
import com.evo.attendance.service.IRzAttendanceStatisticalService;
import com.evo.common.annotation.Log;
import com.evo.common.annotation.StatisticalOperationLog;
import com.evo.common.core.domain.entity.SysUser;
import com.evo.common.core.domain.model.LoginUser;
import com.evo.common.enums.BusinessStatus;
import com.evo.common.enums.HttpMethod;
import com.evo.common.filter.PropertyPreExcludeFilter;
import com.evo.common.utils.ParamUtils;
import com.evo.common.utils.SecurityUtils;
import com.evo.common.utils.ServletUtils;
import com.evo.common.utils.StringUtils;
import com.evo.common.utils.ip.IpUtils;
import com.evo.framework.manager.AsyncManager;
import com.evo.framework.manager.factory.AsyncFactory;
import com.evo.system.domain.SysOperLog;
import com.evo.system.domain.SysStatisticalOperationLog;
import com.evo.system.service.AsyncLogService;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.ibatis.session.SqlSession;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;
import java.util.Objects;
/**
* 考勤操作记录类
*
* @ClassName:StatisticalOperationAspect
* @date: 2025年09月18日 15:26
* @author: andy.shi
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Aspect
@Component
public class StatisticalOperationAspect {
private final AsyncLogService asyncLogService;
private final IRzAttendanceStatisticalService rzAttendanceStatisticalService;
private final SqlSession sqlSession;
public StatisticalOperationAspect(AsyncLogService asyncLogService, IRzAttendanceStatisticalService rzAttendanceStatisticalService, SqlSession sqlSession) {
this.asyncLogService = asyncLogService;
this.rzAttendanceStatisticalService = rzAttendanceStatisticalService;
this.sqlSession = sqlSession;
}
/**
* 切点扫描ApiLog注解的类
*/
@Pointcut("@annotation(com.evo.common.annotation.StatisticalOperationLog)")
public void applicationPackagePointcut() {
// 方法为空因为这只是一个切入点实现在advices.
}
public HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
}
/**
* 在进入和退出方法时记录日志
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("applicationPackagePointcut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = null;
if(ParamUtils.checkLogOperation()){
/**
* 登录前和退出后中获取不到currentUser信息所以在这里做特殊处理
*/
SysStatisticalOperationLog log = getLog(joinPoint);
//记录原始数据
if(log.getBusinessId() != null){
log.setOldInfo(StringUtils.substring(JSON.toJSONString(rzAttendanceStatisticalService.selectRzAttendanceStatisticalById(log.getBusinessId())), 0, 2000));
// sqlSession.clearCache();
}
result = joinPoint.proceed();
//记录新的数据
if(log.getBusinessId() != null && Integer.valueOf(String.valueOf(result)) == Integer.valueOf("1")){
log.setNewInfo(StringUtils.substring(JSON.toJSONString(rzAttendanceStatisticalService.selectRzAttendanceStatisticalById(log.getBusinessId())), 0, 2000));
}
asyncLogService.saveStatisticalOperationLog(log);
}else{
result = joinPoint.proceed();
}
return result;
}
public static SysStatisticalOperationLog getLog(JoinPoint joinPoint) {
try
{
// 获取当前的用户
LoginUser loginUser = SecurityUtils.getLoginUser();
// *========数据库日志=========*//
SysStatisticalOperationLog sysStatisticalOperationLog = new SysStatisticalOperationLog();
if (loginUser != null)
{
sysStatisticalOperationLog.setOperationAccount(loginUser.getUsername());
sysStatisticalOperationLog.setOperationTime(new Date());
}
Object[] paramsArray = joinPoint.getArgs();
if (paramsArray != null && paramsArray.length > 0){
RzAttendanceStatistical rzAttendanceStatistical = (RzAttendanceStatistical)paramsArray[0];
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;
// 处理设置注解上的参数
}catch (Exception exp)
{
// 记录本地异常日志
exp.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,37 @@
package com.evo.system.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.evo.common.core.domain.BaseEntity;
import lombok.Data;
import java.util.Date;
/**
* 考勤操作记录
*
* @author evo
*/
@Data
public class SysStatisticalOperationLog extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 日志主键 */
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**操作年月 */
private Date month;
/** 原始数据 */
private String oldInfo;
/** 新数据 */
private String newInfo;
/** 操作人员 */
private String operationAccount;
/** 操作时间 */
private Date operationTime;
/** 业务数据名称 */
private String businessName;
/** 业务数据id */
private Long businessId;
}

View File

@ -0,0 +1,26 @@
package com.evo.system.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* 考勤操作记录
*
* @author evo
*/
@Data
public class SysStatisticalOperationLogVO<T>
{
private static final long serialVersionUID = 1L;
/** 原始数据 */
private T oldInfo;
/** 新数据 */
private T newInfo;
/** 操作人员 */
private String operationAccount;
/** 操作时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date operationTime;
}

View File

@ -0,0 +1,16 @@
package com.evo.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evo.system.domain.SysStaff;
import com.evo.system.domain.SysStatisticalOperationLog;
/**
* 接口
*
* @ClassName:SysStatisticalOperationLogMapper
* @date: 2025年09月18日 16:35
* @author: andy.shi
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
public interface SysStatisticalOperationLogMapper extends BaseMapper<SysStatisticalOperationLog> {
}

View File

@ -0,0 +1,31 @@
package com.evo.system.service;
import com.evo.system.domain.SysStatisticalOperationLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
/**
*
*
* @ClassName:AsyncLogService
* @date: 2025年09月18日 15:29
* @author: andy.shi
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Service
public class AsyncLogService {
@Autowired
private ISysStatisticalOperationLogService sysStatisticalOperationLogService;
/**
* 异步保存日志
*
* @throws Throwable
*/
@Async
public void saveStatisticalOperationLog(SysStatisticalOperationLog log) {
sysStatisticalOperationLogService.save(log);
}
}

View File

@ -0,0 +1,20 @@
package com.evo.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.evo.system.domain.SysOperLog;
import com.evo.system.domain.SysStatisticalOperationLog;
import com.evo.system.domain.vo.SysStatisticalOperationLogVO;
import org.apache.poi.ss.formula.functions.T;
import java.util.List;
/**
* 操作日志 服务层
*
* @author evo
*/
public interface ISysStatisticalOperationLogService extends IService<SysStatisticalOperationLog>
{
<T> List<SysStatisticalOperationLogVO<T>> getOperationByBusinessId(Long businessId, Class<T> objectClass);
}

View File

@ -0,0 +1,46 @@
package com.evo.system.service.impl;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evo.common.utils.Collections;
import com.evo.common.utils.bean.BeanUtils;
import com.evo.system.domain.SysStatisticalOperationLog;
import com.evo.system.domain.vo.SysStatisticalOperationLogVO;
import com.evo.system.mapper.SysStatisticalOperationLogMapper;
import com.evo.system.service.ISysStatisticalOperationLogService;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
*
*
* @ClassName:SysStatisticalOperationLogServiceImpl
* @date: 2025年09月18日 16:34
* @author: andy.shi
* @remark: 开发人员联系方式 1042025947@qq.com/微信同步
*/
@Service
public class SysStatisticalOperationLogServiceImpl extends ServiceImpl<SysStatisticalOperationLogMapper, SysStatisticalOperationLog> implements ISysStatisticalOperationLogService {
@Override
public <T> List<SysStatisticalOperationLogVO<T>> getOperationByBusinessId(Long businessId, Class<T> objectClass) {
List<SysStatisticalOperationLog> operationLogList = list(new LambdaQueryWrapper<SysStatisticalOperationLog>().eq(SysStatisticalOperationLog::getBusinessId, businessId).orderByDesc(SysStatisticalOperationLog::getOperationTime));
if(Collections.isNotEmpty(operationLogList)){
return operationLogList.stream().map(data -> buildSysStatisticalOperationLogVO(data, objectClass)).collect(Collectors.toList());
}
return Collections.emptyList();
}
public <T> SysStatisticalOperationLogVO<T> buildSysStatisticalOperationLogVO(SysStatisticalOperationLog data, Class<T> objectClass){
SysStatisticalOperationLogVO vo = new SysStatisticalOperationLogVO<SysStatisticalOperationLog>();
BeanUtils.copyProperties(data, vo);
vo.setNewInfo(JSONObject.parseObject(data.getNewInfo(), objectClass));
vo.setOldInfo(JSONObject.parseObject(data.getOldInfo(), objectClass));
return vo;
}
}