puzhibing
2026-02-28 a4a89d08964c39dce87dd0076c89b61244f40729
新增加排班计划相关接口
4个文件已添加
10个文件已修改
812 ■■■■■ 已修改文件
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/vehicleConvoy/XpFleetOperationsClientFallbackFactory.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/vehicleConvoy/XpFleetOperationsClient.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpScheduling.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpSchedulingDetail.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpSchedulingDetailController.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/dto/ExportSchedulingDetailDto.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/dto/SchedulingDetailDto.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpSchedulingDetailService.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpSchedulingDetailServiceImpl.java 472 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/SaveSchedulingDetailDay.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/SaveSchedulingDetailVo.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/SaveSchedulingVo.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/resources/mapper/maintenance/XpSchedulingDetailMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetOperationsController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/vehicleConvoy/XpFleetOperationsClientFallbackFactory.java
@@ -33,6 +33,13 @@
                log.error("根据人员ID获取车队信息失败 {}",  cause.getMessage());
                return R.fail("根据人员ID获取车队信息失败");
            }
            @Override
            public R<List<Long>> getOperationsIdsByFleetId(Long fleetId) {
                log.error("根据车队ID获取人员信息失败 {}",  cause.getMessage());
                return R.fail("根据车队ID获取人员信息失败");
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/vehicleConvoy/XpFleetOperationsClient.java
@@ -37,4 +37,14 @@
     */
    @GetMapping("/inner/fleet-operations/getFleetIdsByUserId/{userId}")
    R<List<Long>> getFleetIdsByUserId(@PathVariable("userId") Long userId);
    /**
     * 根据车队ID查询关联的运维人员ID列表
     *
     * @param fleetId 车队ID
     * @return 运维人员ID列表
     */
    @GetMapping("/inner/fleet-operations/getOperationsIdsByFleetId/{fleetId}")
    R<List<Long>> getOperationsIdsByFleetId(@PathVariable("fleetId") Long fleetId);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpScheduling.java
@@ -3,6 +3,8 @@
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.io.Serializable;
@@ -34,7 +36,7 @@
    private Long id;
    @ApiModelProperty(value = "排版日期")
    private LocalDateTime schedulingDate;
    private LocalDate schedulingDate;
    @ApiModelProperty(value = "排版人员id")
    private Long commitUserId;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpSchedulingDetail.java
@@ -3,6 +3,8 @@
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.io.Serializable;
@@ -46,6 +48,6 @@
    private Boolean isAllDay;
    @ApiModelProperty(value = "计划时间")
    private LocalDateTime planTime;
    private LocalDate planTime;
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpSchedulingDetailController.java
@@ -1,13 +1,15 @@
package com.xiaopeng.maintenance.controller;
import com.xiaopeng.api.model.maintenance.XpErrorType;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.api.model.account.SysUser;import com.xiaopeng.api.model.maintenance.XpErrorType;
import com.xiaopeng.api.vo.account.LoginUser;import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.common.security.utils.SecurityUtils;
import com.xiaopeng.maintenance.dto.SchedulingDetailDto;
import com.xiaopeng.maintenance.dto.ShiftAttendanceDTO;
import com.xiaopeng.maintenance.service.IXpSchedulingDetailService;
import com.xiaopeng.maintenance.vo.SaveSchedulingVo;
import com.xiaopeng.maintenance.vo.SchedulingDetailVo;
import com.xiaopeng.maintenance.vo.ShiftAttendanceVO;
import io.swagger.annotations.Api;
@@ -15,6 +17,9 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
@@ -30,9 +35,10 @@
@RequestMapping("")
public class XpSchedulingDetailController {
    @Autowired
    @Resource
    private IXpSchedulingDetailService xpSchedulingDetailService;
    @Autowired
    @Resource
    private TokenService tokenService;
    @ApiOperation(value = "查询个人排班与考勤信息", response = XpErrorType.class, tags = "运维APP-排班与考勤")
@@ -44,11 +50,27 @@
    }
//    public R<PageInfo<SchedulingDetailDto>> pageList(@RequestBody SchedulingDetailVo query){
//
//    }
    @ApiOperation(value = "排班考勤-排班计划管理-查询列表", response = XpErrorType.class, tags = "管理后台-运维执行")
    @PostMapping("/api/v1/scheduling/pageList")
    public R<PageInfo<SchedulingDetailDto>> pageList(@RequestBody SchedulingDetailVo query){
        PageInfo<SchedulingDetailDto> pageInfo = xpSchedulingDetailService.pageList(query);
        return R.ok(pageInfo);
    }
    @ApiOperation(value = "排班考勤-排班计划管理-保存排班数据", response = XpErrorType.class, tags = "管理后台-运维执行")
    @PostMapping("/api/v1/scheduling/saveSchedulingDetail")
    public R<?> saveSchedulingDetail(@RequestBody SaveSchedulingVo vo){
        SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        return xpSchedulingDetailService.saveSchedulingDetail(vo, sysUser.getId());
    }
    @ApiOperation(value = "排班考勤-排班计划管理-导出排班数据", response = XpErrorType.class, tags = "管理后台-运维执行")
    @GetMapping("/api/v1/scheduling/exportExcel")
    public void exportExcel(@RequestParam("month") String month, HttpServletResponse response) {
        xpSchedulingDetailService.exportExcel(month, response);
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/dto/ExportSchedulingDetailDto.java
New file
@@ -0,0 +1,92 @@
package com.xiaopeng.maintenance.dto;
import com.xiaopeng.common.core.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Map;
@Data
@ApiModel
public class ExportSchedulingDetailDto {
    private String fleetId;
    @Excel(name = "序号", sort = 1)
    private String sort;
    @Excel(name = "队伍", sort = 2)
    private String fleetName;
    @Excel(name = "1", sort = 3)
    private String one;
    @Excel(name = "2", sort = 4)
    private String two;
    @Excel(name = "3", sort = 5)
    private String three;
    @Excel(name = "4", sort = 6)
    private String four;
    @Excel(name = "5", sort = 7)
    private String five;
    @Excel(name = "6", sort = 8)
    private String six;
    @Excel(name = "7", sort = 9)
    private String seven;
    @Excel(name = "8", sort = 10)
    private String eight;
    @Excel(name = "9", sort = 11)
    private String nine;
    @Excel(name = "10", sort = 12)
    private String ten;
    @Excel(name = "11", sort = 13)
    private String eleven;
    @Excel(name = "12", sort = 14)
    private String twelve;
    @Excel(name = "13", sort = 15)
    private String thirteen;
    @Excel(name = "14", sort = 16)
    private String fourteen;
    @Excel(name = "15", sort = 17)
    private String fifteen;
    @Excel(name = "16", sort = 18)
    private String sixteen;
    @Excel(name = "17", sort = 19)
    private String seventeen;
    @Excel(name = "18", sort = 20)
    private String eighteen;
    @Excel(name = "19", sort = 21)
    private String nineteen;
    @Excel(name = "20", sort = 22)
    private String twenty;
    @Excel(name = "21", sort = 23)
    private String twentyOne;
    @Excel(name = "22", sort = 24)
    private String twentyTwo;
    @Excel(name = "23", sort = 25)
    private String twentyThree;
    @Excel(name = "24", sort = 26)
    private String twentyFour;
    @Excel(name = "25", sort = 27)
    private String twentyFive;
    @Excel(name = "26", sort = 28)
    private String twentySix;
    @Excel(name = "27", sort = 29)
    private String twentySeven;
    @Excel(name = "28", sort = 30)
    private String twentyEight;
    @Excel(name = "29", sort = 31)
    private String twentyNine;
    @Excel(name = "30", sort = 32)
    private String thirty;
    @Excel(name = "31", sort = 33)
    private String thirtyOne;
    @Excel(name = "排班小时", sort = 34)
    private String allDay;
    @Excel(name = "", sort = 35)
    private String morning;
    @Excel(name = "", sort = 36)
    private String midDay;
    @Excel(name = "", sort = 37)
    private String evening;
    /**
     * 天数,用逗号分隔
     */
    private String days;
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/dto/SchedulingDetailDto.java
@@ -4,73 +4,87 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Map;
@Data
@ApiModel
public class SchedulingDetailDto {
    @ApiModelProperty("排班ID")
    private Long schedulingId;
    @ApiModelProperty("车队ID")
    private String fleetId;
    @ApiModelProperty("车队")
    private String fleetName;
    @ApiModelProperty("1")
    private String one;
    private Map<String, String> one;
    @ApiModelProperty("2")
    private String two;
    private Map<String, String> two;
    @ApiModelProperty("3")
    private String three;
    private Map<String, String> three;
    @ApiModelProperty("4")
    private String four;
    private Map<String, String> four;
    @ApiModelProperty("5")
    private String five;
    private Map<String, String> five;
    @ApiModelProperty("6")
    private String six;
    private Map<String, String> six;
    @ApiModelProperty("7")
    private String seven;
    private Map<String, String> seven;
    @ApiModelProperty("8")
    private String eight;
    private Map<String, String> eight;
    @ApiModelProperty("9")
    private String nine;
    private Map<String, String> nine;
    @ApiModelProperty("10")
    private String ten;
    private Map<String, String> ten;
    @ApiModelProperty("11")
    private String eleven;
    private Map<String, String> eleven;
    @ApiModelProperty("12")
    private String twelve;
    private Map<String, String> twelve;
    @ApiModelProperty("13")
    private String thirteen;
    private Map<String, String> thirteen;
    @ApiModelProperty("14")
    private String fourteen;
    private Map<String, String> fourteen;
    @ApiModelProperty("15")
    private String fifteen;
    private Map<String, String> fifteen;
    @ApiModelProperty("16")
    private String sixteen;
    private Map<String, String> sixteen;
    @ApiModelProperty("17")
    private String seventeen;
    private Map<String, String> seventeen;
    @ApiModelProperty("18")
    private String eighteen;
    private Map<String, String> eighteen;
    @ApiModelProperty("19")
    private String nineteen;
    private Map<String, String> nineteen;
    @ApiModelProperty("20")
    private String twenty;
    private Map<String, String> twenty;
    @ApiModelProperty("21")
    private String twentyOne;
    private Map<String, String> twentyOne;
    @ApiModelProperty("22")
    private String twentyTwo;
    private Map<String, String> twentyTwo;
    @ApiModelProperty("23")
    private String twentyThree;
    private Map<String, String> twentyThree;
    @ApiModelProperty("24")
    private String twentyFour;
    private Map<String, String> twentyFour;
    @ApiModelProperty("25")
    private String twentyFive;
    private Map<String, String> twentyFive;
    @ApiModelProperty("26")
    private String twentySix;
    private Map<String, String> twentySix;
    @ApiModelProperty("27")
    private String twentySeven;
    private Map<String, String> twentySeven;
    @ApiModelProperty("28")
    private String twentyEight;
    private Map<String, String> twentyEight;
    @ApiModelProperty("29")
    private String twentyNine;
    private Map<String, String> twentyNine;
    @ApiModelProperty("30")
    private String thirty;
    private Map<String, String> thirty;
    @ApiModelProperty("31")
    private String thirtyOne;
    private Map<String, String> thirtyOne;
    @ApiModelProperty("全天")
    private Long allDay;
    @ApiModelProperty("早")
    private Long morning;
    @ApiModelProperty("中")
    private Long midDay;
    @ApiModelProperty("晚")
    private Long evening;
    /**
     * 天数,用逗号分隔
     */
    private String days;
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpSchedulingDetailService.java
@@ -2,12 +2,17 @@
import com.xiaopeng.api.model.maintenance.XpSchedulingDetail;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.dto.SchedulingDetailDto;
import com.xiaopeng.maintenance.dto.ShiftAttendanceDTO;
import com.xiaopeng.maintenance.vo.SaveSchedulingVo;
import com.xiaopeng.maintenance.vo.SchedulingDetailVo;
import com.xiaopeng.maintenance.vo.ShiftAttendanceVO;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletResponse;
/**
 * <p>
@@ -33,4 +38,20 @@
     * @return
     */
    PageInfo<SchedulingDetailDto> pageList(SchedulingDetailVo query);
    /**
     * 保存排班明细
     * @param vo
     * @return
     */
    R saveSchedulingDetail(SaveSchedulingVo vo, Long userId);
    /**
     * 导出排班计划
     * @param month
     * @param response
     */
    void exportExcel(String month, HttpServletResponse response);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpSchedulingDetailServiceImpl.java
@@ -1,15 +1,19 @@
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.model.maintenance.XpCheckLocation;
import com.xiaopeng.api.model.maintenance.XpClockIn;
import com.xiaopeng.api.model.maintenance.XpSchedulingDetail;
import com.xiaopeng.api.model.maintenance.XpShift;
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;
@@ -17,12 +21,21 @@
import com.xiaopeng.maintenance.mapper.XpSchedulingDetailMapper;
import com.xiaopeng.maintenance.mapper.XpShiftMapper;
import com.xiaopeng.maintenance.service.IXpSchedulingDetailService;
import com.xiaopeng.maintenance.vo.SchedulingDetailVo;
import com.xiaopeng.maintenance.vo.ShiftAttendanceVO;
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 java.util.Objects;
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>
@@ -35,14 +48,22 @@
@Service
public class XpSchedulingDetailServiceImpl extends ServiceImpl<XpSchedulingDetailMapper, XpSchedulingDetail> implements IXpSchedulingDetailService {
    @Autowired
    @Resource
    private XpFleetClient xpFleetClient;
    @Autowired
    @Resource
    private XpCheckLocationMapper xpCheckLocationMapper;
    @Autowired
    @Resource
    private XpShiftMapper xpShiftMapper;
    @Autowired
    @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) {
@@ -78,10 +99,10 @@
                .eq(XpClockIn::getAppUserId, dto.getOperationsUserId())
                .likeRight(XpClockIn::getClockInTime, dto.getSchedulingDate())
                .last("LIMIT 1"));
        if(Objects.isNull(xpClockIn)){
        if (Objects.isNull(xpClockIn)) {
            shiftAttendanceVO.setClockIn(false);
            shiftAttendanceVO.setClockOut(false);
        }else {
        } else {
            shiftAttendanceVO.setXpClockIn(xpClockIn);
            shiftAttendanceVO.setClockIn(true);
            shiftAttendanceVO.setClockOut(xpClockIn.getClockOutTime() != null);
@@ -92,15 +113,438 @@
    /**
     * 排班明细分页列表
     *
     * @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;
        }
    }
        return null;
    /**
     * 给每天的字段赋值
     * @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] + "月");
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/SaveSchedulingDetailDay.java
New file
@@ -0,0 +1,14 @@
package com.xiaopeng.maintenance.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel
public class SaveSchedulingDetailDay {
    @ApiModelProperty("日期yyyy-MM-dd")
    private String dayTime;
    @ApiModelProperty("班次id")
    private Long shiftId;
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/SaveSchedulingDetailVo.java
New file
@@ -0,0 +1,16 @@
package com.xiaopeng.maintenance.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel
public class SaveSchedulingDetailVo {
    @ApiModelProperty("车队id")
    private Long fleetId;
    @ApiModelProperty("每日配置数据")
    private List<SaveSchedulingDetailDay> days;
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/SaveSchedulingVo.java
New file
@@ -0,0 +1,14 @@
package com.xiaopeng.maintenance.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.util.List;
@Data
@ApiModel
public class SaveSchedulingVo {
    @ApiModelProperty("日期")
    private String month;
    @ApiModelProperty("保存数据")
    private List<SaveSchedulingDetailVo> datas;
}
xp-robotaxi-maintenance-boot/src/main/resources/mapper/maintenance/XpSchedulingDetailMapper.xml
@@ -4,9 +4,20 @@
    <select id="pageList" resultType="com.xiaopeng.maintenance.dto.SchedulingDetailDto">
        select * from xp_scheduling_detail where 1=1
        SELECT
            aa.fleet_id as fleetId
            aa.fleet_name as fleetName,
            bb.days
        FROM
            xp_fleet aa
        LEFT JOIN (
            select
            a.fleet_id, GROUP_CONCAT(concat(DATE_FORMAT(a.plan_time, '%d' ), '_', a.shift_id, '_', b.shift_name, '_', b.shift_color)) as days
            from xp_scheduling_detail a
            left join xp_shift b on (a.shift_id = b.id)
            where a.is_deleted = 0 and DATE_FORMAT(a.plan_time, '%Y-%m') = #{month}
            group by a.fleet_id
        ) AS bb ON ( aa.id = bb.fleet_id)
        WHERE aa.is_deleted = 0
    </select>
</mapper>
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetOperationsController.java
@@ -44,7 +44,7 @@
     * @return 车辆isd
     */
    @GetMapping("/inner/fleet-operations/getVehicleByUserId/{id}")
    R<List<Long>> getVehicleByUserId(@PathVariable("id") Long id){
    public R<List<Long>> getVehicleByUserId(@PathVariable("id") Long id){
        List<Long> fleetIds = xpFleetOperationsService.lambdaQuery().eq(XpFleetOperations::getOperationsUserId, id)
                .list().stream().map(XpFleetOperations::getFleetId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(fleetIds)){
@@ -73,4 +73,23 @@
                .collect(Collectors.toList());
        return R.ok(fleetIds);
    }
    /**
     * 根据车队ID查询关联的运维人员ID列表(内部接口)
     *
     * @param fleetId 车队ID
     * @return 运维人员ID列表
     */
    @GetMapping("/inner/fleet-operations/getOperationsIdsByFleetId/{fleetId}")
    public R<List<Long>> getOperationsIdsByFleetId(@PathVariable("fleetId") Long fleetId) {
        List<Long> operationsIds = xpFleetOperationsService.lambdaQuery()
                .eq(XpFleetOperations::getFleetId, fleetId)
                .list()
                .stream()
                .map(XpFleetOperations::getOperationsUserId)
                .distinct()
                .collect(Collectors.toList());
        return R.ok(operationsIds);
    }
}