feat(smartfactory): 增加工种筛选功能并优化考勤记录逻辑
- 在 StaffAttendanceRecordReqVO 中添加 workTypeId 字段,用于工种筛选 - 修改 StaffService 接口,增加按工种筛选的 getListByFactory 方法 - 重构 StaffAttendanceRecordServiceImpl 中的 convertRecord 方法,提高代码可读性和维护性 - 优化 StaffSalaryServiceImpl 中的扣款金额计算逻辑 - 在 StaffMapper 和 StaffSalaryMapper 中添加创建时间降序排序
This commit is contained in:
parent
224a758f11
commit
875a3ff406
@ -149,8 +149,9 @@ public class StaffAttendanceRecordController {
|
||||
// 查询该厂区员工在 其他厂区得考勤记录
|
||||
List<StaffAttendanceRecordDO> otherRecordDOS = staffAttendanceRecordService.getOtherRecord(reqVO);
|
||||
|
||||
// 获取工厂员工列表
|
||||
List<StaffDO> staffDOS = staffService.getListByFactory(reqVO.getFactoryId(), true);
|
||||
// 获取工厂员工列表,支持工种筛选
|
||||
List<Integer> workTypeIds = reqVO.getWorkTypeId() != null ? Collections.singletonList(reqVO.getWorkTypeId()) : null;
|
||||
List<StaffDO> staffDOS = staffService.getListByFactory(reqVO.getFactoryId(), true, workTypeIds);
|
||||
Map<Long, StaffDO> staffMap = convertMap(staffDOS, StaffDO::getId);
|
||||
|
||||
if (CollUtil.isNotEmpty(recordDOS)) {
|
||||
@ -180,7 +181,7 @@ public class StaffAttendanceRecordController {
|
||||
|
||||
recordRespVO.addAll(otherRespVO);
|
||||
return success(recordRespVO);
|
||||
}else {
|
||||
} else {
|
||||
// 判断是否 新增考勤情况
|
||||
if (reqVO.getFactoryId() != null && reqVO.getMonth() != null && reqVO.getType() != null) {
|
||||
|
||||
@ -196,7 +197,7 @@ public class StaffAttendanceRecordController {
|
||||
.setStaffName(staffDO.getNickName())
|
||||
.setWorkTypeId(staffDO.getWorkTypeId());
|
||||
return success(Collections.singletonList(respVO));
|
||||
}else {
|
||||
} else {
|
||||
List<StaffAttendanceRecordRespVO> respVO = staffDOS.stream()
|
||||
.map(staffDO -> new StaffAttendanceRecordRespVO()
|
||||
.setStaffId(staffDO.getId())
|
||||
@ -220,7 +221,7 @@ public class StaffAttendanceRecordController {
|
||||
@PreAuthorize("@ss.hasPermission('smartfactory:staff-attendance-record:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportStaffAttendanceRecordExcel(@Valid StaffAttendanceRecordReqVO reqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
HttpServletResponse response) throws IOException {
|
||||
|
||||
List<StaffAttendanceRecordDO> recordDOS = staffAttendanceRecordService.getStaffAttendanceRecordList(reqVO);
|
||||
// 导出 Excel
|
||||
@ -239,4 +240,4 @@ public class StaffAttendanceRecordController {
|
||||
staffAttendanceRecordService.updateReview(factoryId, month);
|
||||
return success(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,4 +20,7 @@ public class StaffAttendanceRecordReqVO {
|
||||
|
||||
@Schema(description = "考勤方式 | 1.正常月份 2.25号开始计算至下个月24号", example = "1")
|
||||
private Integer type;
|
||||
}
|
||||
|
||||
@Schema(description = "工种id", example = "1")
|
||||
private Integer workTypeId;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ public interface StaffMapper extends BaseMapperX<StaffDO> {
|
||||
query.eqIfPresent(StaffDO::getFactoryId, pageReqVO.getFactoryId());
|
||||
query.eqIfPresent(StaffDO::getWorkTypeId, pageReqVO.getWorkTypeId());
|
||||
query.eqIfPresent(StaffDO::getId, pageReqVO.getStaffId());
|
||||
|
||||
query.orderByDesc(StaffSalaryDO::getCreateTime);
|
||||
return selectJoinPage(pageReqVO, StaffSalaryRespVO.class, query);
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ public interface StaffSalaryMapper extends BaseMapperX<StaffSalaryDO> {
|
||||
query.eqIfPresent(StaffSalaryDO::getStatus, reqVO.getStatus());
|
||||
query.eqIfPresent(StaffSalaryDO::getIsGrant, reqVO.getIsGrant());
|
||||
query.apply(Objects.nonNull(reqVO.getWorkTypeId()), "staff.work_type_id = {0} ", reqVO.getWorkTypeId());
|
||||
|
||||
query.orderByDesc(StaffSalaryDO::getCreateTime);
|
||||
return selectJoinPage(reqVO, StaffSalaryRespVO.class, query);
|
||||
}
|
||||
|
||||
@ -60,4 +60,4 @@ public interface StaffSalaryMapper extends BaseMapperX<StaffSalaryDO> {
|
||||
|
||||
return selectJoinList(StaffSalaryRespVO.class, query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ public class StaffAttendanceRecordServiceImpl implements StaffAttendanceRecordSe
|
||||
|
||||
List<StaffAttendanceRecordDO> lastMonthRecord = staffAttendanceRecordMapper.selectList(new LambdaQueryWrapperX<StaffAttendanceRecordDO>()
|
||||
.eq(StaffAttendanceRecordDO::getStaffId, staffId)
|
||||
.betweenIfPresent(StaffAttendanceRecordDO::getPunchTime, new LocalDate[]{ beginDate, lastMonthEnd }));
|
||||
.betweenIfPresent(StaffAttendanceRecordDO::getPunchTime, new LocalDate[]{beginDate, lastMonthEnd}));
|
||||
|
||||
recordDOS.addAll(lastMonthRecord);
|
||||
}
|
||||
@ -176,7 +176,7 @@ public class StaffAttendanceRecordServiceImpl implements StaffAttendanceRecordSe
|
||||
// 获取查询月份得第25日日期
|
||||
LocalDate lastMonthEnd = now.withDayOfMonth(25);
|
||||
|
||||
date = new LocalDate[]{ beginDate, lastMonthEnd };
|
||||
date = new LocalDate[]{beginDate, lastMonthEnd};
|
||||
}
|
||||
return staffAttendanceRecordMapper.selectRecordList(reqVO, date);
|
||||
}
|
||||
@ -216,48 +216,20 @@ public class StaffAttendanceRecordServiceImpl implements StaffAttendanceRecordSe
|
||||
public List<StaffAttendanceRecordRespVO> convertRecord(StaffAttendanceRecordReqVO reqVO,
|
||||
List<StaffAttendanceRecordDO> recordDOS,
|
||||
List<StaffAttendanceRecordDO> otherRecordDOS) {
|
||||
// 根据考勤类型 生成对应得日期数据
|
||||
List<AttendanceRecordVO> punchTimeList = new ArrayList<>();
|
||||
// 根据考勤类型生成对应的日期列表
|
||||
List<AttendanceRecordVO> punchTimeList = generatePunchTimeList(reqVO);
|
||||
|
||||
// 获取所选月份的第一天
|
||||
LocalDate now = LocalDate.parse(reqVO.getMonth() + "-01", DateTimeFormatter.ISO_LOCAL_DATE);
|
||||
if (reqVO.getType() == 1) {
|
||||
|
||||
// 获取上月26日日期
|
||||
LocalDate beginDate = now.minusMonths(1).withDayOfMonth(26);
|
||||
// 本月25日日期
|
||||
LocalDate lastMonthEnd = now.withDayOfMonth(25);
|
||||
|
||||
while (!beginDate.isAfter(lastMonthEnd)) {
|
||||
AttendanceRecordVO attendanceRecordVO = new AttendanceRecordVO()
|
||||
.setPunchTime(beginDate);
|
||||
punchTimeList.add(attendanceRecordVO);
|
||||
|
||||
beginDate = beginDate.plusDays(1);
|
||||
}
|
||||
}
|
||||
if (reqVO.getType() == 2) {
|
||||
// 获取所选月份的第一天
|
||||
LocalDate firstDayOfMonth = LocalDate.parse(reqVO.getMonth() + "-01", DateTimeFormatter.ISO_LOCAL_DATE);
|
||||
|
||||
// 生成当月每一天的 LocalDate
|
||||
for (int i = 0; i < firstDayOfMonth.lengthOfMonth(); i++) {
|
||||
AttendanceRecordVO attendanceRecordVO = new AttendanceRecordVO()
|
||||
.setPunchTime(firstDayOfMonth.plusDays(i));
|
||||
punchTimeList.add(attendanceRecordVO);
|
||||
}
|
||||
}
|
||||
// 获取员工信息
|
||||
// 获取员工信息 - 在当前厂区打卡的员工信息
|
||||
List<StaffDO> staffDOS = staffService.getList(convertSet(recordDOS, StaffAttendanceRecordDO::getStaffId));
|
||||
Map<Long, StaffDO> staffMap = convertMap(staffDOS, StaffDO::getId);
|
||||
|
||||
// 获取厂区信息
|
||||
// 获取厂区信息 - 获取员工所打卡的所有厂区ids - 获取所有厂区信息
|
||||
Set<Long> factoryIds = convertSet(recordDOS, StaffAttendanceRecordDO::getFactoryId);
|
||||
factoryIds.addAll(convertList(otherRecordDOS, StaffAttendanceRecordDO::getFactoryId));
|
||||
List<FactoryInfoDO> factoryDOS = factoryInfoService.getFactoryList(factoryIds);
|
||||
Map<Long, FactoryInfoDO> factoryMap = convertMap(factoryDOS, FactoryInfoDO::getId);
|
||||
|
||||
// 根据用户 分组打卡记录
|
||||
// 根据用户分组打卡记录
|
||||
Map<Long, List<StaffAttendanceRecordDO>> recordMap = convertMultiMap(recordDOS, StaffAttendanceRecordDO::getStaffId);
|
||||
|
||||
// 重组数据
|
||||
@ -275,10 +247,12 @@ public class StaffAttendanceRecordServiceImpl implements StaffAttendanceRecordSe
|
||||
reqVO.getType(),
|
||||
reqVO.getMonth());
|
||||
|
||||
// 筛选同一个工厂打卡数据并按日期建立映射
|
||||
Map<LocalDate, AttendanceRecordVO> records = entry.getValue().stream()
|
||||
.filter(record -> record.getFactoryId().equals(reqVO.getFactoryId())) // 筛选同一个工厂打卡数据
|
||||
.filter(record -> record.getFactoryId().equals(reqVO.getFactoryId()))
|
||||
.map(item -> BeanUtils.toBean(item, AttendanceRecordVO.class))
|
||||
.collect(Collectors.toMap(AttendanceRecordVO::getPunchTime, value -> value));
|
||||
|
||||
// 设置打卡数据
|
||||
List<AttendanceRecordVO> recordVOS = punchTimeList.stream()
|
||||
.map(record -> {
|
||||
@ -289,44 +263,16 @@ public class StaffAttendanceRecordServiceImpl implements StaffAttendanceRecordSe
|
||||
return recordVO;
|
||||
}).collect(Collectors.toList());
|
||||
respVO.setRecords(recordVOS);
|
||||
// 设置员工名称
|
||||
respVO.setStaffName(staffMap.get(entry.getKey()).getNickName());
|
||||
// 设置工种
|
||||
respVO.setWorkTypeId(staffMap.get(entry.getKey()).getWorkTypeId());
|
||||
// 设置厂区名称
|
||||
|
||||
// 设置员工名称、工种、厂区名称
|
||||
StaffDO staffDO = staffMap.get(entry.getKey());
|
||||
respVO.setStaffName(staffDO.getNickName());
|
||||
respVO.setWorkTypeId(staffDO.getWorkTypeId());
|
||||
respVO.setFactoryName(factoryMap.get(reqVO.getFactoryId()) != null ? factoryMap.get(reqVO.getFactoryId()).getName() : null);
|
||||
|
||||
// 处理其他厂区的考勤记录
|
||||
if (CollUtil.isNotEmpty(otherRecordDOS)) {
|
||||
// 获得该员工 在其他工厂的考勤记录
|
||||
Map<Long, List<StaffAttendanceRecordDO>> factoryRecordMap = convertMultiMap(otherRecordDOS, StaffAttendanceRecordDO::getFactoryId);
|
||||
|
||||
List<StaffAttendanceRecordRespVO> childRespVO = otherRecordDOS.stream()
|
||||
.map(recordDO -> new StaffAttendanceRecordRespVO(
|
||||
recordDO.getStaffId(),
|
||||
recordDO.getFactoryId(),
|
||||
recordDO.getType(),
|
||||
recordDO.getMonth()))
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
childRespVO.forEach(vo -> {
|
||||
if (!staffMap.containsKey(vo.getStaffId())) {
|
||||
return;
|
||||
}
|
||||
// 设置员工名称
|
||||
vo.setStaffName(staffMap.get(vo.getStaffId()).getNickName());
|
||||
// 设置工种
|
||||
vo.setWorkTypeId(staffMap.get(vo.getStaffId()).getWorkTypeId());
|
||||
// 设置厂区名称
|
||||
vo.setFactoryName(factoryMap.get(vo.getFactoryId()) != null ? factoryMap.get(vo.getFactoryId()).getName() : null);
|
||||
|
||||
if (factoryRecordMap.containsKey(vo.getFactoryId())) {
|
||||
|
||||
// 设置打卡记录
|
||||
vo.setRecords(BeanUtils.toBean(factoryRecordMap.get(vo.getFactoryId()), AttendanceRecordVO.class));
|
||||
}
|
||||
});
|
||||
// 插入其他考勤记录
|
||||
List<StaffAttendanceRecordRespVO> childRespVO = processOtherFactoryRecords(otherRecordDOS, staffMap, factoryMap);
|
||||
respVO.setChildRecords(childRespVO);
|
||||
}
|
||||
|
||||
@ -336,4 +282,65 @@ public class StaffAttendanceRecordServiceImpl implements StaffAttendanceRecordSe
|
||||
|
||||
return respVOs;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据考勤类型生成对应的日期列表
|
||||
*/
|
||||
private List<AttendanceRecordVO> generatePunchTimeList(StaffAttendanceRecordReqVO reqVO) {
|
||||
List<AttendanceRecordVO> punchTimeList = new ArrayList<>();
|
||||
|
||||
LocalDate now = LocalDate.parse(reqVO.getMonth() + "-01", DateTimeFormatter.ISO_LOCAL_DATE);
|
||||
if (reqVO.getType() == 1) {
|
||||
LocalDate beginDate = now.minusMonths(1).withDayOfMonth(26);
|
||||
LocalDate lastMonthEnd = now.withDayOfMonth(25);
|
||||
|
||||
while (!beginDate.isAfter(lastMonthEnd)) {
|
||||
punchTimeList.add(new AttendanceRecordVO().setPunchTime(beginDate));
|
||||
beginDate = beginDate.plusDays(1);
|
||||
}
|
||||
} else if (reqVO.getType() == 2) {
|
||||
LocalDate firstDayOfMonth = now;
|
||||
int lengthOfMonth = firstDayOfMonth.lengthOfMonth();
|
||||
for (int i = 0; i < lengthOfMonth; i++) {
|
||||
punchTimeList.add(new AttendanceRecordVO().setPunchTime(firstDayOfMonth.plusDays(i)));
|
||||
}
|
||||
}
|
||||
|
||||
return punchTimeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理其他厂区的考勤记录
|
||||
*/
|
||||
private List<StaffAttendanceRecordRespVO> processOtherFactoryRecords(List<StaffAttendanceRecordDO> otherRecordDOS,
|
||||
Map<Long, StaffDO> staffMap,
|
||||
Map<Long, FactoryInfoDO> factoryMap) {
|
||||
Map<Long, List<StaffAttendanceRecordDO>> factoryRecordMap = convertMultiMap(otherRecordDOS, StaffAttendanceRecordDO::getFactoryId);
|
||||
|
||||
return otherRecordDOS.stream()
|
||||
.map(recordDO -> new StaffAttendanceRecordRespVO(
|
||||
recordDO.getStaffId(),
|
||||
recordDO.getFactoryId(),
|
||||
recordDO.getType(),
|
||||
recordDO.getMonth()))
|
||||
.distinct()
|
||||
.peek(vo -> {
|
||||
if (staffMap.containsKey(vo.getStaffId())) {
|
||||
StaffDO staffDO = staffMap.get(vo.getStaffId());
|
||||
vo.setStaffName(staffDO.getNickName());
|
||||
vo.setWorkTypeId(staffDO.getWorkTypeId());
|
||||
|
||||
if (factoryMap.containsKey(vo.getFactoryId())) {
|
||||
vo.setFactoryName(factoryMap.get(vo.getFactoryId()).getName());
|
||||
}
|
||||
|
||||
if (factoryRecordMap.containsKey(vo.getFactoryId())) {
|
||||
vo.setRecords(BeanUtils.toBean(factoryRecordMap.get(vo.getFactoryId()), AttendanceRecordVO.class));
|
||||
}
|
||||
}
|
||||
})
|
||||
.filter(vo -> staffMap.containsKey(vo.getStaffId()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -92,6 +92,8 @@ public interface StaffService {
|
||||
*/
|
||||
List<StaffDO> getListByFactory(Long factoryId, Boolean isIn);
|
||||
|
||||
List<StaffDO> getListByFactory(Long factoryId, Boolean isIn, List<Integer> workTypeIds);
|
||||
|
||||
/**
|
||||
* 获取指定厂区得员工列表
|
||||
*
|
||||
|
@ -250,10 +250,16 @@ public class StaffServiceImpl implements StaffService {
|
||||
|
||||
@Override
|
||||
public List<StaffDO> getListByFactory(Long factoryId, Boolean isIn) {
|
||||
return this.getListByFactory(factoryId, isIn, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StaffDO> getListByFactory(Long factoryId, Boolean isIn, List<Integer> workTypeIds) {
|
||||
return staffMapper.selectList(new LambdaQueryWrapperX<StaffDO>()
|
||||
.eq(isIn, StaffDO::getFactoryId, factoryId)
|
||||
.ne(!isIn, StaffDO::getFactoryId, factoryId)
|
||||
.ne(StaffDO::getStatus, 0));
|
||||
.ne(StaffDO::getStatus, 0)
|
||||
.in(CollUtil.isNotEmpty(workTypeIds), StaffDO::getWorkTypeId, workTypeIds));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -111,7 +111,7 @@ public class StaffSalaryServiceImpl implements StaffSalaryService {
|
||||
|
||||
if (pageReqVO.getMonth() != null && pageReqVO.getStatus() == null) {
|
||||
return staffMapper.selectSalaryPage(pageReqVO);
|
||||
}else {
|
||||
} else {
|
||||
return staffSalaryMapper.selectSalaryPage(pageReqVO);
|
||||
}
|
||||
}
|
||||
@ -154,7 +154,7 @@ public class StaffSalaryServiceImpl implements StaffSalaryService {
|
||||
firstDayOfMonth.minusMonths(1).withDayOfMonth(26),
|
||||
firstDayOfMonth.withDayOfMonth(25)
|
||||
};
|
||||
}else if (type == 2) {
|
||||
} else if (type == 2) {
|
||||
|
||||
date = new LocalDate[]{
|
||||
firstDayOfMonth,
|
||||
@ -213,10 +213,12 @@ public class StaffSalaryServiceImpl implements StaffSalaryService {
|
||||
|
||||
// 设置扣款明细 默认扣除保险 50元
|
||||
salaryDO.setDeductionItems(Collections.singletonList(
|
||||
new DeductionItemsVO()
|
||||
.setKey("insurance")
|
||||
.setValue("50")
|
||||
));
|
||||
new DeductionItemsVO()
|
||||
.setKey("insurance")
|
||||
.setValue("50")
|
||||
));
|
||||
// 设置扣款金额
|
||||
salaryDO.setDeductionAmount(BigDecimal.valueOf(50));
|
||||
|
||||
// 计算应发工资
|
||||
BigDecimal salary = staffDO.getSalary();
|
||||
@ -226,14 +228,14 @@ public class StaffSalaryServiceImpl implements StaffSalaryService {
|
||||
// 设置应发工资
|
||||
salaryDO.setPayableAmount(salary);
|
||||
// 设置实发工资
|
||||
salaryDO.setRealAmount(salary.subtract(BigDecimal.valueOf(50)));
|
||||
salaryDO.setRealAmount(salary.subtract(salaryDO.getDeductionAmount()));
|
||||
} else {
|
||||
BigDecimal payableAmount = salary.divide(BigDecimal.valueOf(workDays), 0, RoundingMode.DOWN)
|
||||
.multiply(BigDecimal.valueOf(salaryDO.getAttendanceDays()));
|
||||
// 设置应发工资
|
||||
salaryDO.setPayableAmount(payableAmount);
|
||||
// 设置实发工资
|
||||
salaryDO.setRealAmount(payableAmount.subtract(BigDecimal.valueOf(50)));
|
||||
salaryDO.setRealAmount(payableAmount.subtract(salaryDO.getDeductionAmount()));
|
||||
}
|
||||
|
||||
// 设置薪资主体数据
|
||||
@ -262,9 +264,10 @@ public class StaffSalaryServiceImpl implements StaffSalaryService {
|
||||
.setId(id)
|
||||
.setIsGrant(isGrant))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 更新
|
||||
staffSalaryMapper.updateBatch(salaryDOS);
|
||||
if (CollUtil.isNotEmpty(salaryDOS)) {
|
||||
// 更新
|
||||
staffSalaryMapper.updateBatch(salaryDOS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -300,4 +303,4 @@ public class StaffSalaryServiceImpl implements StaffSalaryService {
|
||||
|
||||
return salaryTotalVO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user