package com.xiaopeng.maintenance.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
|
import com.xiaopeng.api.feignClient.maintenance.XpCheckLocationClient;
|
import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetClient;
|
import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetOperationsClient;
|
import com.xiaopeng.api.model.account.XpOperationsUser;import com.xiaopeng.api.model.maintenance.*;
|
import com.xiaopeng.api.model.vehicleConvoy.XpFleet;
|
import com.xiaopeng.common.core.domain.R;
|
import com.xiaopeng.common.core.utils.poi.ExcelUtil;
|
import com.xiaopeng.common.core.web.page.PageInfo;
|
import com.xiaopeng.maintenance.dto.ExportSchedulingDetailDto;
|
import com.xiaopeng.maintenance.dto.SchedulingDetailDto;
|
import com.xiaopeng.maintenance.dto.ShiftAttendanceDTO;
|
import com.xiaopeng.maintenance.mapper.XpCheckLocationMapper;
|
import com.xiaopeng.maintenance.mapper.XpClockInMapper;
|
import com.xiaopeng.maintenance.mapper.XpSchedulingDetailMapper;
|
import com.xiaopeng.maintenance.mapper.XpShiftMapper;
|
import com.xiaopeng.maintenance.service.IXpSchedulingDetailService;
|
import com.xiaopeng.maintenance.service.IXpSchedulingService;
|
import com.xiaopeng.maintenance.service.IXpShiftService;
|
import com.xiaopeng.maintenance.vo.*;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import javax.servlet.http.HttpServletResponse;
|
import java.time.DayOfWeek;
|
import java.time.LocalDate;
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.time.format.TextStyle;
|
import java.time.temporal.TemporalAdjusters;
|
import java.util.*;
|
|
/**
|
* <p>
|
* 排班明细 服务实现类
|
* </p>
|
*
|
* @author mitao
|
* @since 2026-02-03
|
*/
|
@Service
|
public class XpSchedulingDetailServiceImpl extends ServiceImpl<XpSchedulingDetailMapper, XpSchedulingDetail> implements IXpSchedulingDetailService {
|
|
@Resource
|
private XpFleetClient xpFleetClient;
|
@Resource
|
private XpCheckLocationMapper xpCheckLocationMapper;
|
@Resource
|
private XpShiftMapper xpShiftMapper;
|
@Resource
|
private XpClockInMapper xpClockInMapper;
|
@Resource
|
private IXpSchedulingService xpSchedulingService;
|
@Resource
|
private IXpShiftService xpShiftService;
|
@Resource
|
private XpFleetOperationsClient xpFleetOperationsClient;
|
@Resource
|
private XpOperationUserClient xpOperationUserClient;
|
|
@Override
|
public ShiftAttendanceVO shiftAttendance(ShiftAttendanceDTO dto) {
|
// 查询用户所属车队
|
XpFleet xpFleet = xpFleetClient.getFleetByOperationsUserId(dto.getOperationsUserId()).getData();
|
if (Objects.isNull(xpFleet)) {
|
return null;
|
}
|
// 查询打卡地
|
XpCheckLocation xpCheckLocation = xpCheckLocationMapper.selectById(xpFleet.getLocationId());
|
if (Objects.isNull(xpCheckLocation)) {
|
return null;
|
}
|
// 查询排班明细
|
XpSchedulingDetail schedulingDetail = this.getOne(Wrappers.lambdaQuery(XpSchedulingDetail.class)
|
.likeRight(XpSchedulingDetail::getPlanTime, dto.getSchedulingDate())
|
.eq(XpSchedulingDetail::getFleetId, xpFleet.getId())
|
.last("LIMIT 1"));
|
if (Objects.isNull(schedulingDetail)) {
|
return null;
|
}
|
// 查询班次
|
XpShift xpShift = xpShiftMapper.selectById(schedulingDetail.getShiftId());
|
if (Objects.isNull(xpShift)) {
|
return null;
|
}
|
|
ShiftAttendanceVO shiftAttendanceVO = new ShiftAttendanceVO();
|
shiftAttendanceVO.setXpShift(xpShift);
|
shiftAttendanceVO.setXpCheckLocation(xpCheckLocation);
|
// 查询当前用户打卡信息
|
XpClockIn xpClockIn = xpClockInMapper.selectOne(Wrappers.lambdaQuery(XpClockIn.class)
|
.eq(XpClockIn::getAppUserId, dto.getOperationsUserId())
|
.likeRight(XpClockIn::getClockInTime, dto.getSchedulingDate())
|
.last("LIMIT 1"));
|
if (Objects.isNull(xpClockIn)) {
|
shiftAttendanceVO.setClockIn(false);
|
shiftAttendanceVO.setClockOut(false);
|
} else {
|
shiftAttendanceVO.setXpClockIn(xpClockIn);
|
shiftAttendanceVO.setClockIn(true);
|
shiftAttendanceVO.setClockOut(xpClockIn.getClockOutTime() != null);
|
}
|
return shiftAttendanceVO;
|
}
|
|
|
/**
|
* 排班明细分页列表
|
*
|
* @param query
|
* @return
|
*/
|
@Override
|
public PageInfo<SchedulingDetailDto> pageList(SchedulingDetailVo query) {
|
PageInfo<SchedulingDetailDto> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
|
List<SchedulingDetailDto> schedulingDetailDtos = this.baseMapper.pageList(pageInfo, query.getMonth());
|
LocalDate parse1 = LocalDate.parse(query.getMonth(), DateTimeFormatter.ofPattern("yyyy-MM"));
|
//找出月份的最大天
|
int dayOfMonth = parse1.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();
|
for (SchedulingDetailDto schedulingDetailDto : schedulingDetailDtos) {
|
String days = schedulingDetailDto.getDays();
|
if (StringUtils.isNotBlank(days)) {
|
String[] split = days.split(",");
|
List<String> list = Arrays.asList(split);
|
for (int i = 1; i <= dayOfMonth; i++) {
|
Map<String, String> map1 = new HashMap<>();
|
for (String s : split) {
|
String[] split1 = s.split("_");
|
if (i == Integer.parseInt(split1[0])) {
|
map1.put("shiftId", split1[1]);
|
map1.put("shiftName", split1[2]);
|
map1.put("shiftColor", split1[3]);
|
break;
|
}
|
}
|
setEnglishDay(i, schedulingDetailDto, map1);
|
}
|
long allDay = list.stream().filter(s -> s.contains("全天")).count();
|
long morning = list.stream().filter(s -> s.contains("早")).count();
|
long midDay = list.stream().filter(s -> s.contains("中")).count();
|
long evening = list.stream().filter(s -> s.contains("晚")).count();
|
schedulingDetailDto.setAllDay(allDay);
|
schedulingDetailDto.setMorning(morning);
|
schedulingDetailDto.setMidDay(midDay);
|
schedulingDetailDto.setEvening(evening);
|
}
|
}
|
pageInfo.setRecords(schedulingDetailDtos);
|
return pageInfo;
|
}
|
|
|
/**
|
* 给每天的字段赋值
|
* @param day
|
* @param dto
|
* @param map
|
*/
|
private void setEnglishDay(int day, SchedulingDetailDto dto, Map<String, String> map) {
|
switch (day) {
|
case 1:
|
dto.setOne(map);
|
break;
|
case 2:
|
dto.setTwo(map);
|
break;
|
case 3:
|
dto.setThree(map);
|
break;
|
case 4:
|
dto.setFour(map);
|
break;
|
case 5:
|
dto.setFive(map);
|
break;
|
case 6:
|
dto.setSix(map);
|
break;
|
case 7:
|
dto.setSeven(map);
|
break;
|
case 8:
|
dto.setEight(map);
|
break;
|
case 9:
|
dto.setNine(map);
|
break;
|
case 10:
|
dto.setTen(map);
|
break;
|
case 11:
|
dto.setEleven(map);
|
break;
|
case 12:
|
dto.setTwelve(map);
|
break;
|
case 13:
|
dto.setThirteen(map);
|
break;
|
case 14:
|
dto.setFourteen(map);
|
break;
|
case 15:
|
dto.setFifteen(map);
|
break;
|
case 16:
|
dto.setSixteen(map);
|
break;
|
case 17:
|
dto.setSeventeen(map);
|
break;
|
case 18:
|
dto.setEighteen(map);
|
break;
|
case 19:
|
dto.setNineteen(map);
|
break;
|
case 20:
|
dto.setTwenty(map);
|
break;
|
case 21:
|
dto.setTwentyOne(map);
|
break;
|
case 22:
|
dto.setTwentyTwo(map);
|
break;
|
case 23:
|
dto.setTwentyThree(map);
|
break;
|
case 24:
|
dto.setTwentyFour(map);
|
break;
|
case 25:
|
dto.setTwentyFive(map);
|
break;
|
case 26:
|
dto.setTwentySix(map);
|
break;
|
case 27:
|
dto.setTwentySeven(map);
|
break;
|
case 28:
|
dto.setTwentyEight(map);
|
break;
|
case 29:
|
dto.setTwentyNine(map);
|
break;
|
case 30:
|
dto.setThirty(map);
|
break;
|
case 31:
|
dto.setThirtyOne(map);
|
break;
|
}
|
}
|
|
/**
|
* 给每天的字段赋值
|
* @param day
|
* @param dto
|
* @param shiftName
|
*/
|
private void setEnglishDay(int day, ExportSchedulingDetailDto dto, String shiftName) {
|
switch (day) {
|
case 1:
|
dto.setOne(shiftName);
|
break;
|
case 2:
|
dto.setTwo(shiftName);
|
break;
|
case 3:
|
dto.setThree(shiftName);
|
break;
|
case 4:
|
dto.setFour(shiftName);
|
break;
|
case 5:
|
dto.setFive(shiftName);
|
break;
|
case 6:
|
dto.setSix(shiftName);
|
break;
|
case 7:
|
dto.setSeven(shiftName);
|
break;
|
case 8:
|
dto.setEight(shiftName);
|
break;
|
case 9:
|
dto.setNine(shiftName);
|
break;
|
case 10:
|
dto.setTen(shiftName);
|
break;
|
case 11:
|
dto.setEleven(shiftName);
|
break;
|
case 12:
|
dto.setTwelve(shiftName);
|
break;
|
case 13:
|
dto.setThirteen(shiftName);
|
break;
|
case 14:
|
dto.setFourteen(shiftName);
|
break;
|
case 15:
|
dto.setFifteen(shiftName);
|
break;
|
case 16:
|
dto.setSixteen(shiftName);
|
break;
|
case 17:
|
dto.setSeventeen(shiftName);
|
break;
|
case 18:
|
dto.setEighteen(shiftName);
|
break;
|
case 19:
|
dto.setNineteen(shiftName);
|
break;
|
case 20:
|
dto.setTwenty(shiftName);
|
break;
|
case 21:
|
dto.setTwentyOne(shiftName);
|
break;
|
case 22:
|
dto.setTwentyTwo(shiftName);
|
break;
|
case 23:
|
dto.setTwentyThree(shiftName);
|
break;
|
case 24:
|
dto.setTwentyFour(shiftName);
|
break;
|
case 25:
|
dto.setTwentyFive(shiftName);
|
break;
|
case 26:
|
dto.setTwentySix(shiftName);
|
break;
|
case 27:
|
dto.setTwentySeven(shiftName);
|
break;
|
case 28:
|
dto.setTwentyEight(shiftName);
|
break;
|
case 29:
|
dto.setTwentyNine(shiftName);
|
break;
|
case 30:
|
dto.setThirty(shiftName);
|
break;
|
case 31:
|
dto.setThirtyOne(shiftName);
|
break;
|
}
|
}
|
|
|
/**
|
* 保存排班明细
|
*
|
* @param vo
|
* @return
|
*/
|
@Override
|
public R saveSchedulingDetail(SaveSchedulingVo vo, Long userId) {
|
String month = vo.getMonth();
|
List<XpSchedulingDetail> list = this.list(new QueryWrapper<XpSchedulingDetail>().eq("is_deleted", 0).last(" and DATE_FORMAT(planTime,'%Y-%m') = '" + month + "'"));
|
//保存排班数据
|
XpScheduling xpScheduling = xpSchedulingService.getOne(new QueryWrapper<XpScheduling>().eq("is_deleted", 0).last(" and DATE_FORMAT(schedulingDate,'%Y-%m') = '" + month + "'"));
|
if(null == xpScheduling){
|
xpScheduling = new XpScheduling();
|
xpScheduling.setDeleted(false);
|
xpScheduling.setCreateTime(LocalDateTime.now());
|
xpScheduling.setUpdateTime(LocalDateTime.now());
|
xpScheduling.setCreateBy(userId.toString());
|
xpScheduling.setUpdateBy(userId.toString());
|
}
|
xpScheduling.setSchedulingDate(LocalDate.parse(month, DateTimeFormatter.ofPattern("yyyy-MM")));
|
xpScheduling.setCommitUserId(userId);
|
xpSchedulingService.saveOrUpdate(xpScheduling);
|
|
List<XpShift> xpShifts = xpShiftService.list(new QueryWrapper<XpShift>().eq("is_deleted", 0));
|
|
//构建排班明细数据
|
List<SaveSchedulingDetailVo> datas = vo.getDatas();
|
List<XpSchedulingDetail> schedulingDetails = new ArrayList<>();
|
for (SaveSchedulingDetailVo data : datas) {
|
Long fleetId = data.getFleetId();
|
List<SaveSchedulingDetailDay> days = data.getDays();
|
for (SaveSchedulingDetailDay day : days) {
|
Long shiftId = day.getShiftId();
|
LocalDate parse = LocalDate.parse(day.getDayTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
//查询判断数据是否存在
|
XpSchedulingDetail schedulingDetail = list.stream().filter(s -> s.getFleetId().equals(fleetId)
|
&& s.getShiftId().equals(shiftId)
|
&& s.getPlanTime().equals(parse)
|
).findAny().orElse(null);
|
//构建存储对象
|
if(null == schedulingDetail){
|
schedulingDetail = new XpSchedulingDetail();
|
schedulingDetail.setCreateBy(userId.toString());
|
schedulingDetail.setCreateTime(LocalDateTime.now());
|
schedulingDetail.setUpdateBy(userId.toString());
|
schedulingDetail.setUpdateTime(LocalDateTime.now());
|
schedulingDetail.setDeleted(false);
|
}else{
|
//构建通知消息
|
Long old_shiftId = schedulingDetail.getShiftId();
|
if(!old_shiftId.equals(shiftId)){
|
//获取车队的所有人员
|
XpShift xpShift1 = xpShifts.stream().filter(s -> s.getId().equals(old_shiftId)).findAny().orElse(null);
|
XpShift xpShift2 = xpShifts.stream().filter(s -> s.getId().equals(shiftId)).findAny().orElse(null);
|
|
List<Long> operationsIds = xpFleetOperationsClient.getOperationsIdsByFleetId(fleetId).getData();
|
if(null != operationsIds && !operationsIds.isEmpty()){
|
List<XpOperationsUser> data1 = xpOperationUserClient.listByIds(operationsIds).getData();
|
for (XpOperationsUser xpOperationsUser : data1) {
|
String nickName = xpOperationsUser.getNickName();
|
String message = nickName + "请注意," + month + "你的排班由" + xpShift1.getShiftName() + "变更为了" + xpShift2.getShiftName() + "。详情请联系平台管理员。";
|
|
}
|
}
|
}
|
|
}
|
schedulingDetail.setSchedulingId(xpScheduling.getId());
|
schedulingDetail.setFleetId(fleetId);
|
schedulingDetail.setShiftId(shiftId);
|
|
XpShift xpShift = xpShifts.stream().filter(s -> s.getId().equals(shiftId)).findAny().orElse(null);
|
schedulingDetail.setIsAllDay(xpShift.getShiftName().contains("全天"));
|
schedulingDetail.setPlanTime(parse);
|
schedulingDetails.add(schedulingDetail);
|
}
|
}
|
//批量保存排班明细数据
|
if(schedulingDetails.isEmpty()){
|
this.saveOrUpdateBatch(schedulingDetails);
|
}
|
return R.ok();
|
}
|
|
|
/**
|
* 导出排班数据
|
* @param month
|
* @param response
|
*/
|
@Override
|
public void exportExcel(String month, HttpServletResponse response) {
|
PageInfo<SchedulingDetailDto> pageInfo = new PageInfo<>(0, 10000);
|
List<SchedulingDetailDto> schedulingDetailDtos = this.baseMapper.pageList(pageInfo, month);
|
List<ExportSchedulingDetailDto> exportSchedulingDetailDtos = new ArrayList<>();
|
//获取月份的最大天数
|
LocalDate parse1 = LocalDate.parse(month, DateTimeFormatter.ofPattern("yyyy-MM"));
|
int dayOfMonth = parse1.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();
|
//构建表头第二行数据
|
ExportSchedulingDetailDto exportSchedulingDetailDto = new ExportSchedulingDetailDto();
|
exportSchedulingDetailDto.setFleetName("");
|
for (int i = 1; i <= dayOfMonth; i++) {
|
LocalDate parse = LocalDate.parse(month + "-" + i, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
String week = "";
|
switch (parse.getDayOfWeek()){
|
case MONDAY:
|
week = "一";
|
break;
|
case TUESDAY:
|
week = "二";
|
break;
|
case WEDNESDAY:
|
week = "三";
|
break;
|
case THURSDAY:
|
week = "四";
|
break;
|
case FRIDAY:
|
week = "五";
|
break;
|
case SATURDAY:
|
week = "六";
|
break;
|
case SUNDAY:
|
week = "日";
|
break;
|
}
|
setEnglishDay(i, exportSchedulingDetailDto, week);
|
}
|
exportSchedulingDetailDto.setAllDay("全天");
|
exportSchedulingDetailDto.setMorning("早");
|
exportSchedulingDetailDto.setMidDay("中");
|
exportSchedulingDetailDto.setEvening("晚");
|
exportSchedulingDetailDtos.add(exportSchedulingDetailDto);
|
|
//构建数据部分的内容
|
for (SchedulingDetailDto schedulingDetailDto : schedulingDetailDtos) {
|
exportSchedulingDetailDto = new ExportSchedulingDetailDto();
|
exportSchedulingDetailDto.setFleetName(schedulingDetailDto.getFleetName());
|
String days = schedulingDetailDto.getDays();
|
if (StringUtils.isNotBlank(days)) {
|
String[] split = days.split(",");
|
List<String> list = Arrays.asList(split);
|
for (int i = 1; i <= dayOfMonth; i++) {
|
String shiftName = "休";
|
for (String s : split) {
|
String[] split1 = s.split("_");
|
if (i == Integer.parseInt(split1[0])) {
|
shiftName = split1[2];
|
break;
|
}
|
}
|
setEnglishDay(i, exportSchedulingDetailDto, shiftName);
|
}
|
long allDay = list.stream().filter(s -> s.contains("全天")).count();
|
long morning = list.stream().filter(s -> s.contains("早")).count();
|
long midDay = list.stream().filter(s -> s.contains("中")).count();
|
long evening = list.stream().filter(s -> s.contains("晚")).count();
|
exportSchedulingDetailDto.setAllDay(allDay + "");
|
exportSchedulingDetailDto.setMorning(morning + "");
|
exportSchedulingDetailDto.setMidDay(midDay + "");
|
exportSchedulingDetailDto.setEvening(evening + "");
|
}else{
|
for (int i = 1; i <= 31; i++) {
|
String shiftName = "休";
|
setEnglishDay(i, exportSchedulingDetailDto, shiftName);
|
}
|
exportSchedulingDetailDto.setAllDay("0");
|
exportSchedulingDetailDto.setMorning("0");
|
exportSchedulingDetailDto.setMidDay("0");
|
exportSchedulingDetailDto.setEvening("0");
|
}
|
exportSchedulingDetailDtos.add(exportSchedulingDetailDto);
|
}
|
|
String[] split = month.split("-");
|
ExcelUtil<ExportSchedulingDetailDto> excelUtil = new ExcelUtil<>(ExportSchedulingDetailDto.class);
|
excelUtil.exportExcel(response, exportSchedulingDetailDtos, "排班计划", "日期:" + split[0] + "年" + split[1] + "月");
|
|
}
|
}
|