新增车间计算记录与数据看板

This commit is contained in:
2025-05-15 21:35:16 +08:00
parent a63afc6bfb
commit a0bc26ef3a
31 changed files with 1127 additions and 78 deletions

View File

@@ -0,0 +1,56 @@
package com.ruoyi.oa.service;
import com.ruoyi.oa.domain.vo.OaAttendanceRecordVo;
import com.ruoyi.oa.domain.bo.OaAttendanceRecordBo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 计算记录Service接口
*
* @author ruoyi
* @date 2025-05-15
*/
public interface IOaAttendanceRecordService {
/**
* 查询计算记录
*/
OaAttendanceRecordVo queryById(Long recordId);
/**
* 查询计算记录列表
*/
TableDataInfo<OaAttendanceRecordVo> queryPageList(OaAttendanceRecordBo bo, PageQuery pageQuery);
/**
* 查询计算记录列表
*/
List<OaAttendanceRecordVo> queryList(OaAttendanceRecordBo bo);
/**
* 新增计算记录
*/
Boolean insertByBo(OaAttendanceRecordBo bo);
/**
* 修改计算记录
*/
Boolean updateByBo(OaAttendanceRecordBo bo);
/**
* 校验并批量删除计算记录信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 获取某月的所有数据报告的生成日期
* @param date
* @return
*/
List<String> listGenDate(String date);
}

View File

@@ -1,6 +1,7 @@
package com.ruoyi.oa.service;
import com.ruoyi.oa.domain.LaborCostData;
import com.ruoyi.oa.domain.vo.AttendanceMonthlyCount;
import com.ruoyi.oa.domain.vo.SysOaAttendanceVo;
import com.ruoyi.oa.domain.bo.SysOaAttendanceBo;
import com.ruoyi.common.core.page.TableDataInfo;
@@ -77,4 +78,15 @@ public interface ISysOaAttendanceService {
* @return
*/
int delOaAttendanceAll(Long day);
/**
* @param refDate
* @return
*/
List<AttendanceMonthlyCount> selectLastSixMonthsByMonth(String refDate);
AttendanceMonthlyCount selectAttendanceMonthlyCountByMonth(String refDate);
List<AttendanceMonthlyCount> selectMonthlyCounts(String refDate);
}

View File

