puzhibing
2026-04-20 f5560820431163db68ccea4c850fb90a0eebf467
Merge remote-tracking branch 'origin/1.0' into 1.0
27个文件已添加
40个文件已修改
1844 ■■■■■ 已修改文件
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserCouponController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpAppUserCouponService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpAppUserCouponServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpAppUserCouponMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/account/XpAppUserCouponClientFallbackFactory.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/account/XpOperationUserClientFallbackFactory.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/maintenance/XpVehicleModelClientFallbackFactory.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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/account/XpAppUserCouponClient.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/account/XpOperationUserClient.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/maintenance/XpVehicleModelClient.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/vehicleConvoy/XpFleetOperationsClient.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/account/XpAppUserCoupon.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpClockIn.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpActicityStrategy.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpActicityUser.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpActivity.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpCoupon.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPasswordFreePolicy.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPointSituationReport.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPricing.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/account/XpAppUserCouponPageListQuery.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/XpActivityPageListQuery.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/XpPasswordFreePolicyQuery.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/XpPointSituationReportQuery.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/XpPointSituationReportVo.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpClockInController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCruiseCheckInRuleController.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleModelController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/mapper/XpCruiseCheckInRecordMapper.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpCruiseCheckInRecordService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpCruiseCheckInRecordServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/XpCruiseCheckInRecordQuery.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/XpCruiseCheckInRecordVO.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/resources/mapper/maintenance/XpCruiseCheckInRecordMapper.xml 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpActicityController.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpActicityStrategyController.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpActicityUserController.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCouponController.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPasswordFreePolicyController.java 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPointSituationReportController.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/exportExcle/XpPointSituationReportExportExcel.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/mapper/XpActicityMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/mapper/XpActicityStrategyMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/mapper/XpActicityUserMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/mapper/XpPasswordFreePolicyMapper.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/mapper/XpPointSituationReportMapper.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpActicityService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpActicityStrategyService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpActicityUserService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpPointSituationReportService.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/XpPasswordFreePolicyService.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpActicityServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpActicityStrategyServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpActicityUserServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPasswordFreePolicyServiceImpl.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPointSituationReportServiceImpl.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/vo/PricingPageListVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpActicityMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpActicityStrategyMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpActicityUserMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpPasswordFreePolicyMapper.xml 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpPointSituationReportMapper.xml 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetOperationsController.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserCouponController.java
@@ -294,6 +294,15 @@
    }
    @GetMapping("/logan/inner/appUserCoupon/holding")
    @ApiOperation(value = "查询优惠券是否已有用户使用", tags = {"管理后台-优惠券是否占用"})
    public R<Boolean> holding(@RequestParam Long couponId) {
        return R.ok(xpAppUserCouponService.holding(couponId));
    }
    /**
     * 1.0获取用户可用优惠券数量
     */
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpAppUserCouponService.java
@@ -78,4 +78,6 @@
     * @return
     */
    Integer getUserCouponNum(String uid);
    Boolean holding(Long couponId);
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpAppUserCouponServiceImpl.java
@@ -202,6 +202,11 @@
        return num.intValue();
    }
    @Override
    public Boolean holding(Long couponId) {
        return baseMapper.selectCount(new LambdaQueryWrapper<XpAppUserCoupon>().eq(XpAppUserCoupon::getCouponId, couponId).ne(XpAppUserCoupon::getStatus, 0)) > 0;
    }
    /**
     * 是否在运营内
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpAppUserCouponMapper.xml
@@ -4,7 +4,7 @@
    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, full_money, money, expiration_time, status, coupon_type, app_user_id, coupon_id, activity_id, activity_type, is_deleted, create_time, update_time, create_by, update_by
        id, full_money, money, money2, money3 , expiration_time, status, coupon_type, app_user_id, coupon_id, activity_id, activity_type, is_deleted, create_time, update_time, create_by, update_by
    </sql>
    <select id="pageList" resultType="com.xiaopeng.account.model.vo.XpAppUserCouponListVo">
@@ -20,6 +20,9 @@
        <if test="query.status != null">
            and a.status = #{query.status}
        </if>
        <if test="query.couponType != null">
            and a.coupon_type = #{query.couponType}
        </if>
        <if test="query.acticityIds != null">
            and a.activity_id in
            <foreach item="item" collection="query.acticityIds" separator="," open="(" close=")" index="">
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/account/XpAppUserCouponClientFallbackFactory.java
@@ -46,6 +46,12 @@
                return null;
            }
            @Override
            public boolean isHolding(Long id) {
                log.error("优惠券服务繁忙,原因: {}", cause.getMessage());
                return false;
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/account/XpOperationUserClientFallbackFactory.java
@@ -10,6 +10,7 @@
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -22,7 +23,7 @@
        return new XpOperationUserClient() {
            @Override
            public R<List<XpOperationsUser>> listByIds(List<Long> ids) {
            public R<List<XpOperationsUser>> listByIds(Collection<Long> ids) {
                log.error("批量查询运维人员用户信息失败,原因: {}", cause.getMessage());
                // 降级返回空列表
                return R.ok(new ArrayList<>());
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/maintenance/XpVehicleModelClientFallbackFactory.java
New file
@@ -0,0 +1,31 @@
package com.xiaopeng.api.factory.maintenance;
import com.xiaopeng.api.feignClient.maintenance.XpVehicleModelClient;
import com.xiaopeng.api.model.maintenance.XpVehicleModel;
import com.xiaopeng.common.core.domain.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.List;
@Slf4j
@Component
public class XpVehicleModelClientFallbackFactory implements FallbackFactory<XpVehicleModelClient> {
    @Override
    public XpVehicleModelClient create(Throwable cause) {
        return new XpVehicleModelClient() {
            @Override
            public R<List<XpVehicleModel>> listByIds(Collection<String> ids) {
                log.error("获取车型数据失败, 异常: {}",cause.getMessage(), cause);
                return R.fail("获取车型数据失败:" + cause.getMessage());
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/vehicleConvoy/XpFleetOperationsClientFallbackFactory.java
@@ -1,6 +1,7 @@
package com.xiaopeng.api.factory.vehicleConvoy;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetOperationsClient;
import com.xiaopeng.api.model.vehicleConvoy.XpFleet;
import com.xiaopeng.api.model.vehicleConvoy.XpFleetOperations;
import com.xiaopeng.common.core.domain.R;
import lombok.extern.slf4j.Slf4j;
@@ -30,6 +31,12 @@
            }
            @Override
            public R<List<XpFleet>> getFleetByUserId(Long id) {
                log.error("根据人员id 获取所属车队,人员ID: {},原因: {}", id, cause.getMessage());
                return R.ok(new ArrayList<>());
            }
            @Override
            public R<List<Long>> getFleetIdsByUserId(Long userId) {
                log.error("根据人员ID获取车队信息失败 {}",  cause.getMessage());
                return R.fail("根据人员ID获取车队信息失败");
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/account/XpAppUserCouponClient.java
@@ -7,6 +7,7 @@
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;
@@ -38,4 +39,6 @@
    R<BigDecimal> backUserCoupon(@RequestBody UseUserCouponDto dto);
    @GetMapping("/logan/inner/appUserCoupon/holding")
    boolean isHolding(Long id);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/account/XpOperationUserClient.java
@@ -1,20 +1,19 @@
package com.xiaopeng.api.feignClient.account;
import com.xiaopeng.api.dto.account.XpOperationsUserQueryDTO;
import com.xiaopeng.api.factory.account.XpAppUserClientFallbackFactory;
import com.xiaopeng.api.factory.account.XpOperationUserClientFallbackFactory;
import com.xiaopeng.api.model.account.XpOperationsRole;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum;
import io.swagger.annotations.ApiOperation;
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.Collection;
import java.util.List;
/**
@@ -32,7 +31,7 @@
     * @return 用户列表
     */
    @PostMapping("/logan/inner/xpOperationsUser/listByIds")
    R<List<XpOperationsUser>> listByIds(@RequestBody List<Long> ids);
    R<List<XpOperationsUser>> listByIds(@RequestBody Collection<Long> ids);
    /**
     * 根据ID查询运维用户信息
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/maintenance/XpVehicleModelClient.java
New file
@@ -0,0 +1,30 @@
package com.xiaopeng.api.feignClient.maintenance;
import com.xiaopeng.api.factory.maintenance.XpVehicleModelClientFallbackFactory;
import com.xiaopeng.api.model.maintenance.XpVehicleModel;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.Collection;
import java.util.List;
@FeignClient(contextId = "XpVehicleModelClient",
        value = ServiceNameConstantsEnum.XP_MAINTENANCE_SERVICE,
        fallbackFactory = XpVehicleModelClientFallbackFactory.class)
public interface XpVehicleModelClient {
    /**
     * 根据ID列表批量查询打卡地址
     */
    @PostMapping("/logan/inner/xpVehicleModel/listByIds")
    R<List<XpVehicleModel>> listByIds(@RequestBody Collection<String> ids);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/vehicleConvoy/XpFleetOperationsClient.java
