xuhy
2026-02-14 9b5212d6c65512f6321035c19b76b1b26bd3e237
运维排班考勤
11个文件已添加
15个文件已修改
702 ■■■■■ 已修改文件
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/vehicleConvoy/XpFleetClientFallbackFactory.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/vehicleConvoy/XpFleetClient.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpClockIn.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrderTimeoutLog.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCheckLocationController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpClockInController.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpSchedulingDetailController.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpShiftController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/dto/ClockDTO.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/dto/ShiftAttendanceDTO.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/dto/VerifyRangeDTO.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpCheckLocationService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpClockInService.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpSchedulingDetailService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpCheckLocationServiceImpl.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpClockInServiceImpl.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpSchedulingDetailServiceImpl.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/ShiftAttendanceVO.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/AbstractJob.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/EndTripJob.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/OrderCancelJob.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/mapper/XpOrderTimeoutLogMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/XpOrderTimeoutLogService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderTimeoutLogServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/vehicleConvoy/XpFleetClientFallbackFactory.java
@@ -29,6 +29,13 @@
                // 降级返回空列表
                return R.ok(new ArrayList<>());
            }
            @Override
            public R<XpFleet> getFleetByOperationsUserId(Long operationsUserId) {
                log.error("通过运营人员id查询车队信息失败,原因: {}", cause.getMessage());
                // 降级返回空列表
                return R.fail("通过运营人员id查询车队信息失败,"+cause.getMessage());
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/vehicleConvoy/XpFleetClient.java
@@ -5,8 +5,10 @@
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@@ -28,4 +30,12 @@
     */
    @PostMapping("/inner/fleet/listByIds")
    R<List<XpFleet>> listByIds(@RequestBody List<Long> ids);
    /**
     * 通过运营人员id查询车队信息
     *
     * @param operationsUserId 运营人员id
     * @return 车队信息
     */
    @GetMapping("/inner/v1/fleet/getFleetByOperationsUserId")
    R<XpFleet> getFleetByOperationsUserId(@RequestParam Long operationsUserId);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpClockIn.java
@@ -3,9 +3,12 @@
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;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -36,19 +39,33 @@
    @ApiModelProperty(value = "用户id")
    private Long appUserId;
    @ApiModelProperty(value = "打卡日期")
    private LocalDateTime clockTime;
    @ApiModelProperty(value = "上班打卡日期")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private LocalDateTime clockInTime;
    @ApiModelProperty(value = "上班打卡日期")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private LocalDateTime clockOutTime;
    @ApiModelProperty(value = "班次id")
    private Long shiftId;
    @ApiModelProperty(value = "打卡结果 1=正常 2=迟到 3=缺卡")
    private Integer clockResult;
    @ApiModelProperty(value = "上班打卡结果 1=正常 2=迟到 3=缺卡")
    private Integer clockInResult;
    @ApiModelProperty(value = "打卡经度")
    private Double clockLon;
    @ApiModelProperty(value = "下班打卡结果 1=正常 2=早退 3=缺卡")
    private Integer clockOutResult;
    @ApiModelProperty(value = "打卡纬度")
    private Double clockLat;
    @ApiModelProperty(value = "上班打卡经度")
    private Double clockInLon;
    @ApiModelProperty(value = "上班打卡纬度")
    private Double clockInLat;
    @ApiModelProperty(value = "下班打卡经度")
    private Double clockOutLon;
    @ApiModelProperty(value = "下班打卡纬度")
    private Double clockOutLat;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrderTimeoutLog.java
New file
@@ -0,0 +1,44 @@
package com.xiaopeng.api.model.order;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xiaopeng.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
 * <p>
 * 订单超时表
 * </p>
 *
 * @author xiaochen
 * @since 2026-02-14
 */
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("xp_order_timeout_log")
@ApiModel(value="XpOrderTimeoutLog对象", description="订单超时表")
public class XpOrderTimeoutLog extends BaseModel {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "自增id")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "订单id")
    @TableField("order_id")
    private Long orderId;
    @ApiModelProperty(value = "小程序用户id")
    @TableField("user_id")
    private Long userId;
}
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -315,7 +315,7 @@
            R<?> r = xpOrderClient.cancelOrder(String.valueOf(xpOrder.getId()));
            if (r.getCode() == R.SUCCESS){
                log.info("取消订单成功");
                // 重新派单
                // TODO 重新派单
                ReassignOrderDTO reassignOrderDTO = new ReassignOrderDTO();
                reassignOrderDTO.setUid(xpOrder.getAppUserId().toString());
                reassignOrderDTO.setOrderNo(xpOrder.getOrderNumber());
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCheckLocationController.java
@@ -3,6 +3,7 @@
import com.xiaopeng.api.model.maintenance.XpCheckLocation;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.enums.DisabledEnum;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.maintenance.service.IXpCheckLocationService;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
@@ -24,6 +25,7 @@
@RequiredArgsConstructor(onConstructor_ = @Lazy)
public class XpCheckLocationController {
    private final IXpCheckLocationService xpCheckLocationService;
    private final TokenService tokenService;
    @GetMapping("/api/v1/check-location/list")
    @ApiOperation(value = "获取打卡地址列表", tags = {"管理后台-车队管理"})
@@ -36,4 +38,12 @@
    public R<XpCheckLocation> queryById(@RequestParam Long id) {
        return R.ok(xpCheckLocationService.getById(id));
    }
    @ApiOperation(value = "根据ID查询打卡地址", tags = {"运维APP-排班与考勤"})
    @GetMapping("/api/v1/check-location/queryByUserId")
    public R<XpCheckLocation> queryByUserId() {
        Long id = tokenService.getLoginOperationUser().getId();
        return R.ok(xpCheckLocationService.queryByUserId(id));
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpClockInController.java
New file
@@ -0,0 +1,60 @@
package com.xiaopeng.maintenance.controller;
import com.xiaopeng.api.model.maintenance.XpErrorType;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.maintenance.dto.ClockDTO;
import com.xiaopeng.maintenance.dto.ShiftAttendanceDTO;
import com.xiaopeng.maintenance.dto.VerifyRangeDTO;
import com.xiaopeng.maintenance.service.IXpClockInService;
import com.xiaopeng.maintenance.vo.ShiftAttendanceVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * 打卡明细 前端控制器
 * </p>
 *
 * @author xiaochen
 * @since 2026-02-06
 */
@Api(tags = "打卡明细")
@RestController
@RequestMapping("")
public class XpClockInController {
    @Autowired
    private IXpClockInService xpClockInService;
    @Autowired
    private TokenService tokenService;
    @ApiOperation(value = "校验是否在打卡范围内", tags = "运维APP-排班与考勤")
    @PostMapping("/api/v1/clock/verifyRange")
    public R<Boolean> verifyRange(@RequestBody VerifyRangeDTO dto) {
        return R.ok(xpClockInService.verifyRange(dto));
    }
    @ApiOperation(value = "上班打卡", tags = "运维APP-排班与考勤")
    @PostMapping("/api/v1/clock/clockIn")
    public R<String> clockIn(@RequestBody ClockDTO dto) {
        Long id = tokenService.getLoginOperationUser().getId();
        dto.setOperationsUserId(id);
        return xpClockInService.clockIn(dto);
    }
    @ApiOperation(value = "下班打卡", tags = "运维APP-排班与考勤")
    @PostMapping("/api/v1/clock/clockOut")
    public R<String> clockOut(@RequestBody ClockDTO dto) {
        Long id = tokenService.getLoginOperationUser().getId();
        dto.setOperationsUserId(id);
        return xpClockInService.clockOut(dto);
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpSchedulingDetailController.java
New file
@@ -0,0 +1,44 @@
package com.xiaopeng.maintenance.controller;
import com.xiaopeng.api.model.maintenance.XpErrorType;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.maintenance.dto.ShiftAttendanceDTO;
import com.xiaopeng.maintenance.service.IXpSchedulingDetailService;
import com.xiaopeng.maintenance.vo.ShiftAttendanceVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * <p>
 * 排班明细 前端控制器
 * </p>
 *
 * @author xiaochen
 * @since 2026-02-06
 */
@Api(tags = "排班明细")
@RestController
@RequestMapping("")
public class XpSchedulingDetailController {
    @Autowired
    private IXpSchedulingDetailService xpSchedulingDetailService;
    @Autowired
    private TokenService tokenService;
    @ApiOperation(value = "查询个人排班与考勤信息", response = XpErrorType.class, tags = "运维APP-排班与考勤")
    @PostMapping("/api/v1/scheduling/shiftAttendance")
    public R<ShiftAttendanceVO> shiftAttendance(@RequestBody ShiftAttendanceDTO dto) {
        Long id = tokenService.getLoginOperationUser().getId();
        dto.setOperationsUserId(id);
        return R.ok(xpSchedulingDetailService.shiftAttendance(dto));
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpShiftController.java
New file
@@ -0,0 +1,20 @@
package com.xiaopeng.maintenance.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * 班次管理 前端控制器
 * </p>
 *
 * @author xiaochen
 * @since 2026-02-06
 */
@RestController
@RequestMapping("/xp-shift")
public class XpShiftController {
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/dto/ClockDTO.java
New file
@@ -0,0 +1,28 @@
package com.xiaopeng.maintenance.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "运维APP-打卡DTO")
public class ClockDTO implements Serializable {
    @ApiModelProperty(value = "用户经度")
    private Double userLon;
    @ApiModelProperty(value = "用户纬度")
    private Double userLat;
    @ApiModelProperty(value = "班次id 只传上班打卡的情况")
    private Long shiftId;
    @ApiModelProperty(value = "打卡地id")
    private Long locationId;
    @ApiModelProperty(value = "运维用户id 前端忽略")
    private Long operationsUserId;
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/dto/ShiftAttendanceDTO.java
New file
@@ -0,0 +1,21 @@
package com.xiaopeng.maintenance.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDate;
@Data
@ApiModel(value = "运维APP-查询个人排版与考勤dto")
public class ShiftAttendanceDTO implements Serializable {
    @ApiModelProperty(value = "排班时间")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private LocalDate schedulingDate;
    @ApiModelProperty(value = "运维用户id 前端忽略")
    private Long operationsUserId;
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/dto/VerifyRangeDTO.java
New file
@@ -0,0 +1,22 @@
package com.xiaopeng.maintenance.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "运维APP-验证范围DTO")
public class VerifyRangeDTO implements Serializable {
    @ApiModelProperty(value = "打卡地id")
    private Long locationId;
    @ApiModelProperty(value = "用户经度")
    private Double userLon;
    @ApiModelProperty(value = "用户纬度")
    private Double userLat;
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpCheckLocationService.java
@@ -13,4 +13,11 @@
 */
public interface IXpCheckLocationService extends IService<XpCheckLocation> {
    /**
     * 根据用户id查询打卡地址
     *
     * @param id
     * @return
     */
    XpCheckLocation queryByUserId(Long id);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpClockInService.java
@@ -2,6 +2,9 @@
import com.xiaopeng.api.model.maintenance.XpClockIn;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.maintenance.dto.ClockDTO;
import com.xiaopeng.maintenance.dto.VerifyRangeDTO;
/**
 * <p>
@@ -13,4 +16,27 @@
 */
public interface IXpClockInService extends IService<XpClockIn> {
    /**
     * 验证打卡范围
     *
     * @param dto
     * @return
     */
    Boolean verifyRange(VerifyRangeDTO dto);
    /**
     * 打卡
     *
     * @param dto
     * @return
     */
    R<String> clockIn(ClockDTO dto);
    /**
     * 下班打卡
     *
     * @param dto
     * @return
     */
    R<String> clockOut(ClockDTO dto);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpSchedulingDetailService.java
@@ -2,6 +2,8 @@
import com.xiaopeng.api.model.maintenance.XpSchedulingDetail;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.maintenance.dto.ShiftAttendanceDTO;
import com.xiaopeng.maintenance.vo.ShiftAttendanceVO;
/**
 * <p>
@@ -13,4 +15,10 @@
 */
public interface IXpSchedulingDetailService extends IService<XpSchedulingDetail> {
    /**
     * 查询个人排班与考勤信息
     * @param dto
     * @return
     */
    ShiftAttendanceVO shiftAttendance(ShiftAttendanceDTO dto);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpCheckLocationServiceImpl.java
@@ -1,10 +1,16 @@
package com.xiaopeng.maintenance.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetClient;
import com.xiaopeng.api.model.maintenance.XpCheckLocation;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.vehicleConvoy.XpFleet;
import com.xiaopeng.maintenance.mapper.XpCheckLocationMapper;
import com.xiaopeng.maintenance.service.IXpCheckLocationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Objects;
/**
 * <p>
@@ -16,5 +22,15 @@
 */
@Service
public class XpCheckLocationServiceImpl extends ServiceImpl<XpCheckLocationMapper, XpCheckLocation> implements IXpCheckLocationService {
    @Autowired
    private XpFleetClient xpFleetClient;
    @Override
    public XpCheckLocation queryByUserId(Long id) {
        // 查询运维人员的车队信息
        XpFleet xpFleet = xpFleetClient.getFleetByOperationsUserId(id).getData();
        if (Objects.isNull(xpFleet)) {
            return null;
        }
        return this.getById(xpFleet.getLocationId());
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpClockInServiceImpl.java
@@ -1,10 +1,28 @@
package com.xiaopeng.maintenance.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xiaopeng.api.model.maintenance.XpCheckLocation;
import com.xiaopeng.api.model.maintenance.XpClockIn;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.maintenance.XpShift;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.utils.DateUtils;
import com.xiaopeng.common.core.utils.GeodesyUtil;
import com.xiaopeng.maintenance.dto.ClockDTO;
import com.xiaopeng.maintenance.dto.VerifyRangeDTO;
import com.xiaopeng.maintenance.mapper.XpCheckLocationMapper;
import com.xiaopeng.maintenance.mapper.XpClockInMapper;
import com.xiaopeng.maintenance.mapper.XpShiftMapper;
import com.xiaopeng.maintenance.service.IXpClockInService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;
/**
 * <p>
@@ -17,4 +35,113 @@
@Service
public class XpClockInServiceImpl extends ServiceImpl<XpClockInMapper, XpClockIn> implements IXpClockInService {
    @Autowired
    private XpCheckLocationMapper xpCheckLocationMapper;
    @Autowired
    private XpShiftMapper xpShiftMapper;
    @Autowired
    private XpClockInMapper xpClockInMapper;
    @Override
    public Boolean verifyRange(VerifyRangeDTO dto) {
        XpCheckLocation xpCheckLocation = xpCheckLocationMapper.selectById(dto.getLocationId());
        Map<String, Double> distance = GeodesyUtil.getDistance(dto.getUserLon()+","+dto.getUserLat(), xpCheckLocation.getLocationLon()+","+xpCheckLocation.getLocationLat());
        if (null != distance) {
            Double distance1 = distance.get("WGS84");
            if (BigDecimal.valueOf(distance1).compareTo(xpCheckLocation.getLocationRange())>0) {
                return false;
            }else {
                return true;
            }
        } else {
            log.error("调用高德计算距离出错");
            return false;
        }
    }
    @Override
    public R<String> clockIn(ClockDTO dto) {
        XpCheckLocation xpCheckLocation = xpCheckLocationMapper.selectById(dto.getLocationId());
        Map<String, Double> distance = GeodesyUtil.getDistance(dto.getUserLon()+","+dto.getUserLat(), xpCheckLocation.getLocationLon()+","+xpCheckLocation.getLocationLat());
        if (null != distance) {
            Double distance1 = distance.get("WGS84");
            if (BigDecimal.valueOf(distance1).compareTo(xpCheckLocation.getLocationRange()) > 0) {
                return R.fail("不在打卡范围内");
            }
        }else {
            return R.fail("打卡失败");
        }
        // 查询班次
        XpShift xpShift = xpShiftMapper.selectById(dto.getShiftId());
        if (null == xpShift) {
            return R.fail("班次不存在");
        }
        // 开始打卡时间
        String startTime = xpShift.getStartTime();
        LocalDateTime startLocalDateTime = DateUtils.stringToLocalDateTime(LocalDate.now() + " " + startTime + ":00");
        XpClockIn xpClockIn = new XpClockIn();
        xpClockIn.setAppUserId(dto.getOperationsUserId());
        xpClockIn.setClockInTime(LocalDateTime.now());
        xpClockIn.setClockInLon(dto.getUserLon());
        xpClockIn.setClockInLat(dto.getUserLat());
        xpClockIn.setShiftId(dto.getShiftId());
        if (xpClockIn.getClockInTime().isAfter(startLocalDateTime)) {
            xpClockIn.setClockInResult(2);
        }else {
            xpClockIn.setClockInResult(1);
        }
        this.save(xpClockIn);
        return R.ok();
    }
    @Override
    public R<String> clockOut(ClockDTO dto) {
        XpCheckLocation xpCheckLocation = xpCheckLocationMapper.selectById(dto.getLocationId());
        Map<String, Double> distance = GeodesyUtil.getDistance(dto.getUserLon()+","+dto.getUserLat(), xpCheckLocation.getLocationLon()+","+xpCheckLocation.getLocationLat());
        if (null != distance) {
            Double distance1 = distance.get("WGS84");
            if (BigDecimal.valueOf(distance1).compareTo(xpCheckLocation.getLocationRange()) > 0) {
                return R.fail("不在打卡范围内");
            }
        }else {
            return R.fail("打卡失败");
        }
        // 查询上班打卡信息
        XpClockIn xpClockIn = xpClockInMapper.selectOne(Wrappers.lambdaQuery(XpClockIn.class)
                .eq(XpClockIn::getAppUserId, dto.getOperationsUserId())
                .likeRight(XpClockIn::getClockInTime, LocalDate.now())
                .last("LIMIT 1"));
        if(Objects.isNull(xpClockIn)){
            return R.fail("请先上班打卡");
        }
        // 查询班次
        XpShift xpShift = xpShiftMapper.selectById(xpClockIn.getShiftId());
        if (null == xpShift) {
            return R.fail("班次不存在");
        }
        // 开始打卡时间
        String endTime = xpShift.getEndTime();
        LocalDateTime endLocalDateTime = DateUtils.stringToLocalDateTime(LocalDate.now() + " " + endTime + ":00");
        xpClockIn.setClockOutTime(LocalDateTime.now());
        xpClockIn.setClockOutLon(dto.getUserLon());
        xpClockIn.setClockOutLat(dto.getUserLat());
        if (xpClockIn.getClockOutTime().isBefore(endLocalDateTime)) {
            xpClockIn.setClockInResult(2);
        }else {
            xpClockIn.setClockInResult(1);
        }
        this.updateById(xpClockIn);
        return R.ok();
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpSchedulingDetailServiceImpl.java
@@ -1,10 +1,25 @@
package com.xiaopeng.maintenance.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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.model.vehicleConvoy.XpFleet;
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.vo.ShiftAttendanceVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Objects;
/**
 * <p>
@@ -17,4 +32,56 @@
@Service
public class XpSchedulingDetailServiceImpl extends ServiceImpl<XpSchedulingDetailMapper, XpSchedulingDetail> implements IXpSchedulingDetailService {
    @Autowired
    private XpFleetClient xpFleetClient;
    @Autowired
    private XpCheckLocationMapper xpCheckLocationMapper;
    @Autowired
    private XpShiftMapper xpShiftMapper;
    @Autowired
    private XpClockInMapper xpClockInMapper;
    @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.setClockIn(true);
            shiftAttendanceVO.setClockOut(xpClockIn.getClockOutTime() != null);
        }
        return shiftAttendanceVO;
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/ShiftAttendanceVO.java
New file
@@ -0,0 +1,26 @@
package com.xiaopeng.maintenance.vo;
import com.xiaopeng.api.model.maintenance.XpCheckLocation;
import com.xiaopeng.api.model.maintenance.XpShift;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "运维APP-排班明细返回")
public class ShiftAttendanceVO implements Serializable {
    @ApiModelProperty(value = "班次信息")
    private XpShift xpShift;
    @ApiModelProperty(value = "打卡地信息")
    private XpCheckLocation xpCheckLocation;
    @ApiModelProperty(value = "是否上班打卡 true false")
    private boolean isClockIn;
    @ApiModelProperty(value = "是否下班打卡 true false")
    private boolean isClockOut;
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/AbstractJob.java
@@ -3,6 +3,7 @@
import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient;
import com.xiaopeng.order.service.IXpOrderService;
import com.xiaopeng.order.job.utils.SpringContextsUtil;
import com.xiaopeng.order.service.XpOrderTimeoutLogService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
@@ -17,10 +18,12 @@
    protected IXpOrderService xpOrderService;
    protected XpPushMessageClient xpPushMessageClient;
    protected XpOrderTimeoutLogService xpOrderTimeoutLogService;
    public AbstractJob(){
        this.xpOrderService = SpringContextsUtil.getBean(IXpOrderService.class);
        this.xpPushMessageClient = SpringContextsUtil.getBean(XpPushMessageClient.class);
        this.xpOrderTimeoutLogService = SpringContextsUtil.getBean(XpOrderTimeoutLogService.class);
    }
     
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/EndTripJob.java
@@ -1,23 +1,15 @@
package com.xiaopeng.order.job.jobs;
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.api.dto.pushMessage.SendMessageDTO;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.common.core.enums.OrderStatusEnum;
import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
import com.xiaopeng.api.model.order.XpOrderTimeoutLog;
import com.xiaopeng.order.job.base.AbstractJob;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
 * 直播推送定时任务
 * 推送定时任务
 * @author Administrator
 *
 */
@@ -33,7 +25,14 @@
        Long orderId = maps.getLong("id");
        try {
            log.info("开始执行自动结束行程任务");
            // TODO 自动结束行程任务
            XpOrder xpOrder = xpOrderService.getById(orderId);
            xpOrderService.endTrip(xpOrder.getId(), String.valueOf(xpOrder.getAppUserId()));
            log.info("结束执行自动结束行程任务");
            // 添加超时记录
            XpOrderTimeoutLog xpOrderTimeoutLog = new XpOrderTimeoutLog();
            xpOrderTimeoutLog.setOrderId(xpOrder.getId());
            xpOrderTimeoutLog.setUserId(xpOrder.getAppUserId());
            xpOrderTimeoutLogService.save(xpOrderTimeoutLog);
        }catch(Exception e){
            e.printStackTrace();
        }
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/OrderCancelJob.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.api.dto.pushMessage.SendMessageDTO;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.enums.OrderStatusEnum;
import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
import com.xiaopeng.order.job.base.AbstractJob;
@@ -35,23 +36,9 @@
            log.info("开始执行订单取消任务");
            XpOrder xpOrder = xpOrderService.getById(orderId);
            if(Objects.nonNull(xpOrder)){
                xpOrder.setStatus(OrderStatusEnum.CANCELED.getCode());
                xpOrderService.updateById(xpOrder);
                log.info("订单取消开始");
                xpOrderService.cancelOrder(String.valueOf(xpOrder.getId()));
                log.info("订单取消状态修改完成");
                // 消息推送
                Map<String, Object> params = new HashMap<>();
                Map<String, Object> content = new HashMap<>();
                content.put("orderId",xpOrder.getId());
                content.put("status",OrderStatusEnum.CANCELED.getCode());
                params.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc());
                params.put("content", JSONObject.toJSONString(content));
                params.put("timestamp", new Date().getTime()+"");
                String message = JSONObject.toJSONString(params);
                SendMessageDTO sendMessageDTO = new SendMessageDTO();
                sendMessageDTO.setMessage(message);
                sendMessageDTO.setAppUserId(String.valueOf(xpOrder.getAppUserId()));
                xpPushMessageClient.sendStatus(sendMessageDTO);
                log.info("订单取消消息推送完毕");
            }
        }catch(Exception e){
            e.printStackTrace();
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/mapper/XpOrderTimeoutLogMapper.java
New file
@@ -0,0 +1,16 @@
package com.xiaopeng.order.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaopeng.api.model.order.XpOrderTimeoutLog;
/**
 * <p>
 * 订单超时表 Mapper 接口
 * </p>
 *
 * @author xiaochen
 * @since 2026-02-14
 */
public interface XpOrderTimeoutLogMapper extends BaseMapper<XpOrderTimeoutLog> {
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/XpOrderTimeoutLogService.java
New file
@@ -0,0 +1,16 @@
package com.xiaopeng.order.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.order.XpOrderTimeoutLog;
/**
 * <p>
 * 订单超时表 服务类
 * </p>
 *
 * @author xiaochen
 * @since 2026-02-14
 */
public interface XpOrderTimeoutLogService extends IService<XpOrderTimeoutLog> {
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderTimeoutLogServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.xiaopeng.order.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.order.XpOrderTimeoutLog;
import com.xiaopeng.order.mapper.XpOrderTimeoutLogMapper;
import com.xiaopeng.order.service.XpOrderTimeoutLogService;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 订单超时表 服务实现类
 * </p>
 *
 * @author xiaochen
 * @since 2026-02-14
 */
@Service
public class XpOrderTimeoutLogServiceImpl extends ServiceImpl<XpOrderTimeoutLogMapper, XpOrderTimeoutLog> implements XpOrderTimeoutLogService {
}
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java
@@ -1,6 +1,8 @@
package com.xiaopeng.vehicleConvoy.controller;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xiaopeng.api.model.vehicleConvoy.XpFleet;
import com.xiaopeng.api.model.vehicleConvoy.XpFleetOperations;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.vehicleConvoy.model.dto.FleetAddDTO;
@@ -9,6 +11,7 @@
import com.xiaopeng.vehicleConvoy.model.query.FleetUserPageQuery;
import com.xiaopeng.vehicleConvoy.model.query.FleetVehiclePageQuery;
import com.xiaopeng.vehicleConvoy.model.vo.*;
import com.xiaopeng.vehicleConvoy.service.IXpFleetOperationsService;
import com.xiaopeng.vehicleConvoy.service.IXpFleetService;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
@@ -19,6 +22,7 @@
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
 * <p>
@@ -34,6 +38,7 @@
public class XpFleetController {
    private final IXpFleetService xpFleetService;
    private final IXpFleetOperationsService xpFleetOperationsService;
    /**
     * 根据ID列表批量查询车队信息(内部接口)
@@ -49,6 +54,28 @@
        }
        return R.ok(xpFleetService.listByIds(ids));
    }
    /**
     * 通过运营人员id查询车队信息
     *
     * @param operationsUserId 运营人员id
     * @return 车队信息
     */
    @ApiOperation(value = "通过运维人员id查询车队信息", tags = {"内部接口"})
    @GetMapping("/inner/v1/fleet/getFleetByOperationsUserId")
    public R<XpFleet> getFleetByOperationsUserId(@RequestParam Long operationsUserId) {
        if (Objects.isNull(operationsUserId)) {
            return R.ok();
        }
        // 查询车队人员关联关系
        XpFleetOperations fleetOperations = xpFleetOperationsService.getOne(Wrappers.lambdaQuery(XpFleetOperations.class)
                .eq(XpFleetOperations::getOperationsUserId, operationsUserId)
                .last("LIMIT 1"));
        if (Objects.isNull(fleetOperations)) {
            return R.ok();
        }
        XpFleet xpFleet = xpFleetService.getById(fleetOperations.getFleetId());
        return R.ok(xpFleet);
    }
    /**
     * 添加车队