package com.xiaopeng.maintenance.service.impl;
import com.alibaba.fastjson2.JSONObject;
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.dto.pushMessage.AliPushMessageDTO;
import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
import com.xiaopeng.api.feignClient.account.XpOperationUserNotificationClient;
import com.xiaopeng.api.feignClient.maintenance.XpCheckLocationClient;
import com.xiaopeng.api.feignClient.pushMessage.XpAliPushMessageClient;
import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient;
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.account.XpOperationsUserNotification;
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.enums.NotificationTypeEnum;
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.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
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.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
*
* 排班明细 服务实现类
*
*
* @author mitao
* @since 2026-02-03
*/
@Service
public class XpSchedulingDetailServiceImpl extends ServiceImpl 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;
@Resource
private XpAliPushMessageClient xpAliPushMessageClient;
@Resource
private XpOperationUserNotificationClient xpOperationUserNotificationClient;
@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 pageList(SchedulingDetailVo query) {
PageInfo pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
List schedulingDetailDtos = this.baseMapper.pageList(pageInfo, query.getMonth());
LocalDate parse1 = LocalDate.parse(query.getMonth() + "-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//找出月份的最大天
int dayOfMonth = parse1.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();
List xpShifts = xpShiftService.list(new QueryWrapper().eq("is_deleted", 0).orderByAsc("id"));
for (SchedulingDetailDto schedulingDetailDto : schedulingDetailDtos) {
String days = schedulingDetailDto.getDays();
if (StringUtils.isNotBlank(days)) {
String[] split = days.split(",");
List list = Arrays.asList(split);
for (int i = 1; i <= dayOfMonth; i++) {
Map 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);
}
List