@@ -1,7 +1,7 @@
package com.xiaopeng.api.feignClient.vehicleConvoy;
import com.xiaopeng.api.factory.vehicleConvoy.XpFleetOperationsClientFallbackFactory;
import com.xiaopeng.api.factory.vehicleConvoy.XpFleetVehicleClientFallbackFactory;
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.dto.ServiceNameConstantsEnum;
@@ -33,6 +33,15 @@
    R<List<Long>> getVehicleByUserId(@PathVariable("id") Long id);
    /**
     * 根据人员id 获取所属车队
     *
     * @param id 运维人员id
     * @return 车辆isd
     */
    @GetMapping("/logan/inner/fleet-operations/getFleetByUserId/{id}")
    R<List<XpFleet>> getFleetByUserId(@PathVariable("id") Long id);
    /**
     * 根据运维人员ID查询关联的车队ID列表
     *
     * @param userId 运维人员ID
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/account/XpAppUserCoupon.java
@@ -9,6 +9,10 @@
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@@ -33,10 +37,21 @@
    private Long id;
    @ApiModelProperty(value = "满减金额")
    @Min(0)@Max(9999)
    private BigDecimal fullMoney;
    @ApiModelProperty(value = "金额")
    @ApiModelProperty(value = "满减面额,对应couponType=1")
    @Min(0)@Max(9999)
    private BigDecimal money;
    @ApiModelProperty(value = "抹零后金额,对应couponType=3")
    @Min(0)@Max(9999)
    private BigDecimal money3;
    @ApiModelProperty(value = "折扣,对应couponType=2")
    @DecimalMin(value = "0.1", inclusive = true)
    @DecimalMax(value = "10", inclusive = true)
    private BigDecimal money2;
    @ApiModelProperty(value = "过期时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@@ -50,7 +65,7 @@
    @ApiModelProperty(value = "状态(1=未使用,2=已使用,3=已过期  0=待领取 4=占用中)")
    private Integer status;
    @ApiModelProperty(value = "优惠券类型(1=抵扣,2=满减)")
    @ApiModelProperty(value = "优惠券类型(1=抵扣,2=满减,3=抹零)")
    private Integer couponType;
    @ApiModelProperty(value = "用户id")
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpClockIn.java
@@ -1,13 +1,8 @@
package com.xiaopeng.api.model.maintenance;
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.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
@@ -16,6 +11,8 @@
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
 * <p>
 * 打卡明细
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpActicityStrategy.java
New file
@@ -0,0 +1,74 @@
package com.xiaopeng.api.model.operation;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
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 lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
 * <p>
 * 活动策略配置
 * </p>
 *
 * @author mitao
 * @since 2026-04-20
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("xp_acticity_strategy")
@ApiModel(value="XpActicityStrategy对象", description="活动策略配置")
public class XpActicityStrategy extends BaseModel {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "主键")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty(value = "活动id")
    private Integer actitcityId;
    @ApiModelProperty(value = "策略名称")
    private String name;
    @ApiModelProperty(value = "发放规则(1=每日循环发放,2=仅发放一次,3=使用后发放)")
    private Integer distributionRules;
    @ApiModelProperty(value = "使用后发放规则json")
    private String distributionRulesAfterUse;
    @ApiModelProperty(value = "生效规则(1=次日0点失效,2=指定有效天数,3=指定日期失效)")
    private Integer effectiveRules;
    @ApiModelProperty(value = "有效天数")
    private Integer effectiveDays;
    @ApiModelProperty(value = "有效结束时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime endTime;
    @ApiModelProperty(value = "是否叠加使用(0=否,1=是)")
    private Integer stackedUsage;
    @ApiModelProperty(value = "使用时段json")
    private String usagePeriod;
    @ApiModelProperty(value = "每人限领数量")
    private Integer limitNumber;
    @ApiModelProperty(value = "发放总数")
    private Integer distributionsTotal;
    @ApiModelProperty(value = "是否自动使用(0=不开启,1=冒泡发单时自动使用)")
    private Integer startUsing;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpActicityUser.java
New file
@@ -0,0 +1,46 @@
package com.xiaopeng.api.model.operation;
import com.baomidou.mybatisplus.annotation.IdType;
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 lombok.experimental.Accessors;
/**
 * <p>
 * 活动发放用户
 * </p>
 *
 * @author mitao
 * @since 2026-04-20
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("xp_acticity_user")
@ApiModel(value="XpActicityUser对象", description="活动发放用户")
public class XpActicityUser extends BaseModel {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "主键")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty(value = "活动id")
    private Integer actitcityId;
    @ApiModelProperty(value = "策略id")
    private Integer actitcityStrategeId;
    @ApiModelProperty(value = "用户类型(1=全部用户,2=老用户,3=新用户,4=流失用户,5=指定用户)")
    private Integer userType;
    @ApiModelProperty(value = "指定用户json数组")
    private String userList;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpActivity.java
@@ -36,6 +36,9 @@
    @ApiModelProperty(value = "活动名称")
    private String acticityName;
    @ApiModelProperty(value = "活动类型 如新人活动、媒体邀约活动、日常提频等")
    private Integer activityType;
    @ApiModelProperty(value = "开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime startTime;
@@ -62,4 +65,7 @@
    @ApiModelProperty(value = "图片")
    private String img;
    @ApiModelProperty(value = "富文本内容")
    private String richText;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpCoupon.java
@@ -1,30 +1,21 @@
package com.xiaopeng.api.model.operation;
import java.io.IOException;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
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 lombok.experimental.Accessors;
import org.apache.commons.lang3.StringEscapeUtils;
import org.springframework.stereotype.Component;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.math.BigDecimal;
/**
 * <p>
@@ -50,7 +41,7 @@
    @ApiModelProperty(value = "优惠券")
    private String couponName;
    @ApiModelProperty(value = "类型 1=抵扣 2=满减")
    @ApiModelProperty(value = "类型 1=抵扣 2=满减 3=抹零")
    private Integer couponType;
    @ApiModelProperty(value = "条件金额")
@@ -59,6 +50,15 @@
    @ApiModelProperty(value = "金额")
    private BigDecimal amount;
    @ApiModelProperty(value = "抹零后金额,对应couponType=3")
    @Min(0)@Max(9999)
    private BigDecimal amount2;
    @ApiModelProperty(value = "折扣,对应couponType=2")
    @DecimalMin(value = "0.1", inclusive = true)
    @DecimalMax(value = "10", inclusive = true)
    private BigDecimal amount3;
    @ApiModelProperty(value = "描述")
    private String couponDescription;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPasswordFreePolicy.java
New file
@@ -0,0 +1,84 @@
package com.xiaopeng.api.model.operation;
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 javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.time.LocalDateTime;
/**
 *免密支付策略
 */
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("xp_password_free_policy")
@ApiModel(value="XpPasswordFreePolicy 对象", description="免密支付策略")
public class XpPasswordFreePolicy extends BaseModel {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "省份名称")
    private String provinceName;
    @ApiModelProperty(value = "省份code")
    private String provinceCode;
    @ApiModelProperty(value = "城市名称")
    private String cityName;
    @ApiModelProperty(value = "城市code")
    private String cityCode;
    @ApiModelProperty(value = "最大重试次数")
    @Min(value = 0L, message = "最大重试次数不能小于0")
    @Max(value = 10L, message = "最大重试次数不能大于10")
    private Integer maxRetriesNumber;
    @ApiModelProperty(value = "重试间隔(秒)")
    private Integer retriesInterval;
    @ApiModelProperty(value = "重试失败后是否发送通知(0=否,1=是)")
    private Boolean sendNotification;
    @ApiModelProperty(value = "预估金额与实际金额差异大于x%,乘客端触发二次确认弹框")
    @Min(value = 0, message = "金额差异阈值能小于0")
    @Max(value = 1001L, message = "金额差异阈值不能大于1000")
    private Integer differenceRatio;
    @ApiModelProperty(value = "状态(1=启用,2=禁用)")
    private Integer status;
    public String getStatusName() {
        if(status != null){
            if(status == 1){
                return "启用";
            }else if(status == 2){
                return "禁用";
            }
        }
        return "";
    }
    @ApiModelProperty(value = "区域id")
    private String areaId;
    @ApiModelProperty(value = "区域名称")
    @TableField(exist = false)
    private String areaName;
    @ApiModelProperty(value = "有效期开始时间")
    private LocalDateTime validTimeStart;
    @ApiModelProperty(value = "有效期结束时间")
    private LocalDateTime validTimeEnd;
    @ApiModelProperty(value = "长期有效")
    private Boolean validTimeLong;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPointSituationReport.java
@@ -32,7 +32,19 @@
     */
    @ApiModelProperty("现场情况(1=正常,2=异常)")
    @TableField("field_situation")
    private String fieldSituation;
    private Integer fieldSituation;
    public String getFieldSituationName() {
        if(fieldSituation != null){
            if(fieldSituation == 1){
                return "正常";
            }else if(fieldSituation == 2){
                return "异常";
            }
        }
        return "";
    }
    /**
     * 现场照片JSON数组
     */
