liujie
2026-02-25 13978ae9ed56ec816823c74589e4c6745f184dff
Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi
8个文件已添加
35个文件已修改
847 ■■■■■ 已修改文件
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsUserMapper.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/dto/EnableDisableDTO.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/dto/RePasswordDTO.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/dto/XpOperationsUserAddDTO.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpOperationsUserQuery.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpOperationsUserService.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpClockIn.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpVehicleDescription.java 2 ●●●●● 补丁 | 查看 | 原始文档 | 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/model/operation/XpSystemSetting.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/XpOperationsUserVO.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpShiftController.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleDescriptionController.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleDetectionController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/dto/ClockDTO.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/mapper/XpClockInMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/mapper/XpShiftMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpShiftQuery.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpShiftService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpClockInServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpShiftServiceImpl.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/resources/mapper/maintenance/XpClockInMapper.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/resources/mapper/maintenance/XpShiftMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpAgreementController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpFrequentlyAskedQuestionsController.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpSystemSettingController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/PricingSetPriceDTO.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/XpAgreementDTO.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/XpFrequentlyAskedQuestionsDTO.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpFrequentlyAskedQuestionsService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/XpAgreementService.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/XpOpenCityService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpAgreementServiceImpl.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpFrequentlyAskedQuestionsServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpOpenCityServiceImpl.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/vo/PricingPageListVO.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpPricingMapper.xml 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/resources/mapper/vehicleConvoy/XpVehicleMapper.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java
@@ -2,12 +2,17 @@
import com.xiaopeng.account.mapper.XpOperationsRoleMapper;
import com.xiaopeng.account.model.dto.EnableDisableDTO;
import com.xiaopeng.account.model.dto.RePasswordDTO;
import com.xiaopeng.account.model.dto.XpOperationsUserAddDTO;
import com.xiaopeng.account.model.dto.XpOperationsUserDTO;
import com.xiaopeng.account.model.query.XpOperationsUserPageQuery;
import com.xiaopeng.account.model.query.XpOperationsUserQuery;
import com.xiaopeng.account.service.IXpOperationsUserService;
import com.xiaopeng.api.dto.account.XpOperationsUserQueryDTO;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.vo.account.XpOperationsUserProfileVO;
import com.xiaopeng.api.vo.account.XpOperationsUserVO;
import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
@@ -144,4 +149,48 @@
        xpOperationsUserService.saveCertificate(dto);
        return R.ok();
    }
    @ApiOperation(value = "运维人员管理分页列表", tags = {"管理后台-运维执行"})
    @PostMapping("/api/v1/operationsUser/pageList")
    public R<PageInfo<XpOperationsUserVO>> pageList(@RequestBody XpOperationsUserQuery query){
        PageInfo<XpOperationsUserVO> pageList = xpOperationsUserService.pageList(query);
        return R.ok(pageList);
    }
    @ApiOperation(value = "运维人员管理新增", tags = {"管理后台-运维执行"})
    @PostMapping("/api/v1/operationsUser/add")
    public R<String> add(@RequestBody XpOperationsUserAddDTO dto){
        return xpOperationsUserService.addOperationsUser(dto);
    }
    @ApiOperation(value = "运维人员管理编辑", tags = {"管理后台-运维执行"})
    @PostMapping("/api/v1/operationsUser/edit")
    public R<String> edit(@RequestBody XpOperationsUserAddDTO dto){
        return xpOperationsUserService.editOperationsUser(dto);
    }
    @ApiOperation(value = "运维人员管理启用禁用", tags = {"管理后台-运维执行"})
    @PostMapping("/api/v1/operationsUser/enableDisableById")
    public R<String> enableDisableById(@RequestBody EnableDisableDTO dto){
        xpOperationsUserService.enableDisableById(dto);
        return R.ok();
    }
    @ApiOperation(value = "运维人员管理删除", tags = {"管理后台-运维执行"})
    @DeleteMapping("/api/v1/operationsUser/deleteById")
    public R<String> deleteById(@RequestParam Long id){
        xpOperationsUserService.removeById(id);
        return R.ok();
    }
    @ApiOperation(value = "运维人员管理重置密码", tags = {"管理后台-运维执行"})
    @DeleteMapping("/api/v1/operationsUser/rePassword")
    public R<String> rePassword(@RequestBody RePasswordDTO dto){
        xpOperationsUserService.rePassword(dto);
        return R.ok();
    }
    @ApiOperation(value = "运维人员管理详情", tags = {"管理后台-运维执行"})
    @GetMapping("/api/v1/operationsUser/detailById")
    public R<XpOperationsUserVO> detailById(@RequestParam Long id){
        XpOperationsUserVO xpOperationsUserVO = xpOperationsUserService.detailById(id);
        return R.ok(xpOperationsUserVO);
    }
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsUserMapper.java
@@ -3,9 +3,14 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaopeng.account.model.query.XpOperationsUserPageQuery;
import com.xiaopeng.account.model.query.XpOperationsUserQuery;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.vo.account.XpOperationsUserVO;
import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO;
import com.xiaopeng.common.core.web.page.PageInfo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
@@ -23,4 +28,13 @@
     * @return
     */
    Page<XpOperationsUserWithRoleVO> selectUserPageByConditions(Page<XpOperationsUserWithRoleVO> xpOperationsUserWithRoleVOPage, @Param("query") XpOperationsUserPageQuery query);
    /**
     * 分页查询
     * @param pageInfo
     * @param query
     * @return
     */
    List<XpOperationsUserVO> pageList(@Param("pageInfo") PageInfo<XpOperationsUserVO> pageInfo, @Param("query")XpOperationsUserQuery query);
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/dto/EnableDisableDTO.java
New file
@@ -0,0 +1,19 @@
package com.xiaopeng.account.model.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "启用禁用参数EnableDisableDTO")
public class EnableDisableDTO implements Serializable {
    @ApiModelProperty(value = "用户ID")
    private Long id;
    @ApiModelProperty(value = "启用禁用状态 1=启用 0=禁用")
    private Boolean status;
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/dto/RePasswordDTO.java
New file
@@ -0,0 +1,19 @@
package com.xiaopeng.account.model.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "重置密码参数RePasswordDTO")
public class RePasswordDTO implements Serializable {
    @ApiModelProperty(value = "用户ID")
    private Long id;
    @ApiModelProperty(value = "密码")
    private String newPassword;
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/dto/XpOperationsUserAddDTO.java
New file
@@ -0,0 +1,17 @@
package com.xiaopeng.account.model.dto;
import com.xiaopeng.api.model.account.XpOperationsUser;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel(value = "新增运维人员数据传输对象XpOperationsUserAddDTO")
public class XpOperationsUserAddDTO extends XpOperationsUser {
    @ApiModelProperty(value = "角色id集合")
    private List<Long> roleIds;
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpOperationsUserQuery.java
New file
@@ -0,0 +1,24 @@
package com.xiaopeng.account.model.query;
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "运维人员查询参数XpOperationsUserQuery")
public class XpOperationsUserQuery extends BasePage {
    @ApiModelProperty(value = "员工姓名")
    private String nickName;
    @ApiModelProperty(value = "联系电话")
    private String phoneNumber;
    @ApiModelProperty(value = "角色id")
    private Long roleId;
    @ApiModelProperty(value = "状态 1=启用 0=禁用")
    private Boolean status;
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpOperationsUserService.java
@@ -1,11 +1,17 @@
package com.xiaopeng.account.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.account.model.dto.EnableDisableDTO;
import com.xiaopeng.account.model.dto.RePasswordDTO;
import com.xiaopeng.account.model.dto.XpOperationsUserAddDTO;
import com.xiaopeng.account.model.dto.XpOperationsUserDTO;
import com.xiaopeng.account.model.query.XpOperationsUserPageQuery;
import com.xiaopeng.account.model.query.XpOperationsUserQuery;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.vo.account.XpOperationsUserProfileVO;
import com.xiaopeng.api.vo.account.XpOperationsUserVO;
import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import javax.validation.Valid;
@@ -47,4 +53,42 @@
     * @param dto
     */
    void saveCertificate(@Valid XpOperationsUserDTO dto);
    /**
     * 运维人员管理分页列表
     * @param query
     * @return
     */
    PageInfo<XpOperationsUserVO> pageList(XpOperationsUserQuery query);
    /**
     * 新增运维人员
     * @param dto
     */
    R<String> addOperationsUser(XpOperationsUserAddDTO dto);
    /**
     * 修改运维人员
     * @param dto
     */
    R<String> editOperationsUser(XpOperationsUserAddDTO dto);
    /**
     * 启用禁用
     * @param dto
     */
    void enableDisableById(EnableDisableDTO dto);
    /**
     * 重置密码
     * @param dto
     */
    void rePassword(RePasswordDTO dto);
    /**
     * 详情
     * @param id
     * @return
     */
    XpOperationsUserVO detailById(Long id);
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java
@@ -1,26 +1,33 @@
package com.xiaopeng.account.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaopeng.account.constant.I18nKeyConstant;
import com.xiaopeng.account.mapper.SysRoleMapper;
import com.xiaopeng.account.mapper.XpOperationsRoleMapper;
import com.xiaopeng.account.mapper.XpOperationsUserMapper;
import com.xiaopeng.account.model.dto.EnableDisableDTO;
import com.xiaopeng.account.model.dto.RePasswordDTO;
import com.xiaopeng.account.model.dto.XpOperationsUserAddDTO;
import com.xiaopeng.account.model.dto.XpOperationsUserDTO;
import com.xiaopeng.account.model.query.XpOperationsUserPageQuery;
import com.xiaopeng.account.model.query.XpOperationsUserQuery;
import com.xiaopeng.account.service.IXpOperationsRoleService;
import com.xiaopeng.account.service.IXpOperationsUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.account.service.IXpQualificationAuditService;
import com.xiaopeng.api.feignClient.maintenance.XpClockInClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetOperationsClient;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.account.XpQualificationAudit;
import com.xiaopeng.api.model.account.*;
import com.xiaopeng.api.model.vehicleConvoy.XpFleet;
import com.xiaopeng.api.vo.account.FleetInfoVO;
import com.xiaopeng.api.vo.account.XpOperationsUserProfileVO;
import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO;
import com.xiaopeng.api.vo.account.*;
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.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
@@ -52,12 +59,16 @@
    @Autowired
    private XpOperationsRoleMapper xpOperationsRoleMapper;
    @Autowired
    private IXpOperationsRoleService xpOperationsRoleService;
    @Autowired
    private XpClockInClient xpClockInClient;
    @Autowired
    private IXpQualificationAuditService xpQualificationAuditService;
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Override
    public List<XpOperationsUser> listByName(String nickName) {
@@ -168,4 +179,137 @@
        xpQualificationAudit.setAuditStatus(1);
        xpQualificationAuditService.save(xpQualificationAudit);
    }
    @Override
    public PageInfo<XpOperationsUserVO> pageList(XpOperationsUserQuery query) {
        PageInfo<XpOperationsUserVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        List<XpOperationsUserVO> list = this.baseMapper.pageList(pageInfo, query);
        if(CollectionUtils.isEmpty(list)){
            return pageInfo;
        }
        // 查询角色名称
        List<Long> operationsUserIds = list.stream().map(XpOperationsUserVO::getId).collect(Collectors.toList());
        // 查询用户信息
        List<XpOperationsRole> xpOperationsRoles = xpOperationsRoleMapper.selectList(Wrappers.lambdaQuery(XpOperationsRole.class)
                .in(XpOperationsRole::getOperationsUserId, operationsUserIds));
        if(!CollectionUtils.isEmpty(xpOperationsRoles)){
            List<Long> roleIds = xpOperationsRoles.stream().map(XpOperationsRole::getRoleId).collect(Collectors.toList());
            // 查询列表关联的所有角色
            List<SysRole> sysRoles = sysRoleMapper.selectList(Wrappers.lambdaQuery(SysRole.class)
                    .in(SysRole::getId, roleIds));
            if(!CollectionUtils.isEmpty(sysRoles)){
                // 角色匹配账号id
                Map<Long, List<SysRole>> map = new HashMap<>();
                for (XpOperationsRole xpOperationsRole : xpOperationsRoles) {
                    List<SysRole> sysRoleList = sysRoles.stream().filter(sysRole -> sysRole.getId().equals(xpOperationsRole.getRoleId())).collect(Collectors.toList());
                    map.put(xpOperationsRole.getOperationsUserId(), sysRoleList);
                }
                // 角色名称匹配
                for (XpOperationsUserVO xpOperationsUserVO : list) {
                    xpOperationsUserVO.setSysRoles(map.get(xpOperationsUserVO.getId()));
                }
            }
        }
        pageInfo.setRecords(list);
        return pageInfo;
    }
    @Override
    public R<String> addOperationsUser(XpOperationsUserAddDTO dto) {
        long userCount = this.count(Wrappers.lambdaQuery(XpOperationsUser.class)
                .eq(XpOperationsUser::getPhoneNumber, dto.getPhoneNumber()));
        if (StringUtils.isNotBlank(dto.getPhoneNumber()) && userCount>0) {
            throw new ServiceException("登录账号重复", I18nKeyConstant.ACCOUNT_DUPLICATE);
        }
        //校验编号是否唯一
        long numberCount = this.count(Wrappers.lambdaQuery(XpOperationsUser.class)
                .eq(XpOperationsUser::getUniqueNumber, dto.getUniqueNumber()));
        if (numberCount > 0) {
            throw new ServiceException("用户编号已存在", I18nKeyConstant.ACCOUNT_UNIQUE_NUMBER_DUPLICATE);
        }
        // 密码加密
        dto.setPassword(SecurityUtils.encryptPassword(dto.getPassword()));
        // 保存
        this.save(dto);
        // 存储角色
        List<Long> roleIds = dto.getRoleIds();
        if(!CollectionUtils.isEmpty(roleIds)){
            List<XpOperationsRole> xpOperationsRoles = roleIds.stream().map(roleId -> {
                XpOperationsRole xpOperationsRole = new XpOperationsRole();
                xpOperationsRole.setOperationsUserId(dto.getId());
                xpOperationsRole.setRoleId(roleId);
                return xpOperationsRole;
            }).collect(Collectors.toList());
            xpOperationsRoleService.saveBatch(xpOperationsRoles);
        }
        return R.ok();
    }
    @Override
    public R<String> editOperationsUser(XpOperationsUserAddDTO dto) {
        XpOperationsUser operationsUser = this.getOne(Wrappers.lambdaQuery(XpOperationsUser.class)
                .eq(XpOperationsUser::getPhoneNumber, dto.getPhoneNumber())
                .last("LIMIT 1"));
        if (StringUtils.isNotBlank(dto.getPhoneNumber()) && (Objects.nonNull(operationsUser) && !dto.getId().equals(operationsUser.getId()) )) {
            throw new ServiceException("手机号已开通账号", I18nKeyConstant.ACCOUNT_PHONE_DUPLICATE);
        }
        if (dto.getPassword() != null && !dto.getPassword().isEmpty()) {
            dto.setPassword(null);
        }
        this.updateById(dto);
        //删除旧的角色数据,添加新的角色
        xpOperationsRoleService.remove(new LambdaQueryWrapper<XpOperationsRole>().eq(XpOperationsRole::getOperationsUserId, dto.getId()));
        // 存储角色
        List<Long> roleIds = dto.getRoleIds();
        if(!CollectionUtils.isEmpty(roleIds)){
            List<XpOperationsRole> xpOperationsRoles = roleIds.stream().map(roleId -> {
                XpOperationsRole xpOperationsRole = new XpOperationsRole();
                xpOperationsRole.setOperationsUserId(dto.getId());
                xpOperationsRole.setRoleId(roleId);
                return xpOperationsRole;
            }).collect(Collectors.toList());
            xpOperationsRoleService.saveBatch(xpOperationsRoles);
        }
        return R.ok();
    }
    @Override
    public void enableDisableById(EnableDisableDTO dto) {
        XpOperationsUser operationsUser = this.getById(dto.getId());
        operationsUser.setStatus(dto.getStatus());
        this.updateById(operationsUser);
    }
    @Override
    public void rePassword(RePasswordDTO dto) {
        XpOperationsUser operationsUser = this.getById(dto.getId());
        // 密码加密
        operationsUser.setPassword(SecurityUtils.encryptPassword(dto.getNewPassword()));
        this.updateById(operationsUser);
    }
    @Override
    public XpOperationsUserVO detailById(Long id) {
        // 查询用户信息
        XpOperationsUser xpOperationsUser = this.getById(id);
        XpOperationsUserVO xpOperationsUserVO = new XpOperationsUserVO();
        BeanUtils.copyProperties(xpOperationsUser, xpOperationsUserVO);
        // 查询角色
        List<XpOperationsRole> xpOperationsRoles = xpOperationsRoleMapper.selectList(Wrappers.lambdaQuery(XpOperationsRole.class)
                .eq(XpOperationsRole::getOperationsUserId, id));
        if(!CollectionUtils.isEmpty(xpOperationsRoles)){
            List<Long> roleIds = xpOperationsRoles.stream().map(XpOperationsRole::getRoleId).collect(Collectors.toList());
            List<SysRole> sysRoles = sysRoleMapper.selectList(Wrappers.lambdaQuery(SysRole.class)
                    .in(SysRole::getId, roleIds));
            xpOperationsUserVO.setSysRoles(sysRoles);
        }
        return xpOperationsUserVO;
    }
}
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml
@@ -27,5 +27,28 @@
        </if>
     </where>
    </select>
    <select id="pageList" resultType="com.xiaopeng.api.vo.account.XpOperationsUserVO">
        SELECT xou.id, xou.nick_name, xou.unique_number, xou.avatar, xou.password, xou.phone_number, xou.remarks, xou.status,
        xou.id_card_front, xou.id_card_back, xou.driver_license, xou.certificate_of_no_criminal_record,
        xou.training_graduation_certificate, xou.is_deleted, xou.create_time, xou.update_time, xou.create_by
            from xp_operations_user xou
        left join xp_operations_role xor on xou.id = xor.operations_user_id
        <where>
            <if test="query.nickName != null and query.nickName != ''">
                and xou.nick_name like concat('%',#{query.nickName},'%')
            </if>
            <if test="query.phoneNumber != null and query.phoneNumber != ''">
                and xou.phone_number like concat('%',#{query.phoneNumber},'%')
            </if>
            <if test="query.roleId != null">
                and xor.role_id = #{query.roleId}
            </if>
            <if test="query.status != null">
                and xou.status = #{query.status}
            </if>
            AND xou.is_deleted = 0
        </where>
        order by xou.create_time desc
    </select>
</mapper>
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpClockIn.java
@@ -68,4 +68,10 @@
    @ApiModelProperty(value = "下班打卡纬度")
    private Double clockOutLat;
    @ApiModelProperty(value = "上班打卡地址")
    private String clockInAddress;
    @ApiModelProperty(value = "下班打卡地址")
    private String clockOutAddress;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpVehicleDescription.java
@@ -34,7 +34,7 @@
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "车辆说明1胎压说明 2灯光说明 3车身标识及清洁说明 4舱内清洁及消毒 5遗失物品上报 6车辆充电说明 7车辆检测说明 8=车辆运维规则")
    @ApiModelProperty(value = "车辆说明1胎压说明 2灯光说明 3车身标识及清洁说明 4舱内清洁及消毒 5遗失物品上报 6车辆充电说明 7车辆检测说明 8=车辆保险标准说明 9=车辆年检标准说明 10=车辆保养标准说明 11=车辆运营资质标准说明")
    private Integer descriptionType;
    @ApiModelProperty(value = "富文本内容")
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPricing.java
@@ -43,6 +43,10 @@
    @TableField("city_id")
    private Integer cityId;
    @ApiModelProperty(value = "城市名称")
    @TableField(exist = false)
    private String cityName;
    @ApiModelProperty(value = "备注说明")
    @TableField("remark")
    private String remark;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpSystemSetting.java
@@ -4,11 +4,14 @@
import com.baomidou.mybatisplus.annotation.TableField;
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 java.time.LocalDateTime;
/**
 * <p>
@@ -21,7 +24,7 @@
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("xp_system_setting")
@ApiModel(value="XpSystemSetting对象", description="系统设置表")
@ApiModel(value = "XpSystemSetting对象", description = "系统设置表")
public class XpSystemSetting extends BaseModel {
    private static final long serialVersionUID = 1L;
@@ -46,21 +49,30 @@
    @TableField("arrive_time")
    private Integer arriveTime;
    @ApiModelProperty(value = "常见问题首页展示数")
    @TableField("head_show_count")
    private Integer headShowCount;
    @ApiModelProperty(value = "附近站点距离")
    @TableField("near_point_distance")
    private Integer nearPointDistance;
    @ApiModelProperty(value = "吸附距离")
    @TableField("adsorption_distance")
    private Integer adsorptionDistance;
    @ApiModelProperty(value = "热修复状态 0-关闭 1-开始")
    @TableField("hotfix_status")
    private Integer hotfixStatus;
    @ApiModelProperty(value = "热修复开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @TableField("hotfix_start_time")
    private LocalDateTime hotfixStartTime;
    @ApiModelProperty(value = "热修复结束时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @TableField("hotfix_end_time")
    private LocalDateTime hotfixEndTime;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/XpOperationsUserVO.java
New file
@@ -0,0 +1,18 @@
package com.xiaopeng.api.vo.account;
import com.xiaopeng.api.model.account.SysRole;
import com.xiaopeng.api.model.account.XpOperationsUser;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel(value = "运维人员列表XpOperationsUserVO")
public class XpOperationsUserVO extends XpOperationsUser {
    @ApiModelProperty(value = "角色集合")
    private List<SysRole> sysRoles;
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpShiftController.java
@@ -1,8 +1,18 @@
package com.xiaopeng.maintenance.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.xiaopeng.api.model.maintenance.XpShift;
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.VerifyRangeDTO;
import com.xiaopeng.maintenance.model.query.XpShiftQuery;
import com.xiaopeng.maintenance.service.IXpClockInService;
import com.xiaopeng.maintenance.service.IXpShiftService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
 * <p>
@@ -12,9 +22,42 @@
 * @author xiaochen
 * @since 2026-02-06
 */
@Api(tags = "班次管理")
@RestController
@RequestMapping("/xp-shift")
public class XpShiftController {
    @Autowired
    private IXpShiftService xpShiftService;
    @Autowired
    private TokenService tokenService;
    @ApiOperation(value = "班次管理分页列表", tags = "管理后台-运维执行")
    @PostMapping("/api/v1/shift/pageList")
    public R<PageInfo<XpShift>> pageList(@RequestBody XpShiftQuery query) {
        PageInfo<XpShift> pageInfo = xpShiftService.pageList(query);
        return R.ok(pageInfo);
    }
    @ApiOperation(value = "班次管理新增", tags = "管理后台-运维执行")
    @PostMapping("/api/v1/shift/add")
    public R<String> add(@RequestBody XpShift dto) {
        xpShiftService.save(dto);
        return R.ok();
    }
    @ApiOperation(value = "班次管理编辑", tags = "管理后台-运维执行")
    @PostMapping("/api/v1/shift/edit")
    public R<String> edit(@RequestBody XpShift dto) {
        xpShiftService.updateById(dto);
        return R.ok();
    }
    @ApiOperation(value = "班次管理删除", tags = "管理后台-运维执行")
    @DeleteMapping("/api/v1/shift/deleteById")
    public R<String> deleteById(@RequestParam Long id) {
        xpShiftService.removeById(id);
        return R.ok();
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleDescriptionController.java
@@ -6,13 +6,11 @@
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.maintenance.service.IXpVehicleDescriptionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
/**
 * <p>
@@ -24,7 +22,6 @@
 */
@Api(tags = "车辆整备、充电、检测说明")
@RestController
@RequestMapping("/xp-vehicle-description")
public class XpVehicleDescriptionController {
    private final IXpVehicleDescriptionService xpVehicleDescriptionService;
@@ -34,7 +31,7 @@
        this.xpVehicleDescriptionService = xpVehicleDescriptionService;
    }
    @ApiOperation(value = "获取车辆整备、充电、检测说明",notes = "车辆说明1胎压说明 2灯光说明 3车身标识及清洁说明 4舱内清洁及消毒 5遗失物品上报 6车辆充电说明 7车辆检测说明 8=车辆运维规则",tags = {"运维APP-车辆管理"})
    @ApiOperation(value = "获取车辆整备、充电、检测、保险、年检、保养、运营资质说明",notes = "车辆说明1胎压说明 2灯光说明 3车身标识及清洁说明 4舱内清洁及消毒 5遗失物品上报 6车辆充电说明 7车辆检测说明 8=车辆保险标准说明 9=车辆年检标准说明 10=车辆保养标准说明 11=车辆运营资质标准说明",tags = {"运维APP-车辆管理"})
    @GetMapping("/api/v1/vehicle/vehicleDescription")
    public R<XpVehicleDescription> getVehicleDescription(@RequestParam Integer descriptionType) {
        XpVehicleDescription xpVehicleDescription = xpVehicleDescriptionService.getOne(Wrappers.lambdaQuery(XpVehicleDescription.class)
@@ -43,5 +40,35 @@
        return R.ok(xpVehicleDescription);
    }
    @ApiOperation(value = "获取车辆整备、充电、检测、保险、年检、保养、运营资质说明",notes = "车辆说明1胎压说明 2灯光说明 3车身标识及清洁说明 4舱内清洁及消毒 5遗失物品上报 6车辆充电说明 7车辆检测说明 8=车辆保险标准说明 9=车辆年检标准说明 10=车辆保养标准说明 11=车辆运营资质标准说明",tags = {"管理后台-内容中心"})
    @GetMapping("/api/v1/vehicle-description/vehicleDescription")
    @ApiImplicitParam(name = "descriptionType", value = "车辆说明1胎压说明 2灯光说明 3车身标识及清洁说明 4舱内清洁及消毒 5遗失物品上报 6车辆充电说明 7车辆检测说明 8=车辆保险标准说明 9=车辆年检标准说明 10=车辆保养标准说明 11=车辆运营资质标准说明", required = true, paramType = "query", dataTypeClass = Integer.class)
    public R<XpVehicleDescription> getVehicleDescriptionByType(@RequestParam Integer descriptionType) {
        XpVehicleDescription xpVehicleDescription = xpVehicleDescriptionService.getOne(Wrappers.lambdaQuery(XpVehicleDescription.class)
                .eq(XpVehicleDescription::getDescriptionType, descriptionType)
                .last("LIMIT 1"));
        return R.ok(xpVehicleDescription);
    }
    @ApiOperation(value = "保存车辆整备、充电、检测、保险、年检、保养、运营资质说明", tags = {"管理后台-内容中心"})
    @PostMapping("/api/v1/vehicle-description/save")
    public R<?> saveVehicleDescription(@RequestBody XpVehicleDescription xpVehicleDescription) {
        if (xpVehicleDescription.getDescriptionType() == null) {
            return R.fail("descriptionType不能为空");
        }
        // 先查询是否存在
        XpVehicleDescription existing = xpVehicleDescriptionService.getOne(Wrappers.lambdaQuery(XpVehicleDescription.class)
                .eq(XpVehicleDescription::getDescriptionType, xpVehicleDescription.getDescriptionType())
                .last("LIMIT 1"));
        if (existing != null) {
            // 存在则更新
            existing.setDescriptionContent(xpVehicleDescription.getDescriptionContent());
            xpVehicleDescriptionService.updateById(existing);
        } else {
            // 不存在则插入
            xpVehicleDescriptionService.save(xpVehicleDescription);
        }
        return R.ok();
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleDetectionController.java
@@ -21,6 +21,8 @@
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
@@ -52,11 +54,18 @@
     */
    @ApiOperation(value = "车辆运维-车辆运维-开始自检", tags = {"运维APP-车辆管理"})
    @GetMapping("/api/v1/vehicleDetection/startDetection")
    public R<String> startDetection(@RequestParam Long vehicleId) {
    public R<Map<String,Integer>> startDetection(@RequestParam Long vehicleId) {
        // TODO 开始自检
        return R.ok();
        Map<String,Integer> result = new HashMap<>(6);
        result.put("networkDetection", 1); // 网络检测
        result.put("remoteSelfCheck", 1); // 远程自检
        result.put("versionVerification", 1); // 版本验证
        result.put("collisionAvoidanceActivation", 1); // 碰撞回避激活
        result.put("communicationSelfCheck", 1); // 通信自检
        result.put("sensorSelfCheck", 1); // 传感器自检
        return R.ok(result);
    }
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/dto/ClockDTO.java
@@ -22,6 +22,12 @@
    @ApiModelProperty(value = "打卡地id")
    private Long locationId;
    @ApiModelProperty(value = "上班打卡地址")
    private String clockInAddress;
    @ApiModelProperty(value = "下班打卡地址")
    private String clockOutAddress;
    @ApiModelProperty(value = "运维用户id 前端忽略")
    private Long operationsUserId;
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/mapper/XpClockInMapper.java
@@ -19,14 +19,12 @@
    /**
     * 查询用户当天的打卡记录
     * @param tableSuffix 分表后缀 (0-9)
     * @param appUserId 用户ID
     * @param startTime 开始时间 (当天00:00:00)
     * @param endTime 结束时间 (当天23:59:59)
     * @return 打卡记录列表
     */
    List<XpClockIn> selectTodayClockInRecords(
        @Param("tableSuffix") Integer tableSuffix,
        @Param("appUserId") Long appUserId,
        @Param("startTime") LocalDateTime startTime,
        @Param("endTime") LocalDateTime endTime
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/mapper/XpShiftMapper.java
@@ -2,6 +2,11 @@
import com.xiaopeng.api.model.maintenance.XpShift;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.model.query.XpShiftQuery;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
@@ -13,4 +18,11 @@
 */
public interface XpShiftMapper extends BaseMapper<XpShift> {
    /**
     * 分页查询
     * @param query
     * @param pageInfo
     * @return
     */
    List<XpShift> pageList(@Param("query") XpShiftQuery query, @Param("pageInfo")PageInfo<XpShift> pageInfo);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/XpShiftQuery.java
New file
@@ -0,0 +1,10 @@
package com.xiaopeng.maintenance.model.query;
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@Data
@ApiModel(value = "班次查询参数XpShiftQuery")
public class XpShiftQuery extends BasePage {
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpShiftService.java
@@ -2,6 +2,8 @@
import com.xiaopeng.api.model.maintenance.XpShift;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.model.query.XpShiftQuery;
/**
 * <p>
@@ -13,4 +15,11 @@
 */
public interface IXpShiftService extends IService<XpShift> {
    /**
     * 获取班次分页列表
     *
     * @param query 查询参数
     * @return
     */
    PageInfo<XpShift> pageList(XpShiftQuery query);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpClockInServiceImpl.java
@@ -99,6 +99,7 @@
        xpClockIn.setClockInLon(dto.getUserLon());
        xpClockIn.setClockInLat(dto.getUserLat());
        xpClockIn.setShiftId(dto.getShiftId());
        xpClockIn.setClockInAddress(dto.getClockInAddress());
        if (xpClockIn.getClockInTime().isAfter(startLocalDateTime)) {
            xpClockIn.setClockInResult(2);
        }else {
@@ -143,7 +144,7 @@
        xpClockIn.setClockOutTime(LocalDateTime.now());
        xpClockIn.setClockOutLon(dto.getUserLon());
        xpClockIn.setClockOutLat(dto.getUserLat());
        xpClockIn.setClockOutAddress(dto.getClockOutAddress());
        if (xpClockIn.getClockOutTime().isBefore(endLocalDateTime)) {
            xpClockIn.setClockInResult(2);
        }else {
@@ -164,12 +165,9 @@
            LocalDateTime startTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN); // 00:00:00
            LocalDateTime endTime = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);   // 23:59:59
            // 2. 计算分表后缀 (userId % 10)
            Integer tableSuffix = (int) (appUserId % 10);
            // 3. 查询当天打卡记录
            List<XpClockIn> records = baseMapper.selectTodayClockInRecords(
                tableSuffix, appUserId, startTime, endTime
                 appUserId, startTime, endTime
            );
            // 4. 判断上班状态
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpShiftServiceImpl.java
@@ -1,10 +1,20 @@
package com.xiaopeng.maintenance.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.maintenance.XpShift;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.maintenance.mapper.XpShiftMapper;
import com.xiaopeng.maintenance.model.query.XpShiftQuery;
import com.xiaopeng.maintenance.model.vo.OperationRecordsVO;
import com.xiaopeng.maintenance.service.IXpShiftService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
@@ -17,4 +27,11 @@
@Service
public class XpShiftServiceImpl extends ServiceImpl<XpShiftMapper, XpShift> implements IXpShiftService {
    @Override
    public PageInfo<XpShift> pageList(XpShiftQuery query) {
        PageInfo<XpShift> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        List<XpShift> list = this.baseMapper.pageList(query,pageInfo);
        pageInfo.setRecords(list);
        return pageInfo;
    }
}
xp-robotaxi-maintenance-boot/src/main/resources/mapper/maintenance/XpClockInMapper.xml
@@ -5,11 +5,15 @@
    <resultMap id="BaseResultMap" type="com.xiaopeng.api.model.maintenance.XpClockIn">
        <id column="id" property="id" />
        <result column="app_user_id" property="appUserId" />
        <result column="clock_time" property="clockTime" />
        <result column="clock_in_time" property="clockInTime" />
        <result column="clock_out_time" property="clockOutTime" />
        <result column="shift_id" property="shiftId" />
        <result column="clock_result" property="clockResult" />
        <result column="clock_lon" property="clockLon" />
        <result column="clock_lat" property="clockLat" />
        <result column="clock_in_result" property="clockInResult" />
        <result column="clock_out_result" property="clockOutResult" />
        <result column="clock_in_lon" property="clockInLon" />
        <result column="clock_in_lat" property="clockInLat" />
        <result column="clock_out_lon" property="clockOutLon" />
        <result column="clock_out_lat" property="clockOutLat" />
        <result column="create_time" property="createTime" />
        <result column="update_time" property="updateTime" />
    </resultMap>
@@ -17,13 +21,13 @@
    <!-- 查询用户当天的打卡记录 -->
    <select id="selectTodayClockInRecords" resultMap="BaseResultMap">
        SELECT
            id, app_user_id, clock_time, shift_id, clock_result,
            clock_lon, clock_lat, create_time, update_time
        FROM xp_clock_in_${tableSuffix}
            id, app_user_id, clock_in_time,clock_out_time, shift_id, clock_in_result,clock_out_result,
            clock_in_lon, clock_in_lat,clock_out_lon, clock_out_lat, create_time, update_time
        FROM xp_clock_in
        WHERE app_user_id = #{appUserId}
          AND clock_time BETWEEN #{startTime} AND #{endTime}
          AND clock_result IN (1, 2)
        ORDER BY clock_time ASC
          AND clock_in_time BETWEEN #{startTime} AND #{endTime}
          AND clock_in_result IN (1, 2)
        ORDER BY clock_in_time ASC
    </select>
</mapper>
xp-robotaxi-maintenance-boot/src/main/resources/mapper/maintenance/XpShiftMapper.xml
@@ -2,4 +2,10 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiaopeng.maintenance.mapper.XpShiftMapper">
    <select id="pageList" resultType="com.xiaopeng.api.model.maintenance.XpShift">
        select id, shift_name, shift_color, start_time, end_time, is_rest,
       rest_start_time, rest_end_time, create_by, create_time, update_by, update_time, is_deleted
        from xp_shift
        order by create_time desc
    </select>
</mapper>
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpAgreementController.java
@@ -1,19 +1,23 @@
package com.xiaopeng.operation.controller;
import com.xiaopeng.api.model.operation.XpAgreement;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.controller.BaseController;
import com.xiaopeng.operation.dto.XpAgreementDTO;
import com.xiaopeng.operation.service.XpAgreementService;
import com.xiaopeng.operation.vo.XpAgreementVo;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.apiguardian.api.API;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@Slf4j
@Validated
@RestController
public class XpAgreementController extends BaseController {
@@ -43,4 +47,16 @@
    public R<XpAgreementVo> getAppContent(@ApiParam(name = "type", value = "类型 1=用户服务协议 2=平台隐私政策 ") @PathVariable Integer type) {
        return R.ok(xpAgreementService.getContentByType(type));
    }
    @ApiOperation(value = "获取协议",tags = {"管理后台-内容中心"})
    @GetMapping("/api/v1/agreement/content/{type}")
    public R<XpAgreement> getAgreementContent(@ApiParam(name = "type", value = "类型 1=用户服务协议 2=平台隐私政策 3=敏感个人信息处理情况说明 4=向第三方提供个人信息情况的说明 5=乘车须知 6=计费规则说明 ") @PathVariable Integer type) {
        return R.ok(xpAgreementService.getAgreementContent(type));
    }
    @ApiOperation(value = "保存协议",tags = {"管理后台-内容中心"})
    @PostMapping("/api/v1/agreement/save")
    public R<?> saveAgreement(@RequestBody @Valid XpAgreementDTO dto){
        xpAgreementService.saveAgreement(dto);
        return R.ok();
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpFrequentlyAskedQuestionsController.java
@@ -5,16 +5,15 @@
import com.xiaopeng.api.model.operation.XpFrequentlyAskedQuestions;
import com.xiaopeng.api.model.operation.XpSystemSetting;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.operation.dto.XpFrequentlyAskedQuestionsDTO;
import com.xiaopeng.operation.service.IXpFrequentlyAskedQuestionsService;
import com.xiaopeng.operation.service.XpSystemSettingService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@@ -29,8 +28,6 @@
@Slf4j
@RestController
@RequestMapping("/base/v1/mini-program")
@Api(tags = "常见问题")
public class XpFrequentlyAskedQuestionsController {
    private final IXpFrequentlyAskedQuestionsService xpFrequentlyAskedQuestionsService;
@@ -42,11 +39,32 @@
    }
    @GetMapping("/frequently-asked-questions/getList")
    @GetMapping("/base/v1/mini-program/frequently-asked-questions/getList")
    @ApiOperation(value = "获取常见问题列表",tags = {"常见问题列表"},response = XpFrequentlyAskedQuestions.class)
    public R<List<XpFrequentlyAskedQuestions>> getList() {
        XpSystemSetting systemSetting = xpSystemSettingService.getOne(null);
        List<XpFrequentlyAskedQuestions> list = xpFrequentlyAskedQuestionsService.list(new LambdaQueryWrapper<XpFrequentlyAskedQuestions>().last("limit "+systemSetting.getHeadShowCount()));
        return R.ok(list);
    }
    @GetMapping("/api/v1/frequently-asked-questions/getList")
    @ApiOperation(value = "获取常见问题列表",tags = {"管理后台-内容中心"},response = XpFrequentlyAskedQuestions.class)
    public R<List<XpFrequentlyAskedQuestions>> getQuestionList() {
        List<XpFrequentlyAskedQuestions> list = xpFrequentlyAskedQuestionsService.list();
        return R.ok(list);
    }
    @ApiOperation(value = "保存常见问题")
    @PostMapping("/api/v1/frequently-asked-questions/save")
    public R<?> saveQuestion(@RequestBody XpFrequentlyAskedQuestionsDTO dto) {
        xpFrequentlyAskedQuestionsService.saveQuestion(dto);
        return R.ok();
    }
    @ApiOperation(value = "删除常见问题")
    @DeleteMapping("/api/v1/frequently-asked-questions/delete/{id}")
    public R<?> deleteQuestion(@PathVariable Long id) {
        xpFrequentlyAskedQuestionsService.removeById(id);
        return R.ok();
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java
@@ -20,9 +20,7 @@
import com.xiaopeng.operation.dto.PricingSetRuleDTO;
import com.xiaopeng.operation.dto.XpOrderDto;
import com.xiaopeng.operation.query.PricingPageListQuery;
import com.xiaopeng.operation.service.IXpGeoQueryEntityService;
import com.xiaopeng.operation.service.IXpWhitelistService;
import com.xiaopeng.operation.service.XpPricingService;
import com.xiaopeng.operation.service.*;
import com.xiaopeng.operation.vo.PricingPageListVO;
import com.xiaopeng.operation.vo.SaveOrderVo;
import com.xiaopeng.unifiedverification.interceptor.XpClientCheck;
@@ -54,13 +52,14 @@
    private final IXpGeoQueryEntityService xpGeoQueryEntityService;
    private final UserResourcesClient userResourcesClient;
    private final IXpWhitelistService xpWhitelistService;
    private final XpOpenCityService xpOpenCityService;
    public XpPricingController(XpPricingService xpPricingService, IXpGeoQueryEntityService xpGeoQueryEntityService, UserResourcesClient userResourcesClient, IXpWhitelistService xpWhitelistService) {
    public XpPricingController(XpPricingService xpPricingService, IXpGeoQueryEntityService xpGeoQueryEntityService, UserResourcesClient userResourcesClient, IXpWhitelistService xpWhitelistService, XpRegionService xpRegionService, XpOpenCityService xpOpenCityService) {
        this.xpPricingService = xpPricingService;
        this.xpGeoQueryEntityService = xpGeoQueryEntityService;
        this.userResourcesClient = userResourcesClient;
        this.xpWhitelistService = xpWhitelistService;
        this.xpOpenCityService = xpOpenCityService;
    }
@@ -174,6 +173,9 @@
        if (pricing == null) {
            throw new ServiceException("定价不存在", I18nKeyConstant.PRICING_NOT_EXIST);
        }
        //获取城市信息
        String cityName = xpOpenCityService.getNameWithCityName(pricing.getCityId());
        pricing.setCityName(cityName);
        return R.ok(pricing);
    }
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpSystemSettingController.java
@@ -1,5 +1,6 @@
package com.xiaopeng.operation.controller;
import com.xiaopeng.api.model.operation.XpSystemSetting;
import com.xiaopeng.common.core.constant.CacheConstants;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.controller.BaseController;
@@ -10,14 +11,14 @@
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@Validated
@RestController
@RequestMapping("")
@Api(tags = "系统设置模块")
public class XpSystemSettingController extends BaseController {
    // 系统设置实现类
@@ -71,4 +72,11 @@
            return R.ok(new CustomerServicePhoneVo(xpSystemSettingService.getCustomerServicePhone()));
        }
    }
    @ApiOperation(value = "获取系统配置、热修复", tags = {"管理后台-系统"})
    @GetMapping("/api/v1/systemSetting")
    public R<XpSystemSetting> getSystemSetting(){
        return R.ok(xpSystemSettingService.lambdaQuery().last("limit 1").one());
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/PricingSetPriceDTO.java
@@ -1,5 +1,6 @@
package com.xiaopeng.operation.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -19,7 +20,6 @@
    private Long id;
    @ApiModelProperty(value = "基础价格json配置", required = true, notes = "{\n" +
            "  \"num3\": \"起步价数值1\",\n" +
            "  \"num4\": \"起步价数值2\",\n" +
            "  \"num5\": \"起步价数值3\",\n" +
            "  \"num6\": \"起步价数值4\",\n" +
@@ -93,7 +93,6 @@
            "    \"num7\": \"起步价数值5\"\n" +
            "  }\n" +
            "]")
    @NotBlank(message = "起步价json配置不能为空")
    private String startingFareJson;
    @ApiModelProperty(value = "动态价格json配置", required = true, notes = "  {\n" +
@@ -109,4 +108,8 @@
            "  }")
    @NotBlank(message = "动态价格json配置不能为空")
    private String dynamicPricingJson;
    @ApiModelProperty(value = "是否动态价格 0否 1是")
    private Integer isDynamicPrice;
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/XpAgreementDTO.java
New file
@@ -0,0 +1,26 @@
package com.xiaopeng.operation.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
 * @author MiTao
 * @date 2026-02-25 14:41
 *
 */
@Data
@ApiModel("协议数据传输对象")
public class XpAgreementDTO {
    @NotNull(message = "协议类型不能为空")
    @ApiModelProperty(value = "类型 1=用户服务协议 2=平台隐私政策 3=敏感个人信息处理情况说明 4=向第三方提供个人信息情况的说明 5=乘车须知 6=计费规则说明")
    private Integer contentType;
    @NotBlank(message = "协议内容不能为空")
    @ApiModelProperty(value = "内容")
    private String content;
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/XpFrequentlyAskedQuestionsDTO.java
New file
@@ -0,0 +1,23 @@
package com.xiaopeng.operation.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.xiaopeng.api.model.operation.XpFrequentlyAskedQuestions;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
 * @author MiTao
 * @date 2026-02-25 15:12
 *
 */
@Data
@ApiModel(value = "常见问题数据传输对象")
public class XpFrequentlyAskedQuestionsDTO {
    @ApiModelProperty(value = "常见问题列表")
    private List<XpFrequentlyAskedQuestions> frequentlyAskedQuestionsList;
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpFrequentlyAskedQuestionsService.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.operation.XpFrequentlyAskedQuestions;
import com.xiaopeng.operation.dto.XpFrequentlyAskedQuestionsDTO;
/**
 * <p>
@@ -13,4 +14,5 @@
 */
public interface IXpFrequentlyAskedQuestionsService extends IService<XpFrequentlyAskedQuestions> {
    void saveQuestion(XpFrequentlyAskedQuestionsDTO dto);
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/XpAgreementService.java
@@ -3,8 +3,10 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.operation.XpAgreement;
import com.xiaopeng.operation.dto.XpAgreementDTO;
import com.xiaopeng.operation.vo.XpAgreementVo;
import javax.validation.Valid;
import java.util.List;
/**
@@ -29,6 +31,16 @@
     */
    List<XpAgreementVo> getContentByTypeAll();
    /**
     * 根据类型获取配置
     * @param type
     * @return
     */
    XpAgreement getAgreementContent(Integer type);
    /**
     * 保存协议
     * @param dto
     */
    void saveAgreement(@Valid XpAgreementDTO dto);
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/XpOpenCityService.java
@@ -67,4 +67,11 @@
     * @return
     */
    void upDown(Long id, Integer status);
    /**
     * 获取开通城市名称,如果开通城市层级是区级,则返回市级名称>区名称
     * @param cityId
     * @return
     */
    String getNameWithCityName(Integer cityId);
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpAgreementServiceImpl.java
@@ -1,18 +1,17 @@
package com.xiaopeng.operation.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.operation.dto.XpAgreementDTO;
import com.xiaopeng.operation.mapper.XpAgreementMapper;
import com.xiaopeng.api.model.operation.XpAgreement;
import com.xiaopeng.operation.service.XpAgreementService;
import com.xiaopeng.operation.vo.XpAgreementVo;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.*;
/**
 * <p>
@@ -53,4 +52,30 @@
        }
        return xpAgreementVos;
    }
    /**
     * 根据类型获取配置
     * @param type
     * @return
     */
    @Override
    public XpAgreement getAgreementContent(Integer type) {
        return this.lambdaQuery().eq(XpAgreement::getContentType, type).last("limit 1").one();
    }
    @Override
    public void saveAgreement(XpAgreementDTO dto) {
        //根据类型查询协议
        Optional<XpAgreement> opt = this.lambdaQuery().eq(XpAgreement::getContentType, dto.getContentType()).last("limit 1").oneOpt();
        //如果存在则更新,不存在则新增
        if (opt.isPresent()) {
            XpAgreement xpAgreement = opt.get();
            xpAgreement.setContent(dto.getContent());
            updateById(xpAgreement);
        } else {
            XpAgreement xpAgreement = BeanUtil.copyProperties(dto, XpAgreement.class);
            this.save(xpAgreement);
        }
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpFrequentlyAskedQuestionsServiceImpl.java
@@ -1,10 +1,14 @@
package com.xiaopeng.operation.service.impl;
import com.xiaopeng.api.model.operation.XpFrequentlyAskedQuestions;
import com.xiaopeng.operation.dto.XpFrequentlyAskedQuestionsDTO;
import com.xiaopeng.operation.mapper.XpFrequentlyAskedQuestionsMapper;
import com.xiaopeng.operation.service.IXpFrequentlyAskedQuestionsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.operation.service.IXpFrequentlyAskedQuestionsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
 * <p>
@@ -16,5 +20,10 @@
 */
@Service
public class XpFrequentlyAskedQuestionsServiceImpl extends ServiceImpl<XpFrequentlyAskedQuestionsMapper, XpFrequentlyAskedQuestions> implements IXpFrequentlyAskedQuestionsService {
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveQuestion(XpFrequentlyAskedQuestionsDTO dto) {
        List<XpFrequentlyAskedQuestions> frequentlyAskedQuestionsList = dto.getFrequentlyAskedQuestionsList();
        saveOrUpdateBatch(frequentlyAskedQuestionsList);
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpOpenCityServiceImpl.java
@@ -142,4 +142,18 @@
    public void upDown(Long id, Integer status) {
        lambdaUpdate().eq(XpOpenCity::getId, id).set(XpOpenCity::getStatus, status).update();
    }
    @Override
    public String getNameWithCityName(Integer cityId) {
        String cityName = "";
        XpOpenCity openCity = getById(cityId);
        if (Objects.nonNull(openCity)) {
            if (StringUtils.isNotBlank(openCity.getDistrictCode())) {
                cityName = openCity.getCityName() + ">" + openCity.getDistrictName();
            } else {
                cityName = openCity.getCityName();
            }
        }
        return cityName;
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java
@@ -26,6 +26,7 @@
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
import com.xiaopeng.common.core.utils.DateUtils;
import com.xiaopeng.common.core.utils.StringUtils;
import com.xiaopeng.common.core.utils.uuid.UUID;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.redis.service.RedisService;
@@ -718,11 +719,16 @@
        if (pricing == null) {
            throw new ServiceException("定价不存在", I18nKeyConstant.PRICING_NOT_EXIST);
        }
        try {
            JSONObject.parseObject(dto.getBasicPricingJson());
            JSONArray.parseArray(dto.getStartingFareJson());
            JSONObject.parseObject(dto.getDynamicPricingJson());
            if (StringUtils.isNotBlank(dto.getBasicPricingJson())) {
                JSONObject.parseObject(dto.getBasicPricingJson());
            }
            if (StringUtils.isNotBlank(dto.getStartingFareJson())) {
                JSONArray.parseArray(dto.getStartingFareJson());
            }
            if (StringUtils.isNotBlank(dto.getDynamicPricingJson())) {
                JSONObject.parseObject(dto.getDynamicPricingJson());
            }
        } catch (Exception e) {
            throw new ServiceException("价格配置JSON格式不正确", I18nKeyConstant.PRICING_JSON_INVALID);
        }
@@ -730,8 +736,9 @@
        XpPricing update = new XpPricing();
        update.setId(dto.getId());
        update.setBasicPricingJson(dto.getBasicPricingJson());
        update.setStartingFareJson(dto.getStartingFareJson());
        update.setStartingFareJson(StringUtils.isNotBlank(dto.getStartingFareJson()) ? dto.getStartingFareJson() : null);
        update.setDynamicPricingJson(dto.getDynamicPricingJson());
        update.setIsDynamicPrice(dto.getIsDynamicPrice());
        this.updateById(update);
    }
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/vo/PricingPageListVO.java
@@ -15,7 +15,9 @@
public class PricingPageListVO implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "id")
    private Long id;
    @ApiModelProperty(value = "创建时间")
    private Date createTime;
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpPricingMapper.xml
@@ -4,6 +4,7 @@
    <select id="pageList" resultType="com.xiaopeng.operation.vo.PricingPageListVO">
        SELECT
            p.id,
            p.create_time AS createTime,
            p.vehicle_model AS vehicleModel,
            CASE
xp-robotaxi-vehicle-convoy-boot/src/main/resources/mapper/vehicleConvoy/XpVehicleMapper.xml
@@ -7,7 +7,7 @@
        id, vehicle_code, vehicle_vin, plate_number, vehicle_model, vehicle_color, vehicle_pictures,
          procurement_source, remarks, annual_inspection_date, insurance_company, insurance_phone,
          insurance_end_time, inspection_attachments, policy_information, electronic_id,
          operation_qualification, qualification_expire_time, status, operating_status,mileageRange,
          operation_qualification, qualification_expire_time, status, operating_status,mileage_range,
          warehousing_time, vehicle_type, accept_or_test, accept_or_test_status, current_electricity,
          is_deleted, create_time, update_time, create_by, update_by
    </sql>