1.发送微信订阅通知 完成40%
2.通过围栏查询 场站
3.围栏详情查询 点位、场站信息 (总数量、启动中、待启动、已停用、已失效)
4.班次 需要增加一个是否跨天
5.修改接口, /map/base/v1/mini-program/cities/list
增加参数 type 1=围栏 2场站 添加场站是否收藏的字段
6.点位情况上报 详情增加上报人的角色
| | |
| | | return R.ok(xpOperationsUserService.listByIds(ids)); |
| | | } |
| | | |
| | | @PostMapping("/logan/inner/xpOperationsUser/findList") |
| | | public R<List<XpOperationsUserWithRoleVO>> findList(@RequestBody XpOperationsUserQueryDTO query) { |
| | | return R.ok(xpOperationsUserService.findList(query)); |
| | | } |
| | | |
| | | /** |
| | | * 根据ID查询运维用户信息 |
| | | * @return 用户列表 |
| | |
| | | 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.dto.account.XpOperationsUserQueryDTO; |
| | | import com.xiaopeng.api.model.account.XpOperationsUser; |
| | | import com.xiaopeng.api.vo.account.ExportOperationsUserVo; |
| | | import com.xiaopeng.api.vo.account.XpOperationsUserVO; |
| | |
| | | */ |
| | | Page<XpOperationsUserWithRoleVO> selectUserPageByConditions(PageInfo<XpOperationsUserWithRoleVO> pageInfo, @Param("query") XpOperationsUserPageQuery query); |
| | | |
| | | List<XpOperationsUserWithRoleVO> selectUserPageByConditions( @Param("query") XpOperationsUserQueryDTO query); |
| | | |
| | | /** |
| | | * 分页查询 |
| | | * @param pageInfo |
| | |
| | | private Integer itemType; |
| | | |
| | | @ApiModelProperty(value = "经度") |
| | | @NotNull(message = "经度不能为空") |
| | | // @NotNull(message = "经度不能为空") |
| | | private Double longitude; |
| | | |
| | | @ApiModelProperty(value = "纬度") |
| | | @NotNull(message = "纬度不能为空") |
| | | // @NotNull(message = "纬度不能为空") |
| | | private Double latitude; |
| | | |
| | | |
| | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 运维人员查询条件DTO |
| | | * |
| | |
| | | |
| | | @ApiModelProperty(value = "角色ID(精确查询)") |
| | | private Long roleId; |
| | | |
| | | @ApiModelProperty(value = "ids") |
| | | private List<Long> ids; |
| | | } |
| | |
| | | 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.dto.account.XpOperationsUserQueryDTO; |
| | | import com.xiaopeng.api.model.account.XpOperationsUser; |
| | | import com.xiaopeng.api.vo.account.XpOperationsUserProfileVO; |
| | | import com.xiaopeng.api.vo.account.XpOperationsUserVO; |
| | |
| | | */ |
| | | List<XpOperationsUser> listByName(String nickName); |
| | | |
| | | /** |
| | | * 根据条件查询用户及角色信息 |
| | | * @param query |
| | | * @return |
| | | */ |
| | | PageInfo<XpOperationsUserWithRoleVO> selectUserPageByConditions(XpOperationsUserPageQuery query); |
| | | |
| | | List<XpOperationsUserWithRoleVO> findList(XpOperationsUserQueryDTO query); |
| | | |
| | | /** |
| | | * 获取运维人员个人中心首页信息 |
| | | * |
| | |
| | | @Override |
| | | public Boolean collectAddr(CollectAddrDTO dto, String uid) { |
| | | Long userId = Long.parseLong(uid); |
| | | if(dto.getItemType() == 1){ |
| | | if(dto.getItemType() == 1){//收藏对象类型 1=站点 2=场站,不传时默认按站点处理 |
| | | if(dto.getLatitude() == null || dto.getLongitude() == null){ |
| | | throw new ServiceException("经度、纬度不能为空"); |
| | | } |
| | | XpPointExportExcelQuery xpPointExportExcelQuery = new XpPointExportExcelQuery(); |
| | | xpPointExportExcelQuery.setPointIds(Arrays.asList(dto.getPointId())); |
| | | List<XpPoint> data = xpPointClient.getByIds(xpPointExportExcelQuery).getData(); |
| | |
| | | import com.xiaopeng.account.model.query.XpOperationsUserQuery; |
| | | import com.xiaopeng.account.service.*; |
| | | import com.xiaopeng.account.util.AliOssDownloadUtil; |
| | | import com.xiaopeng.api.dto.account.XpOperationsUserQueryDTO; |
| | | import com.xiaopeng.api.feignClient.maintenance.XpClockInClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetOperationsClient; |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<XpOperationsUserWithRoleVO> findList(XpOperationsUserQueryDTO query){ |
| | | return baseMapper.selectUserPageByConditions(query); |
| | | } |
| | | |
| | | @Override |
| | | public XpOperationsUserProfileVO getUserProfile(Long userId) { |
| | | // 1. 查询运维人员基础信息 |
| | | XpOperationsUser user = this.getById(userId); |
| | |
| | | <if test="query.roleId != null"> |
| | | AND r.id = #{query.roleId} |
| | | </if> |
| | | <if test="query.ids != null and query.ids.size() > 0"> |
| | | AND u.id IN |
| | | <foreach collection="query.ids" item="id" open="(" separator="," close=")"> |
| | | #{id} |
| | | </foreach> |
| | | </if> |
| | | |
| | | </where> |
| | | GROUP BY u.id |
| | | ORDER BY u.create_time DESC |
| | |
| | | </if> |
| | | order by xou.create_time desc |
| | | </select> |
| | | |
| | | |
| | | <select id="findList" resultType="com.xiaopeng.api.vo.account.XpOperationsUserVO"> |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 运维人员查询条件DTO |
| | | * |
| | |
| | | |
| | | @ApiModelProperty(value = "角色ID(精确查询)") |
| | | private Long roleId; |
| | | |
| | | @ApiModelProperty(value = "ids") |
| | | private List<Long> ids; |
| | | } |
| | |
| | | return new XpOperationUserClient() { |
| | | |
| | | @Override |
| | | public R<List<XpOperationsUserWithRoleVO>> findList(XpOperationsUserQueryDTO query) { |
| | | log.error("根据条件查询运维用户信息失败,原因:{}", cause.getMessage()); |
| | | return R.fail("根据条件查询运维用户信息失败:" + cause.getMessage()); |
| | | } |
| | | |
| | | @Override |
| | | public R<List<XpOperationsUser>> listByIds(Collection<Long> ids) { |
| | | log.error("批量查询运维人员用户信息失败,原因: {}", cause.getMessage()); |
| | | // 降级返回空列表 |
| | |
| | | package com.xiaopeng.api.factory.pushMessage; |
| | | |
| | | import com.xiaopeng.api.feignClient.pushMessage.SubscribeMessageClient; |
| | | import com.xiaopeng.api.vo.pushMessage.SendSubscribeMessageVo; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.cloud.openfeign.FallbackFactory; |
| | |
| | | log.error("获取openid失败: {}", cause.getMessage()); |
| | | return R.fail("获取openid失败"); |
| | | } |
| | | |
| | | @Override |
| | | public R<?> sendSubscribeMessage(SendSubscribeMessageVo vo) { |
| | | log.error("发送订阅消息失败: {}", cause.getMessage()); |
| | | return R.fail("发送订阅消息失败"); |
| | | } |
| | | }; |
| | | } |
| | | } |
| | |
| | | value = ServiceNameConstantsEnum.XP_ACCOUNT_SERVICE, |
| | | fallbackFactory = XpOperationUserClientFallbackFactory.class) |
| | | public interface XpOperationUserClient { |
| | | |
| | | |
| | | @PostMapping("/logan/inner/xpOperationsUser/findList") |
| | | R<List<XpOperationsUserWithRoleVO>> findList(@RequestBody XpOperationsUserQueryDTO query) ; |
| | | /** |
| | | * 根据ID列表批量查询运维用户信息 |
| | | * @param ids 用户ID列表 |
| | |
| | | * @param id |
| | | * @return |
| | | */ |
| | | @GetMapping("/logan/inner/v1/xpStation/getXpStationById") |
| | | @GetMapping("/logan/inner/v1/xpStation/getXpStationById/{id}") |
| | | R<XpStation> getXpStationById(@PathVariable("id") Long id); |
| | | } |
| | |
| | | |
| | | |
| | | import com.xiaopeng.api.factory.pushMessage.SubscribeMessageClientFallbackFactory; |
| | | import com.xiaopeng.api.vo.pushMessage.SendSubscribeMessageVo; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum; |
| | | import org.springframework.cloud.openfeign.FeignClient; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.PathVariable; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | |
| | | @FeignClient(contextId = "SubscribeMessageClient", |
| | | value = ServiceNameConstantsEnum.XP_PUSH_MESSAGE_SERVICE, |
| | |
| | | */ |
| | | @GetMapping("/logan/inner/v1/subscribeMessage/getOpenId/{code}") |
| | | R<String> getOpenId(@PathVariable("code") String code); |
| | | |
| | | |
| | | |
| | | /** |
| | | * 发送订阅消息 |
| | | * @param vo |
| | | * @return |
| | | */ |
| | | @PostMapping("/logan/inner/v1/subscribeMessage/sendSubscribeMessage") |
| | | R<?> sendSubscribeMessage(@RequestBody SendSubscribeMessageVo vo); |
| | | |
| | | } |
| | |
| | | * @since 2026-02-03 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = false) |
| | | //@EqualsAndHashCode(callSuper = false) |
| | | @Accessors(chain = true) |
| | | @TableName("xp_app_user_collect_addr") |
| | | @ApiModel(value = "XpAppUserCollectAddr对象", description = "用户收藏地址") |
| | |
| | | package com.xiaopeng.api.model.account; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.xiaopeng.common.core.web.domain.BaseModel; |
| | |
| | | |
| | | @ApiModelProperty(value = "设备类型 1-Android 2-iOS") |
| | | private Integer deviceType; |
| | | |
| | | |
| | | } |
| | |
| | | @ApiModelProperty(value = "生效周期 1=每日 2=仅工作日 3=仅非工作日 4=仅节假日") |
| | | private Integer effectivePeriod; |
| | | |
| | | @ApiModelProperty(value = "生效时间段") |
| | | /** |
| | | * 数据结构 [{"endTime": "18:00", "startTime": "05:00"}] |
| | | */ |
| | | @ApiModelProperty(value = "生效时间段 json") |
| | | private String effectiveTimePeriod; |
| | | |
| | | @ApiModelProperty(value = "是否同步运营信息到子点位 0=否 1=是") |
| | |
| | | package com.xiaopeng.api.vo.operation; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | |
| | | @ApiModelProperty(value = "区域id") |
| | | private Long electronicAreaId; |
| | | |
| | | @ApiModelProperty(value = "所属场站id,为空表示运营区直属点位") |
| | | private String stationId; |
| | | |
| | | @ApiModelProperty("是否收藏 1是 2否") |
| | | private Integer isCollect=2; |
| | |
| | | @ApiModelProperty(value = "围栏区域id") |
| | | private String areaId; |
| | | |
| | | @ApiModelProperty(value = "所属场站id,为空表示运营区直属点位") |
| | | private String stationId; |
| | | |
| | | @ApiModelProperty(value = "围栏名称") |
| | | private String name; |
| | | |
| | | @ApiModelProperty(value = "1=围栏 2场站") |
| | | private Integer type; |
| | | |
| | | @ApiModelProperty(value = "围栏规则") |
| | | private String rule; |
| | | |
| | | @ApiModelProperty(value = "场站是否收藏") |
| | | private Boolean stationIsCollect; |
| | | |
| | | |
| | | @ApiModelProperty(value = "多边形顶点坐标数组") |
| | | private List<XpPointsVo> points; |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | */ |
| | | @ApiModelProperty(value = "上报运维名称") |
| | | private String operationsUserName; |
| | | @ApiModelProperty(value = "上报运维角色名称") |
| | | private String operationsUserRoleName; |
| | | |
| | | |
| | | /** |
| New file |
| | |
| | | package com.xiaopeng.common.core.enums; |
| | | |
| | | import lombok.Getter; |
| | | |
| | | @Getter |
| | | public enum MessageTemplateEnum { |
| | | // {"character_string1":{"value":"订单编号"},"phrase3":{"value":"订单状态"},"thing5":{"value":"备注"},"time8":{"value":"时间"}} |
| | | A(1,"微信","NOi0ff4rpuTxcRnnZl0SJxg9SMbvrc8xB8VJgrwu3oo","订单状态更新通知", |
| | | "{\"character_string1\":{\"value\":\"订单编号\"},\"phrase3\":{\"value\":\"订单状态\"},\"thing5\":{\"value\":\"备注\"},\"time8\":{\"value\":\"时间\"}}"), |
| | | |
| | | B(1,"微信","S6gGP8jyuDTkW03h8LhOm2KVDdUtHr0OhL-Mt_PyRPU","运营活动通用模板", |
| | | "{\"thing3\":{\"value\":\"活动名称\"},\"time1\":{\"value\":\"开始时间\"},\"time4\":{\"value\":\"结束时间\"},\"thing6\":{\"value\":\"温馨提示\"}}"), |
| | | |
| | | C(1,"微信","ANtToR63JPCV_ujV69gmO15xCa8O3elnLWB52HLdcHM","券效期通用模板", |
| | | "{\"thing1\":{\"value\":\"优惠券名称\"},\"thing2\":{\"value\":\"备注\"}}"), |
| | | |
| | | D(1,"微信","P7z_ksdyzpiiOBO07EJ1AZ6WeHlWs4XveQYjmt9JRE8","券到账通用模板", |
| | | "{\"thing1\":{\"value\":\"优惠券名称\"},\"time2\":{\"value\":\"券有效期\"},\"thing3\":{\"value\":\"使用规则\"}}"), |
| | | |
| | | E(1,"微信","elyV30kO0BZAD2OtihJ4Wdu7fwR3FdvCZYCM1BEbqWs","车辆接单/改派通知", |
| | | "{\"car_number1\":{\"value\":\"车牌号\"},\"time3\":{\"value\":\"报警时间\"}}"), |
| | | |
| | | ; |
| | | |
| | | private final int type; //消息类型 |
| | | private final String typeName; //消息类型 |
| | | private final String templateId;// 模板id |
| | | private final String name;// 消息名称 |
| | | private final String remarks;// 备注 |
| | | |
| | | MessageTemplateEnum(int type,String typeName , String templateId, String name, String remarks) { |
| | | this.type = type; |
| | | this.typeName = typeName; |
| | | this.templateId = templateId; |
| | | this.name = name; |
| | | this.remarks = remarks; |
| | | } |
| | | } |
| | |
| | | return resultType.getDesc(); |
| | | } |
| | | } |
| | | return null; |
| | | return ""; |
| | | } |
| | | } |
| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.validation.Valid; |
| | | import java.util.List; |
| | | |
| | |
| | | @ApiOperation(value = "获取地图开放区域围栏",tags = {"小程序-获取地图开放区域围栏"},response = XpElectronicFenceVo.class) |
| | | @GetMapping("/base/v1/mini-program/cities/list") |
| | | @XpClientCheck(checkToken = false, checkOtpToken = true) |
| | | public R<List<XpElectronicFenceVo>> citiesList(@RequestParam String cityCode) { |
| | | return R.ok(xpElectronicFenceAreaService.citiesList(cityCode)); |
| | | public R<List<XpElectronicFenceVo>> citiesList(@RequestParam String cityCode, HttpServletRequest request) { |
| | | String uid = request.getHeader("XP-Uid"); |
| | | return R.ok(xpElectronicFenceAreaService.citiesList(cityCode,uid)); |
| | | } |
| | | |
| | | /** |
| | |
| | | @ApiOperation(value = "获取地图开放区域围栏",tags = {"运维APP-电子围栏"},response = XpElectronicFenceVo.class) |
| | | @GetMapping("/maintenance-app/api/v1/fence/listByCityCode") |
| | | public R<List<XpElectronicFenceVo>> listByCityCode(@RequestParam String cityCode) { |
| | | return R.ok(xpElectronicFenceAreaService.citiesList(cityCode)); |
| | | return R.ok(xpElectronicFenceAreaService.citiesList(cityCode,null)); |
| | | } |
| | | |
| | | @ApiOperation(value = "判断当前位置是否在运营区域内",tags = {"小程序-判断当前位置是否在运营区域内"}) |
| | |
| | | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.date.DatePattern; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.date.LocalDateTimeUtil; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.xiaopeng.api.dto.operation.ElectronicFenceAddDto; |
| | | import com.xiaopeng.api.dto.operation.ElectronicFenceAreaUpdateStatusDto; |
| | |
| | | import javax.annotation.Resource; |
| | | import javax.validation.Valid; |
| | | import javax.validation.constraints.NotNull; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | |
| | | case 1: |
| | | stationNumbers.setPendingLaunch(stationNumbers.getPendingLaunch() + 1); |
| | | break; |
| | | case 2: |
| | | stationNumbers.setStartingUp(stationNumbers.getStartingUp() + 1); |
| | | case 2: //启动中 判断 待启动的状态 ,当前时间在 运营时间 内是启动中,否则是 待启动 |
| | | |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | |
| | | if(xpStation.getOperationType() ==1){//运营类型 1=与运营区同步 2=自定义时间段 |
| | | LocalDateTime startTime = electronicFence.getEffectTime();//生效时间 |
| | | LocalDateTime endTime = electronicFence.getFailureTime();//失效时间 |
| | | if(electronicFence.getFailureType() ==1) {// 失效类型 1=永不失效 2=定时失效 |
| | | endTime = LocalDateTime.now().plusYears(1); |
| | | } |
| | | if(!now.isBefore(startTime) && !now.isAfter(endTime)){ |
| | | stationNumbers.setStartingUp(stationNumbers.getStartingUp() + 1); |
| | | }else{ |
| | | stationNumbers.setPendingLaunch(stationNumbers.getPendingLaunch() + 1); |
| | | } |
| | | }else { |
| | | //数据结构 [{"endTime": "18:00", "startTime": "05:00"}] |
| | | JSONArray jsonArray = JSONObject.parseArray(xpStation.getEffectiveTimePeriod()); |
| | | |
| | | boolean flag = false; |
| | | for (Object object : jsonArray) { |
| | | JSONObject jsonObject = (JSONObject) object; |
| | | String startTimeStr = jsonObject.getString("startTime"); |
| | | String endTimeStr = jsonObject.getString("endTime"); |
| | | startTimeStr = LocalDate.now() +" "+ startTimeStr+":00"; |
| | | endTimeStr = LocalDate.now() + " " + endTimeStr + ":00"; |
| | | LocalDateTime startTime = LocalDateTimeUtil.parse(startTimeStr, DatePattern.NORM_DATETIME_PATTERN); |
| | | LocalDateTime endTime = LocalDateTimeUtil.parse(endTimeStr, DatePattern.NORM_DATETIME_PATTERN); |
| | | if(!now.isBefore(startTime) && !now.isAfter(endTime)){ |
| | | flag = true; |
| | | }else{ |
| | | stationNumbers.setPendingLaunch(stationNumbers.getPendingLaunch() + 1); |
| | | } |
| | | } |
| | | if (flag){ |
| | | stationNumbers.setStartingUp(stationNumbers.getStartingUp() + 1); |
| | | }else{ |
| | | stationNumbers.setPendingLaunch(stationNumbers.getPendingLaunch() + 1); |
| | | } |
| | | } |
| | | break; |
| | | case 3: |
| | | stationNumbers.setDisabled(stationNumbers.getDisabled() + 1); |
| | |
| | | * @param id |
| | | * @return |
| | | */ |
| | | @GetMapping("/logan/inner/v1/xpStation/getXpStationById") |
| | | @GetMapping("/logan/inner/v1/xpStation/getXpStationById/{id}") |
| | | public R<XpStation> getXpStationById(@PathVariable("id") Long id){ |
| | | XpStation xpStation = xpStationService.getById(id); |
| | | return R.ok(xpStation); |
| | |
| | | return R.fail("参数错误"); |
| | | } |
| | | //场站状态 0=草稿 1=待启用 2=启用中 3=已停用 4=失效 |
| | | if(bean.getStatus() == 2){ |
| | | return R.fail("场站在启动中不能编辑"); |
| | | } |
| | | // if(bean.getStatus() == 2){ |
| | | // return R.fail("场站在启动中不能编辑"); |
| | | // } |
| | | |
| | | LoginUser loginUser = tokenService.getLoginUser(); |
| | | |
| | |
| | | * 获取所有的开放区域 |
| | | * @return |
| | | */ |
| | | List<XpElectronicFenceVo> citiesList(String cityCode); |
| | | List<XpElectronicFenceVo> citiesList(String cityCode,String uid); |
| | | |
| | | |
| | | /** |
| | |
| | | import javax.validation.Valid; |
| | | import java.time.LocalTime; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | |
| | | PageInfo<XpPoint> pageList(PointPageListListQuery query); |
| | | |
| | | Set<Long> getCollectStationIds(String uid); |
| | | |
| | | List<XpPoint> listByStationId(Long stationId); |
| | | |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | |
| | | PageInfo<XpStation> pageList(XpStationQuery query); |
| | | |
| | | boolean isPolygonInPolygon(String innerFencePoints, String outerFencePoints); |
| | | |
| | | void validate(XpStationVo dto); |
| | | |
| | | @Transactional |
| | |
| | | package com.xiaopeng.map.service.serviceimpl; |
| | | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.alibaba.fastjson2.JSONArray; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | |
| | | import com.xiaopeng.map.mapper.XpElectronicFenceAreaMapper; |
| | | import com.xiaopeng.map.mapper.XpElectronicFenceMapper; |
| | | import com.xiaopeng.map.service.XpElectronicFenceAreaService; |
| | | import com.xiaopeng.map.service.XpPointService; |
| | | import com.xiaopeng.map.utils.AmapWalkingRouteUtil; |
| | | import com.xiaopeng.map.utils.ElectricFenceUtil; |
| | | import com.xiaopeng.map.utils.GDMapGeocodingUtil; |
| | |
| | | import com.xiaopeng.map.utils.holiday.HolidayUtil; |
| | | import com.xiaopeng.map.vo.IsInOperationAreaVo; |
| | | import com.xiaopeng.map.vo.WalkTimeVo; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.geo.Point; |
| | | import org.springframework.data.mongodb.core.MongoTemplate; |
| | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.concurrent.ExecutorService; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.stream.Collectors; |
| | |
| | | |
| | | @Resource |
| | | private GDMapGeocodingUtil gdMapGeocodingUtil; |
| | | @Autowired |
| | | private XpPointService xpPointService; |
| | | |
| | | |
| | | |
| | | @Override |
| | | public List<XpElectronicFenceVo> citiesList(String cityCode) { |
| | | public List<XpElectronicFenceVo> citiesList(String cityCode,String uid) { |
| | | List<XpGeoFencingPolygon> xpGeoFencingPolygons = mongoTemplate.find(new Query(Criteria.where("cityCode").is(cityCode)), XpGeoFencingPolygon.class); |
| | | if(xpGeoFencingPolygons.isEmpty()){ |
| | | return new ArrayList<>(); |
| | |
| | | if(xpElectronicFences==null){ |
| | | return new ArrayList<>(); |
| | | } |
| | | Set<Long> collectStationIds = null; |
| | | if(null!= uid){ |
| | | collectStationIds = xpPointService.getCollectStationIds(uid); |
| | | } |
| | | |
| | | for (XpGeoFencingPolygon polygon : xpGeoFencingPolygons) { |
| | | XpElectronicFence xpElectronicFence = xpElectronicFences.getData().stream().filter(e -> e.getId().toString().equals(polygon.getFenceId())).findFirst().orElse(null); |
| | | if(xpElectronicFence==null){ |
| | |
| | | // 设置id(使用siteId作为id) |
| | | vo.setFenceId(polygon.getFenceId()); |
| | | vo.setAreaId(polygon.getAreaId()); |
| | | vo.setStationId(polygon.getStationId()); |
| | | vo.setStationIsCollect(false); |
| | | if(StrUtil.isNotBlank(polygon.getStationId())){ |
| | | if (CollUtil.isNotEmpty(collectStationIds) && collectStationIds.contains(Long.valueOf(polygon.getStationId()) ) ) { |
| | | vo.setStationIsCollect(true); |
| | | } |
| | | } |
| | | // 设置围栏名称 |
| | | vo.setName(polygon.getName()); |
| | | // 转换GeoJsonPolygon为List<XpPointsVo> |
| | |
| | | pointsVoList.add(pointsVo); |
| | | } |
| | | } |
| | | vo.setType(polygon.getStationId() == null ? 1 : 2); |
| | | vo.setPoints(pointsVoList); |
| | | vo.setRule(operationStrategy); |
| | | result.add(vo); |
| | |
| | | * 查询用户收藏的场站ID。 |
| | | * 收藏服务异常时降级为空集合,避免影响场站详情主流程。 |
| | | */ |
| | | private Set<Long> getCollectStationIds(String uid) { |
| | | @Override |
| | | public Set<Long> getCollectStationIds(String uid) { |
| | | if (!StringUtils.hasText(uid)) { |
| | | return Collections.emptySet(); |
| | | } |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 判断一个坐标点位是否在一个坐标区域内 |
| | | * @param longitude 经度 |
| | | * @param latitude 纬度 |
| | | * @param fencePoints 围栏点位字符串,格式为 "lng1_lat1,lng2_lat2,..." |
| | | * @return 是否在区域内 true在 false不在 |
| | | */ |
| | | public boolean isPointInPolygon(double longitude, double latitude, String fencePoints) { |
| | | if (fencePoints == null || fencePoints.trim().isEmpty()) { |
| | | return false; |
| | | } |
| | | |
| | | // 解析围栏点位 |
| | | String[] points = fencePoints.split(","); |
| | | if (points.length < 3) { |
| | | return false; |
| | | } |
| | | |
| | | int n = points.length; |
| | | boolean inside = false; |
| | | |
| | | double x = longitude, y = latitude; |
| | | double[] xs = new double[n]; |
| | | double[] ys = new double[n]; |
| | | |
| | | for (int i = 0; i < n; i++) { |
| | | String[] coords = points[i].split("_"); |
| | | if (coords.length != 2) { |
| | | continue; |
| | | } |
| | | try { |
| | | xs[i] = Double.parseDouble(coords[0]); |
| | | ys[i] = Double.parseDouble(coords[1]); |
| | | } catch (NumberFormatException e) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // 使用射线法判断点是否在多边形内 |
| | | for (int i = 0, j = n - 1; i < n; j = i++) { |
| | | if (((ys[i] > y) != (ys[j] > y)) && |
| | | (x < (xs[j] - xs[i]) * (y - ys[i]) / (ys[j] - ys[i]) + xs[i])) { |
| | | inside = !inside; |
| | | } |
| | | } |
| | | |
| | | return inside; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 判断一个坐标区域(多边形A)是否完全在另一个坐标区域(多边形B)内 |
| | | * 原理:如果多边形A的所有顶点都在多边形B内,则认为A在B内 |
| | | * @param innerFencePoints 内部围栏点位字符串(待判断是否在外的围栏),格式为 "lng1_lat1,lng2_lat2,..." |
| | | * @param outerFencePoints 外部围栏点位字符串(参考围栏),格式为 "lng1_lat1,lng2_lat2,..." |
| | | * @return 是否在内 true在内 false不在 |
| | | */ |
| | | @Override |
| | | public boolean isPolygonInPolygon(String innerFencePoints, String outerFencePoints) { |
| | | if (innerFencePoints == null || innerFencePoints.trim().isEmpty() |
| | | || outerFencePoints == null || outerFencePoints.trim().isEmpty()) { |
| | | return false; |
| | | } |
| | | |
| | | // 解析内部围栏点位 |
| | | String[] innerPoints = innerFencePoints.split(","); |
| | | if (innerPoints.length < 3) { |
| | | return false; |
| | | } |
| | | |
| | | // 检查内部围栏的每一个顶点是否都在外部围栏内 |
| | | for (String pointStr : innerPoints) { |
| | | String[] coords = pointStr.split("_"); |
| | | if (coords.length != 2) { |
| | | continue; |
| | | } |
| | | try { |
| | | double lon = Double.parseDouble(coords[0]); |
| | | double lat = Double.parseDouble(coords[1]); |
| | | |
| | | // 如果有一个顶点不在外部围栏内,则整个区域不在内部 |
| | | if (!isPointInPolygon(lon, lat, outerFencePoints)) { |
| | | return false; |
| | | } |
| | | } catch (NumberFormatException e) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 根据围栏点位字符串计算中心点坐标 |
| | | * @param fencePoints 围栏点位字符串,格式为 "lng1_lat1,lng2_lat2,..." |
| | | * @return double[0] 经度, double[1] 纬度 |
| | | */ |
| | | public double[] calculateCenterPoint(String fencePoints) { |
| | | if (fencePoints == null || fencePoints.trim().isEmpty()) { |
| | | return new double[]{0.0, 0.0}; |
| | | } |
| | | |
| | | String[] points = fencePoints.split(","); |
| | | if (points.length == 0) { |
| | | return new double[]{0.0, 0.0}; |
| | | } |
| | | |
| | | double sumLon = 0.0; |
| | | double sumLat = 0.0; |
| | | int count = 0; |
| | | |
| | | for (String point : points) { |
| | | String[] coords = point.split("_"); |
| | | if (coords.length == 2) { |
| | | try { |
| | | double lon = Double.parseDouble(coords[0]); |
| | | double lat = Double.parseDouble(coords[1]); |
| | | sumLon += lon; |
| | | sumLat += lat; |
| | | count++; |
| | | } catch (NumberFormatException e) { |
| | | // 忽略解析错误的点 |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (count == 0) { |
| | | return new double[]{0.0, 0.0}; |
| | | } |
| | | |
| | | double centerLon = sumLon / count; |
| | | double centerLat = sumLat / count; |
| | | |
| | | return new double[]{centerLon, centerLat}; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public void validate(XpStationVo dto) { |
| | | if (dto.getElectronicAreaId() == null) { |
| | |
| | | XpElectronicFence electronicFence = xpElectronicFenceService.getById(electronicFenceArea.getElectronicId()); |
| | | dto.setCityCode(electronicFence.getCityCode()); |
| | | |
| | | double[] centerPoints = calculateCenterPoint(dto.getFencePoints());//场站中心点位 |
| | | double[] centerPoints = polygonOverlapService.calculateCenterPoint(dto.getFencePoints());//场站中心点位 |
| | | dto.setCenterLon(centerPoints[0]); |
| | | dto.setCenterLat(centerPoints[1]); |
| | | //判断场站是否在 围栏里 |
| | | boolean polygonInPolygon = isPolygonInPolygon( dto.getFencePoints(),electronicFenceArea.getFencePoints()); |
| | | boolean polygonInPolygon = polygonOverlapService.isPolygonInPolygon( dto.getFencePoints(),electronicFenceArea.getFencePoints()); |
| | | if(!polygonInPolygon){ |
| | | throw new ServiceException("场站不在"+electronicFence.getElectronicName()+"围栏内"); |
| | | |
| | |
| | | |
| | | if(!dto.getXpPointList().isEmpty()) { |
| | | for (XpPoint xpPoint : dto.getXpPointList()) { |
| | | if(!isPointInPolygon(xpPoint.getPointLon(),xpPoint.getPointLat(),dto.getFencePoints())){ |
| | | if(!polygonOverlapService.isPointInPolygon(xpPoint.getPointLon(),xpPoint.getPointLat(),dto.getFencePoints())){ |
| | | throw new ServiceException(xpPoint.getPointName()+" 点位不在 "+dto.getStationName()+"场站内"); |
| | | } |
| | | } |
| | |
| | | if(dto.getStatus() == 2){//场站状态 0=草稿 1=待启用 2=启用中 3=已停用 4=失效 |
| | | //运营状态 1=待启用 2=启用中 3=已停用 4=已失效 |
| | | xpPoint.setOperationStatus(2); |
| | | }else if(dto.getStatus() == 3){ |
| | | xpPoint.setOperationStatus(3); |
| | | } |
| | | |
| | | if(xpPoint.getId() == null){ |
| | |
| | | pointsVoList.add(pointsVo); |
| | | } |
| | | } |
| | | vo.setType(polygon.getStationId() == null ? 1 : 2); |
| | | vo.setPoints(pointsVoList); |
| | | vo.setRule(operationStrategy); |
| | | result.add(vo); |
| | |
| | | LinearRing linearRing = geometryFactory.createLinearRing(coordinates); |
| | | return geometryFactory.createPolygon(linearRing); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 判断一个坐标点位是否在一个坐标区域内 |
| | | * @param longitude 经度 |
| | | * @param latitude 纬度 |
| | | * @param fencePoints 围栏点位字符串,格式为 "lng1_lat1,lng2_lat2,..." |
| | | * @return 是否在区域内 true在 false不在 |
| | | */ |
| | | public boolean isPointInPolygon(double longitude, double latitude, String fencePoints) { |
| | | if (fencePoints == null || fencePoints.trim().isEmpty()) { |
| | | return false; |
| | | } |
| | | |
| | | // 解析围栏点位 |
| | | String[] points = fencePoints.split(","); |
| | | if (points.length < 3) { |
| | | return false; |
| | | } |
| | | |
| | | int n = points.length; |
| | | boolean inside = false; |
| | | |
| | | double x = longitude, y = latitude; |
| | | double[] xs = new double[n]; |
| | | double[] ys = new double[n]; |
| | | |
| | | for (int i = 0; i < n; i++) { |
| | | String[] coords = points[i].split("_"); |
| | | if (coords.length != 2) { |
| | | continue; |
| | | } |
| | | try { |
| | | xs[i] = Double.parseDouble(coords[0]); |
| | | ys[i] = Double.parseDouble(coords[1]); |
| | | } catch (NumberFormatException e) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // 使用射线法判断点是否在多边形内 |
| | | for (int i = 0, j = n - 1; i < n; j = i++) { |
| | | if (((ys[i] > y) != (ys[j] > y)) && |
| | | (x < (xs[j] - xs[i]) * (y - ys[i]) / (ys[j] - ys[i]) + xs[i])) { |
| | | inside = !inside; |
| | | } |
| | | } |
| | | |
| | | return inside; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 判断一个坐标区域(多边形A)是否完全在另一个坐标区域(多边形B)内 |
| | | * 原理:如果多边形A的所有顶点都在多边形B内,则认为A在B内 |
| | | * @param innerFencePoints 内部围栏点位字符串(待判断是否在外的围栏),格式为 "lng1_lat1,lng2_lat2,..." |
| | | * @param outerFencePoints 外部围栏点位字符串(参考围栏),格式为 "lng1_lat1,lng2_lat2,..." |
| | | * @return 是否在内 true在内 false不在 |
| | | */ |
| | | |
| | | public boolean isPolygonInPolygon(String innerFencePoints, String outerFencePoints) { |
| | | if (innerFencePoints == null || innerFencePoints.trim().isEmpty() |
| | | || outerFencePoints == null || outerFencePoints.trim().isEmpty()) { |
| | | return false; |
| | | } |
| | | |
| | | // 解析内部围栏点位 |
| | | String[] innerPoints = innerFencePoints.split(","); |
| | | if (innerPoints.length < 3) { |
| | | return false; |
| | | } |
| | | |
| | | // 检查内部围栏的每一个顶点是否都在外部围栏内 |
| | | for (String pointStr : innerPoints) { |
| | | String[] coords = pointStr.split("_"); |
| | | if (coords.length != 2) { |
| | | continue; |
| | | } |
| | | try { |
| | | double lon = Double.parseDouble(coords[0]); |
| | | double lat = Double.parseDouble(coords[1]); |
| | | |
| | | // 如果有一个顶点不在外部围栏内,则整个区域不在内部 |
| | | if (!isPointInPolygon(lon, lat, outerFencePoints)) { |
| | | return false; |
| | | } |
| | | } catch (NumberFormatException e) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 根据围栏点位字符串计算中心点坐标 |
| | | * @param fencePoints 围栏点位字符串,格式为 "lng1_lat1,lng2_lat2,..." |
| | | * @return double[0] 经度, double[1] 纬度 |
| | | */ |
| | | public double[] calculateCenterPoint(String fencePoints) { |
| | | if (fencePoints == null || fencePoints.trim().isEmpty()) { |
| | | return new double[]{0.0, 0.0}; |
| | | } |
| | | |
| | | String[] points = fencePoints.split(","); |
| | | if (points.length == 0) { |
| | | return new double[]{0.0, 0.0}; |
| | | } |
| | | |
| | | double sumLon = 0.0; |
| | | double sumLat = 0.0; |
| | | int count = 0; |
| | | |
| | | for (String point : points) { |
| | | String[] coords = point.split("_"); |
| | | if (coords.length == 2) { |
| | | try { |
| | | double lon = Double.parseDouble(coords[0]); |
| | | double lat = Double.parseDouble(coords[1]); |
| | | sumLon += lon; |
| | | sumLat += lat; |
| | | count++; |
| | | } catch (NumberFormatException e) { |
| | | // 忽略解析错误的点 |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (count == 0) { |
| | | return new double[]{0.0, 0.0}; |
| | | } |
| | | |
| | | double centerLon = sumLon / count; |
| | | double centerLat = sumLat / count; |
| | | |
| | | return new double[]{centerLon, centerLat}; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | @Resource |
| | | private AliOssService aliOssService; |
| | | |
| | | |
| | | /** |
| | | * 如果站点是挂在场站下的 需要返回一个场站id stationId |
| | | * @param dto |
| | | * @param uid |
| | | * @return |
| | | */ |
| | | @Override |
| | | public NearestVo nearest(NearestDto dto,String uid) { |
| | | // 走缓存 |
| | |
| | | nearestNextVo.setAddress(xpPoint.getPointAddress()); |
| | | nearestNextVo.setTime(xpPoint.getParkingTimeLimit()); |
| | | nearestNextVo.setElectronicAreaId(xpPoint.getElectronicAreaId()); |
| | | nearestNextVo.setStationId(xpPoint.getStationId().toString()); |
| | | |
| | | // 判断是否收藏 |
| | | if(pointIdsByUserId!=null && !pointIdsByUserId.getData().isEmpty()){ |
| | |
| | | continue; |
| | | } |
| | | String downloadUrl = jsonObject.getString("url");; |
| | | try { |
| | | downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true); |
| | | } catch (UnsupportedEncodingException e) { |
| | | log.error("获取图片下载地址失败", e); |
| | | } |
| | | // try { |
| | | // downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true); |
| | | // } catch (UnsupportedEncodingException e) { |
| | | // log.error("获取图片下载地址失败", e); |
| | | // } |
| | | jsonObject.put("url", downloadUrl); |
| | | } |
| | | xpPoint.setPointPictures(JSONArray.toJSONString(jsonArray)); |
| | |
| | | package com.xiaopeng.order.service; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.xiaopeng.api.feignClient.operation.XpPricingClient; |
| | | import com.xiaopeng.api.feignClient.pushMessage.SubscribeMessageClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; |
| | | import com.xiaopeng.api.model.operation.XpPricing; |
| | | import com.xiaopeng.api.model.order.XpOrder; |
| | | import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; |
| | | import com.xiaopeng.api.vo.pushMessage.SendSubscribeMessageVo; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.common.core.enums.MessageTemplateEnum; |
| | | import com.xiaopeng.common.core.enums.OrderStatusEnum; |
| | | import com.xiaopeng.common.core.exception.ServiceException; |
| | | import com.xiaopeng.common.redis.service.RedisService; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.time.LocalDateTime; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | @Service |
| | | public class BootCommonService { |
| | |
| | | @Resource |
| | | @Lazy |
| | | private IXpOrderService xpOrderService; |
| | | // @Override |
| | | @Resource |
| | | private RedisService redisService; |
| | | @Resource |
| | | private SubscribeMessageClient subscribeMessageClient; |
| | | |
| | | |
| | | public XpOrder getXpOrder(Long orderId) { |
| | | |
| | | XpOrder xpOrder = xpOrderService.getById(orderId); |
| | |
| | | } |
| | | return xpOrder; |
| | | } |
| | | // @Override |
| | | public XpVehicle getXpVehicle(Long vehicleId) { |
| | | |
| | | R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(vehicleId); |
| | |
| | | } |
| | | return xpVehicleR.getData(); |
| | | } |
| | | // @Override |
| | | public String getVehicleModelId(Long orderId) { |
| | | if(orderId!= null){ |
| | | XpOrder xpOrder = getXpOrder(orderId); |
| | |
| | | return null; |
| | | } |
| | | |
| | | // @Override |
| | | public XpPricing getPricingByCid(Long cityId, String vehicleModelId) { |
| | | R<XpPricing> xpPricingR = xpPricingClient.getPricingByCid(cityId,vehicleModelId); |
| | | if (xpPricingR.getCode() != R.SUCCESS || xpPricingR.getData() == null) { |
| | |
| | | } |
| | | return xpPricingR.getData(); |
| | | } |
| | | |
| | | // @Override |
| | | public XpPricing getXpPricing(Long orderId) { |
| | | if(orderId != null){ |
| | | XpOrder xpOrder = getXpOrder(orderId); |
| | |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | // @Override |
| | | public XpPricing getXpPricing(Long cityId, Long vehicleId) { |
| | | String vehicleModelId = null; |
| | | if(vehicleId != null){ |
| | |
| | | } |
| | | return getPricingByCid(cityId, vehicleModelId); |
| | | } |
| | | |
| | | // @Override |
| | | public XpPricing getXpPricing(Long cityId, Long orderId, Long vehicleId) { |
| | | String vehicleModelId = null; |
| | | if(vehicleId != null ){ |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 设置缓存订单状态 |
| | | * 并发送微信通知 |
| | | * @param xpOrderId 订单id |
| | | * @param order OrderStatusEnum 订单状态 |
| | | * oldStatus 订单旧状态 |
| | | */ |
| | | public void setCache_orderStatus(Long xpOrderId, XpOrder order ,OrderStatusEnum status) { |
| | | if(order == null){ |
| | | order = xpOrderService.getById(xpOrderId); |
| | | } |
| | | redisService.setCacheObject("ORDER_STATUS:" + xpOrderId, status.getCode(), 24L, TimeUnit.HOURS); |
| | | |
| | | SendSubscribeMessageVo vo = new SendSubscribeMessageVo(); |
| | | vo.setUserId(order.getAppUserId()); |
| | | String json = null; |
| | | if(order.getStatus() == OrderStatusEnum.PENDING_ORDER.getCode()){ |
| | | String plateNumber = null; |
| | | // 查询车辆 |
| | | XpVehicle xpVehicle = xpVehicleClient.queryById(order.getVehicleId()).getData(); |
| | | if(xpVehicle != null){ |
| | | plateNumber = xpVehicle.getPlateNumber(); |
| | | } |
| | | if(StrUtil.isNotBlank(plateNumber)){ |
| | | vo.setTemplateId(MessageTemplateEnum.E.getTemplateId()); |
| | | json = MessageTemplateEnum.E.getRemarks(); |
| | | json = json.replace("车牌号", plateNumber); |
| | | json = json.replace("报警时间", LocalDateTime.now().toString()); |
| | | } |
| | | }else{ |
| | | |
| | | vo.setTemplateId(MessageTemplateEnum.A.getTemplateId()); |
| | | json = MessageTemplateEnum.A.getRemarks(); |
| | | json = json.replace("订单编号", order.getOrderNumber()); |
| | | json = json.replace("订单状态", status.getDesc() ); |
| | | json = json.replace("订单状态", OrderStatusEnum.getDescByCode(order.getStatus())); |
| | | json = json.replace("备注", ""); |
| | | json = json.replace("时间", LocalDateTime.now().toString()); |
| | | vo.setPage(""); |
| | | } |
| | | if(StrUtil.isNotBlank(json)){ |
| | | vo.setJson(json); |
| | | subscribeMessageClient.sendSubscribeMessage(vo); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | order.setAppUserId(null); |
| | | baseMapper.updateById(order); |
| | | order.setAppUserId(appUserId); |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS); |
| | | bootCommonService.setCache_orderStatus(order.getId(),order,null); |
| | | //删除蓝牙秘钥 |
| | | String token = redisService.getCacheObject("rt:bluetooth:unlock:order:" + order.getId()); |
| | | if(StringUtils.isNotBlank(token)){ |
| | |
| | | // 1. 更新订单状态为已取消(0) |
| | | lambdaUpdate().set(XpOrder::getStatus, 0) |
| | | .eq(XpOrder::getId, order.getId()).update(); |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS); |
| | | order.setStatus(OrderStatusEnum.CANCELED.getCode()); |
| | | |
| | | bootCommonService.setCache_orderStatus(order.getId(),order,null); |
| | | |
| | | // 2. 保存取消记录 |
| | | XpOrderCancel orderCancel = new XpOrderCancel(); |
| | |
| | | Long appUserId = order.getAppUserId(); |
| | | order.setAppUserId(null); |
| | | this.updateById(order); |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 7, 24L, TimeUnit.HOURS); |
| | | |
| | | bootCommonService.setCache_orderStatus(order.getId(),order,null); |
| | | |
| | | // 消息推送 |
| | | Map<String, Object> params1 = new HashMap<>(); |
| | |
| | | order.setAppUserId(null); |
| | | baseMapper.updateById(order); |
| | | order.setAppUserId(appUserId); |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS); |
| | | bootCommonService.setCache_orderStatus(order.getId(),order,null); |
| | | //删除蓝牙秘钥 |
| | | String token = redisService.getCacheObject("rt:bluetooth:unlock:order:" + order.getId()); |
| | | if(StringUtils.isNotBlank(token)){ |
| | |
| | | order.setAppUserId(null); |
| | | baseMapper.updateById(order); |
| | | order.setAppUserId(appUserId); |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS); |
| | | bootCommonService.setCache_orderStatus(order.getId(),order,null); |
| | | //删除蓝牙秘钥 |
| | | String token = redisService.getCacheObject("rt:bluetooth:unlock:order:" + order.getId()); |
| | | if(StringUtils.isNotBlank(token)){ |
| | |
| | | xpOrder.setAppUserId(null); |
| | | xpOrder.setStatus(10); |
| | | baseMapper.updateById(xpOrder); |
| | | redisService.setCacheObject("ORDER_STATUS:" + xpOrder.getId(), 10, 24L, TimeUnit.HOURS); |
| | | bootCommonService.setCache_orderStatus(xpOrder.getId(),xpOrder,null); |
| | | |
| | | XpOrderEvaluate evaluate = new XpOrderEvaluate(); |
| | | evaluate.setOrderId(xpOrder.getId()); |
| | |
| | | xpOrder.setStatus(status); |
| | | xpOrder.setAppUserId(null); |
| | | this.updateById(xpOrder); |
| | | redisService.setCacheObject("ORDER_STATUS:" + xpOrder.getId(), status, 24L, TimeUnit.HOURS); |
| | | bootCommonService.setCache_orderStatus(xpOrder.getId(),xpOrder,null); |
| | | return R.ok(); |
| | | } |
| | | |
| | |
| | | xpOrder1.setStatus(OrderStatusEnum.PENDING_PAYMENT.getCode()); |
| | | xpOrder1.setUpdateTime(LocalDateTime.now()); |
| | | baseMapper.updateById(xpOrder1); |
| | | redisService.setCacheObject("ORDER_STATUS:" + id, xpOrder1.getStatus(), 24L, TimeUnit.HOURS); |
| | | bootCommonService.setCache_orderStatus(xpOrder1.getId(),xpOrder1,null); |
| | | |
| | | } |
| | | |
| | |
| | | order.setTripEnd(LocalDateTime.now()); |
| | | baseMapper.updateById(order); |
| | | order.setAppUserId(appUserId); |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 8, 24L, TimeUnit.HOURS); |
| | | bootCommonService.setCache_orderStatus(order.getId(),order,null); |
| | | //删除蓝牙秘钥 |
| | | String token = redisService.getCacheObject("rt:bluetooth:unlock:order:" + orderId); |
| | | if(StringUtils.isNotBlank(token)){ |
| | |
| | | } |
| | | } |
| | | baseMapper.updateById(order); |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 9, 24L, TimeUnit.HOURS); |
| | | bootCommonService.setCache_orderStatus(order.getId(),order,null); |
| | | return R.ok(); |
| | | } |
| | | |
| | |
| | | order.setAcceptanceTime(LocalDateTime.now()); |
| | | R<XpVehicle> byVehicleVin = xpVehicleClient.findByVehicleVin(dto.getXpVehicleVin()); |
| | | XpVehicle vehicle = null; |
| | | String plateNumber = null; |
| | | if (byVehicleVin.getCode() == 200) { |
| | | vehicle = byVehicleVin.getData(); |
| | | order.setVehicleId(vehicle.getId()); |
| | | order.setFleetId(vehicle.getFleetId()); |
| | | plateNumber = vehicle.getPlateNumber(); |
| | | addTaxiPassengerVo.setVin(vehicle.getVehicleVin()); |
| | | } |
| | | order.setStatus(2); |
| | |
| | | addTaxiPassengerVo.setUid(appUserId.toString()); |
| | | order.setAppUserId(null); |
| | | this.updateById(order); |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 2, 24L, TimeUnit.HOURS); |
| | | bootCommonService.setCache_orderStatus(order.getId(),order,null); |
| | | |
| | | //构建推送消息 |
| | | Map<String, Object> params = new HashMap<>(); |
| | |
| | | } |
| | | }); |
| | | } |
| | | |
| | | |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 2, 24L, TimeUnit.HOURS); |
| | | // redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 2, 24L, TimeUnit.HOURS);//没看懂为啥重复 缓存 |
| | | addTaxiPassengerVo.setOrderNo(order.getOrderNumber()); |
| | | addTaxiPassengerVo.setAppId(appid); |
| | | userVehicleClient.addTaxiPassenger(addTaxiPassengerVo); |
| | |
| | | import com.xiaopeng.api.model.order.XpOrder; |
| | | import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; |
| | | import com.xiaopeng.api.vo.vehicleConvoy.BluetoothDeliverVo; |
| | | import com.xiaopeng.common.core.enums.OrderStatusEnum; |
| | | import com.xiaopeng.common.core.utils.StringUtils; |
| | | import com.xiaopeng.common.redis.service.RedisService; |
| | | import com.xiaopeng.order.service.BootCommonService; |
| | | import com.xiaopeng.order.service.IXpOrderService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | |
| | | |
| | | @Resource |
| | | private BluetoothUnlockClient bluetoothUnlockClient; |
| | | @Resource |
| | | private BootCommonService bootCommonService; |
| | | |
| | | /** |
| | | * 30秒执行一次 |
| | |
| | | order.setAppUserId(null); |
| | | order.setStatus(0); |
| | | xpOrderService.updateById(order); |
| | | |
| | | order.setAppUserId(appUserId); |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS); |
| | | bootCommonService.setCache_orderStatus(order.getId(), order, null); |
| | | //删除蓝牙秘钥 |
| | | String token = redisService.getCacheObject("rt:bluetooth:unlock:order:" + order.getId()); |
| | | if(StringUtils.isNotBlank(token)){ |