package com.xiaopeng.account.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; 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.ISysRoleService; 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.*; import com.xiaopeng.api.model.vehicleConvoy.XpFleet; 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.utils.poi.ExcelUtil; 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; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.time.LocalDateTime; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; /** *

* 运维人员 服务实现类 *

* * @author mitao * @since 2026-02-03 */ @Slf4j @Service public class XpOperationsUserServiceImpl extends ServiceImpl implements IXpOperationsUserService { @Autowired private XpFleetOperationsClient xpFleetOperationsClient; @Autowired private XpFleetClient xpFleetClient; @Autowired private XpOperationsRoleMapper xpOperationsRoleMapper; @Autowired private IXpOperationsRoleService xpOperationsRoleService; @Autowired private XpClockInClient xpClockInClient; @Autowired private IXpQualificationAuditService xpQualificationAuditService; @Autowired private SysRoleMapper sysRoleMapper; @Autowired private ISysRoleService iSysRoleService; @Override public List listByName(String nickName) { if (StringUtils.isBlank(nickName)) { return Collections.emptyList(); } return lambdaQuery().like(XpOperationsUser::getNickName, nickName).list(); } @Override public PageInfo selectUserPageByConditions(XpOperationsUserPageQuery query) { PageInfo pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); Page page = baseMapper.selectUserPageByConditions(pageInfo, query); pageInfo.setRecords(page.getRecords()); return pageInfo; } @Override public XpOperationsUserProfileVO getUserProfile(Long userId) { // 1. 查询运维人员基础信息 XpOperationsUser user = this.getById(userId); if (user == null) { throw new ServiceException("运维人员不存在"); } XpOperationsUserProfileVO vo = new XpOperationsUserProfileVO(); BeanUtils.copyProperties(user, vo); // 2. 查询关联的车队ID列表(一个运维人员只能关联一个车队) R> fleetIdsResult = xpFleetOperationsClient.getFleetIdsByUserId(userId); List fleetIds = fleetIdsResult.getData(); if (!CollectionUtils.isEmpty(fleetIds)) { // 3. 获取第一个车队ID(因为只能关联一个车队) Long fleetId = fleetIds.get(0); // 4. 查询车队信息 R> fleetsResult = xpFleetClient.listByIds(Collections.singletonList(fleetId)); List fleets = fleetsResult.getData(); if (!CollectionUtils.isEmpty(fleets)) { XpFleet fleet = fleets.get(0); // 5. 组装车队信息VO FleetInfoVO fleetVO = new FleetInfoVO(); fleetVO.setFleetId(fleet.getId()); fleetVO.setFleetName(fleet.getFleetName()); fleetVO.setProvinceName(fleet.getProvinceName()); fleetVO.setCityName(fleet.getCityName()); fleetVO.setDistrictName(fleet.getDistrictName()); // 6. 查询并填充车队队长信息 if (fleet.getOperationsUserId() != null) { XpOperationsUser captain = this.getById(fleet.getOperationsUserId()); if (captain != null) { fleetVO.setCaptainId(captain.getId()); fleetVO.setFleetLeaderName(captain.getNickName()); fleetVO.setFleetLeaderAvatar(captain.getAvatar()); } } vo.setFleet(fleetVO); } } // 7. 查询是否上班中 try { R workStatusResult = xpClockInClient.checkWorkStatus(userId); if (workStatusResult != null && workStatusResult.getCode() == 200) { vo.setWorkFlag(workStatusResult.getData()); } else { // 调用失败,默认 false vo.setWorkFlag(false); log.warn("查询用户上班状态失败, userId={}, result={}", userId, workStatusResult); } } catch (Exception e) { // 异常情况,默认 false vo.setWorkFlag(false); log.error("查询用户上班状态异常, userId={}", userId, e); } // 8. 查询角色信息 List userWithRoles = this.selectUsersWithRoleByIds(Collections.singletonList(userId)); XpOperationsUserWithRoleVO operationsUserWithRoleVO = userWithRoles.get(0); if (CollUtil.isNotEmpty(operationsUserWithRoleVO.getRoles())) { List roleVOs = operationsUserWithRoleVO.getRoles().stream() .map(item -> { XpOperationsUserProfileVO.RoleInfoVO roleInfoVO = BeanUtil.copyProperties(item, XpOperationsUserProfileVO.RoleInfoVO.class); roleInfoVO.setRoleId(item.getId()); return roleInfoVO; }) .collect(Collectors.toList()); vo.setRoles(roleVOs); } return vo; } @Transactional(rollbackFor = Exception.class) @Override public void saveCertificate(XpOperationsUserDTO dto) { XpOperationsUser xpOperationsUser = BeanUtil.copyProperties(dto, XpOperationsUser.class); updateById(xpOperationsUser); //保存审核记录 XpQualificationAudit xpQualificationAudit = BeanUtil.copyProperties(dto, XpQualificationAudit.class, "id"); xpQualificationAudit.setAuditStatus(1); xpQualificationAudit.setOperationsUserId(dto.getId()); xpQualificationAuditService.save(xpQualificationAudit); } @Override public PageInfo pageList(XpOperationsUserQuery query) { PageInfo pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List list = this.baseMapper.pageList(pageInfo, query); if(CollectionUtils.isEmpty(list)){ return pageInfo; } // 查询角色名称 List operationsUserIds = list.stream().map(XpOperationsUserVO::getId).collect(Collectors.toList()); // 查询用户信息 List xpOperationsRoles = xpOperationsRoleMapper.selectList(Wrappers.lambdaQuery(XpOperationsRole.class) .in(XpOperationsRole::getOperationsUserId, operationsUserIds)); if(!CollectionUtils.isEmpty(xpOperationsRoles)){ List roleIds = xpOperationsRoles.stream().map(XpOperationsRole::getRoleId).distinct().collect(Collectors.toList()); // 查询列表关联的所有角色 List sysRoles = sysRoleMapper.selectList(Wrappers.lambdaQuery(SysRole.class) .in(SysRole::getId, roleIds)); if(!CollectionUtils.isEmpty(sysRoles)){ // 角色匹配账号id Map> map = new HashMap<>(); for (XpOperationsRole xpOperationsRole : xpOperationsRoles) { List sysRoleList = sysRoles.stream().filter(sysRole -> sysRole.getId().equals(xpOperationsRole.getRoleId())).collect(Collectors.toList()); List roleList = map.get(xpOperationsRole.getOperationsUserId()); if(!CollectionUtils.isEmpty(roleList)){ sysRoleList.addAll(roleList); } map.put(xpOperationsRole.getOperationsUserId(), sysRoleList); } // 角色名称匹配 for (XpOperationsUserVO xpOperationsUserVO : list) { xpOperationsUserVO.setSysRoles(map.get(xpOperationsUserVO.getId())); } } } pageInfo.setRecords(list); return pageInfo; } @Override public R 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 roleIds = dto.getRoleIds(); if(!CollectionUtils.isEmpty(roleIds)){ List 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 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().eq(XpOperationsRole::getOperationsUserId, dto.getId())); // 存储角色 List roleIds = dto.getRoleIds(); if(!CollectionUtils.isEmpty(roleIds)){ List 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 xpOperationsRoles = xpOperationsRoleMapper.selectList(Wrappers.lambdaQuery(XpOperationsRole.class) .eq(XpOperationsRole::getOperationsUserId, id)); if(!CollectionUtils.isEmpty(xpOperationsRoles)){ List roleIds = xpOperationsRoles.stream().map(XpOperationsRole::getRoleId).collect(Collectors.toList()); List sysRoles = sysRoleMapper.selectList(Wrappers.lambdaQuery(SysRole.class) .in(SysRole::getId, roleIds)); xpOperationsUserVO.setSysRoles(sysRoles); } return xpOperationsUserVO; } /** * 导出运维人员列表 * @param query */ @Override public void exportOperationsUser(XpOperationsUserQuery query, HttpServletResponse response) { List list = this.baseMapper.exportOperationsUser(query); ExcelUtil util = new ExcelUtil(ExportOperationsUserVo.class); util.exportExcel(response, list, "运维人员管理列表"); } /** * 导入运维人员数据 * @param file */ @Override public void importOperationsUser(MultipartFile file) { ExcelUtil util = new ExcelUtil(ExportOperationsUserVo.class); try { List list = util.importExcel(file.getInputStream()); for (ExportOperationsUserVo exportOperationsUserVo : list) { XpOperationsUser xpOperationsUser = new XpOperationsUser(); xpOperationsUser.setNickName(exportOperationsUserVo.getNickName()); xpOperationsUser.setUniqueNumber(exportOperationsUserVo.getUniqueNumber()); xpOperationsUser.setAvatar(exportOperationsUserVo.getAvatar()); xpOperationsUser.setPhoneNumber(exportOperationsUserVo.getPhoneNumber()); xpOperationsUser.setRemarks(exportOperationsUserVo.getRemarks()); xpOperationsUser.setStatus(true); xpOperationsUser.setIdCardFront(exportOperationsUserVo.getIdCardFront()); xpOperationsUser.setIdCardBack(exportOperationsUserVo.getIdCardBack()); xpOperationsUser.setDriverLicense(exportOperationsUserVo.getDriverLicense()); xpOperationsUser.setCertificateOfNoCriminalRecord(exportOperationsUserVo.getCertificateOfNoCriminalRecord()); xpOperationsUser.setTrainingGraduationCertificate(exportOperationsUserVo.getTrainingGraduationCertificate()); xpOperationsUser.setDeleted(false); xpOperationsUser.setCreateTime(LocalDateTime.now()); xpOperationsUser.setUpdateTime(LocalDateTime.now()); this.save(xpOperationsUser); } } catch (Exception e) { throw new RuntimeException(e); } } /** * 导出模板 * @param response */ @Override public void exportTemplate(HttpServletResponse response) { ExcelUtil util = new ExcelUtil(ExportOperationsUserVo.class); util.importTemplateExcel(response, "运维人员管理列表"); } @Override public List selectUsersWithRoleByIds(List ids) { if (CollUtil.isEmpty(ids)) { return Collections.emptyList(); } List operationsUsers = listByIds(ids); if (CollUtil.isEmpty(operationsUsers)) { return Collections.emptyList(); } // 查询用户角色信息 List userIds = operationsUsers.stream() .map(XpOperationsUser::getId) .filter(Objects::nonNull) .distinct() .collect(Collectors.toList()); if (CollUtil.isEmpty(userIds)) { return Collections.emptyList(); } // 获取关联角色ids List operationsRoles = xpOperationsRoleMapper.selectList( Wrappers.lambdaQuery(XpOperationsRole.class) .in(XpOperationsRole::getOperationsUserId, userIds) ); // userId -> 该用户关联的 roleId 列表 Map> userRoleIdsMap = CollUtil.isNotEmpty(operationsRoles) ? operationsRoles.stream() .filter(r -> r.getOperationsUserId() != null && r.getRoleId() != null) .collect(Collectors.groupingBy( XpOperationsRole::getOperationsUserId, Collectors.mapping(XpOperationsRole::getRoleId, Collectors.collectingAndThen(Collectors.toList(), list -> list.stream().distinct().collect(Collectors.toList()))) )) : Collections.emptyMap(); // 一次性查出所有角色 List roleIds = userRoleIdsMap.values().stream() .flatMap(Collection::stream) .distinct() .collect(Collectors.toList()); Map roleMap = CollUtil.isNotEmpty(roleIds) ? iSysRoleService.listByIds(roleIds).stream() .collect(Collectors.toMap(SysRole::getId, Function.identity(), (a, b) -> a)) : Collections.emptyMap(); // 组装 VO:每个用户对应角色列表 return operationsUsers.stream().map(u -> { Long uid = u.getId(); List roleIdList = userRoleIdsMap.getOrDefault(uid, Collections.emptyList()); List roles = roleIdList.stream() .map(roleMap::get) .filter(Objects::nonNull) .collect(Collectors.toList()); // 根据你的 VO 字段调整 XpOperationsUserWithRoleVO vo = BeanUtil.copyProperties(u, XpOperationsUserWithRoleVO.class); vo.setRoles(roles); return vo; }).collect(Collectors.toList()); } }