@@ -0,0 +1,133 @@
package com.ruoyi.oa.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.oa.domain.bo.OaAttendanceRecordBo;
import com.ruoyi.oa.domain.vo.OaAttendanceRecordVo;
import com.ruoyi.oa.domain.OaAttendanceRecord;
import com.ruoyi.oa.mapper.OaAttendanceRecordMapper;
import com.ruoyi.oa.service.IOaAttendanceRecordService;
import java.util.*;
/**
* 计算记录Service业务层处理
*
* @author ruoyi
* @date 2025-05-15
*/
@RequiredArgsConstructor
@Service
public class OaAttendanceRecordServiceImpl implements IOaAttendanceRecordService {
private final OaAttendanceRecordMapper baseMapper;
/**
* 查询计算记录
*/
@Override
public OaAttendanceRecordVo queryById(Long recordId){
return baseMapper.selectVoByIdPlus(recordId);
}
/**
* 查询计算记录列表
*/
@Override
public TableDataInfo<OaAttendanceRecordVo> queryPageList(OaAttendanceRecordBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<OaAttendanceRecord> lqw = buildQueryWrapper(bo);
Page<OaAttendanceRecordVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
private LambdaQueryWrapper<OaAttendanceRecord> buildQueryWrapper(OaAttendanceRecordBo bo) {
LambdaQueryWrapper<OaAttendanceRecord> lqw = Wrappers.lambdaQuery();
if (bo.getRelationMonth() != null) {
lqw.apply(
"YEAR(relation_month) = YEAR({0}) AND MONTH(relation_month) = MONTH({1})",
bo.getRelationMonth(), bo.getRelationMonth());
if (bo.getCalcTime() != null) {
// 2a) 如果前端传了 genTime就按那天精准过滤
lqw.apply("DATE(calc_time) = {0}", bo.getCalcTime());
} else {
// 2b) 如果没传 genTime就只拿该月最新一次的记录
lqw.apply(
"calc_time = (" +
"SELECT MAX(calc_time) FROM oa_attendance_record " +
"WHERE YEAR(relation_month)=YEAR({0}) AND MONTH(relation_month)=MONTH({1})" +
")",
bo.getRelationMonth(), bo.getRelationMonth()
);
}
}
return lqw;
}
/**
* 查询计算记录列表
*/
@Override
public List<OaAttendanceRecordVo> queryList(OaAttendanceRecordBo bo) {
LambdaQueryWrapper<OaAttendanceRecord> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
/**
* 新增计算记录
*/
@Override
public Boolean insertByBo(OaAttendanceRecordBo bo) {
OaAttendanceRecord add = BeanUtil.toBean(bo, OaAttendanceRecord.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setRecordId(add.getRecordId());
}
return flag;
}
/**
* 修改计算记录
*/
@Override
public Boolean updateByBo(OaAttendanceRecordBo bo) {
OaAttendanceRecord update = BeanUtil.toBean(bo, OaAttendanceRecord.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(OaAttendanceRecord entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除计算记录
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
@Override
public List<String> listGenDate(String date) {
return baseMapper.listGenDate(date);
}
}

View File

@@ -88,11 +88,13 @@ public class OaProgressServiceImpl implements IOaProgressService {
OaProgress add = BeanUtil.toBean(bo, OaProgress.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
List<OaProgressDetailBo> detailList = bo.getDetailList();
for (OaProgressDetailBo detailBo : detailList) {
detailBo.setProgressId(add.getProgressId());
detailService.insertByBo(detailBo);
if(bo.getDetailList() != null && !bo.getDetailList().isEmpty()) {
for (OaProgressDetailBo detailBo : bo.getDetailList()) {
detailBo.setProgressId(add.getProgressId());
detailService.insertByBo(detailBo);
}
}
return flag;
}

View File

@@ -38,7 +38,7 @@ public class OaReportDetailServiceImpl implements IOaReportDetailService {
@Override
public OaReportDetailVo queryById(Long id){
return baseMapper.selectVoById(id);
return baseMapper.selectVoByIdPlus(id);
}
/**
@@ -119,7 +119,7 @@ public class OaReportDetailServiceImpl implements IOaReportDetailService {
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
bo.setDetailId(add.getDetailId());
}
return flag;
}

View File

@@ -78,7 +78,7 @@ public class OaReportSummaryServiceImpl implements IOaReportSummaryService {
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
bo.setSummaryId(add.getSummaryId());
}
return flag;
}

View File

@@ -8,8 +8,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.oa.domain.LaborCostData;
import com.ruoyi.oa.domain.OaAttendanceRecord;
import com.ruoyi.oa.domain.vo.AttendanceMonthlyCount;
import com.ruoyi.oa.domain.vo.SysOaProjectVo;
import com.ruoyi.oa.domain.vo.SysUserVo;
import com.ruoyi.oa.mapper.OaAttendanceRecordMapper;
import com.ruoyi.oa.service.ISysOaProjectService;
import com.ruoyi.system.mapper.SysUserRoleMapper;
import com.ruoyi.system.service.ISysUserService;
@@ -23,9 +26,10 @@ import com.ruoyi.oa.domain.SysOaAttendance;
import com.ruoyi.oa.mapper.SysOaAttendanceMapper;
import com.ruoyi.oa.service.ISysOaAttendanceService;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 人员考勤Service业务层处理
@@ -49,6 +53,9 @@ public class SysOaAttendanceServiceImpl implements ISysOaAttendanceService {
@Autowired
private ISysOaProjectService projectService;
@Autowired
private OaAttendanceRecordMapper recordMapper;
/**
* 查询人员考勤
*/
@@ -84,7 +91,7 @@ public class SysOaAttendanceServiceImpl implements ISysOaAttendanceService {
lqw.eq(bo.getProjectId() != null, SysOaAttendance::getProjectId, bo.getProjectId());
lqw.eq(bo.getDayLength() != null, SysOaAttendance::getDayLength, bo.getDayLength());
lqw.eq(bo.getHour() != null, SysOaAttendance::getHour, bo.getHour());
lqw.like(bo.getCreateTime()!=null, SysOaAttendance::getCreateTime, bo.getCreateTime());
lqw.like(bo.getCreateTime() != null, SysOaAttendance::getCreateTime, bo.getCreateTime());
return lqw;
}
@@ -122,8 +129,8 @@ public class SysOaAttendanceServiceImpl implements ISysOaAttendanceService {
sysOaAttendanceVo.setProjectId(bo.getProjectId());
sysOaAttendanceVo.setCreateTime(firstDay);
sysOaAttendanceVo.setDelFlag(0L);
sysOaAttendanceVo.setDayLength(bo.getDayLength()!=null?bo.getDayLength():0);
sysOaAttendanceVo.setHour(bo.getHour()!=null?bo.getHour():0);
sysOaAttendanceVo.setDayLength(bo.getDayLength() != null ? bo.getDayLength() : 0);
sysOaAttendanceVo.setHour(bo.getHour() != null ? bo.getHour() : 0);
return baseMapper.updateDelAttendance(BeanUtil.toBean(sysOaAttendanceVo, SysOaAttendance.class)) > 0;
}
@@ -201,13 +208,29 @@ public class SysOaAttendanceServiceImpl implements ISysOaAttendanceService {
*/
@Override
public List<LaborCostData> workerCalc(Date time) {
// 查询所有的工人
List<Long> userIds = sysUserRoleMapper.selectUserIdsByRoleId(1852970465740505090L);
Date firstDay = getFirstDay(time);
Date lastDay = getLastDay(time);
// 查询所有的工人
List<Long> userIds = sysUserRoleMapper.selectUserIdsByRoleId(1852970465740505090L);
List<Long> workerIds = baseMapper.selectNowMonthUserId(firstDay);
// 合并并去重
workerIds = Stream
.concat(userIds.stream(), workerIds.stream())
.distinct()
.collect(Collectors.toList());
List<LaborCostData> costDataList = new ArrayList<>();
for (Long userId : userIds) {
// 检测当天是否生成了完全一样的数据
List<Long> recordIds = recordMapper.listCommonDateRecord(DateUtils.getDate(), firstDay);
if (!recordIds.isEmpty()) {
// 如果有重复的就删掉
recordMapper.deleteBatchIds(recordIds);
}
// 开始写入
for (Long userId : workerIds) {
SysUserVo sysUser = BeanUtil.toBean(sysUserService.selectUserByIdIncludingDel(userId), SysUserVo.class);
SysOaAttendanceVo sysOaAttendanceVo = new SysOaAttendanceVo();
sysOaAttendanceVo.setUserId(sysUser.getUserId());
@@ -218,8 +241,19 @@ public class SysOaAttendanceServiceImpl implements ISysOaAttendanceService {
Double workTimes = 0.0;
Double hourWorkTimes = 0.0;
Double overTime = 0.0;
Double tripDays = 0.0;
Double leaveCount = 0.0;
Double workDays = 0.0;
Set<Long> projSet = new HashSet<>();
for (SysOaAttendanceVo oaAttendanceVo : sysOaAttendanceVos) {
// 出差问题解决
// 出差
if (oaAttendanceVo.getProjectId() == 0) {
tripDays++;
} else if (oaAttendanceVo.getProjectId() == 1) {
leaveCount++;
}
if (oaAttendanceVo.getProjectId() != 0 && oaAttendanceVo.getProjectId() != 1) {
SysOaProjectVo sysOaProjectVo = projectService.queryById(oaAttendanceVo.getProjectId());
oaAttendanceVo.setColor(sysOaProjectVo.getColor());
@@ -228,7 +262,9 @@ public class SysOaAttendanceServiceImpl implements ISysOaAttendanceService {
projectVos.add(sysOaProjectVo);
workTimes += oaAttendanceVo.getWorkTimes();
hourWorkTimes += oaAttendanceVo.getHourWorkTimes();
overTime+=oaAttendanceVo.getOverTime();
overTime += oaAttendanceVo.getOverTime();
projSet.add(oaAttendanceVo.getProjectId());
workDays++;
}
}
// 此为所有小时计的综合
@@ -238,16 +274,43 @@ public class SysOaAttendanceServiceImpl implements ISysOaAttendanceService {
laborCostData.setAttendances(sysOaAttendanceVos);
laborCostData.setSysUser(sysUser);
laborCostData.setWorkTimes(workTimes);
laborCostData.setTripTimes(tripDays);
laborCostData.setAbsenceDays(leaveCount);
laborCostData.setHourWorkTime(hourWorkTimes);
// 加班时间
laborCostData.setOvertime(overTime);
costDataList.add(laborCostData);
// 构造并保存记录
addGenData(firstDay, sysUser, tripDays, leaveCount, workDays, projSet, overTime);
}
return costDataList;
}
private void addGenData(Date firstDay, SysUserVo sysUser, Double tripDays, Double leaveCount, Double workDays, Set<Long> projSet, Double overtimeSum) {
OaAttendanceRecord rec = new OaAttendanceRecord();
// relationMonth 只保留年月,可直接传入 firstDay其 day=1
rec.setRelationMonth(firstDay);
// calcTime 为当前时间
rec.setCalcTime(new Date());
// 当前操作人昵称
rec.setNickName(sysUser.getNickName());
rec.setUserId(sysUser.getUserId());
rec.setTrips(BigDecimal.valueOf(tripDays));
rec.setNotNum(BigDecimal.valueOf(leaveCount));
rec.setWorks(BigDecimal.valueOf(workDays));
rec.setProjectIds(
String.join(",",
projSet.stream().map(String::valueOf).toArray(String[]::new)
)
);
rec.setOverNum(BigDecimal.valueOf(overtimeSum));
rec.setRemark("自动统计生成");
recordMapper.insert(rec);
}
/**
* 删除当月某日所有人的记录
*
@@ -261,6 +324,25 @@ public class SysOaAttendanceServiceImpl implements ISysOaAttendanceService {
return baseMapper.delOaAttendanceAll(getFirstDay(now), getLastDay(now), day);
}
@Override
public List<AttendanceMonthlyCount> selectLastSixMonthsByMonth(String refDate) {
return baseMapper.selectLastSixMonthsByMonth(refDate);
}
@Override
public AttendanceMonthlyCount selectAttendanceMonthlyCountByMonth(String refDate) {
return baseMapper.selectAttendanceMonthlyCountByMonth(refDate);
}
@Override
public List<AttendanceMonthlyCount> selectMonthlyCounts(String refDate) {
return baseMapper.selectMonthlyCounts(refDate);
}
private Date getFirstDay(Date time) {
String firstDay = DateUtils.parseDateToStr("yyyy-MM-01", time);
return DateUtils.parseDate(firstDay);