| | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.security.KeyPair; |
| | | import java.time.Duration; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.concurrent.TimeUnit; |
| | |
| | | */ |
| | | @RestController |
| | | public class SysUserController extends BaseController { |
| | | private static final DateTimeFormatter UNIQUE_NUMBER_DATE_FORMATTER = DateTimeFormatter.BASIC_ISO_DATE; |
| | | private static final String UNIQUE_NUMBER_REDIS_KEY_PREFIX = "sys:user:unique-number:"; |
| | | |
| | | @Resource |
| | | private ISysUserService userService; |
| | | |
| | |
| | | if (StringUtils.isNotEmpty(user.getUserAccount()) && !userService.checkUserNameUnique(user)) { |
| | | throw new ServiceException("登录账号重复", I18nKeyConstant.ACCOUNT_DUPLICATE); |
| | | } |
| | | //校验编号是否唯一 |
| | | Long count = userService.lambdaQuery().eq(SysUser::getUniqueNumber, user.getUniqueNumber()).count(); |
| | | if (count > 0) { |
| | | throw new ServiceException("用户编号已存在", I18nKeyConstant.ACCOUNT_UNIQUE_NUMBER_DUPLICATE); |
| | | } |
| | | user.setUniqueNumber(generateUniqueNumber()); |
| | | user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); |
| | | //TODO 手机号脱敏存储 |
| | | userService.insertUser(user); |
| | |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | private String generateUniqueNumber() { |
| | | LocalDate today = LocalDate.now(); |
| | | String dateStr = UNIQUE_NUMBER_DATE_FORMATTER.format(today); |
| | | String redisKey = UNIQUE_NUMBER_REDIS_KEY_PREFIX + dateStr; |
| | | |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | LocalDateTime tomorrowStart = today.plusDays(1).atStartOfDay(); |
| | | long expireSeconds = Duration.between(now, tomorrowStart).getSeconds() + 60; |
| | | |
| | | for (int i = 0; i < 10; i++) { |
| | | Long seq = redisService.redisTemplate.opsForValue().increment(redisKey); |
| | | if (seq == null) { |
| | | throw new ServiceException("用户编号生成失败"); |
| | | } |
| | | if (expireSeconds > 0) { |
| | | redisService.expire(redisKey, expireSeconds, TimeUnit.SECONDS); |
| | | } |
| | | if (seq > 999999L) { |
| | | throw new ServiceException("当天生成用户编号已达上限"); |
| | | } |
| | | String uniqueNumber = dateStr + String.format("%06d", seq); |
| | | |
| | | Long count = userService.lambdaQuery().eq(SysUser::getUniqueNumber, uniqueNumber).count(); |
| | | if (count == null || count == 0L) { |
| | | return uniqueNumber; |
| | | } |
| | | } |
| | | throw new ServiceException("用户编号生成失败,请稍后重试"); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/verifyUserNameRepeat/{username}") |
| | | @ApiOperation(value = "校验账号是否重复", tags = {"管理后台-系统用户管理"}) |
| | |
| | | private String groupName; |
| | | |
| | | @ApiModelProperty(value = "备注", required = true) |
| | | @NotBlank(message = "{validation.group.remarks.notBlank}") |
| | | private String remarks; |
| | | |
| | | @ApiModelProperty(value = "分组类型 1=管理端 2=运维app") |
| | |
| | | FROM xp_operations_user u |
| | | LEFT JOIN xp_operations_role ur ON u.id = ur.operations_user_id |
| | | LEFT JOIN sys_role r ON ur.role_id = r.id AND r.is_deleted = 0 |
| | | WHERE 1=1 |
| | | <where> |
| | | u.is_deleted = 0 |
| | | <if test="nickName != null and nickName != ''"> |
| | | AND u.nick_name LIKE CONCAT('%', #{nickName}, '%') |
| | | </if> |
| | |
| | | <if test="roleId != null"> |
| | | AND r.id = #{roleId} |
| | | </if> |
| | | </where> |
| | | </select> |
| | | <select id="selectSysUserRoleByOperationUserId" |
| | | resultType="com.xiaopeng.api.model.account.XpOperationsRole"> |
| | |
| | | LEFT JOIN xp_operations_role ur ON u.id = ur.operations_user_id |
| | | LEFT JOIN sys_role r ON ur.role_id = r.id AND r.is_deleted = 0 |
| | | <where> |
| | | u.is_deleted = 0 |
| | | <if test="query.nickName != null and query.nickName != ''"> |
| | | AND u.nick_name LIKE CONCAT('%', #{query.nickName}, '%') |
| | | </if> |
| | |
| | | package com.xiaopeng.api.model.operation; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "电子围栏区域id") |
| | | @TableField("electronic_area_id") |
| | | @TableField(value = "electronic_area_id", updateStrategy = FieldStrategy.NEVER) |
| | | private Long electronicAreaId; |
| | | |
| | | @ApiModelProperty(value = "点位名称") |
| | |
| | | @ApiModelProperty(value = "点位类型1运营点位 2测试点位") |
| | | private Integer pointType; |
| | | |
| | | @ApiModelProperty(value = "点位状态(多选) 1待测试 2测试中 3测试不通过 4可运营 5待生效 6启用中 7已停用 8已失效") |
| | | private List<Integer> operationStatusList; |
| | | |
| | | } |
| | |
| | | private String pointNumber; |
| | | @ApiModelProperty(value = "点位名称") |
| | | private String pointName; |
| | | @ApiModelProperty(value = "点位状态 1待测试 2测试中 3测试不通过 4可运营 5待生效 6启用中 7已停用 8失效") |
| | | private Integer operationStatus; |
| | | @ApiModelProperty(value = "点位状态(多选) 1待测试 2测试中 3测试不通过 4可运营 5待生效 6启用中 7已停用 8失效") |
| | | private List<Integer> operationStatusList; |
| | | @ApiModelProperty(value = "限停时长") |
| | | private Integer parkingTimeLimit; |
| | | @ApiModelProperty(value = "点位经纬度") |
| | |
| | | import org.springframework.data.mongodb.core.geo.GeoJsonPoint; |
| | | import org.springframework.data.mongodb.core.query.Criteria; |
| | | import org.springframework.data.mongodb.core.query.Query; |
| | | import org.springframework.data.mongodb.core.query.Update; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | |
| | | |
| | | ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1000)); |
| | | Long finalOrderId = orderId; |
| | | Long finalOrderId1 = orderId; |
| | | threadPoolExecutor.execute(() -> { |
| | | //等待10秒后开始执行车子位移 |
| | | try { |
| | |
| | | VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class); |
| | | if (null == vehiclePosition) { |
| | | vehiclePosition = new VehiclePosition(); |
| | | } |
| | | vehiclePosition.setVin(vin); |
| | | vehiclePosition.setPoint(new GeoJsonPoint(longitude, latitude)); |
| | | vehiclePosition.setCourse(60D); |
| | | vehiclePosition.setAlt(100F); |
| | | //车辆动态信息 |
| | | vehiclePosition.setSpeed(50F); |
| | | vehiclePosition.setCurrentElectricity(80); |
| | | vehiclePosition.setMileageRange(300f); |
| | | vehiclePosition.setOrderId(finalOrderId); |
| | | vehiclePosition.setHasOrder(0); |
| | | vehiclePosition.setOrderId(finalOrderId1); |
| | | mongoTemplate.save(vehiclePosition); |
| | | }else{ |
| | | vehiclePosition.setOrderId(finalOrderId1); |
| | | Update update = new Update() |
| | | .set("point", new GeoJsonPoint(longitude, latitude)) |
| | | .set("course", 60D) |
| | | .set("alt", 100F) |
| | | .set("speed", 50F) |
| | | .set("currentElectricity", 80) |
| | | .set("mileageRange", 300f) |
| | | .set("hasOrder", 0) |
| | | .set("orderId", finalOrderId1); |
| | | mongoTemplate.updateFirst(new Query(Criteria.where("vin").is(vin)), update, VehiclePosition.class); |
| | | } |
| | | //调用推送服务接口 |
| | | if (null != finalOrderId) { |
| | | PushOrderRouteDTO dto = new PushOrderRouteDTO(); |
| | |
| | | |
| | | ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1000)); |
| | | Long finalOrderId = orderId; |
| | | Long finalOrderId1 = orderId; |
| | | threadPoolExecutor.execute(() -> { |
| | | //等待10秒后开始执行车子位移 |
| | | try { |
| | |
| | | VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class); |
| | | if (null == vehiclePosition) { |
| | | vehiclePosition = new VehiclePosition(); |
| | | } |
| | | vehiclePosition.setVin(vin); |
| | | vehiclePosition.setPoint(new GeoJsonPoint(longitude, latitude)); |
| | | vehiclePosition.setCourse(60D); |
| | | vehiclePosition.setAlt(100F); |
| | | //车辆动态信息 |
| | | vehiclePosition.setSpeed(50F); |
| | | vehiclePosition.setCurrentElectricity(80); |
| | | vehiclePosition.setMileageRange(300f); |
| | | vehiclePosition.setOrderId(finalOrderId); |
| | | vehiclePosition.setHasOrder(0); |
| | | vehiclePosition.setOrderId(finalOrderId1); |
| | | mongoTemplate.save(vehiclePosition); |
| | | }else{ |
| | | vehiclePosition.setOrderId(finalOrderId1); |
| | | Update update = new Update() |
| | | .set("point", new GeoJsonPoint(longitude, latitude)) |
| | | .set("course", 60D) |
| | | .set("alt", 100F) |
| | | .set("speed", 50F) |
| | | .set("currentElectricity", 80) |
| | | .set("mileageRange", 300f) |
| | | .set("hasOrder", 0) |
| | | .set("orderId", finalOrderId1); |
| | | mongoTemplate.updateFirst(new Query(Criteria.where("vin").is(vin)), update, VehiclePosition.class); |
| | | } |
| | | //调用推送服务接口 |
| | | if (null != finalOrderId) { |
| | | PushOrderRouteDTO dto = new PushOrderRouteDTO(); |
| | |
| | | String NO_CURRENT_REGION = "no.current.region"; |
| | | |
| | | |
| | | |
| | | |
| | | String NO_CURRENT_POINT = "no.current.point"; |
| | | |
| | | String SYSTEM_EXCEPTION = "system.exception"; |
| | |
| | | XpElectronicFence xpElectronicFence = xpElectronicFenceMapper.selectById(xpElectronicFenceArea.getElectronicId()); |
| | | String operationStrategy = xpElectronicFence.getOperationStrategy(); |
| | | Boolean inOperationTime = isInOperationTime(operationStrategy); |
| | | // if (!inOperationTime) { |
| | | // throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION); |
| | | // } |
| | | if (!inOperationTime && xpElectronicFence.getFailureType()!=1) { |
| | | throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION); |
| | | } |
| | | |
| | | |
| | | Integer cancelCount = xpTradingStrategyMapper.selectOne(null).getCancleCount(); |
| | |
| | | |
| | | // 获取起点经纬度 |
| | | XpPoint xpPoint = xpPointService.getById(dto.getStartPointId()); |
| | | if(xpPoint.getOperationStatus()!=2){ |
| | | throw new ServiceException("该站点已停止运营", I18nKeyConstant.NO_CURRENT_POINT); |
| | | } |
| | | |
| | | // 终点 |
| | | XpPoint endXpPoint = xpPointService.getById(dto.getEndPointId()); |
| | | if(endXpPoint.getOperationStatus()!=2){ |
| | | throw new ServiceException("该站点已停止运营", I18nKeyConstant.NO_CURRENT_POINT); |
| | | } |
| | | |
| | | // 判断点位是否在运营区域内 |
| | | boolean inTime = xpPointClient.nowInTimePoint(dto.getStartPointId()).getData(); |
| | |
| | | routeAndFareDto.setDestination(lonLatDto1); |
| | | |
| | | |
| | | XpOpenCity xpOpenCity = xpOpenCityMapper.selectById(dto.getOpenCityId()); |
| | | Map<String, String> geocode = gdMapGeocodingUtil.geocode(xpPoint.getPointLon().toString(), xpPoint.getPointLat().toString()); |
| | | if(null == geocode){ |
| | | throw new ServiceException("获取城市信息失败", I18nKeyConstant.CITY_NOT_FOUND); |
| | | } |
| | | String cityCode = geocode.get("cityCode"); |
| | | List<XpOpenCity> openCities = xpOpenCityMapper.selectList(new LambdaQueryWrapper<XpOpenCity>().eq(XpOpenCity::getCityCode, cityCode)); |
| | | if (openCities == null || openCities.isEmpty()) { |
| | | throw new ServiceException("获取城市信息失败", I18nKeyConstant.CITY_NOT_FOUND); |
| | | } |
| | | XpOpenCity xpOpenCity = openCities.get(0); |
| | | dto.setOpenCityId(xpOpenCity.getId()); |
| | | XpRoutePlan xpRoutePlan = xpRoutePlanMapper.selectOne(new LambdaQueryWrapper<XpRoutePlan>().eq(XpRoutePlan::getAuditStatus, 2).eq(XpRoutePlan::getCityCode, xpOpenCity.getCityCode())); |
| | | if (xpRoutePlan != null) { |
| | | routeAndFareDto.setRoutePlanRule(xpRoutePlan.getRoutePlanRule()); |
| | |
| | | import com.xiaopeng.api.query.operation.PointListQuery; |
| | | import com.xiaopeng.api.query.operation.PointPageListListQuery; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.common.core.exception.ServiceException; |
| | | import com.xiaopeng.common.core.utils.WebUtils; |
| | | import com.xiaopeng.common.core.web.controller.BaseController; |
| | | import com.xiaopeng.common.core.web.page.PageInfo; |
| | | import com.xiaopeng.api.dto.map.XpPointExportExcelQuery; |
| | | import com.xiaopeng.map.exportExcel.XpPointExportExcel; |
| | | import com.xiaopeng.map.service.XpElectronicFenceAreaService; |
| | | import com.xiaopeng.map.service.XpElectronicFenceService; |
| | | import com.xiaopeng.map.service.XpPointService; |
| | | import cn.afterturn.easypoi.excel.ExcelExportUtil; |
| | | import cn.afterturn.easypoi.excel.entity.ExportParams; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.poi.ss.usermodel.Workbook; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.ServletOutputStream; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.net.URLEncoder; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.function.Function; |
| | | import java.util.stream.Collectors; |
| | | |
| | | |
| | |
| | | @RequestMapping("/api/v1/point") |
| | | @Api(tags = "点位管理") |
| | | public class XpPointManagementController extends BaseController { |
| | | |
| | | private static final DateTimeFormatter EXPORT_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | @Resource |
| | | private XpPointService xpPointService; |
| | |
| | | List<XpPoint> list = xpPointService.lambdaQuery().in(XpPoint::getId, query.getPointIds()).list(); |
| | | return R.ok(list); |
| | | } |
| | | // "2029885249115987970" "2029883649798512642" |
| | | @ApiOperation(value = "点位导出") |
| | | @PostMapping("/exportExcel") |
| | | public void exportExcel(@RequestBody XpPointExportExcelQuery query) { |
| | | List<Long> pointIds = query == null ? Collections.emptyList() : query.getPointIds(); |
| | | List<Long> distinctIds = pointIds == null |
| | | ? Collections.emptyList() |
| | | : pointIds.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList()); |
| | | |
| | | List<XpPoint> points = distinctIds.isEmpty() |
| | | ? Collections.emptyList() |
| | | : xpPointService.lambdaQuery().in(XpPoint::getId, distinctIds).list(); |
| | | Map<Long, XpPoint> pointById = points.stream() |
| | | .filter(p -> p.getId() != null) |
| | | .collect(Collectors.toMap(XpPoint::getId, Function.identity(), (a, b) -> a)); |
| | | |
| | | List<XpPointExportExcel> exportList = new ArrayList<>(points.size()); |
| | | for (Long id : distinctIds) { |
| | | XpPoint xpPoint = pointById.get(id); |
| | | if (xpPoint == null) { |
| | | continue; |
| | | } |
| | | exportList.add(toExportRow(xpPoint)); |
| | | } |
| | | |
| | | HttpServletResponse response = WebUtils.response(); |
| | | if (response == null) { |
| | | throw new ServiceException("导出失败:未获取到响应对象"); |
| | | } |
| | | response.setContentType("application/vnd.ms-excel"); |
| | | response.setCharacterEncoding(StandardCharsets.UTF_8.name()); |
| | | try { |
| | | String fileName = URLEncoder.encode("点位列表.xls", StandardCharsets.UTF_8.name()); |
| | | response.setHeader("Content-disposition", "attachment;filename=" + fileName); |
| | | try (Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), XpPointExportExcel.class, exportList); |
| | | ServletOutputStream outputStream = response.getOutputStream()) { |
| | | workbook.write(outputStream); |
| | | } |
| | | } catch (IOException e) { |
| | | log.error("点位导出失败 pointIds={}", distinctIds, e); |
| | | throw new ServiceException("点位导出失败"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 新增点位 |
| | |
| | | // @ShardingSphereTransactionType(TransactionType.BASE) |
| | | public R edit(@Validated @RequestBody PointUpdateDto pointAddDto) { |
| | | XpPoint xpPoint = xpPointService.getById(pointAddDto.getId()); |
| | | //先删除原有的数据,因为会存在点位的从属区域变化的情况,所以先删除原有的数据后添加新的数据重新分片到新的库中 |
| | | xpPointService.removeById(pointAddDto.getId()); |
| | | if (!xpPoint.getElectronicAreaId().equals(pointAddDto.getElectronicAreaId())) { |
| | | BeanUtils.copyProperties(pointAddDto, xpPoint); |
| | | xpPointService.updateById(xpPoint); |
| | | } else { |
| | | //先删除原有的数据,因为会存在点位的从属区域变化的情况,所以先删除原有的数据后添加新的数据重新分片到新的库中 |
| | | BeanUtils.copyProperties(pointAddDto, xpPoint); |
| | | xpPointService.removeById(pointAddDto.getId()); |
| | | xpPoint.setId(null); |
| | | xpPointService.save(xpPoint); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | |
| | | return R.ok(); |
| | | } |
| | | |
| | | private static XpPointExportExcel toExportRow(XpPoint xpPoint) { |
| | | XpPointExportExcel exportExcel = new XpPointExportExcel(); |
| | | exportExcel.setPointNumber(xpPoint.getPointNumber()); |
| | | exportExcel.setPointName(xpPoint.getPointName()); |
| | | exportExcel.setStatus(calcExportStatus(xpPoint.getOperationStatus(), xpPoint.getVerificationStatus())); |
| | | exportExcel.setParkingTimeLimit(xpPoint.getParkingTimeLimit() == null ? null : String.valueOf(xpPoint.getParkingTimeLimit())); |
| | | exportExcel.setPointLon(xpPoint.getPointLon()); |
| | | exportExcel.setPointLat(xpPoint.getPointLat()); |
| | | exportExcel.setCreateBy(xpPoint.getCreateBy()); |
| | | exportExcel.setCreateTime(formatExportTime(xpPoint.getCreateTime())); |
| | | return exportExcel; |
| | | } |
| | | |
| | | private static String formatExportTime(LocalDateTime time) { |
| | | return time == null ? null : EXPORT_TIME_FORMATTER.format(time); |
| | | } |
| | | |
| | | private static Integer calcExportStatus(Integer operationStatus, Integer verificationStatus) { |
| | | if (operationStatus == null) { |
| | | return null; |
| | | } |
| | | if (verificationStatus == 1) { |
| | | return 1; |
| | | } |
| | | if (verificationStatus == 2) { |
| | | return 2; |
| | | } |
| | | if (verificationStatus == 4) { |
| | | return 3; |
| | | } |
| | | if (verificationStatus == 3 && operationStatus == 1) { |
| | | return 4; |
| | | } |
| | | if (verificationStatus == 5 && operationStatus == 1) { |
| | | return 5; |
| | | } |
| | | if (operationStatus == 2) { |
| | | return 6; |
| | | } |
| | | if (operationStatus == 3) { |
| | | return 7; |
| | | } |
| | | if (operationStatus == 4) { |
| | | return 8; |
| | | } |
| | | if (operationStatus != 1 || verificationStatus == null) { |
| | | return null; |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | } |
| | |
| | | @cn.afterturn.easypoi.excel.annotation.Excel(name = "点位名称",width = 20) |
| | | private String pointName; |
| | | @ApiModelProperty(value = "状态") |
| | | @cn.afterturn.easypoi.excel.annotation.Excel(name = "状态",width = 20,replace = {"待测试_1","测试中_2","测试不通过_3","可运营_4","待生效_5","启用中_6","已停用_7","失效_8",}) |
| | | @cn.afterturn.easypoi.excel.annotation.Excel(name = "状态",width = 20,replace = {"待测试_1","测试中_2","测试不通过_3","可运营_4","待生效_5","启用中_6","已停用_7","已失效_8",}) |
| | | private Integer status; |
| | | @ApiModelProperty(value = "限停时长") |
| | | @cn.afterturn.easypoi.excel.annotation.Excel(name = "限停时长",width = 20) |
| | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | xpElectronicFence.setCityCode(dto.getCityCode()); |
| | | |
| | | this.updateById(xpElectronicFence); |
| | | |
| | | // 禁行区(areaType=2)差异删除:对比原有禁行区与本次编辑入参禁行区(按id) |
| | | List<XpElectronicFenceArea> existingProhibitedAreas = xpElectronicFenceAreaService.lambdaQuery() |
| | | .eq(XpElectronicFenceArea::getElectronicId, dto.getId()) |
| | | .eq(XpElectronicFenceArea::getAreaType, 2) |
| | | .list(); |
| | | Set<Long> incomingProhibitedIds = updatedElectronicFenceAreas.stream() |
| | | .filter(a -> a != null && a.getAreaType() != null && a.getAreaType() == 2 && a.getId() != null) |
| | | .map(XpElectronicFenceArea::getId) |
| | | .collect(Collectors.toSet()); |
| | | List<Long> toDeleteProhibitedIds = existingProhibitedAreas.stream() |
| | | .map(XpElectronicFenceArea::getId) |
| | | .filter(id -> id != null && !incomingProhibitedIds.contains(id)) |
| | | .collect(Collectors.toList()); |
| | | if (!toDeleteProhibitedIds.isEmpty()) { |
| | | // 逻辑删除MySQL禁行区 |
| | | xpElectronicFenceAreaService.removeByIds(toDeleteProhibitedIds); |
| | | // 同步删除Mongo禁行区多边形 |
| | | List<String> toDeleteAreaIdStrings = toDeleteProhibitedIds.stream().map(String::valueOf).collect(Collectors.toList()); |
| | | Query delMongoQuery = new Query(); |
| | | delMongoQuery.addCriteria(Criteria.where("fenceId").is(String.valueOf(dto.getId()))); |
| | | delMongoQuery.addCriteria(Criteria.where("areaId").in(toDeleteAreaIdStrings)); |
| | | mongoTemplate.remove(delMongoQuery, XpGeoFencingProhibitedPolygon.class); |
| | | } |
| | | // 删除旧的区域数据,然后保存新的区域数据 |
| | | mongoTemplate.remove(new Query(Criteria.where("fenceId").is(String.valueOf(dto.getId()))), XpGeoFencingPolygon.class); |
| | | if (xpElectronicFence.getStatus() == 2) { |
| | |
| | | <if test="query.pointType != null"> |
| | | and t1.point_type = #{query.pointType} |
| | | </if> |
| | | <if test="query.operationStatusIds != null and query.operationStatusIds.size()>0"> |
| | | AND t1.operation_status IN |
| | | <foreach collection="query.operationStatusIds" separator="," item="id" open="(" close=")"> |
| | | #{id} |
| | | <if test="query.operationStatusList != null and query.operationStatusList.size() > 0"> |
| | | <trim prefix="and (" suffix=")" prefixOverrides="OR"> |
| | | <foreach collection="query.operationStatusList" item="st"> |
| | | <choose> |
| | | <when test="st == 1">OR t1.verification_status = 1</when> |
| | | <when test="st == 2">OR t1.verification_status = 2</when> |
| | | <when test="st == 3">OR t1.verification_status = 4</when> |
| | | <when test="st == 4">OR (t1.verification_status = 3 and t1.operation_status = 1)</when> |
| | | <when test="st == 5">OR (t1.verification_status = 5 and t1.operation_status = 1)</when> |
| | | <when test="st == 6">OR t1.operation_status = 2</when> |
| | | <when test="st == 7">OR t1.operation_status = 3</when> |
| | | <when test="st == 8">OR t1.operation_status = 4</when> |
| | | <otherwise>OR 1 = 0</otherwise> |
| | | </choose> |
| | | </foreach> |
| | | </trim> |
| | | </if> |
| | | order by t1.create_time desc |
| | | </select> |
| | |
| | | <if test="query.startTime != null and query.startTime != '' and query.endTime != null and query.endTime != ''"> |
| | | and xp.create_time between #{query.startTime} and #{query.endTime} |
| | | </if> |
| | | <if test="query.operationStatus != null"> |
| | | <if test="query.operationStatus ==1"> |
| | | and xp.verification_status = 1 |
| | | </if> |
| | | <if test="query.operationStatus ==2"> |
| | | and xp.verification_status = 2 |
| | | </if> |
| | | <if test="query.operationStatus ==3"> |
| | | and xp.verification_status = 4 |
| | | </if> |
| | | <if test="query.operationStatus ==4"> |
| | | and xp.verification_status = 3 and xp.operation_status =1 |
| | | </if> |
| | | <if test="query.operationStatus ==5"> |
| | | and xp.verification_status = 3 and xp.operation_status =1 |
| | | </if> |
| | | <if test="query.operationStatus ==6"> |
| | | and xp.operation_status =2 |
| | | </if> |
| | | <if test="query.operationStatus ==7"> |
| | | and xp.operation_status =3 |
| | | </if> |
| | | <if test="query.operationStatus ==8"> |
| | | and xp.operation_status =4 |
| | | </if> |
| | | <if test="query.operationStatusList != null and query.operationStatusList.size() > 0"> |
| | | <trim prefix="and (" suffix=")" prefixOverrides="OR"> |
| | | <foreach collection="query.operationStatusList" item="st"> |
| | | <choose> |
| | | <when test="st == 1">OR xp.verification_status = 1</when> |
| | | <when test="st == 2">OR xp.verification_status = 2</when> |
| | | <when test="st == 3">OR xp.verification_status = 4</when> |
| | | <when test="st == 4">OR (xp.verification_status = 3 and xp.operation_status = 1)</when> |
| | | <when test="st == 5">OR (xp.verification_status = 5 and xp.operation_status = 1)</when> |
| | | <when test="st == 6">OR xp.operation_status = 2</when> |
| | | <when test="st == 7">OR xp.operation_status = 3</when> |
| | | <when test="st == 8">OR xp.operation_status = 4</when> |
| | | <otherwise>OR 1 = 0</otherwise> |
| | | </choose> |
| | | </foreach> |
| | | </trim> |
| | | </if> |
| | | order by xp.create_time desc |
| | | </select> |
| | |
| | | |
| | | @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) { |
| | | public R<XpAgreement> getAgreementContent(@ApiParam(name = "type", value = "类型 1=用户服务协议 2=平台隐私政策 3=敏感个人信息处理情况说明 4=向第三方提供个人信息情况的说明 5=乘车须知 6=计费规则说明 7= 法律法规") @PathVariable Integer type) { |
| | | return R.ok(xpAgreementService.getAgreementContent(type)); |
| | | } |
| | | @ApiOperation(value = "保存协议",tags = {"管理后台-内容中心"}) |
| | |
| | | /** |
| | | * 添加定时任务:具体某个时间点执行一次的任务,如:在某个2015-06-01 12:00发送一条消息 |
| | | * |
| | | * @param jobName |
| | | * 具体的任务名+ID标识唯一 |
| | | * @param jobName 具体的任务名+ID标识唯一 |
| | | * @param jobType |
| | | * @param date |
| | | * @param jp |
| | |
| | | |
| | | /** |
| | | * 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名) |
| | | * |
| | | * @param jobName |
| | | * @param time |
| | | */ |
| | |
| | | package com.xiaopeng.operation.service.impl; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xiaopeng.operation.mapper.XpSystemSettingMapper; |
| | | import com.xiaopeng.api.model.operation.XpSystemSetting; |
| | | import com.xiaopeng.operation.service.XpSystemSettingService; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Override |
| | | public void saveSystemSetting(XpSystemSetting xpSystemSetting) { |
| | | saveOrUpdate(xpSystemSetting); |
| | | if (Objects.nonNull(xpSystemSetting.getId())) { |
| | | update(xpSystemSetting, new LambdaQueryWrapper<XpSystemSetting>().eq(XpSystemSetting::getId, xpSystemSetting.getId())); |
| | | } else { |
| | | save(xpSystemSetting); |
| | | } |
| | | } |
| | | } |
| | |
| | | import com.xiaopeng.api.dto.map.RouteAndFareDto; |
| | | import com.xiaopeng.api.dto.operation.LonLatDto; |
| | | import com.xiaopeng.api.dto.operation.VehiclePositionByVinDto; |
| | | import com.xiaopeng.api.dto.pushMessage.SendMessageDTO; |
| | | import com.xiaopeng.api.dto.vehicleConvoy.BaseVehicleUserDto; |
| | | import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient; |
| | | import com.xiaopeng.api.feignClient.map.XpMapClient; |
| | | import com.xiaopeng.api.feignClient.order.XpCruiseOrderClient; |
| | | import com.xiaopeng.api.feignClient.order.XpOrderClient; |
| | | import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.UserVehicleClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; |
| | | import com.xiaopeng.api.model.operation.XpElectronicFence; |
| | | import com.xiaopeng.api.model.operation.XpTradingStrategy; |
| | |
| | | import com.xiaopeng.api.vo.automaticPilot.VehiclePosition; |
| | | import com.xiaopeng.api.vo.operation.RouteVo; |
| | | import com.xiaopeng.api.vo.operation.VehiclePositionVo; |
| | | import com.xiaopeng.api.vo.vehicleConvoy.AddTaxiPassengerVo; |
| | | import com.xiaopeng.common.core.constant.CacheConstants; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.common.redis.service.RedisService; |
| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.redisson.api.RLock; |
| | | import org.redisson.api.RedissonClient; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
| | | import org.springframework.stereotype.Component; |
| | |
| | | // |
| | | @Resource |
| | | private OrderMissionClient orderMissionClient; |
| | | |
| | | @Resource |
| | | private XpPushMessageClient xpPushMessageClient; |
| | | |
| | | @Resource |
| | | private XpElectronicFenceMapper xpElectronicFenceMapper; |
| | |
| | | // 取消订单 |
| | | R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(Long.valueOf(orderId)); |
| | | if (xpOrderR.getCode() == 200) { |
| | | if (xpOrderR.getData().getStatus() == 1) { |
| | | XpOrder xpOrder = xpOrderR.getData(); |
| | | if (xpOrder.getStatus() == 1) { |
| | | log.info("五轮推单结束,无车辆接单,执行取消订单 {}", orderNo); |
| | | xpOrderClient.cancelOrder(orderId); |
| | | //推送订单状态给乘客 |
| | | SendMessageDTO dto = new SendMessageDTO(); |
| | | dto.setAppUserId(xpOrder.getAppUserId().toString()); |
| | | dto.setMessage("{\"type\":\"ORDER_STATUS\",\"content\":\"{\\\"orderId\\\":\\\"" + orderId + "\\\",\\\"status\\\":0}\",\"timestamp\":\"" + System.currentTimeMillis() + "\"}"); |
| | | xpPushMessageClient.sendStatus(dto); |
| | | //将订单从队列中移除 |
| | | log.info("五轮推单结束,无车辆接单,执行队列移除订单 {}", orderNo); |
| | | redisService.popFirstElement(quoteName); |
| | |
| | | */ |
| | | @SneakyThrows |
| | | private void processPushOrder(String quoteName, int count, int sleepTime, String uid, String[] split, String orderNo, XpTradingStrategy xpTradingStrategy, String distance, String duration, String planRule) { |
| | | System.out.println("进入推单环节"); |
| | | log.info("进入推单环节 单号 {}", orderNo); |
| | | if (count == 0) { |
| | | count = 1; |
| | | } |
| | |
| | | |
| | | for (int i = 0; i < count; i++) { |
| | | //等到sleepTime秒钟 |
| | | Thread.sleep(sleepTime); |
| | | System.out.println("进入找车环节"); |
| | | Thread.sleep(sleepTime * 1000); |
| | | log.info("进入找车环节 单号 {}", orderNo); |
| | | // 根据距离找车 |
| | | // 车多则根据配置找具体车数量 根据距离最近 |
| | | // 更改 暂不限制数量 |
| | | |
| | | List<VehiclePosition> positionList = vehiclePositionService.findAvailableVehiclesNearby(Double.parseDouble(split[0]), Double.parseDouble(split[1]), xpTradingStrategy.getOnePushDistance(), xpTradingStrategy.getSimultaneouslyOrderCount()); |
| | | log.info("根据距离找车 距离 {}KM 经度 {} 维度 {} 查找结果 {}", xpTradingStrategy.getOnePushDistance(), split[0], split[1], positionList); |
| | | log.info("根据距离找车 {} 距离 {}KM 经度 {} 维度 {} 查找结果 {} 单号 {}", orderNo, xpTradingStrategy.getOnePushDistance(), split[0], split[1], positionList, orderNo); |
| | | // 获取车辆的区域信息 |
| | | if (positionList.isEmpty()) { |
| | | continue; |
| | |
| | | |
| | | // 获取车辆的信息 筛选出可用车辆 |
| | | R<List<String>> vehiclePositionVos = xpVehicleClient.queryVehiclePositionByVin(new VehiclePositionByVinDto(xpElectronicFence.getId(), vinList, xpTradingStrategy.getSimultaneouslyOrderCount())); |
| | | log.info("筛选可用车辆结果 {}", JSON.toJSONString(vehiclePositionVos)); |
| | | log.info("筛选可用车辆结果 {} 单号 {}", JSON.toJSONString(vehiclePositionVos), orderNo); |
| | | if (vehiclePositionVos.getCode() != 200) { |
| | | continue; |
| | | } |
| | |
| | | |
| | | if (!availableVehiclesNearby.isEmpty()) { |
| | | if (availableVehiclesNearby.size() > 1) { |
| | | log.info("附近有 {} 辆车,进入权重判断流程", availableVehiclesNearby.size()); |
| | | log.info("附近有 {} 辆车,进入权重判断流程 单号 {}", availableVehiclesNearby.size(), orderNo); |
| | | // 走权重 |
| | | |
| | | // 订单价值 |
| | |
| | | |
| | | RLock lock = redissonClient.getLock("FIND_CAR_" + vehiclePositionVo.getVin()); |
| | | lock.lock(10, TimeUnit.SECONDS); |
| | | System.err.println("队列:" + quoteName + " 车辆:" + vehiclePositionVo.getVin() + "订单" + orderNo); |
| | | log.info("队列 {} 车辆 {} 单号 {}", quoteName, vehiclePositionVo.getVin(), orderNo); |
| | | try { |
| | | // VehiclePosition vehiclePosition = vehiclePositionService.findByVehicleId(vehiclePositionVo.getVehicle_id()); |
| | | R<XpVehicle> vehiclePositionR = xpVehicleClient.findByVehicleVin(vehiclePositionVo.getVin()); |
| | |
| | | continue; |
| | | } |
| | | XpVehicle vehiclePosition = vehiclePositionR.getData(); |
| | | log.info("符合条件的车辆 {} ,直接推单XPU", vehiclePosition.getPlateNumber()); |
| | | log.info("当前车辆状态 {}", vehiclePosition.getStatus()); |
| | | log.info("符合条件的车辆 {} ,直接推单XPU。单号 {}", vehiclePosition.getPlateNumber(), orderNo); |
| | | log.info("当前车辆状态 {} 单号 {}", vehiclePosition.getStatus(), orderNo); |
| | | if (vehiclePosition.getStatus() != 1 || vehiclePosition.getState() != 0 || vehiclePosition.getVehicleType()==1) { |
| | | continue; |
| | | } |
| | | // 关闭巡游单子 |
| | | R<String> stringR = xpCruiseOrderClient.updateCruiseOrder(vehiclePosition.getVehicleVin()); |
| | | if(stringR ==null || stringR.getData()==null){ |
| | | log.info("关闭巡游单子失败"); |
| | | log.info("关闭巡游单子失败 车牌号 {}", vehiclePosition.getPlateNumber()); |
| | | continue; |
| | | } |
| | | |
| | |
| | | pushOrderDto.setStage(1); |
| | | // 调用推送服务 orderId + carVin |
| | | // orderMissionClient.pushOrder(pushOrderDto); |
| | | log.info("开始推送 {} 订单到XPU", xpOrder.getOrderNumber()); |
| | | log.info("开始推送 {} 订单到XPU。单号 {}", xpOrder.getOrderNumber(), orderNo); |
| | | |
| | | redisService.popFirstElement(quoteName); |
| | | log.info("将订单 {} 从队列 {} 弹出去", xpOrder.getOrderNumber(), quoteName); |
| | | log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName); |
| | | return; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | |
| | | continue; |
| | | } |
| | | XpVehicle vehicleId1 = vehicleR.getData(); |
| | | log.info("附近只有一个车辆 {} ,直接推单XPU", vehicleId1.getPlateNumber()); |
| | | log.info("当前车辆状态 {} 运营状态 {}", vehicleId1.getOperatingStatus(), vehicleId1.getState()); |
| | | log.info("附近只有一个车辆 {} ,直接推单XPU。单号 {}", vehicleId1.getPlateNumber(), orderNo); |
| | | log.info("当前车辆状态 {} 运营状态 {} 单号 {}", vehicleId1.getOperatingStatus(), vehicleId1.getState(), orderNo); |
| | | if (vehicleId1.getOperatingStatus() != 1 || vehicleId1.getState() != 0 || vehicleId1.getVehicleType()==1) { |
| | | continue; |
| | | } |
| | | // 关闭巡游单子 |
| | | R<String> stringR = xpCruiseOrderClient.updateCruiseOrder(vehicleId1.getVehicleVin()); |
| | | if(stringR ==null || stringR.getData()==null){ |
| | | log.info("关闭巡游单子失败"); |
| | | log.info("关闭巡游单子失败 车牌号 {}", vehicleId1.getPlateNumber()); |
| | | continue; |
| | | } |
| | | |
| | |
| | | pushOrderDto.setStage(1); |
| | | // 调用推送服务 orderId + carVin |
| | | // orderMissionClient.pushOrder(pushOrderDto); |
| | | log.info("开始推送 {} 订单到XPU", xpOrder.getOrderNumber()); |
| | | log.info("开始推送 {} 订单到XPU。单号 {}", xpOrder.getOrderNumber(), orderNo); |
| | | redisService.popFirstElement(quoteName); |
| | | log.info("将订单 {} 从队列 {} 弹出去", xpOrder.getOrderNumber(), quoteName); |
| | | log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName); |
| | | return; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | |
| | | |
| | | import com.xiaopeng.api.model.operation.XpBanner; |
| | | import com.xiaopeng.operation.service.XpBannerService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | | import org.springframework.stereotype.Component; |
| | |
| | | * @author 无关风月 |
| | | * @date 2026/2/26 9:49 |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class BannerTaskUtil { |
| | | |
| | |
| | | @Scheduled(fixedRate = 60000) |
| | | public void taskMinute() { |
| | | try { |
| | | log.info("处理的banner状态定时任务开始执行,当前时间:{}", LocalDateTime.now()); |
| | | // 根据banner开始、结束时间修改banner状态 |
| | | List<XpBanner> banners = bannerService.list(); |
| | | for (XpBanner banner : banners) { |
| | |
| | | pricing.not.exist=定价不存在 |
| | | pricing.json.invalid=价格配置JSON格式不正确 |
| | | pricing.rule.empty=价格规则不能为空 |
| | | no.current.point=????????? |
| | | no.current.point=该站点已停止运营 |
| | | path.not.found=路径不存在 |
| | | has.unpaid.order=有正在进行的订单 |
| | | cruise.plan.name.empty=计划名称不能为空 |
| | |
| | | pricing.not.exist=Pricing does not exist |
| | | pricing.json.invalid=Invalid JSON format for pricing configuration |
| | | pricing.rule.empty=Price rule cannot be empty |
| | | no.current.point=The current location is not open for service |
| | | no.current.point=This site has ceased operations |
| | | path.not.found=Path does not exist |
| | | has.unpaid.order=There are ongoing orders |
| | | cruise.plan.name.exists=The name of the plan already exists |
| | |
| | | pricing.not.exist=定价不存在 |
| | | pricing.json.invalid=价格配置JSON格式不正确 |
| | | pricing.rule.empty=价格规则不能为空 |
| | | no.current.point=????????? |
| | | no.current.point=该站点已停止运营 |
| | | path.not.found=路径不存在 |
| | | has.unpaid.order=有正在进行的订单 |
| | | cruise.plan.name.exists=计划名称已存在 |
| | |
| | | <if test="query.startTime != null and query.startTime != '' and query.endTime != null and query.endTime != ''"> |
| | | and xp.create_time between #{query.startTime} and #{query.endTime} |
| | | </if> |
| | | <if test="query.operationStatus != null"> |
| | | <if test="query.operationStatus ==1"> |
| | | and xp.verification_status = 1 |
| | | </if> |
| | | <if test="query.operationStatus ==2"> |
| | | and xp.verification_status = 2 |
| | | </if> |
| | | <if test="query.operationStatus ==3"> |
| | | and xp.verification_status = 4 |
| | | </if> |
| | | <if test="query.operationStatus ==4"> |
| | | and xp.verification_status = 3 and xp.operation_status =1 |
| | | </if> |
| | | <if test="query.operationStatus ==5"> |
| | | and xp.verification_status = 3 and xp.operation_status =1 |
| | | </if> |
| | | <if test="query.operationStatus ==6"> |
| | | and xp.operation_status =2 |
| | | </if> |
| | | <if test="query.operationStatus ==7"> |
| | | and xp.operation_status =3 |
| | | </if> |
| | | <if test="query.operationStatus ==8"> |
| | | and xp.operation_status =4 |
| | | </if> |
| | | <if test="query.operationStatusList != null and query.operationStatusList.size() > 0"> |
| | | <trim prefix="and (" suffix=")" prefixOverrides="OR"> |
| | | <foreach collection="query.operationStatusList" item="st"> |
| | | <choose> |
| | | <when test="st == 1">OR xp.verification_status = 1</when> |
| | | <when test="st == 2">OR xp.verification_status = 2</when> |
| | | <when test="st == 3">OR xp.verification_status = 4</when> |
| | | <when test="st == 4">OR (xp.verification_status = 3 and xp.operation_status = 1)</when> |
| | | <when test="st == 5">OR (xp.verification_status = 5 and xp.operation_status = 1)</when> |
| | | <when test="st == 6">OR xp.operation_status = 2</when> |
| | | <when test="st == 7">OR xp.operation_status = 3</when> |
| | | <when test="st == 8">OR xp.operation_status = 4</when> |
| | | <otherwise>OR 1 = 0</otherwise> |
| | | </choose> |
| | | </foreach> |
| | | </trim> |
| | | </if> |
| | | order by xp.create_time desc |
| | | </select> |
| | |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.xiaopeng.api.dto.operation.VehiclePositionByVinDto; |
| | | import com.mongodb.client.MongoCollection;import com.xiaopeng.api.dto.operation.VehiclePositionByVinDto; |
| | | import com.xiaopeng.api.dto.vehicleConvoy.UpdateVehicleStateDto; |
| | | import com.xiaopeng.api.dto.vehicleConvoy.VehicleTemperatureDto; |
| | | import com.xiaopeng.api.feignClient.maintenance.XpChargingRecordClient; |
| | |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException; |
| | | import org.apache.poi.ss.usermodel.Workbook; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.bson.Document;import org.springframework.beans.BeanUtils; |
| | | import org.springframework.context.MessageSource; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.context.i18n.LocaleContextHolder; |
| | |
| | | return R.ok(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 删除mongodb中的文档 |
| | | * @param collectionName |
| | | * @return |
| | | */ |
| | | @PostMapping("/base/vi/removeMongodb") |
| | | public R<?> removeMongodb(String collectionName){ |
| | | MongoCollection<Document> collection = mongoTemplate.getCollection(collectionName); |
| | | collection.drop(); |
| | | return R.ok(); |
| | | } |
| | | } |
| | |
| | | if (excludeFleetId != null) { |
| | | wrapper.ne(XpFleetOperations::getFleetId, excludeFleetId); |
| | | } |
| | | wrapper.last("limit 1"); |
| | | XpFleetOperations operations = xpFleetOperationsService.getOne(wrapper); |
| | | if (operations != null) { |
| | | // 查询人员姓名和车队名称 |
| | |
| | | if (excludeFleetId != null) { |
| | | wrapper.ne(XpFleetVehicle::getFleetId, excludeFleetId); |
| | | } |
| | | wrapper.last("limit 1"); |
| | | XpFleetVehicle fleetVehicle = xpFleetVehicleService.getOne(wrapper); |
| | | if (fleetVehicle != null) { |
| | | // 车辆已绑定其他车队,自动解绑 |
| | |
| | | FleetDetailVO vo = new FleetDetailVO(); |
| | | BeanUtils.copyProperties(fleet, vo); |
| | | |
| | | // 3. 统计人员数量 |
| | | long userCount = xpFleetOperationsService.count(new LambdaQueryWrapper<XpFleetOperations>() |
| | | .eq(XpFleetOperations::getFleetId, id)); |
| | | vo.setUserCount((int) userCount); |
| | | // 3. 统计人员数量(过滤已删除人员) |
| | | List<Long> bindUserIds = xpFleetOperationsService.lambdaQuery() |
| | | .eq(XpFleetOperations::getFleetId, id) |
| | | .list() |
| | | .stream() |
| | | .map(XpFleetOperations::getOperationsUserId) |
| | | .filter(Objects::nonNull) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | int userCount = 0; |
| | | if (!CollectionUtils.isEmpty(bindUserIds)) { |
| | | try { |
| | | R<List<XpOperationsUser>> usersResult = xpOperationUserClient.listByIds(bindUserIds); |
| | | if (usersResult != null && usersResult.getData() != null) { |
| | | userCount = usersResult.getData().size(); |
| | | } else { |
| | | userCount = bindUserIds.size(); |
| | | } |
| | | } catch (Exception e) { |
| | | userCount = bindUserIds.size(); |
| | | } |
| | | } |
| | | vo.setUserCount(userCount); |
| | | |
| | | // 4. 统计车辆数量 |
| | | long vehicleCount = xpFleetVehicleService.count(new LambdaQueryWrapper<XpFleetVehicle>() |
| | | .eq(XpFleetVehicle::getFleetId, id)); |
| | | vo.setVehicleCount((int) vehicleCount); |
| | | // 4. 统计车辆数量(过滤已删除车辆) |
| | | List<Long> bindVehicleIds = xpFleetVehicleService.lambdaQuery() |
| | | .eq(XpFleetVehicle::getFleetId, id) |
| | | .list() |
| | | .stream() |
| | | .map(XpFleetVehicle::getVehicleId) |
| | | .filter(Objects::nonNull) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | int vehicleCount = 0; |
| | | if (!CollectionUtils.isEmpty(bindVehicleIds)) { |
| | | try { |
| | | R<List<XpVehicle>> vehiclesResult = xpVehicleClient.listByIds(bindVehicleIds); |
| | | if (vehiclesResult != null && vehiclesResult.getData() != null) { |
| | | vehicleCount = vehiclesResult.getData().size(); |
| | | } else { |
| | | vehicleCount = bindVehicleIds.size(); |
| | | } |
| | | } catch (Exception e) { |
| | | vehicleCount = bindVehicleIds.size(); |
| | | } |
| | | } |
| | | vo.setVehicleCount(vehicleCount); |
| | | |
| | | // 5. 查询负责人信息 |
| | | if (fleet.getOperationsUserId() != null) { |
| | |
| | | wrapper.le(XpVehicleAnnualRecord::getCreateTime, LocalDateTime.of(query.getEndTime(), LocalTime.MAX)); |
| | | } |
| | | wrapper.like(StringUtils.isNotBlank(query.getOperationsUserName()), XpVehicleAnnualRecord::getCreateBy, query.getOperationsUserName()); |
| | | wrapper.eq(XpVehicleAnnualRecord::getVehicleId, query.getVehicleId()); |
| | | wrapper.orderByDesc(XpVehicleAnnualRecord::getCreateTime); |
| | | return this.page(page, wrapper); |
| | | } |