@@ -53,6 +65,7 @@
    /**
     * 现场情况上报时间
     */
    @ApiModelProperty("现场情况上报时间")
    @TableField("reporting_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime reportingTime;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPricing.java
@@ -35,6 +35,10 @@
    @TableField("vehicle_model")
    private String vehicleModel;
    @ApiModelProperty(value = "车型名称")
    @TableField(exist = false)
    private String vehicleModelName;
    @ApiModelProperty(value = "渠道")
    @TableField("channel")
    private String channel;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/account/XpAppUserCouponPageListQuery.java
@@ -22,6 +22,9 @@
    @ApiModelProperty(value = "活动名称")
    private String acticityName;
    @ApiModelProperty(value = "优惠券类型")
    private Integer couponType;
    @ApiModelProperty(value = "领取时间开始")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private LocalDateTime createTimeStart;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/XpActivityPageListQuery.java
New file
@@ -0,0 +1,61 @@
package com.xiaopeng.api.query.operation;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
 * <p>
 * 活动管理
 * </p>
 *
 * @author mitao
 * @since 2026-02-03
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="XpActicity对象", description="活动管理")
public class XpActivityPageListQuery extends BasePage {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "活动名称")
    private String acticityName;
    @ApiModelProperty(value = "开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime startTime;
    @ApiModelProperty(value = "结束时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime endTime;
    @ApiModelProperty(value = "状态 1=未开始 2=进行中 3=已结束 4=暂停")
    private Integer status;
    @ApiModelProperty(value = "备注")
    private String remarks;
    @ApiModelProperty(value = "注册启用 1=是 0=否")
    private Boolean registerEnable;
    @ApiModelProperty(value = "邀请启用 1=是 0=否")
    private Boolean inviteEnable;
    @ApiModelProperty(value = "是否删除")
    private String deleted;
    @ApiModelProperty(value = "图片")
    private String img;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/XpPasswordFreePolicyQuery.java
New file
@@ -0,0 +1,27 @@
package com.xiaopeng.api.query.operation;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class XpPasswordFreePolicyQuery extends BasePage {
    @ApiModelProperty(value = "城市名称")
    private String cityName;
    @ApiModelProperty(value = "有效期开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTimeStart;
    @ApiModelProperty(value = "有效期结束时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTimeEnd;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/XpPointSituationReportQuery.java
New file
@@ -0,0 +1,52 @@
package com.xiaopeng.api.query.operation;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class XpPointSituationReportQuery extends BasePage {
    private Long id;
    private List<Long> ids;
    @ApiModelProperty(value = "点位名称")
    private String pointName;
    @ApiModelProperty(value = "点位编号唯一")
    private String pointNumber;
    @ApiModelProperty(value = "点位状态值")
    private String pointStatusValue;
    /**
     * 现场情况(1=正常,2=异常)
     */
    @ApiModelProperty("现场情况(1=正常,2=异常)")
    private Integer fieldSituation;
    /**
     * 上报运维id
     */
    @TableField("operations_user_id")
    private Long operationsUserId;
    /**
     * 现场情况上报时间
     */
    @TableField("reporting_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime reportingTimeStart;
    /**
     * 现场情况上报时间
     */
    @TableField("reporting_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime reportingTimeEnd;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/XpPointSituationReportVo.java
New file
@@ -0,0 +1,50 @@
package com.xiaopeng.api.vo.operation;
import com.baomidou.mybatisplus.annotation.TableField;
import com.xiaopeng.api.model.operation.XpPointSituationReport;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class XpPointSituationReportVo extends XpPointSituationReport {
    @ApiModelProperty(value = "点位名称")
    private String pointName;
    @ApiModelProperty(value = "点位编号唯一")
    private String pointNumber;
    @ApiModelProperty(value = "运营状态 1=待启用 2=启用中 3=已停用 4=已失效")
    private Integer operationStatus;
    @ApiModelProperty(value = "点位类型 1=运营点位 2=测试点位")
    private Integer pointType;
    @ApiModelProperty(value = "验证状态 1=待验证、2=验证中、3=已验证 4验证失败 5待生效")
    private Integer verificationStatus;
    @ApiModelProperty(value = "点位状态名称")
    private String pointStatusName;
    @ApiModelProperty(value = "点位状态值")
    private String pointStatusValue;
    /**
     * 上报运维名称
     */
    @ApiModelProperty(value = "上报运维名称")
    private String operationsUserName;
    /**
     * 上报运维人车队名
     */
    @ApiModelProperty(value = "上报运维人车队名")
    private String operationsUserFleetName;
}
xp-robotaxi-api/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -57,4 +57,5 @@
com.xiaopeng.api.factory.pushMessage.SubscribeMessageClientFallbackFactory
com.xiaopeng.api.factory.account.UserSubscribeMessageClientFallbackFactory
com.xiaopeng.api.factory.operation.XpTradingStrategyClientFallbackFactory
com.xiaopeng.api.factory.operation.XpActicityClientFallbackFactory
com.xiaopeng.api.factory.operation.XpActicityClientFallbackFactory
com.xiaopeng.api.factory.maintenance.XpVehicleModelClientFallbackFactory
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpClockInController.java
@@ -1,22 +1,19 @@
package com.xiaopeng.maintenance.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xiaopeng.api.model.maintenance.XpClockIn;
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.maintenance.dto.*;
import com.xiaopeng.maintenance.dto.ClockDTO;
import com.xiaopeng.maintenance.dto.ClockInStatisticsDto;
import com.xiaopeng.maintenance.dto.GetClockInStatisticsDetailsDto;
import com.xiaopeng.maintenance.dto.VerifyRangeDTO;
import com.xiaopeng.maintenance.service.IXpClockInService;
import com.xiaopeng.maintenance.vo.ClockInStatisticsDetailsVo;
import com.xiaopeng.maintenance.vo.ClockInStatisticsVo;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
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;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCruiseCheckInRuleController.java
@@ -4,12 +4,16 @@
import com.xiaopeng.api.model.maintenance.XpCruiseCheckInRecord;
import com.xiaopeng.api.vo.account.LoginOperationUser;
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.maintenance.model.vo.AppXpCruiseCheckInLocationVo;
import com.xiaopeng.maintenance.model.vo.AppXpCruiseCheckInRuleVo;
import com.xiaopeng.maintenance.model.vo.CheckInMessageVo;
import com.xiaopeng.maintenance.model.vo.RealTimePositionVo;
import com.xiaopeng.maintenance.service.IXpCruiseCheckInRecordService;
import com.xiaopeng.maintenance.service.IXpCruiseCheckInRuleService;
import com.xiaopeng.maintenance.vo.XpCruiseCheckInRecordQuery;
import com.xiaopeng.maintenance.vo.XpCruiseCheckInRecordVO;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
@@ -31,8 +35,8 @@
    @Resource
    private TokenService tokenService;
    @Resource
    private IXpCruiseCheckInRecordService xpCruiseCheckInRecordService;
    @ApiOperation(value = "获取个人中心巡游打卡任务", tags = {"运维APP-个人中心"})
    @GetMapping("/maintenance-app/api/v1/cruiseCheckInRule/getMyXpCruiseCheckInRule")
@@ -82,6 +86,7 @@
            @ApiImplicitParam(value = "任务id", name = "id", required = true, dataType = "Integer"),
            @ApiImplicitParam(value = "打卡点位id", name = "locationId", required = true, dataType = "Long")
    })
    @GetMapping("/maintenance-app/api/v1/cruiseCheckInRule/getCruiseCheckInRecordInfo/{id}/{locationId}")
    public R<XpCruiseCheckInRecord> getCruiseCheckInRecordInfo(@PathVariable("id") Integer id, @PathVariable("locationId") Long locationId) {
        LoginOperationUser loginOperationUser = tokenService.getLoginOperationUser();
@@ -89,4 +94,18 @@
        return R.ok(cruiseCheckInRecordInfo);
    }
    @ApiOperation(value = "查询巡游打卡记录列表", tags = {"管理后台-巡游打卡管理"})
    @PostMapping("/maintenance-admin/api/v1/cruiseCheckInRecord/pageList")
    public R<PageInfo<XpCruiseCheckInRecordVO>> pageList(@RequestBody XpCruiseCheckInRecordQuery query) {
        PageInfo<XpCruiseCheckInRecordVO> pageInfo = xpCruiseCheckInRecordService.pageList(query);
        return R.ok(pageInfo);
    }
    @ApiOperation(value = "查询巡游打卡记录详情", tags = {"管理后台-巡游打卡管理"})
    @GetMapping("/maintenance-admin/api/v1/cruiseCheckInRecord/{id}")
    public R<XpCruiseCheckInRecordVO> pageList(@PathVariable("id")Long id) {
        XpCruiseCheckInRecordVO xpCruiseCheckInRecordVO = xpCruiseCheckInRecordService.detail(id);
        return R.ok(xpCruiseCheckInRecordVO);
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleModelController.java
@@ -1,5 +1,6 @@
package com.xiaopeng.maintenance.controller;
import cn.hutool.core.collection.CollUtil;
import com.xiaopeng.api.feignClient.operation.XpPricingClient;
import com.xiaopeng.api.model.maintenance.XpVehicleModel;
import com.xiaopeng.common.core.domain.R;
@@ -14,6 +15,7 @@
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@@ -34,6 +36,18 @@
        PageInfo<XpVehicleModel> pageInfo = xpVehicleModelService.pageList(query);
        return R.ok(pageInfo);
    }
    @PostMapping("/logan/inner/xpVehicleModel/listByIds")
    @ApiOperation(value = "根据ID列表批量查询", tags = {"内部接口"})
    public R<List<XpVehicleModel>> listByIds(@RequestBody List<String> ids) {
        if (CollUtil.isEmpty(ids)) {
            return R.ok(new ArrayList<>());
        }
        return R.ok(xpVehicleModelService.listByIds(ids));
    }
    @ApiOperation(value = "根据ID查询", tags = "管理后台-车型根据ID查询")
    @GetMapping("/logan/inner/xpVehicleModel/getById")
    public R<XpVehicleModel> getById(@RequestParam String id) {
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/mapper/XpCruiseCheckInRecordMapper.java
@@ -2,6 +2,16 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaopeng.api.model.maintenance.XpCruiseCheckInRecord;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.vo.XpCruiseCheckInRecordQuery;
import com.xiaopeng.maintenance.vo.XpCruiseCheckInRecordVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface XpCruiseCheckInRecordMapper extends BaseMapper<XpCruiseCheckInRecord> {
    List<XpCruiseCheckInRecordVO> selectCruiseCheckInRecordList(@Param("pageInfo") PageInfo<XpCruiseCheckInRecordVO> pageInfo, @Param("query") XpCruiseCheckInRecordQuery query);
    XpCruiseCheckInRecordVO detail(Long id);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpCruiseCheckInRecordService.java
@@ -2,6 +2,13 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.maintenance.XpCruiseCheckInRecord;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.vo.XpCruiseCheckInRecordQuery;
import com.xiaopeng.maintenance.vo.XpCruiseCheckInRecordVO;
public interface IXpCruiseCheckInRecordService extends IService<XpCruiseCheckInRecord> {
    PageInfo<XpCruiseCheckInRecordVO> pageList(XpCruiseCheckInRecordQuery query);
    XpCruiseCheckInRecordVO detail(Long id);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpCruiseCheckInRecordServiceImpl.java
@@ -2,10 +2,32 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.maintenance.XpCruiseCheckInRecord;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.mapper.XpCruiseCheckInRecordMapper;
import com.xiaopeng.maintenance.service.IXpCruiseCheckInRecordService;
import com.xiaopeng.maintenance.vo.XpCruiseCheckInRecordQuery;
import com.xiaopeng.maintenance.vo.XpCruiseCheckInRecordVO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class XpCruiseCheckInRecordServiceImpl extends ServiceImpl<XpCruiseCheckInRecordMapper, XpCruiseCheckInRecord> implements IXpCruiseCheckInRecordService {
    @Resource
    private XpCruiseCheckInRecordMapper xpCruiseCheckInRecordMapper;
    @Override
    public PageInfo<XpCruiseCheckInRecordVO> pageList(XpCruiseCheckInRecordQuery query) {
        PageInfo<XpCruiseCheckInRecordVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        List<XpCruiseCheckInRecordVO> list = xpCruiseCheckInRecordMapper.selectCruiseCheckInRecordList(pageInfo, query);
        pageInfo.setRecords(list);
        return pageInfo;
    }
    @Override
    public XpCruiseCheckInRecordVO detail(Long id) {
        return xpCruiseCheckInRecordMapper.detail(id);
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/XpCruiseCheckInRecordQuery.java
New file
@@ -0,0 +1,42 @@
package com.xiaopeng.maintenance.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDate;
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "巡游打卡记录查询参数")
public class XpCruiseCheckInRecordQuery extends BasePage {
    @ApiModelProperty(value = "巡游结果:1=正常,2=拥堵")
    private Integer fieldSituation;
    @ApiModelProperty(value = "打卡状态:1=正常打卡,2=迟到打卡,3=未打卡")
    private Integer checkInResult;
    @ApiModelProperty(value = "运维人员姓名(模糊匹配)")
    private String operationsUserName;
    @ApiModelProperty(value = "打卡规则名称(模糊匹配)")
    private String ruleName;
    @ApiModelProperty(value = "打卡点位名称(模糊匹配)")
    private String locationAddress;
    @ApiModelProperty(value = "手机号(精确匹配)")
    private String phoneNumber;
    @ApiModelProperty(value = "开始日期")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private LocalDate startDate;
    @ApiModelProperty(value = "结束日期")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private LocalDate endDate;
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/XpCruiseCheckInRecordVO.java
New file
@@ -0,0 +1,54 @@
package com.xiaopeng.maintenance.vo;
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.LocalDateTime;
@Data
@ApiModel(value = "巡游打卡记录返回VO")
public class XpCruiseCheckInRecordVO implements Serializable {
    @ApiModelProperty(value = "主键")
    private Long id;
    @ApiModelProperty(value = "运维人员id")
    private Long operationsUserId;
    @ApiModelProperty(value = "运维人员姓名")
    private String operationsUserName;
    @ApiModelProperty(value = "运维人员手机号")
    private String phoneNumber;
    @ApiModelProperty(value = "打卡点位id")
    private Long checkLocationId;
    @ApiModelProperty(value = "打卡点位名称")
    private String locationAddress;
    @ApiModelProperty(value = "巡游打卡规则id")
    private Integer cruiseCheckInRuleId;
    @ApiModelProperty(value = "打卡规则名称")
    private String ruleName;
    @ApiModelProperty(value = "打卡时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime checkInTime;
    @ApiModelProperty(value = "打卡结果(1=正常打卡,2=迟到打卡,3=未打卡)")
    private Integer checkInResult;
    @ApiModelProperty(value = "现场情况(1=正常,2=拥堵)")
    private Integer fieldSituation;
    @ApiModelProperty(value = "现场照片JSON数组")
    private String scenePhoto;
    @ApiModelProperty(value = "现场情况说明")
    private String sceneDescription;
}
xp-robotaxi-maintenance-boot/src/main/resources/mapper/maintenance/XpCruiseCheckInRecordMapper.xml
@@ -2,4 +2,93 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiaopeng.maintenance.mapper.XpCruiseCheckInRecordMapper">
    <resultMap id="CruiseCheckInRecordVOMap" type="com.xiaopeng.maintenance.vo.XpCruiseCheckInRecordVO">
        <id column="id" property="id"/>
        <result column="operations_user_id" property="operationsUserId"/>
        <result column="operations_user_name" property="operationsUserName"/>
        <result column="phone_number" property="phoneNumber"/>
        <result column="check_location_id" property="checkLocationId"/>
        <result column="location_address" property="locationAddress"/>
        <result column="cruise_check_in_rule_id" property="cruiseCheckInRuleId"/>
        <result column="rule_name" property="ruleName"/>
        <result column="check_in_time" property="checkInTime"/>
        <result column="check_in_result" property="checkInResult"/>
        <result column="field_situation" property="fieldSituation"/>
        <result column="scene_photo" property="scenePhoto"/>
        <result column="scene_description" property="sceneDescription"/>
    </resultMap>
    <select id="selectCruiseCheckInRecordList" resultMap="CruiseCheckInRecordVOMap">
        SELECT
            r.id,
            r.operations_user_id,
            u.nick_name AS operations_user_name,
            u.phone_number,
            r.check_location_id,
            cl.location_address,
            r.cruise_check_in_rule_id,
            cr.name AS rule_name,
            r.check_in_time,
            r.check_in_result,
            r.field_situation,
            r.scene_photo,
            r.scene_description
        FROM xp_cruise_check_in_record r
        LEFT JOIN xp_operations_user u ON r.operations_user_id = u.id AND u.del_flag = '0'
        LEFT JOIN xp_check_location cl ON r.check_location_id = cl.id AND cl.del_flag = '0'
        LEFT JOIN xp_cruise_check_in_rule cr ON r.cruise_check_in_rule_id = cr.id AND cr.del_flag = '0'
        WHERE r.del_flag = '0'
        <if test="query.fieldSituation != null">
            AND r.field_situation = #{query.fieldSituation}
        </if>
        <if test="query.checkInResult != null and query.checkInResult == 3">
            AND r.check_in_result IS NULL
        </if>
        <if test="query.checkInResult != null and query.checkInResult != 3">
            AND r.check_in_result = #{query.checkInResult}
        </if>
        <if test="query.operationsUserName != null and query.operationsUserName != ''">
            AND u.nick_name LIKE CONCAT('%', #{query.operationsUserName}, '%')
        </if>
        <if test="query.ruleName != null and query.ruleName != ''">
            AND cr.name LIKE CONCAT('%', #{query.ruleName}, '%')
        </if>
        <if test="query.locationAddress != null and query.locationAddress != ''">
            AND cl.location_address LIKE CONCAT('%', #{query.locationAddress}, '%')
        </if>
        <if test="query.phoneNumber != null and query.phoneNumber != ''">
            AND u.phone_number = #{query.phoneNumber}
        </if>
        <if test="query.startDate != null">
            AND DATE(r.check_in_time) &gt;= #{query.startDate}
        </if>
        <if test="query.endDate != null">
            AND DATE(r.check_in_time) &lt;= #{query.endDate}
        </if>
        ORDER BY r.check_in_time DESC
    </select>
    <select id="detail" resultMap="CruiseCheckInRecordVOMap">
        SELECT
            r.id,
            r.operations_user_id,
            u.nick_name AS operations_user_name,
            u.phone_number,
            r.check_location_id,
            cl.location_address,
            r.cruise_check_in_rule_id,
            cr.name AS rule_name,
            r.check_in_time,
            r.check_in_result,
            r.field_situation,
            r.scene_photo,
            r.scene_description
        FROM xp_cruise_check_in_record r
        LEFT JOIN xp_operations_user u ON r.operations_user_id = u.id AND u.del_flag = '0'
        LEFT JOIN xp_check_location cl ON r.check_location_id = cl.id AND cl.del_flag = '0'
        LEFT JOIN xp_cruise_check_in_rule cr ON r.cruise_check_in_rule_id = cr.id AND cr.del_flag = '0'
        WHERE r.id = #{id}
          AND r.del_flag = '0'
    </select>
</mapper>
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpActicityController.java
@@ -2,10 +2,13 @@
import com.xiaopeng.api.model.operation.XpActivity;
import com.xiaopeng.api.model.operation.XpCoupon;
import com.xiaopeng.api.query.operation.XpActivityPageListQuery;
import com.xiaopeng.api.vo.operation.XpActivityVo;
import com.xiaopeng.common.core.constant.CacheConstants;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.utils.bean.BeanUtils;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.service.IXpActicityService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -13,7 +16,9 @@
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
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 javax.annotation.Resource;
@@ -35,7 +40,7 @@
public class XpActicityController {
    @Resource
    private IXpActicityService xpActicityService;
    private IXpActicityService service;
    /**
@@ -48,7 +53,7 @@
        if(acticityName == null){
            return R.ok();
        }
        return R.ok(xpActicityService.findListToIds(acticityName));
        return R.ok(service.findListToIds(acticityName));
    }
@@ -66,7 +71,7 @@
        String uid = request.getHeader("XP-Uid");
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        XpActivity activity = xpActicityService.activiting();
        XpActivity activity = service.activiting();
        XpActivityVo ret = new XpActivityVo();
        if (activity !=null) {
            BeanUtils.copyBeanProp(ret, activity);
@@ -78,4 +83,39 @@
    }
    @PostMapping("/v1/api/appUserCoupon/pageList")
    @ApiOperation(value = "活动列表",tags = {"管理后台-活动管理"},response = XpActivity.class)
    public R<PageInfo<XpActivity>> pageList(@RequestBody XpActivityPageListQuery query) {
        PageInfo<XpActivity> pageList = service.pageList(query);
        return R.ok(pageList);
    }
    @PostMapping("/v1/api/xp-coupon/add")
    @ApiOperation(value = "添加活动",tags = {"管理后台-活动管理"},response = XpCoupon.class)
    public R<?> add(@RequestBody XpActivity xpActivity){
        service.save(xpActivity);
        return R.ok();
    }
    @PostMapping("/v1/api/xp-coupon/update")
    @ApiOperation(value = "修改活动",tags = {"管理后台-活动管理"},response = XpCoupon.class)
    public R<XpActivity> updateById(@RequestBody XpActivity xpActivity){
        service.updateById(xpActivity);
        return R.ok();
    }
    @GetMapping("/v1/api/xp-coupon/update")
    @ApiOperation(value = "活动详情",tags = {"管理后台-活动管理"},response = XpCoupon.class)
    public R<XpActivity> queryById(@RequestBody XpActivity xpActivity){
        return R.ok(service.getById(xpActivity));
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpActicityStrategyController.java
New file
@@ -0,0 +1,70 @@
package com.xiaopeng.operation.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaopeng.api.model.operation.XpActicityStrategy;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.operation.service.IXpActicityStrategyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
 * <p>
 * 活动策略配置 前端控制器
 * </p>
 *
 * @author mitao
 * @since 2026-04-20
 */
@Api(tags = "活动策略配置管理")
@RequiredArgsConstructor(onConstructor_ = @Lazy)
@RestController
@RequestMapping("/v1/api/acticity-strategy")
public class XpActicityStrategyController {
    @Resource
    private IXpActicityStrategyService service;
    @PostMapping("/listByActivityId")
    @ApiOperation(value = "根据活动ID查询策略列表", tags = {"管理后台-活动策略配置管理"})
    public R<List<XpActicityStrategy>> listByActivityId(@RequestParam Integer activityId) {
        LambdaQueryWrapper<XpActicityStrategy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(XpActicityStrategy::getActitcityId, activityId);
        queryWrapper.orderByDesc(XpActicityStrategy::getCreateTime);
        List<XpActicityStrategy> list = service.list(queryWrapper);
        return R.ok(list);
    }
    @GetMapping("/{id}")
    @ApiOperation(value = "活动策略详情", tags = {"管理后台-活动策略配置管理"})
    public R<XpActicityStrategy> queryById(@PathVariable Integer id) {
        XpActicityStrategy strategy = service.getById(id);
        return R.ok(strategy);
    }
    @PostMapping("/add")
    @ApiOperation(value = "新增活动策略", tags = {"管理后台-活动策略配置管理"})
    public R<?> add(@RequestBody List<XpActicityStrategy> xpActicityStrategies) {
        service.saveBatch(xpActicityStrategies);
        return R.ok();
    }
    @PostMapping("/update")
    @ApiOperation(value = "修改活动策略", tags = {"管理后台-活动策略配置管理"})
    public R<?> updateById(@RequestBody XpActicityStrategy xpActicityStrategy) {
        service.updateById(xpActicityStrategy);
        return R.ok();
    }
    @DeleteMapping("/{id}")
    @ApiOperation(value = "删除活动策略", tags = {"管理后台-活动策略配置管理"})
    public R<?> deleteById(@PathVariable Integer id) {
        service.removeById(id);
        return R.ok();
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpActicityUserController.java
New file
@@ -0,0 +1,78 @@
package com.xiaopeng.operation.controller;
import com.xiaopeng.api.model.operation.XpActicityUser;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.operation.service.IXpActicityUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
 * <p>
 * 活动发放用户 前端控制器
 * </p>
 *
 * @author mitao
 * @since 2026-04-20
 */
@Api(tags = "活动发放用户管理")
@RequiredArgsConstructor(onConstructor_ = @Lazy)
@RestController
@RequestMapping("/v1/api/acticity-user")
public class XpActicityUserController {
    @Resource
    private IXpActicityUserService service;
    @GetMapping("/{id}")
    @ApiOperation(value = "活动发放用户详情", tags = {"管理后台-活动发放用户管理"})
    public R<XpActicityUser> queryById(@PathVariable Integer id) {
        XpActicityUser user = service.getById(id);
        return R.ok(user);
    }
    @GetMapping("/listByActicityId/{actitcityId}")
    @ApiOperation(value = "根据活动ID获取用户配置", tags = {"管理后台-活动发放用户管理"})
    public R<List<XpActicityUser>> listByActicityId(@PathVariable Integer actitcityId) {
        LambdaQueryWrapper<XpActicityUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(XpActicityUser::getActitcityId, actitcityId);
        List<XpActicityUser> list = service.list(queryWrapper);
        return R.ok(list);
    }
    @PostMapping("/add")
    @ApiOperation(value = "批量新增活动发放用户", tags = {"管理后台-活动发放用户管理"})
    public R<List<XpActicityUser>> add(@RequestBody List<XpActicityUser> xpActicityUsers) {
        service.saveBatch(xpActicityUsers);
        return R.ok(xpActicityUsers);
    }
    @PostMapping("/update")
    @ApiOperation(value = "修改活动发放用户", tags = {"管理后台-活动发放用户管理"})
    public R<?> updateById(@RequestBody XpActicityUser xpActicityUser) {
        service.updateById(xpActicityUser);
        return R.ok();
    }
    @DeleteMapping("/{id}")
    @ApiOperation(value = "删除活动发放用户", tags = {"管理后台-活动发放用户管理"})
    public R<?> deleteById(@PathVariable Integer id) {
        service.removeById(id);
        return R.ok();
    }
    @DeleteMapping("/deleteByActicityId/{actitcityId}")
    @ApiOperation(value = "根据活动ID删除用户配置", tags = {"管理后台-活动发放用户管理"})
    public R<?> deleteByActicityId(@PathVariable Integer actitcityId) {
        LambdaQueryWrapper<XpActicityUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(XpActicityUser::getActitcityId, actitcityId);
        service.remove(queryWrapper);
        return R.ok();
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCouponController.java
@@ -2,17 +2,15 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient;
import com.xiaopeng.api.model.operation.XpCoupon;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.operation.query.XpCouponListQuery;
import com.xiaopeng.operation.service.IXpCouponService;
import com.xiaopeng.operation.vo.XpBannerListVo;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import java.util.List;
import javax.annotation.Resource;
/**
 * <p>
@@ -75,14 +73,23 @@
    }
    @Resource XpAppUserCouponClient xpAppUserCouponClient;
    /**
     * 删除优惠券
     */
    @DeleteMapping("/v1/api/xp-coupon/deleteById")
    @ApiOperation(value = "删除优惠券",tags = {"管理后台-优惠券"},response = XpCoupon.class)
    public R<?> deleteById(@RequestParam Long id){
        xpCouponService.removeById(id);
        return R.ok();
        if (!xpAppUserCouponClient.isHolding(id)){
            xpCouponService.removeById(id);
            return R.ok();
        }
        else{
            return R.fail("该优惠券已有用户使用,无法作废 / 删除");
        }
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPasswordFreePolicyController.java
New file
@@ -0,0 +1,89 @@
package com.xiaopeng.operation.controller;
import com.xiaopeng.api.model.operation.XpPasswordFreePolicy;
import com.xiaopeng.api.query.operation.XpPasswordFreePolicyQuery;
import com.xiaopeng.api.vo.account.LoginUser;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.operation.service.XpPasswordFreePolicyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("")
@Api(tags = "免密支付策略")
public class XpPasswordFreePolicyController {
    @Resource
    private XpPasswordFreePolicyService xpPasswordFreePolicyService;
    @Resource
    private TokenService tokenService;
    /**
     * 分页查询路线规划配置列表
     */
    @ApiOperation(value = "免密支付策略分页列表", tags = {"管理后台-交易定价-免密支付策略"}, response = XpPasswordFreePolicy.class)
    @PostMapping("/api/v1/passwordFreePolicy/pageList")
    public R<PageInfo<XpPasswordFreePolicy>> pageList(@RequestBody XpPasswordFreePolicyQuery query) {
        PageInfo<XpPasswordFreePolicy> pageInfo = xpPasswordFreePolicyService.pageList(query);
        return R.ok(pageInfo);
    }
    /**
     * 新增路线规划配置
     */
    @ApiOperation(value = "新增免密支付策略", tags = {"管理后台-交易定价-免密支付策略"})
    @PostMapping("/api/v1/passwordFreePolicy/add")
    public R<?> add(@Valid @RequestBody XpPasswordFreePolicy dto) {
        LoginUser loginUser = tokenService.getLoginUser();
        dto.setCreateBy(loginUser.getUsername());
        dto.setCreateTime(LocalDateTime.now());
        xpPasswordFreePolicyService.save(dto);
        return R.ok();
    }
    /**
     * 编辑路线规划配置
     */
    @ApiOperation(value = "编辑免密支付策略", tags = {"管理后台-交易定价-免密支付策略"})
    @PostMapping("/api/v1/passwordFreePolicy/edit")
    public R<?> edit(@Valid @RequestBody XpPasswordFreePolicy dto) {
        // 1. 查询原记录是否存在
        XpPasswordFreePolicy routePlan = xpPasswordFreePolicyService.getById(dto.getId());
        if (routePlan == null) {
            throw new ServiceException("数据不存在");
        }
        LoginUser loginUser = tokenService.getLoginUser();
        dto.setUpdateBy(loginUser.getUsername());
        dto.setUpdateTime(LocalDateTime.now());
        xpPasswordFreePolicyService.updateById(dto);
        return R.ok();
    }
    /**
     * 删除路线规划配置
     */
    @ApiOperation(value = "删除免密支付策略", tags = {"管理后台-管理后台-交易定价-免密支付策略"})
    @DeleteMapping("/api/v1/passwordFreePolicy/deleteById/{id}")
    public R<?> deleteById(@PathVariable Long id) {
        xpPasswordFreePolicyService.deleteById(id);
        return R.ok();
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPointSituationReportController.java
@@ -1,20 +1,34 @@
package com.xiaopeng.operation.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.xiaopeng.api.model.account.SysUser;
import com.xiaopeng.api.model.operation.XpPasswordFreePolicy;
import com.xiaopeng.api.model.operation.XpPointSituationReport;
import com.xiaopeng.api.query.operation.XpPointSituationReportQuery;
import com.xiaopeng.api.vo.account.LoginOperationUser;
import com.xiaopeng.api.vo.operation.XpPointSituationReportVo;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.utils.WebUtils;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.operation.exportExcle.XpPointSituationReportExportExcel;
import com.xiaopeng.operation.service.IXpPointSituationReportService;
import com.xiaopeng.operation.vo.XpAgreementVo;
import io.swagger.annotations.ApiOperation;
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;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("")
@@ -28,8 +42,76 @@
    /**
     * 分页查询路线规划配置列表
     */
    @ApiOperation(value = "现场情况上报分页列表", tags = {"管理后台-运维-现场情况上报"}, response = XpPasswordFreePolicy.class)
    @PostMapping("/api/v1/pointSituationReport/pageList")
    public R<PageInfo<XpPointSituationReportVo>> pageList(@RequestBody XpPointSituationReportQuery query) {
        PageInfo<XpPointSituationReportVo> pageInfo = xpPointSituationReportService.pageList(query);
        return R.ok(pageInfo);
    }
    /**
     * 删除路线规划配置
     */
    @ApiOperation(value = "详情现场情况上报", tags = {"管理后台-运维-现场情况上报"})
    @DeleteMapping("/api/v1/pointSituationReport/getdetail/{id}")
    public R<?> getdetail(@PathVariable Long id) {
        xpPointSituationReportService.getdetail(id);
        return R.ok();
    }
    /**
     * 删除路线规划配置
     */
    @ApiOperation(value = "删除现场情况上报", tags = {"管理后台-运维-现场情况上报"})
    @DeleteMapping("/api/v1/pointSituationReport/deleteById/{id}")
    public R<?> deleteById(@PathVariable Long id) {
        xpPointSituationReportService.deleteById(id);
        return R.ok();
    }
    @ApiOperation(value = "导出现场情况上报", tags = {"管理后台-运维-现场情况上报"})
    @PostMapping(value = "/api/v1/pointSituationReport/exportExcels")
    public void exportExcels(@RequestBody XpPointSituationReportQuery query) {
        List<XpPointSituationReportVo> exportList = xpPointSituationReportService.exportList(query);
        List<XpPointSituationReportExportExcel> exportExcels = new ArrayList<>();
        long sequence = 1L;
        for (XpPointSituationReportVo bean : exportList) {
            XpPointSituationReportExportExcel exportExcel = new XpPointSituationReportExportExcel();
            BeanUtils.copyProperties(bean,exportExcel);
            exportExcel.setId(sequence++);
            LocalDateTime time = bean.getReportingTime();
            exportExcel.setReportingTimeStr(time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
            exportExcels.add(exportExcel);
        }
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        //1.获取excel模板
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), XpPointSituationReportExportExcel.class, exportExcels);
        HttpServletResponse response = WebUtils.response();
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        ServletOutputStream outputStream = null;
        try {
            String fileName = URLEncoder.encode("现场情况上报列表.xls", "utf-8");
            response.setHeader("Content-dispodition", "attachment;filename=" + fileName);
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    @ApiOperation(value = "现场情况上报", tags = {"运维APP-站点管理"}, response = XpPointSituationReport.class)
    @PostMapping("/maintenance-app/api/v1/pointSituationReport/addPointSituationReport")
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java
@@ -6,6 +6,8 @@
import com.xiaopeng.api.dto.map.RouteAndFareDto;
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.feignClient.account.UserResourcesClient;
import com.xiaopeng.api.feignClient.maintenance.XpVehicleModelClient;
import com.xiaopeng.api.model.maintenance.XpVehicleModel;
import com.xiaopeng.api.model.operation.XpPricing;
import com.xiaopeng.api.model.operation.XpWhitelist;
import com.xiaopeng.api.vo.operation.RouteAndFareVo;
@@ -27,8 +29,11 @@
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
/**
 * <p>
@@ -51,6 +56,9 @@
    private final IXpWhitelistService xpWhitelistService;
    private final XpOpenCityService xpOpenCityService;
    private final ImageTagProcessor imageTagProcessor;
    @Resource
    private XpVehicleModelClient xpVehicleModelClient;
    public XpPricingController(XpPricingService xpPricingService, IXpGeoQueryEntityService xpGeoQueryEntityService, UserResourcesClient userResourcesClient, IXpWhitelistService xpWhitelistService, XpRegionService xpRegionService, XpOpenCityService xpOpenCityService, ImageTagProcessor imageTagProcessor) {
        this.xpPricingService = xpPricingService;
@@ -206,6 +214,11 @@
        String cityName = xpOpenCityService.getNameWithCityName(pricing.getCityId());
        pricing.setCityName(cityName);
        R<List<XpVehicleModel>> listR = xpVehicleModelClient.listByIds(new ArrayList<String>(){{add(pricing.getVehicleModel());}});
        if(listR != null && listR.getData() != null) {
            XpVehicleModel xpVehicleModel = listR.getData().get(0);
            pricing.setVehicleModelName(xpVehicleModel.getName());
        }
        String priceRule = pricing.getPriceRule();
        if (priceRule != null && priceRule.contains("<img")) {
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/exportExcle/XpPointSituationReportExportExcel.java
New file
@@ -0,0 +1,46 @@
package com.xiaopeng.operation.exportExcle;
import cn.afterturn.easypoi.excel.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value="现场情况上报导出")
public class XpPointSituationReportExportExcel {
    @ApiModelProperty(value = "序号")
    @Excel(name = "序号",width = 20)
    private Long id;
    @ApiModelProperty(value = "点位ID")
    @Excel(name = "点位ID",width = 20)
    private String pointNumber;
    @ApiModelProperty(value = "点位名称")
    @Excel(name = "点位名称",width = 20)
    private String pointName;
    @ApiModelProperty(value = "点位状态名称")
    @Excel(name = "状态",width = 20)
    private String pointStatusName;
    @ApiModelProperty(value = "现场情况(1=正常,2=异常)")
    @Excel(name = "现场情况",width = 20)
    private String fieldSituationName;
    /**
     * 现场情况说明
     */
    @ApiModelProperty("现场情况说明")
    @Excel(name = "现场情况说明",width = 20)
    private String sceneDescription;
    @ApiModelProperty(value = "上报运维名称")
    @Excel(name = "上报人",width = 20)
    private String operationsUserName;
    @ApiModelProperty("上报时间")
    @Excel(name = "序号",width = 20)
    private String reportingTimeStr;
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/mapper/XpActicityMapper.java
@@ -2,6 +2,10 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaopeng.api.model.operation.XpActivity;
import com.xiaopeng.api.query.operation.XpActivityPageListQuery;
import com.xiaopeng.common.core.web.page.PageInfo;
import java.util.List;
/**
 * <p>
@@ -13,4 +17,5 @@
 */
public interface XpActicityMapper extends BaseMapper<XpActivity> {
    List<XpActivity> pageList(PageInfo<XpActivity> pageInfo, XpActivityPageListQuery query);
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/mapper/XpActicityStrategyMapper.java
New file
@@ -0,0 +1,16 @@
package com.xiaopeng.operation.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaopeng.api.model.operation.XpActicityStrategy;
/**
 * <p>
 * 活动策略配置 Mapper 接口
 * </p>
 *
 * @author mitao
 * @since 2026-04-20
 */
public interface XpActicityStrategyMapper extends BaseMapper<XpActicityStrategy> {
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/mapper/XpActicityUserMapper.java
New file
@@ -0,0 +1,16 @@
package com.xiaopeng.operation.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaopeng.api.model.operation.XpActicityUser;
/**
 * <p>
 * 活动发放用户 Mapper 接口
 * </p>
 *
 * @author mitao
 * @since 2026-04-20
 */
public interface XpActicityUserMapper extends BaseMapper<XpActicityUser> {
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/mapper/XpPasswordFreePolicyMapper.java
New file
@@ -0,0 +1,30 @@
package com.xiaopeng.operation.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaopeng.api.model.operation.XpPasswordFreePolicy;
import com.xiaopeng.api.query.operation.XpPasswordFreePolicyQuery;
import com.xiaopeng.api.query.operation.XpPointSituationReportQuery;
import com.xiaopeng.api.vo.operation.XpPointSituationReportVo;
import com.xiaopeng.common.core.web.page.PageInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface XpPasswordFreePolicyMapper extends BaseMapper<XpPasswordFreePolicy> {
    /**
     * 分页查询路线规划配置列表
     *
     * @param pageInfo 分页信息
     * @param query 查询条件
     * @return 路线规划配置列表
     */
    List<XpPasswordFreePolicy> pageList(@Param("pageInfo") PageInfo<XpPasswordFreePolicy> pageInfo,
                                            @Param("query") XpPasswordFreePolicyQuery query);
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/mapper/XpPointSituationReportMapper.java
@@ -2,6 +2,29 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaopeng.api.model.operation.XpPointSituationReport;
import com.xiaopeng.api.query.operation.XpPointSituationReportQuery;
import com.xiaopeng.api.vo.operation.XpPointSituationReportVo;
import com.xiaopeng.common.core.web.page.PageInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface XpPointSituationReportMapper extends BaseMapper<XpPointSituationReport> {
    /**
     * 分页查询路线规划配置列表
     *
     * @param pageInfo 分页信息
     * @param query 查询条件
     * @return 路线规划配置列表
     */
    List<XpPointSituationReportVo> pageList(@Param("pageInfo") PageInfo<XpPointSituationReportVo> pageInfo,
                                            @Param("query") XpPointSituationReportQuery query);
    List<XpPointSituationReportVo> pageList(@Param("query") XpPointSituationReportQuery query);
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpActicityService.java
@@ -2,6 +2,8 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.operation.XpActivity;
import com.xiaopeng.api.query.operation.XpActivityPageListQuery;
import com.xiaopeng.common.core.web.page.PageInfo;
import java.util.List;
@@ -15,6 +17,7 @@
 */
public interface IXpActicityService extends IService<XpActivity> {
    PageInfo<XpActivity> pageList(XpActivityPageListQuery query);
    List<String> findListToIds(String acticityName);
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpActicityStrategyService.java
New file
@@ -0,0 +1,16 @@
package com.xiaopeng.operation.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.operation.XpActicityStrategy;
/**
 * <p>
 * 活动策略配置 服务类
 * </p>
 *
 * @author mitao
 * @since 2026-04-20
 */
public interface IXpActicityStrategyService extends IService<XpActicityStrategy> {
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpActicityUserService.java
New file
@@ -0,0 +1,16 @@
package com.xiaopeng.operation.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.operation.XpActicityUser;
/**
 * <p>
 * 活动发放用户 服务类
 * </p>
 *
 * @author mitao
 * @since 2026-04-20
 */
public interface IXpActicityUserService extends IService<XpActicityUser> {
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpPointSituationReportService.java
@@ -2,6 +2,18 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.operation.XpPointSituationReport;
import com.xiaopeng.api.query.operation.XpPointSituationReportQuery;
import com.xiaopeng.api.vo.operation.XpPointSituationReportVo;
import com.xiaopeng.common.core.web.page.PageInfo;
import java.util.List;
public interface IXpPointSituationReportService extends IService<XpPointSituationReport> {
    PageInfo<XpPointSituationReportVo> pageList(XpPointSituationReportQuery query);
    XpPointSituationReportVo getdetail(Long id);
    List<XpPointSituationReportVo> exportList(XpPointSituationReportQuery query);
    void deleteById(Long id);
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/XpPasswordFreePolicyService.java
New file
@@ -0,0 +1,14 @@
package com.xiaopeng.operation.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.operation.XpPasswordFreePolicy;
import com.xiaopeng.api.query.operation.XpPasswordFreePolicyQuery;
import com.xiaopeng.common.core.web.page.PageInfo;
public interface XpPasswordFreePolicyService extends IService<XpPasswordFreePolicy> {
    PageInfo<XpPasswordFreePolicy> pageList(XpPasswordFreePolicyQuery query);
    void deleteById(Long id);
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpActicityServiceImpl.java
@@ -2,6 +2,8 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaopeng.api.model.operation.XpActivity;
import com.xiaopeng.api.query.operation.XpActivityPageListQuery;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.mapper.XpActicityMapper;
import com.xiaopeng.operation.service.IXpActicityService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -23,6 +25,13 @@
public class XpActicityServiceImpl extends ServiceImpl<XpActicityMapper, XpActivity> implements IXpActicityService {
    @Override
    public PageInfo<XpActivity> pageList(XpActivityPageListQuery query) {
        PageInfo<XpActivity> pageInfo = new PageInfo<>(query.getPageNum(),query.getPageSize());
        List<XpActivity> list = this.baseMapper.pageList(pageInfo,query);
        pageInfo.setRecords(list);
        return pageInfo;
    }
    @Override
    public List<String> findListToIds(String acticityName){
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpActicityStrategyServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.xiaopeng.operation.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.operation.XpActicityStrategy;
import com.xiaopeng.operation.mapper.XpActicityStrategyMapper;
import com.xiaopeng.operation.service.IXpActicityStrategyService;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 活动策略配置 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2026-04-20
 */
@Service
public class XpActicityStrategyServiceImpl extends ServiceImpl<XpActicityStrategyMapper, XpActicityStrategy> implements IXpActicityStrategyService {
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpActicityUserServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.xiaopeng.operation.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.operation.XpActicityUser;
import com.xiaopeng.operation.mapper.XpActicityUserMapper;
import com.xiaopeng.operation.service.IXpActicityUserService;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 活动发放用户 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2026-04-20
 */
@Service
public class XpActicityUserServiceImpl extends ServiceImpl<XpActicityUserMapper, XpActicityUser> implements IXpActicityUserService {
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPasswordFreePolicyServiceImpl.java
New file
@@ -0,0 +1,45 @@
package com.xiaopeng.operation.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.operation.XpPasswordFreePolicy;
import com.xiaopeng.api.query.operation.XpPasswordFreePolicyQuery;
import com.xiaopeng.common.core.exception.ServiceException;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.mapper.XpPasswordFreePolicyMapper;
import com.xiaopeng.operation.service.XpPasswordFreePolicyService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class XpPasswordFreePolicyServiceImpl extends ServiceImpl<XpPasswordFreePolicyMapper, XpPasswordFreePolicy> implements XpPasswordFreePolicyService {
    @Override
    public PageInfo<XpPasswordFreePolicy> pageList(XpPasswordFreePolicyQuery query) {
        // 创建分页对象
        PageInfo<XpPasswordFreePolicy> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        // 调用Mapper查询
        List<XpPasswordFreePolicy> list = this.baseMapper.pageList(pageInfo, query);
        // 设置结果
        pageInfo.setRecords(list);
        return pageInfo;
    }
    @Override
    public void deleteById(Long id) {
        // 1. 检查记录是否存在
        XpPasswordFreePolicy bean = this.getById(id);
        if (bean == null) {
            throw new ServiceException("密支付策略配置不存在");
        }
        // 2. 逻辑删除(MyBatis-Plus自动处理)
        this.removeById(id);
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPointSituationReportServiceImpl.java
@@ -1,12 +1,138 @@
package com.xiaopeng.operation.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetOperationsClient;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.operation.XpPointSituationReport;
import com.xiaopeng.api.model.vehicleConvoy.XpFleet;
import com.xiaopeng.api.query.operation.XpPointSituationReportQuery;
import com.xiaopeng.api.vo.operation.XpPointSituationReportVo;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.mapper.XpPointSituationReportMapper;
import com.xiaopeng.operation.service.IXpPointSituationReportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class XpPointSituationReportServiceImpl extends ServiceImpl<XpPointSituationReportMapper, XpPointSituationReport> implements IXpPointSituationReportService {
    @Autowired
    private XpOperationUserClient xpOperationUserClient;
    @Resource
    private XpFleetOperationsClient xpFleetOperationsClient;
    @Override
    public PageInfo<XpPointSituationReportVo> pageList(XpPointSituationReportQuery query) {
        // 创建分页对象
        PageInfo<XpPointSituationReportVo> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        // 调用Mapper查询
        List<XpPointSituationReportVo> list = this.baseMapper.pageList(pageInfo, query);
        extracted(list);
        // 设置结果
        pageInfo.setRecords(list);
        return pageInfo;
    }
    private void extracted(List<XpPointSituationReportVo> list) {
        if(!list.isEmpty()){
            // 收集所有运维人员ID
            Set<Long> operationsUserIds = list.stream()
                    .map(XpPointSituationReportVo::getOperationsUserId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            // 批量查询操作人信息
            Map<Long, String> userNameMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(operationsUserIds)) {
                R<List<XpOperationsUser>> userResult = xpOperationUserClient.listByIds(operationsUserIds);
                List<XpOperationsUser> users = userResult.getData();
                if (!CollectionUtils.isEmpty(users)) {
                    userNameMap = users.stream()
                            .collect(Collectors.toMap(XpOperationsUser::getId, XpOperationsUser::getNickName));
                }
            }
            for (XpPointSituationReportVo bean : list) {
                if (userNameMap.containsKey(bean.getOperationsUserId())){
                    bean.setOperationsUserName(userNameMap.get(bean.getOperationsUserId()));
                }
                if(bean.getOperationStatus() != null){//运营状态 1=待启用 2=启用中 3=已停用 4=已失效
                    if(bean.getOperationStatus() == 1){
                        bean.setPointStatusName("待启用");
                    }else if(bean.getOperationStatus() == 2){
                        bean.setPointStatusName("启用中");
                    }else if(bean.getOperationStatus() == 3){
                        bean.setPointStatusName("已停用");
                    }else if(bean.getOperationStatus() == 4){
                        bean.setPointStatusName("已失效");
                    }
                }
            }
        }
    }
    @Override
    public XpPointSituationReportVo getdetail(Long id) {
        XpPointSituationReportQuery query = new XpPointSituationReportQuery();
        query.setId(id);
        List<XpPointSituationReportVo> list = this.baseMapper.pageList(query);
        if(list.isEmpty()){
            throw new ServiceException("未查询该数据");
        }
        XpPointSituationReportVo bean = list.get(0);
        // 批量查询操作人信息
        R<List<XpOperationsUser>> userResult = xpOperationUserClient.listByIds(new ArrayList<Long>(){{
            add(bean.getOperationsUserId());
        }} );
        List<XpOperationsUser> users = userResult.getData();
        if (CollectionUtils.isEmpty(users)) {
            throw new ServiceException("未查询该运维人员");
        }
        Map<Long, String> userNameMap = users.stream()
                .collect(Collectors.toMap(XpOperationsUser::getId, XpOperationsUser::getNickName));
        bean.setOperationsUserName(userNameMap.get(bean.getOperationsUserId()));
        R<List<XpFleet>> fleetByUserId = xpFleetOperationsClient.getFleetByUserId(bean.getOperationsUserId());
        if(fleetByUserId.getCode() != R.SUCCESS || fleetByUserId.getData().isEmpty()){
            throw new ServiceException("未查询该车队");
        }
        bean.setOperationsUserFleetName(fleetByUserId.getData().get(0).getFleetName());
        return bean;
    }
    @Override
    public List<XpPointSituationReportVo> exportList(XpPointSituationReportQuery query) {
        List<XpPointSituationReportVo> list = this.baseMapper.pageList(query);
        extracted(list);
        return list;
    }
    @Override
    public void deleteById(Long id) {
        // 1. 检查记录是否存在
        XpPointSituationReport bean = this.getById(id);
        if (bean == null) {
            throw new ServiceException("密支付策略配置不存在");
        }
        // 2. 逻辑删除(MyBatis-Plus自动处理)
        this.removeById(id);
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java
@@ -14,9 +14,10 @@
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.feignClient.account.XpAppUserClient;
import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient;
import com.xiaopeng.api.feignClient.maintenance.XpVehicleModelClient;
import com.xiaopeng.api.feignClient.map.XpMapClient;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.model.account.XpAppUser;
import com.xiaopeng.api.model.maintenance.XpVehicleModel;
import com.xiaopeng.api.model.operation.*;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.vo.account.UserCouponVo;
@@ -34,14 +35,14 @@
import com.xiaopeng.common.redis.service.RedisService;
import com.xiaopeng.operation.constant.I18nKeyConstant;
import com.xiaopeng.operation.dto.*;
import com.xiaopeng.operation.job.base.QuartzManager;
import com.xiaopeng.operation.job.base.TimeJobType;
import com.xiaopeng.operation.job.jobs.DynamicPricingCheckJob;
import com.xiaopeng.operation.mapper.*;
import com.xiaopeng.operation.query.PricingPageListQuery;
import com.xiaopeng.operation.service.IXpGeoQueryEntityService;
import com.xiaopeng.operation.service.XpPointService;
import com.xiaopeng.operation.service.XpPricingService;
import com.xiaopeng.operation.job.base.QuartzManager;
import com.xiaopeng.operation.job.base.TimeJobType;
import com.xiaopeng.operation.job.jobs.DynamicPricingCheckJob;
import com.xiaopeng.operation.utils.XpPricingUtil;
import com.xiaopeng.operation.utils.holiday.HolidayUtil;
import com.xiaopeng.operation.utils.map.FastDistanceCalculator;
@@ -104,6 +105,8 @@
    private XpElectronicFenceAreaMapper xpElectronicFenceAreaMapper;
    @Resource
    private XpVehicleModelClient xpVehicleModelClient;
    @Resource
    private XpWhitelistMapper xpWhitelistMapper;
@@ -685,6 +688,23 @@
        Page<PricingPageListVO> page = this.baseMapper.pageList(pageInfo, query);
        pageInfo.setRecords(page.getRecords());
        pageInfo.setTotal(page.getTotal());
        if(page.getRecords() != null){
            Set<String> vehicleModelIds = page.getRecords().stream().map(PricingPageListVO::getVehicleModel).collect(Collectors.toSet());
            R<List<XpVehicleModel>> listR = xpVehicleModelClient.listByIds(vehicleModelIds);
            if(listR != null && listR.getData() != null){
                List<XpVehicleModel> vehicleModels = listR.getData();
                Map<String, XpVehicleModel> vehicleModelMap = new HashMap<>();
                for (XpVehicleModel vehicleModel : vehicleModels) {
                    vehicleModelMap.put(vehicleModel.getId().toString(), vehicleModel);
                }
                for (PricingPageListVO record : page.getRecords()) {
                    XpVehicleModel xpVehicleModel = vehicleModelMap.get(record.getVehicleModel());
                    if(xpVehicleModel != null){
                        record.setVehicleModelName(xpVehicleModel.getName());
                    }
                }
            }
        }
        return pageInfo;
    }
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/vo/PricingPageListVO.java
@@ -24,6 +24,9 @@
    @ApiModelProperty(value = "车型")
    private String vehicleModel;
    @ApiModelProperty(value = "车型名称")
    private String vehicleModelName;
    @ApiModelProperty(value = "使用城市")
    private String useCity;
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpActicityMapper.xml
@@ -3,4 +3,20 @@
<mapper namespace="com.xiaopeng.operation.mapper.XpActicityMapper">
    <select id="pageList" resultType="com.xiaopeng.api.model.operation.XpActivity">
            select a.*
            from xp_acticity as a
            where a.is_deleted = 0
            <if test="query.acticity_name != null ">
                a.acticity_name >= #{acticityName}
            </if>
            <if test="query.status != null">
                and a.status = #{query.status}
            </if>
            <if test="query.activity_type != null">
                and a.activity_type = #{query.activityType}
            </if>
            order by a.update_time desc
    </select>
</mapper>
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpActicityStrategyMapper.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiaopeng.operation.mapper.XpActicityStrategyMapper">
</mapper>
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpActicityUserMapper.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiaopeng.operation.mapper.XpActicityUserMapper">
</mapper>
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpPasswordFreePolicyMapper.xml
New file
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiaopeng.operation.mapper.XpPasswordFreePolicyMapper">
    <!-- 分页查询路线规划配置列表 -->
    <select id="pageList" resultType="com.xiaopeng.api.model.operation.XpPasswordFreePolicy">
        SELECT a.*
        FROM xp_password_free_policy as a
        WHERE a.is_deleted = 0
        <if test="query.cityName != null and query.cityName != ''">
            AND a.city_name LIKE CONCAT('%', #{query.cityName}, '%')
        </if>
        <if test="query.createTimeStart != null">
            AND a.create_time &gt;= #{query.createTimeStart}
        </if>
        <if test="query.createTimeEnd != null">
            AND a.create_time &lt;= #{query.createTimeEnd}
        </if>
        ORDER BY a.create_time DESC
    </select>
</mapper>
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpPointSituationReportMapper.xml
@@ -2,4 +2,49 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiaopeng.operation.mapper.XpPointSituationReportMapper">
    <!-- 分页查询路线规划配置列表 -->
    <select id="pageList" resultType="com.xiaopeng.api.vo.operation.XpPointSituationReportVo">
        SELECT a.*,b.point_name,b.point_number,b.point_type,b.operation_status,b.verification_status
        FROM xp_point_situation_report as a
        inner join xp_point as b on a.point_id = b.id
        WHERE a.is_deleted = 0
        <if test="query.id != null and query.id != ''">
            AND b.point_name  = #{query.id}
        </if>
        <if test="query.ids != null and query.ids.size() > 0">
            AND a.id IN
            <foreach collection="query.ids" item="id" open="(" separator="," close=")">
                #{id}
            </foreach>
        </if>
        <if test="query.pointName != null and query.pointName != ''">
            AND b.point_name LIKE CONCAT('%', #{query.pointName}, '%')
        </if>
        <if test="query.pointNumber != null and query.pointNumber != ''">
            AND b.point_number LIKE CONCAT('%', #{query.pointNumber}, '%')
        </if>
        <if test="query.fieldSituation != null and query.fieldSituation != ''">
            AND a.field_situation = #{query.fieldSituation}
        </if>
        <if test="query.operationsUserId != null and query.operationsUserId != ''">
            AND a.operations_user_id = #{query.operationsUserId}
        </if>
        <if test="query.reportingTimeStart != null">
            AND a.reporting_time &gt;= #{query.reportingTimeStart}
        </if>
        <if test="query.reportingTimeEnd != null">
            AND a.reporting_time &lt;= #{query.reportingTimeEnd}
        </if>
        ORDER BY a.create_time DESC
    </select>
</mapper>
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetOperationsController.java
@@ -56,6 +56,25 @@
    }
    /**
     * 根据人员id 获取所属车队
     *
     * @param id 运维人员id
     * @return 车辆isd
     */
    @GetMapping("/logan/inner/fleet-operations/getFleetByUserId/{id}")
    public R<List<XpFleet>> getFleetByUserId(@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)){
            return R.ok(new ArrayList<>());
        }
        List<XpFleet> xpFleets = xpFleetService.listByIds(fleetIds);
        return R.ok(xpFleets);
    }
    /**
     * 根据运维人员ID查询关联的车队ID列表(内部接口)
     *
     * @param userId 运维人员ID