liujie
2026-06-09 c96fbe6b0aeb413a17c429133ee6d81d138144b9
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java
@@ -1,19 +1,58 @@
package com.xiaopeng.account.controller;
import cn.hutool.core.util.DesensitizedUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xiaopeng.account.constant.I18nKeyConstant;
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.ISysRoleService;
import com.xiaopeng.account.service.IXpOperationsUserService;
import com.xiaopeng.account.service.IXpQualificationAuditService;
import com.xiaopeng.api.dto.account.XpOperationsUserQueryDTO;
import com.xiaopeng.api.feignClient.account.SysGroupMenuClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetClient;
import com.xiaopeng.api.model.account.SysRole;
import com.xiaopeng.api.model.account.XpOperationsRole;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.account.XpQualificationAudit;
import com.xiaopeng.api.model.vehicleConvoy.XpFleet;
import com.xiaopeng.api.query.account.OptionalUsersPageListQuery;
import com.xiaopeng.api.vo.account.LoginUser;
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.exception.ServiceException;
import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.log.annotation.AdminOperationLog;
import com.xiaopeng.common.log.enums.AdminBusinessType;
import com.xiaopeng.common.log.enums.AdminOperationType;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.evi.oss.service.AliOssService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import com.xiaopeng.common.log.annotation.AdminOperationLog;
import com.xiaopeng.common.log.enums.AdminBusinessType;
import com.xiaopeng.common.log.enums.AdminOperationType;
/**
 * <p>
@@ -31,84 +70,477 @@
    private final XpOperationsRoleMapper xpOperationsRoleMapper;
    private final TokenService tokenService;
    private final XpFleetClient xpFleetClient;
    private final AliOssService aliOssService;
    @Resource
    private IXpQualificationAuditService xpQualificationAuditService;
    @Resource
    private ISysRoleService sysRoleService;
    @Resource
    private SysGroupMenuClient groupMenuClient;
    @Autowired
    public XpOperationsUserController(IXpOperationsUserService xpOperationsUserService, XpOperationsRoleMapper xpOperationsRoleMapper) {
    public XpOperationsUserController(IXpOperationsUserService xpOperationsUserService,
                                      XpOperationsRoleMapper xpOperationsRoleMapper,
                                      TokenService tokenService,
                                      XpFleetClient xpFleetClient, AliOssService aliOssService) {
        this.xpOperationsUserService = xpOperationsUserService;
        this.xpOperationsRoleMapper = xpOperationsRoleMapper;
        this.tokenService = tokenService;
        this.xpFleetClient = xpFleetClient;
        this.aliOssService = aliOssService;
    }
    /**
     * 根据ID列表批量查询运维用户信息
     *
     * @param ids 用户ID列表
     * @return 用户列表
     */
    @PostMapping("/inner/xpOperationsUser/listByIds")
    public R<List<XpOperationsUser>> listByIds(@RequestBody List<Long> ids){
        return R.ok(xpOperationsUserService.listByIds(ids));
    @PostMapping("/logan/inner/xpOperationsUser/listByIds")
    public R<List<XpOperationsUser>> listByIds(@RequestBody List<Long> ids) {
        List<XpOperationsUser> users = xpOperationsUserService.listByIds(ids);
        users.forEach(user -> user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber())));
        return R.ok(users);
    }
    @PostMapping("/logan/inner/xpOperationsUser/pageListByIds")
    public R<PageInfo<XpOperationsUserWithRoleVO>> pageListByIds(@RequestBody OptionalUsersPageListQuery q) {
        return R.ok(xpOperationsUserService.pageListByIds(q));
    }
    @PostMapping("/logan/inner/xpOperationsUser/findList")
    public R<List<XpOperationsUserWithRoleVO>> findList(@RequestBody XpOperationsUserQueryDTO query) {
        return R.ok(xpOperationsUserService.findList(query));
    }
    /**
     * 根据ID查询运维用户信息
     * @return 用户列表
     */
    @GetMapping("/inner/xpOperationsUser/queryById")
    R<XpOperationsUser> queryById(Long id){
        return R.ok(xpOperationsUserService.getById(id));
    @GetMapping("/logan/inner/xpOperationsUser/queryById")
    R<XpOperationsUser> queryById(@RequestParam Long id) {
        XpOperationsUser operationsUser = xpOperationsUserService.getById(id);
        XpOperationsRole operationsUserId = xpOperationsRoleMapper.selectOne(new QueryWrapper<XpOperationsRole>().eq("operations_user_id", id));
        SysRole sysRole = sysRoleService.getById(operationsUserId.getRoleId());
        operationsUser.setRoleName(sysRole.getRoleName());
        operationsUser.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(operationsUser.getPhoneNumber()));
        return R.ok(operationsUser);
    }
    /**
     * 根据ID查询运维用户信息
     * @return 用户列表
     */
    @GetMapping("/logan/inner/xpOperationsUser/queryByIds")
    R<List<XpOperationsUser>> queryByIds(@RequestParam String operationsUserId) {
        List<Long> ids = Arrays.stream(operationsUserId.split(","))
                .map(Long::parseLong)
                .collect(Collectors.toList());
        List<XpOperationsUser> operationsUser = xpOperationsUserService.listByIds(ids);
        for (XpOperationsUser xpOperationsUser : operationsUser) {
            XpOperationsRole role = xpOperationsRoleMapper.selectOne(new QueryWrapper<XpOperationsRole>().eq("operations_user_id", xpOperationsUser.getId()));
            SysRole sysRole = sysRoleService.getById(role.getRoleId());
            xpOperationsUser.setRoleName(sysRole.getRoleName());
            xpOperationsUser.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(xpOperationsUser.getPhoneNumber()));
        }
        return R.ok(operationsUser);
    }
    /**
     * 根据昵称查询运维用户信息
     *
     * @param nickName 昵称
     * @return 运维用户列表
     */
    @PostMapping("/inner/xpOperationsUser/listByName")
    public R<List<XpOperationsUser>> listByName(@RequestBody String nickName) {
    @PostMapping("/logan/inner/xpOperationsUser/listByName")
    public R<List<XpOperationsUser>> listByName(@RequestParam("nickName") String nickName) {
        return R.ok(xpOperationsUserService.listByName(nickName));
    }
    @GetMapping("/logan/inner/xpOperationsUser/profile")
    public R<XpOperationsUserProfileVO> profile(@RequestParam("id")Long id) {
        return R.ok(xpOperationsUserService.getUserProfile(id));
    }
    /**
     * 根据用户ID列表批量查询用户及角色信息(内部接口)
     *
     * @param ids 用户ID列表
     * @return 用户及角色信息列表
     */
    @ApiOperation(value = "批量查询用户及角色信息", tags = {"内部接口"})
    @PostMapping("/inner/xpOperationsUser/listByIdsWithRole")
    @PostMapping("/logan/inner/xpOperationsUser/listByIdsWithRole")
    public R<List<XpOperationsUserWithRoleVO>> listByIdsWithRole(@RequestBody List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return R.ok(new ArrayList<>());
        }
        List<XpOperationsUserWithRoleVO> result = xpOperationsRoleMapper.selectUsersWithRoleByIds(ids);
        List<XpOperationsUserWithRoleVO> result = xpOperationsUserService.selectUsersWithRoleByIds(ids);
        return R.ok(result);
    }
    /**
     * 根据条件查询用户及角色信息(内部接口)
     *
     * @param dto 查询条件
     * @return 用户及角色信息列表
     */
    @ApiOperation(value = "根据条件查询用户及角色信息", tags = {"内部接口"})
    @PostMapping("/inner/xpOperationsUser/queryByConditions")
    @PostMapping("/logan/inner/xpOperationsUser/queryByConditions")
    public R<List<XpOperationsUserWithRoleVO>> queryByConditions(@RequestBody XpOperationsUserQueryDTO dto) {
        List<XpOperationsUserWithRoleVO> result = xpOperationsRoleMapper.selectUsersByConditions(
                dto.getNickName(),
                dto.getPhoneNumber(),
                SensitiveDataCryptoUtil.queryValues(dto.getPhoneNumber()),
                dto.getRoleId()
        );
        result.forEach(user -> user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber())));
        return R.ok(result);
    }
    /**
     * 根据条件查询用户及角色信息
     * @param dto 查询条件
     *
     * @param query 查询条件
     * @return 用户及角色信息列表
     */
    @ApiOperation(value = "根据条件查询用户不分页列表", tags = {"管理后台-车队管理"})
    @ApiOperation(value = "根据条件查询用户分页列表", tags = {"管理后台-车队管理"})
    @PostMapping("/api/v1/xpOperationsUser/queryByConditions")
    public R<List<XpOperationsUserWithRoleVO>> getList(@RequestBody XpOperationsUserQueryDTO dto) {
        List<XpOperationsUserWithRoleVO> result = xpOperationsRoleMapper.selectUsersByConditions(
                dto.getNickName(),
                dto.getPhoneNumber(),
                dto.getRoleId()
        );
    public R<PageInfo<XpOperationsUserWithRoleVO>> getList(@RequestBody XpOperationsUserPageQuery query) {
        return R.ok(xpOperationsUserService.selectUserPageByConditions(query));
    }
    /**
     * 获取运维人员个人中心首页信息
     *
     * @return 个人中心首页信息
     */
    @ApiOperation(value = "获取个人中心首页信息", tags = {"运维APP-个人中心"})
    @GetMapping("/maintenance-app/api/v1/userInfo")
    public R<XpOperationsUserProfileVO> getProfile() {
        // 通过TokenService获取当前登录用户ID
        Long currentUserId = tokenService.getLoginOperationUser().getId();
        // 查询个人中心信息
        XpOperationsUserProfileVO profile = xpOperationsUserService.getUserProfile(currentUserId);
        return R.ok(profile);
    }
    /**
     * 运维APP-个人中心-证件上传
     *
     * @param dto
     * @return
     */
    @ApiOperation(value = "个人中心-证件上传", tags = {"运维APP-个人中心"})
    @PostMapping("/maintenance-app/api/v1/saveCertificate")
    public R<?> saveCertificate(@Valid @RequestBody XpOperationsUserDTO dto) {
        xpOperationsUserService.saveCertificate(dto);
        return R.ok();
    }
    @ApiOperation(value = "个人中心-查询证件上传详情", tags = {"运维APP-个人中心"})
    @PostMapping("/maintenance-app/api/v1/getCertificate")
    public R<XpQualificationAudit> getCertificate() {
        Long id = tokenService.getLoginOperationUser().getId();
        XpQualificationAudit xpQualificationAudit = xpQualificationAuditService.getOne(new QueryWrapper<XpQualificationAudit>().eq("operations_user_id", id)
                .last(" order by create_time desc limit 1"));
        return R.ok(xpQualificationAudit);
    }
    @ApiOperation(value = "运维人员管理分页列表", tags = {"管理后台-运维执行"})
    @PostMapping("/api/v1/operationsUser/pageList")
    public R<PageInfo<XpOperationsUserVO>> pageList(@RequestBody XpOperationsUserQuery query) {
        LoginUser loginUser = tokenService.getLoginUser();
        PageInfo<XpOperationsUserVO> pageList = xpOperationsUserService.pageList(query);
        if(!loginUser.getPhoneDesensitizationExempt()){
            for (XpOperationsUserVO record : pageList.getRecords()) {
                record.setPhoneNumber(DesensitizedUtil.mobilePhone(record.getPhoneNumber()));
            }
        }
        return R.ok(pageList);
    }
    @ApiOperation(value = "运维人员管理不分页列表", tags = {"管理后台-运维执行"})
    @PostMapping("/api/v1/operationsUser/listAll")
    public R<List<XpOperationsUser>> listAll() {
        List<XpOperationsUser> listAll = xpOperationsUserService.list();
        listAll.forEach(user -> user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber())));
        for (XpOperationsUser xpOperationsUser : listAll) {
            // todo 需要上传工单id,根据距离进行排序
        }
        return R.ok(listAll);
    }
    /**
     * 获取所有启用状态的运维用户(内部接口)
     * @return 启用状态的用户列表
     */
    @ApiOperation(value = "获取所有启用状态的运维用户", tags = {"内部接口"})
    @GetMapping("/logan/inner/xpOperationsUser/listAllEnabled")
    public R<List<XpOperationsUser>> listAllEnabled() {
        List<XpOperationsUser> users = xpOperationsUserService.lambdaQuery()
                .eq(XpOperationsUser::getStatus, true)
                .list();
        users.forEach(user -> user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber())));
        return R.ok(users);
    }
    @ApiOperation(value = "运维人员管理新增", tags = {"管理后台-运维执行"})
    @PostMapping("/api/v1/operationsUser/add")
    @AdminOperationLog(
            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
            operationType = AdminOperationType.ADD,
            content = "新增运维人员",
            appendRequestData = true
    )
    public R<String> add(@RequestBody XpOperationsUserAddDTO dto) {
        return xpOperationsUserService.addOperationsUser(dto);
    }
    @ApiOperation(value = "运维人员管理编辑", tags = {"管理后台-运维执行"})
    @PostMapping("/api/v1/operationsUser/edit")
    @AdminOperationLog(
            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
            operationType = AdminOperationType.EDIT,
            content = "编辑运维人员",
            appendRequestData = true
    )
    public R<String> edit(@RequestBody XpOperationsUserAddDTO dto) {
        return xpOperationsUserService.editOperationsUser(dto);
    }
    @ApiOperation(value = "运维人员管理启用禁用", tags = {"管理后台-运维执行"})
    @PostMapping("/api/v1/operationsUser/enableDisableById")
    @AdminOperationLog(
            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
            operationType = AdminOperationType.SWITCH_STATUS,
            content = "运维人员管理启用禁用",
            appendRequestData = true
    )
    public R<String> enableDisableById(@RequestBody EnableDisableDTO dto) {
        xpOperationsUserService.enableDisableById(dto);
        return R.ok();
    }
    @ApiOperation(value = "运维人员管理删除", tags = {"管理后台-运维执行"})
    @DeleteMapping("/api/v1/operationsUser/deleteById")
    @AdminOperationLog(
            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
            operationType = AdminOperationType.DELETE,
            content = "删除运维人员",
            appendRequestData = true
    )
    public R<String> deleteById(@RequestParam Long id) {
        try {
            R<XpFleet> fleetResult = xpFleetClient.getFleetByOperationsUserId(id);
            if (fleetResult == null) {
                throw new ServiceException("请求失败,请稍后重试", I18nKeyConstant.REQUEST_FAILED);
            }
            XpFleet fleet = fleetResult.getData();
            if (fleet != null && fleet.getId() != null) {
                String fleetName = com.xiaopeng.common.core.utils.StringUtils.isBlank(fleet.getFleetName())
                        ? String.valueOf(fleet.getId())
                        : fleet.getFleetName();
                throw new ServiceException(
                        "删除失败,该人员已关联车队:" + fleetName,
                        I18nKeyConstant.OPERATIONS_USER_DELETE_FLEET_BOUND,
                        new Object[]{fleetName}
                );
            }
        } catch (ServiceException e) {
            throw e;
        } catch (Exception e) {
            throw new ServiceException("请求失败,请稍后重试", I18nKeyConstant.REQUEST_FAILED);
        }
        xpOperationsUserService.removeById(id);
        return R.ok();
    }
    @ApiOperation(value = "运维人员管理重置密码", tags = {"管理后台-运维执行"})
    @PostMapping("/api/v1/operationsUser/rePassword")
    @AdminOperationLog(
            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
            operationType = AdminOperationType.RESET_PASSWORD,
            content = "重置运维人员密码",
            appendRequestData = true
    )
    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) {
        LoginUser loginUser = tokenService.getLoginUser();
        XpOperationsUserVO xpOperationsUserVO = xpOperationsUserService.detailById(id);
        if (xpOperationsUserVO.getAvatar() != null) {
            JSONObject jsonObject = JSONObject.parseObject(xpOperationsUserVO.getAvatar());
            if(jsonObject!=null){
                String downloadUrl = null;
                try {
                    // 1
                    downloadUrl= aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                jsonObject.put("url", downloadUrl);
                xpOperationsUserVO.setAvatar(jsonObject.toJSONString());
            }
        }
        if (xpOperationsUserVO.getIdCardFront() != null) {
            JSONObject jsonObject = JSONObject.parseObject(xpOperationsUserVO.getIdCardFront());
            if(jsonObject!=null){
                String downloadUrl = null;
                try {
                    // 1
                    downloadUrl= aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                jsonObject.put("url", downloadUrl);
                xpOperationsUserVO.setIdCardFront(jsonObject.toJSONString());
            }
        }
        if (xpOperationsUserVO.getIdCardBack() != null) {
            JSONObject jsonObject = JSONObject.parseObject(xpOperationsUserVO.getIdCardBack());
            if(jsonObject!=null){
                String downloadUrl = null;
                try {
                    // 1
                    downloadUrl= aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                jsonObject.put("url", downloadUrl);
                xpOperationsUserVO.setIdCardBack(jsonObject.toJSONString());
            }
        }
        if (xpOperationsUserVO.getDriverLicense() != null) {
            JSONObject jsonObject = JSONObject.parseObject(xpOperationsUserVO.getDriverLicense());
            if(jsonObject!=null){
                String downloadUrl = null;
                try {
                    // 1
                    downloadUrl= aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                jsonObject.put("url", downloadUrl);
                xpOperationsUserVO.setDriverLicense(jsonObject.toJSONString());
            }
        }
        if (xpOperationsUserVO.getCertificateOfNoCriminalRecord() != null) {
            JSONObject jsonObject = JSONObject.parseObject(xpOperationsUserVO.getCertificateOfNoCriminalRecord());
            if(jsonObject!=null){
                String downloadUrl = null;
                try {
                    // 1
                    downloadUrl= aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                jsonObject.put("url", downloadUrl);
                xpOperationsUserVO.setCertificateOfNoCriminalRecord(jsonObject.toJSONString());
            }
        }
        if(!loginUser.getPhoneDesensitizationExempt()){
            xpOperationsUserVO.setPhoneNumber(DesensitizedUtil.mobilePhone(xpOperationsUserVO.getPhoneNumber()));
        }
        return R.ok(xpOperationsUserVO);
    }
    @ApiOperation(value = "运维人员管理导出列表", tags = {"管理后台-运维执行"})
    @PostMapping("/api/v1/operationsUser/exportOperationsUser")
    @AdminOperationLog(
            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
            operationType = AdminOperationType.EXPORT,
            content = "导出运维人员列表",
            appendRequestData = true
    )
    public void exportOperationsUser(@RequestBody XpOperationsUserQuery query, HttpServletResponse response) {
        xpOperationsUserService.exportOperationsUser(query, response);
    }
    @ApiOperation(value = "运维人员管理导出模板", tags = {"管理后台-运维执行"})
    @GetMapping("/api/v1/operationsUser/exportTemplate")
    @AdminOperationLog(
            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
            operationType = AdminOperationType.EXPORT,
            content = "导出运维人员模板",
            appendRequestData = false
    )
    public void exportTemplate(HttpServletResponse response) {
        xpOperationsUserService.exportTemplate(response);
    }
    @ApiOperation(value = "运维人员管理导入数据", tags = {"管理后台-运维执行"})
    @PostMapping("/api/v1/operationsUser/importOperationsUser")
    @AdminOperationLog(
            businessType = AdminBusinessType.OPERATIONS_USER_MANAGEMENT,
            operationType = AdminOperationType.IMPORT,
            content = "导入运维人员数据",
            appendRequestData = false
    )
    public R<String> importOperationsUser(@RequestParam("file") MultipartFile file) {
        xpOperationsUserService.importOperationsUser(file);
        return R.ok();
    }
    /**
     * 根据手机号模糊查询用户(内部接口)
     *
     * @param phoneNumber 手机号
     * @return 用户信息列表
     */
    @ApiOperation(value = "根据手机号模糊查询用户及角色信息", tags = {"内部接口"})
    @PostMapping("/logan/inner/xpOperationsUser/getByPhoneNumber")
    public R<List<XpOperationsUser>> getByPhoneNumber(@RequestParam String phoneNumber) {
        List<XpOperationsUser> result = xpOperationsUserService.getByPhoneNumber(phoneNumber);
        return R.ok(result);
    }
    /**
     * 根据手机号精确查询运维用户(内部接口)
     *
     * @param phoneNumber 手机号
     * @return 运维用户信息,不存在返回null
     */
    @ApiOperation(value = "根据手机号精确查询运维用户", tags = {"内部接口"})
    @GetMapping("/logan/inner/xpOperationsUser/getByExactPhone")
    public R<XpOperationsUser> getByExactPhone(@RequestParam("phoneNumber") String phoneNumber) {
        if (com.xiaopeng.common.core.utils.StringUtils.isBlank(phoneNumber)) {
            return R.ok();
        }
        XpOperationsUser user = xpOperationsUserService.lambdaQuery()
                .in(XpOperationsUser::getPhoneNumber, SensitiveDataCryptoUtil.queryValues(phoneNumber))
                .last("LIMIT 1")
                .one();
        if (user != null) {
            user.setPhoneNumber(SensitiveDataCryptoUtil.decryptIfPossible(user.getPhoneNumber()));
        }
        return R.ok(user);
    }
}