综合管理模块排班类型添加项目id

This commit is contained in:
2025-09-22 20:03:46 +08:00
parent a655f14188
commit 28ecf71e0c
8 changed files with 99 additions and 3 deletions

View File

@ -31,6 +31,11 @@ public class OpsSchedulingDate extends BaseEntity {
@TableId(value = "id")
private Long id;
/**
* 项目id
*/
private Long projectId;
/**
* 排班名称
*/
@ -46,5 +51,10 @@ public class OpsSchedulingDate extends BaseEntity {
*/
private LocalTime endTime;
/**
* 时长
*/
private Double duration;
}

View File

@ -27,8 +27,15 @@ public class OpsSchedulingDateBo extends BaseEntity {
/**
* id
*/
@NotNull(message = "id不能为空", groups = { EditGroup.class })
private Long id;
/**
* 项目id
*/
@NotNull(message = "项目id不能为空", groups = { AddGroup.class, EditGroup.class })
private Long projectId;
/**
* 排班名称
*/
@ -47,5 +54,10 @@ public class OpsSchedulingDateBo extends BaseEntity {
@NotNull(message = "结束时间不能为空", groups = { AddGroup.class, EditGroup.class })
private LocalTime endTime;
/**
* 时长
*/
private Double duration;
}

View File

@ -11,6 +11,10 @@ import java.util.List;
public class SchedulingUserGroupDTO implements Serializable {
private Long opsUserId; // 运维人员ID
private String opsUserName; // 运维人员ID
/**
* 总时长
*/
private Double durationCount;
private List<UserTypePairDTO> userTypePairs; // 日期-类型对应列表
}

View File

@ -3,6 +3,9 @@ package org.dromara.personnel.domain.vo;
import java.time.LocalTime;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.NotNull;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.personnel.domain.OpsSchedulingDate;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
@ -37,6 +40,11 @@ public class OpsSchedulingDateVo implements Serializable {
@ExcelProperty(value = "id")
private Long id;
/**
* 项目id
*/
private Long projectId;
/**
* 排班名称
*/
@ -55,5 +63,10 @@ public class OpsSchedulingDateVo implements Serializable {
@ExcelProperty(value = "结束时间")
private LocalTime endTime;
/**
* 时长
*/
private Double duration;
}

View File

@ -74,5 +74,10 @@ public class OpsSchedulingVo implements Serializable {
// @ExcelProperty(value = "排班结束时间")
private LocalDateTime schedulingEndTime;
/**
* 时长
*/
private Double duration;
}

View File

@ -16,6 +16,8 @@ import org.dromara.personnel.domain.OpsSchedulingDate;
import org.dromara.personnel.mapper.OpsSchedulingDateMapper;
import org.dromara.personnel.service.IOpsSchedulingDateService;
import java.time.Duration;
import java.time.LocalTime;
import java.util.List;
import java.util.Map;
import java.util.Collection;
@ -74,6 +76,7 @@ public class OpsSchedulingDateServiceImpl implements IOpsSchedulingDateService {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<OpsSchedulingDate> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(OpsSchedulingDate::getId);
lqw.eq(bo.getProjectId() != null, OpsSchedulingDate::getProjectId, bo.getProjectId());
lqw.like(StringUtils.isNotBlank(bo.getSchedulingName()), OpsSchedulingDate::getSchedulingName, bo.getSchedulingName());
lqw.eq(bo.getStartTime() != null, OpsSchedulingDate::getStartTime, bo.getStartTime());
lqw.eq(bo.getEndTime() != null, OpsSchedulingDate::getEndTime, bo.getEndTime());
@ -89,6 +92,8 @@ public class OpsSchedulingDateServiceImpl implements IOpsSchedulingDateService {
@Override
public Boolean insertByBo(OpsSchedulingDateBo bo) {
OpsSchedulingDate add = MapstructUtils.convert(bo, OpsSchedulingDate.class);
double duration = getDuration(add);
add.setDuration(duration);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
@ -106,10 +111,27 @@ public class OpsSchedulingDateServiceImpl implements IOpsSchedulingDateService {
@Override
public Boolean updateByBo(OpsSchedulingDateBo bo) {
OpsSchedulingDate update = MapstructUtils.convert(bo, OpsSchedulingDate.class);
double duration = getDuration(update);
update.setDuration(duration);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 计算时长
* @param update
* @return
*/
private static double getDuration(OpsSchedulingDate update) {
double duration = 0.0;
if (update.getStartTime().isAfter(update.getEndTime())) {
duration =calculateHourDiffWithDecimal(update.getStartTime(), update.getEndTime());
}else {
duration = calculateHourDiffWithDecimalAndCrossDay(update.getStartTime(), update.getEndTime());
}
return duration;
}
/**
* 保存前的数据校验
*/
@ -131,4 +153,30 @@ public class OpsSchedulingDateServiceImpl implements IOpsSchedulingDateService {
}
return baseMapper.deleteByIds(ids) > 0;
}
/**
* 计算两个LocalTime的小时差保留小数不处理跨天
* @param startTime 开始时间
* @param endTime 结束时间
* @return 小时差如1.5表示1小时30分钟
*/
public static double calculateHourDiffWithDecimal(LocalTime startTime, LocalTime endTime) {
// 1. 计算总分钟差endTime - startTime
long totalMinutes = Duration.between(startTime, endTime).toMinutes();
// 2. 转换为小时除以60.0保留小数)
return totalMinutes / 60.0;
}
/**
* 计算小时差(处理跨天,保留小数)
* 适用场景如23:00到次日01:30 → 2.5小时
*/
public static double calculateHourDiffWithDecimalAndCrossDay(LocalTime startTime, LocalTime endTime) {
long totalMinutes = Duration.between(startTime, endTime).toMinutes();
// 若为负数说明跨天加上24*60分钟一天的总分钟数
if (totalMinutes < 0) {
totalMinutes += 24 * 60;
}
return totalMinutes / 60.0;
}
}

View File

@ -193,12 +193,15 @@ public class OpsSchedulingServiceImpl implements IOpsSchedulingService {
List<UserTypePairDTO> userTypePairDTOS = new ArrayList<>();
dto.setOpsUserId(entry.getKey());
dto.setOpsUserName(remoteUserService.selectNicknameById(entry.getKey()));
entry.getValue().forEach(schedulingDate -> {
double durationCount = 0.0;
for (OpsSchedulingVo schedulingDate : entry.getValue()) {
UserTypePairDTO pairDTO = new UserTypePairDTO();
pairDTO.setSchedulingDate(schedulingDate.getSchedulingDate());
pairDTO.setSchedulingType(schedulingDate.getSchedulingType());
pairDTO.setSchedulingTypeName(schedulingDate.getSchedulingTypeName());
});
durationCount += schedulingDate.getDuration();
}
dto.setDurationCount(durationCount);
dto.setUserTypePairs(userTypePairDTOS);
schedulingDateGroupDTOS.add(dto);
}

View File

@ -13,7 +13,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
os.scheduling_date as schedulingDate,
os.scheduling_start_time as schedulingStartTime,
os.scheduling_end_time as schedulingEndTime,
osd.scheduling_name as schedulingTypeName
osd.scheduling_name as schedulingTypeName,
osd.duration AS duration
FROM
ops_scheduling os
LEFT JOIN ops_scheduling_date osd ON os.scheduling_type = osd.id