This commit is contained in:
shuhongfan
2023-09-04 16:40:17 +08:00
commit cf5ac25c14
8267 changed files with 1305066 additions and 0 deletions

3
sl-express-ms-oms-service/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
.idea
target/
*.iml

View File

@@ -0,0 +1,13 @@
FROM openjdk:11-jdk
LABEL maintainer="研究院研发组 <research@itcast.cn>"
# 时区修改为东八区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
WORKDIR /app
ARG JAR_FILE=target/*.jar
ADD ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["sh","-c","java -Djava.security.egd=file:/dev/./urandom -jar $JAVA_OPTS app.jar"]

View File

@@ -0,0 +1,14 @@
# sl-express-oms使用手册
## 1、说明
oms服务作为订单服务主要包括订单信息订单状态热门货物最近寄递订单货物订单位置等。
主要功能:
- 提供下单、取消订单,订单相关数据查询,订单状态修改功能。
- 提供热门货物,最近货物功能。
- 提供订单位置存储功能。
## 2、流程图

View File

@@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sl-express</groupId>
<artifactId>sl-express-parent</artifactId>
<version>1.4</version>
</parent>
<groupId>com.sl-express.ms.oms</groupId>
<artifactId>sl-express-ms-oms-service</artifactId>
<version>1.1-SNAPSHOT</version>
<description>订单微服务</description>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<sl-express-common.version>1.2-SNAPSHOT</sl-express-common.version>
<sl-express-mq.version>1.1-SNAPSHOT</sl-express-mq.version>
<sl-express-ms-user-api.version>1.1-SNAPSHOT</sl-express-ms-user-api.version>
<sl-express-ms-carriage-api.version>1.1-SNAPSHOT</sl-express-ms-carriage-api.version>
<sl-express-ms-transport-api.version>1.1-SNAPSHOT</sl-express-ms-transport-api.version>
<sl-express-ms-trade-api.version>1.1-SNAPSHOT</sl-express-ms-trade-api.version>
<sl-express-ms-work-api.version>1.1-SNAPSHOT</sl-express-ms-work-api.version>
</properties>
<dependencies>
<dependency>
<groupId>com.sl-express.common</groupId>
<artifactId>sl-express-common</artifactId>
<version>${sl-express-common.version}</version>
</dependency>
<dependency>
<groupId>com.sl-express.ms.oms</groupId>
<artifactId>sl-express-ms-oms-domain</artifactId>
<version>1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.sl-express.ms.user</groupId>
<artifactId>sl-express-ms-user-api</artifactId>
<version>${sl-express-ms-user-api.version}</version>
</dependency>
<dependency>
<groupId>com.sl-express.ms.base</groupId>
<artifactId>sl-express-ms-base-api</artifactId>
<version>1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.sl-express.ms.service-scope</groupId>
<artifactId>sl-express-ms-service-scope-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.sl-express.ms.carriage</groupId>
<artifactId>sl-express-ms-carriage-api</artifactId>
<version>${sl-express-ms-carriage-api.version}</version>
</dependency>
<dependency>
<groupId>com.sl-express.ms.trade</groupId>
<artifactId>sl-express-ms-trade-api</artifactId>
<version>${sl-express-ms-trade-api.version}</version>
</dependency>
<dependency>
<groupId>com.sl-express.ms.transport</groupId>
<artifactId>sl-express-ms-transport-api</artifactId>
<version>${sl-express-ms-transport-api.version}</version>
</dependency>
<dependency>
<groupId>com.sl-express.ms.work</groupId>
<artifactId>sl-express-ms-work-api</artifactId>
<version>${sl-express-ms-work-api.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.sl-express.mq</groupId>
<artifactId>sl-express-mq</artifactId>
<version>${sl-express-mq.version}</version>
</dependency>
<dependency>
<groupId>com.itheima.em</groupId>
<artifactId>eaglemap-spring-boot-starter</artifactId>
<version>${eaglemap.version}</version>
</dependency>
<!--seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
<goal>build-info</goal>
</goals>
</execution>
</executions>
<configuration>
<!--指定主类-->
<mainClass>com.sl.OmsApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,17 @@
package com.sl;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.retry.annotation.EnableRetry;
@EnableRetry
@EnableFeignClients
@SpringBootApplication
public class OmsApplication {
public static void main(String[] args) {
SpringApplication.run(OmsApplication.class, args);
}
}

View File

@@ -0,0 +1,129 @@
package com.sl.ms.oms.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sl.ms.oms.dto.OrderCargoDTO;
import com.sl.ms.oms.entity.OrderCargoEntity;
import com.sl.ms.oms.service.OrderCargoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
/**
* 货品
*/
@RestController
@RequestMapping("cargo")
@Slf4j
public class CargoController {
@Resource
private OrderCargoService orderCargoService;
/**
* 获取货物列表
*
* @param tranOrderId 运单id
* @param orderId 订单id
* @return 货物列表
*/
@GetMapping
public List<OrderCargoDTO> findAll(@RequestParam(name = "tranOrderId", required = false) Long tranOrderId,
@RequestParam(name = "orderId", required = false) Long orderId) {
log.info("oms --- 查询货物列表");
return orderCargoService.findAll(tranOrderId, orderId).stream().map(orderCargo -> {
return BeanUtil.toBean(orderCargo, OrderCargoDTO.class);
}).collect(Collectors.toList());
}
@GetMapping("/list")
public List<OrderCargoDTO> list(@RequestParam(name = "orderIds", required = false) List<String> orderIds) {
LambdaQueryWrapper<OrderCargoEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.in(CollUtil.isNotEmpty(orderIds), OrderCargoEntity::getOrderId, orderIds);
return orderCargoService.list(wrapper).stream()
.map(orderCargo -> BeanUtil.toBean(orderCargo, OrderCargoDTO.class))
.collect(Collectors.toList());
}
/**
* 添加货物
*
* @param dto 货物信息
* @return 货物信息
*/
@PostMapping
public OrderCargoDTO save(@RequestBody OrderCargoDTO dto) {
log.info("保存货物信息:{}", dto);
OrderCargoEntity orderCargo = BeanUtil.toBean(dto, OrderCargoEntity.class);
orderCargoService.saveOrUpdate(orderCargo);
log.info("货物信息入库:{}", dto);
return BeanUtil.toBean(orderCargo, OrderCargoDTO.class);
}
/**
* 更新货物信息
*
* @param id 货物id
* @param dto 货物信息
* @return 货物信息
*/
@PutMapping("/{id}")
public OrderCargoDTO update(@PathVariable(name = "id") Long id, @RequestBody OrderCargoDTO dto) {
dto.setId(id);
OrderCargoEntity orderCargo = BeanUtil.toBean(dto, OrderCargoEntity.class);
orderCargoService.updateById(orderCargo);
return dto;
}
/**
* 删除货物信息
*
* @param id 货物id
* @return 返回信息
*/
@DeleteMapping("/{id}")
public boolean del(@PathVariable(name = "id") Long id) {
return orderCargoService.removeById(id);
}
/**
* 根据id获取货物详情
*
* @param id 货物id
* @return 货物详情
*/
@GetMapping("/{id}")
public OrderCargoDTO findById(@PathVariable(name = "id") Long id) {
OrderCargoEntity orderCargo = orderCargoService.getById(id);
return BeanUtil.toBean(orderCargo, OrderCargoDTO.class);
}
/**
* 根据订单id获取货物详情
*
* @param id 订单id
* @return 货物详情
*/
@GetMapping("/findByOrderId/{id}")
public OrderCargoDTO findByOrderId(@PathVariable(name = "id") Long id) {
return orderCargoService.findByOrderId(id);
}
/**
* 批量查询货物信息表
*
* @param name 热门货品名称
* @return 货物信息表
*/
@GetMapping("/hot")
List<OrderCargoDTO> list(@RequestParam(name = "name", required = false) String name, Long memberId) {
return orderCargoService.listRecent(name, memberId);
}
}

View File

@@ -0,0 +1,50 @@
package com.sl.ms.oms.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sl.ms.oms.dto.OrderCargoDTO;
import com.sl.ms.oms.entity.HotGoodEntity;
import com.sl.ms.oms.service.HotGoodService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
/**
* 热门货物
*/
@RestController
@RequestMapping("/good")
@Slf4j
public class HotGoodController {
@Resource
private HotGoodService hotGoodService;
/**
* 批量查询货物信息表
*
* @param name 热门货品名称
* @return 货品信息
*/
@GetMapping("/hot")
List<OrderCargoDTO> list(@RequestParam(name = "name", required = false) String name) {
return hotGoodService.list(Wrappers.<HotGoodEntity>lambdaQuery()
.like(ObjectUtil.isNotEmpty(name), HotGoodEntity::getName, name)
// 没有名称查询条件 则按照类型分组返回
.groupBy(ObjectUtil.isEmpty(name), HotGoodEntity::getGoodsTypeId)
.last("limit 20")
)
.stream()
.map(hotGoodEntity -> BeanUtil.toBean(hotGoodEntity, OrderCargoDTO.class))
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,241 @@
package com.sl.ms.oms.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sl.ms.oms.dto.*;
import com.sl.ms.oms.entity.OrderEntity;
import com.sl.ms.oms.entity.OrderLocationEntity;
import com.sl.ms.oms.service.CrudOrderService;
import com.sl.ms.oms.service.OrderCargoService;
import com.sl.ms.oms.service.OrderLocationService;
import com.sl.ms.oms.service.OrderService;
import com.sl.transport.common.util.PageResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 订单 前端控制器
*/
@Slf4j
@Api(tags = "订单管理")
@RestController
@RequestMapping("order")
public class OrderController {
@Resource
private OrderService orderService;
@Resource
private OrderLocationService orderLocationService;
@Resource
private CrudOrderService crudOrderService;
@Resource
private OrderCargoService orderCargoService;
/**
* 下单
*
* @param mailingSaveDTO 订单信息
* @return 订单信息
*/
@ApiOperation(value = "下单")
@PostMapping
public OrderDTO mailingSave(@RequestBody MailingSaveDTO mailingSaveDTO) throws Exception {
log.info("保存订单信息:{}", JSONUtil.toJsonStr(mailingSaveDTO));
return orderService.mailingSave(mailingSaveDTO);
}
/**
* 预估总价
*
* @param mailingSaveDTO 订单信息
* @return 预估信息
*/
@ApiOperation("预估总价")
@PostMapping("totalPrice")
public OrderCarriageDTO totalPrice(@RequestBody MailingSaveDTO mailingSaveDTO) {
return orderService.totalPrice(mailingSaveDTO);
}
@GetMapping("count")
@ApiOperation(value = "统计", notes = "统计各个状态的数量")
public List<OrderStatusCountDTO> count(@RequestParam("memberId") Long memberId) {
return crudOrderService.groupByStatus(memberId);
}
/**
* 修改订单信息
*
* @param id 订单id
* @param orderDTO 订单信息
* @return 订单信息
*/
@PutMapping("/{id}")
public OrderDTO updateById(@PathVariable(name = "id") Long id, @RequestBody OrderDTO orderDTO) {
orderDTO.setId(id);
OrderEntity order = BeanUtil.toBean(orderDTO, OrderEntity.class);
orderService.updateById(order);
return orderDTO;
}
/**
* 获取订单分页数据
*
* @param orderDTO 查询条件
* @return 订单分页数据
*/
@PostMapping("/page")
public PageResponse<OrderDTO> findByPage(@RequestBody OrderDTO orderDTO) {
IPage<OrderEntity> orderIPage = crudOrderService.findByPage(orderDTO.getPage(), orderDTO.getPageSize(), orderDTO);
List<OrderDTO> dtoList = new ArrayList<>();
orderIPage.getRecords().forEach(order -> dtoList.add(BeanUtil.toBean(order, OrderDTO.class)));
return PageResponse.<OrderDTO>builder()
.items(dtoList)
.pageSize(orderDTO.getPageSize())
.page(orderDTO.getPage())
.counts(orderIPage.getTotal())
.pages(orderIPage.getPages()).build();
}
/**
* 根据id获取订单详情
*
* @param id 订单Id
* @return 订单详情
*/
@GetMapping("/{id}")
public OrderDTO findById(@PathVariable(name = "id") Long id) {
OrderEntity orderEntity = orderService.getById(id);
if (ObjectUtil.isNotEmpty(orderEntity)) {
return BeanUtil.toBean(orderEntity, OrderDTO.class);
}
return null;
}
/**
* 根据id获取订单详情
*
* @param id 订单Id
* @return 订单详情
*/
@GetMapping("detail/{id}")
public OrderDetailDTO findDetailByOrderId(@PathVariable(name = "id") Long id) {
OrderDetailDTO orderDetailDTO = new OrderDetailDTO();
OrderEntity orderEntity = orderService.getById(id);
if (ObjectUtil.isEmpty(orderEntity)) {
return null;
}
OrderDTO orderDTO = BeanUtil.toBean(orderEntity, OrderDTO.class);
orderDetailDTO.setOrderDTO(orderDTO);
OrderLocationDTO orderLocationByOrderId = orderLocationService.findOrderLocationByOrderId(id);
orderDetailDTO.setOrderLocationDTO(orderLocationByOrderId);
OrderCargoDTO orderCargoDTO = orderCargoService.findByOrderId(id);
orderDetailDTO.getOrderDTO().setOrderCargoDto(orderCargoDTO);
return orderDetailDTO;
}
/**
* 根据ids获取集合
*
* @param ids 订单Ids
* @return 订单详情
*/
@GetMapping("ids")
public List<OrderDTO> findByIds(@RequestParam(name = "ids") List<Long> ids) {
List<OrderEntity> orders = orderService.listByIds(ids);
return orders.stream().map(item -> BeanUtil.toBean(item, OrderDTO.class))
.collect(Collectors.toList());
}
/**
* 列表查询
* @param orderSearchDTO 条件
* @return 订单列表
*/
@ResponseBody
@PostMapping("list")
public List<OrderDTO> list(@RequestBody OrderSearchDTO orderSearchDTO) {
LambdaQueryWrapper<OrderEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ObjectUtil.isNotEmpty(orderSearchDTO.getStatus()), OrderEntity::getStatus, orderSearchDTO.getStatus());
wrapper.in(CollUtil.isNotEmpty(orderSearchDTO.getReceiverCountyIds()), OrderEntity::getReceiverCountyId, orderSearchDTO.getReceiverCountyIds());
wrapper.in(CollUtil.isNotEmpty(orderSearchDTO.getSenderCountyIds()), OrderEntity::getSenderCountyId, orderSearchDTO.getSenderCountyIds());
wrapper.eq(ObjectUtil.isNotEmpty(orderSearchDTO.getCurrentAgencyId()), OrderEntity::getCurrentAgencyId, orderSearchDTO.getCurrentAgencyId());
//快递员端进行条件查询取派件任务时会传入关键词作为订单id或姓名或手机号查询条件
if (StringUtils.isNotBlank(orderSearchDTO.getKeyword())) {
wrapper.like(ObjectUtil.isNotEmpty(orderSearchDTO.getOrderId()), OrderEntity::getId, orderSearchDTO.getKeyword())
.or().like(ObjectUtil.isNotEmpty(orderSearchDTO.getSenderName()), OrderEntity::getSenderName, orderSearchDTO.getSenderName())
.or().like(ObjectUtil.isNotEmpty(orderSearchDTO.getSenderPhone()), OrderEntity::getSenderPhone, orderSearchDTO.getSenderPhone())
.or().like(ObjectUtil.isNotEmpty(orderSearchDTO.getReceiverName()), OrderEntity::getReceiverName, orderSearchDTO.getReceiverName())
.or().like(ObjectUtil.isNotEmpty(orderSearchDTO.getReceiverPhone()), OrderEntity::getReceiverPhone, orderSearchDTO.getReceiverPhone());
}
return orderService.list(wrapper).stream().map(order -> BeanUtil.toBean(order, OrderDTO.class)).collect(Collectors.toList());
}
/**
* 查询订单位置
* @param orderId 订单ID
* @return 位置
*/
@GetMapping("location/{orderId}")
public OrderLocationDTO findOrderLocationByOrderId(@PathVariable(name = "orderId") Long orderId) {
return orderLocationService.findOrderLocationByOrderId(orderId);
}
/**
* 根据orderId列表查询订单的location信息
*
* @param orderIds 订单id列表
* @return 位置
*/
@GetMapping("locations")
public List<OrderLocationDTO> findOrderLocationByOrderIds(@RequestParam("orderIds") List<Long> orderIds) {
QueryWrapper<OrderLocationEntity> queryWrapper = new QueryWrapper<OrderLocationEntity>()
.in("order_id", orderIds);
List<OrderLocationEntity> locationList = orderLocationService.list(queryWrapper);
if (CollUtil.isNotEmpty(locationList)) {
return locationList.stream().map(location -> {
OrderLocationDTO locationDTO = new OrderLocationDTO();
BeanUtil.copyProperties(location, locationDTO);
return locationDTO;
}).collect(Collectors.toList());
}
return new ArrayList<>();
}
/**
* 取件更新
* @param orderPickupDTO 取件更新信息
*/
@PutMapping("orderPickup")
void orderPickup(@RequestBody OrderPickupDTO orderPickupDTO) {
crudOrderService.orderPickup(orderPickupDTO);
}
/**
* 状态更新
* @param orderId 订单ID
* @param code 状态码
*/
@PutMapping("updateStatus")
void updateStatus(@RequestParam("orderId") List<Long> orderId, @RequestParam("code") Integer code) {
crudOrderService.updateStatus(orderId, code);
}
}

View File

@@ -0,0 +1,69 @@
package com.sl.ms.oms.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.sl.transport.common.entity.BaseEntity;
import lombok.Data;
import java.math.BigDecimal;
/**
* 货品总重量
*/
@Data
@TableName("sl_hot_good")
public class HotGoodEntity extends BaseEntity {
/**
* 货物类型id
*/
private String goodsTypeId;
/**
* 货物名称
*/
private String name;
/**
* 货物单位
*/
private String unit;
/**
* 货品货值
*/
private BigDecimal cargoValue;
/**
* 货品条码
*/
private String cargoBarcode;
/**
* 货品数量
*/
private Integer quantity;
/**
* 货品体积
*/
private BigDecimal volume;
/**
* 货品重量
*/
private BigDecimal weight;
/**
* 货品备注
*/
private String remark;
/**
* 货品总体积 m^3
*/
private BigDecimal totalVolume;
/**
* 货品总重量 kg
*/
private BigDecimal totalWeight;
}

View File

@@ -0,0 +1,77 @@
package com.sl.ms.oms.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.sl.transport.common.entity.BaseEntity;
import lombok.Data;
import java.math.BigDecimal;
/**
* 货品总重量
*/
@Data
@TableName("sl_order_cargo")
public class OrderCargoEntity extends BaseEntity {
/**
* 订单id
*/
private Long orderId;
/**
* 运单id
*/
private Long tranOrderId;
/**
* 货物类型id
*/
private String goodsTypeId;
/**
* 货物名称
*/
private String name;
/**
* 货物单位
*/
private String unit;
/**
* 货品货值
*/
private BigDecimal cargoValue;
/**
* 货品条码
*/
private String cargoBarcode;
/**
* 货品数量
*/
private Integer quantity;
/**
* 货品体积
*/
private BigDecimal volume;
/**
* 货品重量
*/
private BigDecimal weight;
/**
* 货品备注
*/
private String remark;
/**
* 货品总体积 m^3
*/
private BigDecimal totalVolume;
/**
* 货品总重量 kg
*/
private BigDecimal totalWeight;
}

View File

@@ -0,0 +1,186 @@
package com.sl.ms.oms.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.sl.transport.common.entity.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 订单状态
*/
@Data
@Builder
@TableName("sl_order")
@NoArgsConstructor
@AllArgsConstructor
public class OrderEntity extends BaseEntity {
private static final long serialVersionUID = 3686422248878046126L;
/**
* 订单类型1为同城订单2为城际订单
*/
private Integer orderType;
/**
* 取件类型1为同城订单2为城际订单
*/
private Integer pickupType;
/**
* 下单时间
*/
private LocalDateTime createTime;
/**
* 客户id
*/
private Long memberId;
/**
* 收件人省份id
*/
private Long receiverProvinceId;
/**
* 收件人城市id
*/
private Long receiverCityId;
/**
* 收件人区县id
*/
private Long receiverCountyId;
/**
* 收件人详细地址
*/
private String receiverAddress;
/**
* 收件人地址Id
*/
private Long receiverAddressId;
/**
* 收件人姓名
*/
private String receiverName;
/**
* 收件人电话
*/
private String receiverPhone;
/**
* 发件人省份id
*/
private Long senderProvinceId;
/**
* 发件人城市id
*/
private Long senderCityId;
/**
* 发件人区县id
*/
private Long senderCountyId;
/**
* 发件人详细地址
*/
private String senderAddress;
/**
* 发件人地址Id
*/
private Long senderAddressId;
/**
* 发件人姓名
*/
private String senderName;
/**
* 发件人电话
*/
private String senderPhone;
/**
* 当前所在网点
*/
private Long currentAgencyId;
/**
* 付款方式,1.预结2到付
*/
private Integer paymentMethod;
/**
* 付款状态,1.未付2已付
*/
private Integer paymentStatus;
/**
* 金额
*/
private BigDecimal amount;
/**
* 预计到达时间
*/
private LocalDateTime estimatedArrivalTime;
/**
* 备注
*/
private String mark;
/**
* 预计取件时间
*/
private LocalDateTime estimatedStartTime;
public LocalDateTime getEstimatedArrivalTime() {
if (createTime == null) {
return null;
}
estimatedArrivalTime = createTime.plusDays(4);
return estimatedArrivalTime;
}
/**
* 距离
*/
@ApiModelProperty(value = "距离,单位:米")
private Double distance;
/**
* 订单状态: 22000已关闭, 23000为待取件,23001为已取件23002为网点自寄23003为网点入库
* 23004为待装车23005为运输中23006为网点出库23007为待派送23008为派送中
* 23009为已签收23010为拒收230011为已取消
*/
private Integer status;
@ApiModelProperty(value = "交易系统订单号【对于三方来说:商户订单】")
private Long tradingOrderNo;
@ApiModelProperty(value = "支付渠道【支付宝、微信、现金、免单挂账】")
private String tradingChannel;
@ApiModelProperty(value = "退款金额【付款后】")
private BigDecimal refund;
@ApiModelProperty(value = "是否有退款YESNO")
private String isRefund;
}

View File

@@ -0,0 +1,42 @@
package com.sl.ms.oms.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.sl.transport.common.entity.BaseEntity;
import lombok.Data;
/**
* 订单位置信息
*/
@Data
@TableName("sl_order_location")
public class OrderLocationEntity extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 订单id
*/
private Long orderId;
/**
* 发送地址坐标
*/
private String sendLocation;
/**
* 收货地址坐标
*/
private String receiveLocation;
/**
* 发送起始网点
*/
private Long sendAgentId;
/**
* 接受的终止网点
*/
private Long receiveAgentId;
/**
* 记录状态 0无效1有效
*/
private String status;
}

View File

@@ -0,0 +1,13 @@
package com.sl.ms.oms.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sl.ms.oms.entity.HotGoodEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* 规则
*/
@Mapper
public interface HotGoodMapper extends BaseMapper<HotGoodEntity> {
}

View File

@@ -0,0 +1,12 @@
package com.sl.ms.oms.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sl.ms.oms.entity.OrderCargoEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* 货品总重量 Mapper 接口
*/
@Mapper
public interface OrderCargoMapper extends BaseMapper<OrderCargoEntity> {
}

View File

@@ -0,0 +1,13 @@
package com.sl.ms.oms.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sl.ms.oms.entity.OrderLocationEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* 位置信息
*/
@Mapper
public interface OrderLocationMapper extends BaseMapper<OrderLocationEntity> {
}

View File

@@ -0,0 +1,13 @@
package com.sl.ms.oms.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sl.ms.oms.entity.OrderEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* 订单状态 Mapper 接口
*/
@Mapper
public interface OrderMapper extends BaseMapper<OrderEntity> {
}

View File

@@ -0,0 +1,129 @@
package com.sl.ms.oms.mq;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.sl.ms.oms.enums.OrderPaymentStatus;
import com.sl.ms.oms.enums.OrderStatus;
import com.sl.ms.oms.service.CrudOrderService;
import com.sl.ms.trade.enums.RefundStatusEnum;
import com.sl.ms.trade.enums.TradingStateEnum;
import com.sl.ms.work.api.TransportOrderFeign;
import com.sl.ms.work.domain.dto.TransportOrderDTO;
import com.sl.ms.work.domain.enums.transportorder.TransportOrderStatus;
import com.sl.transport.common.constant.Constants;
import com.sl.transport.common.vo.TradeStatusMsg;
import com.sl.transport.common.vo.TransportOrderStatusMsg;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
/**
* 消息处理
*
* @author zzj
* @version 1.0
*/
@Slf4j
@Component
public class MQListener {
@Resource
private CrudOrderService crudOrderService;
@Resource
private TransportOrderFeign transportOrderFeign;
/**
* 更新运单状态
*
* @param msg 消息
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = Constants.MQ.Queues.OMS_TRANSPORT_ORDER_UPDATE_STATUS),
exchange = @Exchange(name = Constants.MQ.Exchanges.TRANSPORT_ORDER_DELAYED, type = ExchangeTypes.TOPIC, delayed = Constants.MQ.DELAYED),
key = Constants.MQ.RoutingKeys.TRANSPORT_ORDER_UPDATE_STATUS_PREFIX + "#"
))
public void listenTransportOrderUpdateStatusMsg(String msg) {
log.info("接收到更新运单状态的消息 ({})-> {}", Constants.MQ.Queues.OMS_TRANSPORT_ORDER_UPDATE_STATUS, msg);
TransportOrderStatusMsg transportOrderStatusMsg = JSONUtil.toBean(msg, TransportOrderStatusMsg.class);
// 具体业务逻辑的处理
if (ObjectUtil.isEmpty(transportOrderStatusMsg.getStatusCode())) {
// 无状态值 不处理
return;
}
Integer status = getOrderStatusByTransportOrderStatus(transportOrderStatusMsg.getStatusCode());
List<TransportOrderDTO> list = transportOrderFeign.findByIds(transportOrderStatusMsg.getIdList().toArray(String[]::new));
this.crudOrderService.updateStatus(list.stream().map(TransportOrderDTO::getOrderId).collect(Collectors.toList()), status);
}
private Integer getOrderStatusByTransportOrderStatus(Integer statusCode) {
// 运输中
if (TransportOrderStatus.PROCESSING.getCode().equals(statusCode)) {
return OrderStatus.IN_TRANSIT.getCode();
}
// 派送中
if (TransportOrderStatus.ARRIVED_END.getCode().equals(statusCode)) {
return OrderStatus.DISPATCHING.getCode();
}
// 已拒收
if (TransportOrderStatus.REJECTED.getCode().equals(statusCode)) {
return OrderStatus.REJECTION.getCode();
}
// 默认已关闭
return OrderStatus.CLOSE.getCode();
}
/**
* 更新支付结果
* 支付成功
* @param msg 消息
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = Constants.MQ.Queues.OMS_TRADE_UPDATE_STATUS),
exchange = @Exchange(name = Constants.MQ.Exchanges.TRADE, type = ExchangeTypes.TOPIC),
key = Constants.MQ.RoutingKeys.TRADE_UPDATE_STATUS
))
public void listenTradeUpdatePayStatusMsg(String msg) {
log.info("接收到支付结果状态的消息 ({})-> {}", Constants.MQ.Queues.OMS_TRADE_UPDATE_STATUS, msg);
List<TradeStatusMsg> tradeStatusMsgList = JSONUtil.toBean(msg, new TypeReference<List<TradeStatusMsg>>() {}, false);
// 只处理支付成功的
List<TradeStatusMsg> msgList = tradeStatusMsgList.stream().filter(v -> v.getStatusCode().equals(TradingStateEnum.YJS.getCode())).collect(Collectors.toList());
if (CollUtil.isEmpty(msgList)) {
return;
}
this.crudOrderService.updatePayStatus(msgList.stream().map(TradeStatusMsg::getProductOrderNo).collect(Collectors.toList()), OrderPaymentStatus.PAID.getStatus());
}
/**
* 更新退款结果
* 退款
* @param msg 消息
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = Constants.MQ.Queues.OMS_TRADE_REFUND_STATUS),
exchange = @Exchange(name = Constants.MQ.Exchanges.TRADE, type = ExchangeTypes.TOPIC),
key = Constants.MQ.RoutingKeys.REFUND_UPDATE_STATUS
))
public void listenTradeUpdateRefundStatusMsg(String msg) {
log.info("接收到退款订单的消息 ({})-> {}", Constants.MQ.Queues.OMS_TRADE_REFUND_STATUS, msg);
List<TradeStatusMsg> tradeStatusMsgList = JSONUtil.toBean(msg, new TypeReference<List<TradeStatusMsg>>() {}, false);
// 只处理需要退款的
List<TradeStatusMsg> msgList = tradeStatusMsgList.stream().filter(v -> v.getStatusCode().equals(RefundStatusEnum.SUCCESS.getCode())).collect(Collectors.toList());
if (CollUtil.isEmpty(msgList)) {
return;
}
this.crudOrderService.updateRefundInfo(msgList);
}
}

View File

@@ -0,0 +1,91 @@
package com.sl.ms.oms.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sl.ms.oms.dto.OrderDTO;
import com.sl.ms.oms.dto.OrderPickupDTO;
import com.sl.ms.oms.dto.OrderStatusCountDTO;
import com.sl.ms.oms.entity.OrderCargoEntity;
import com.sl.ms.oms.entity.OrderEntity;
import com.sl.ms.oms.entity.OrderLocationEntity;
import com.sl.transport.common.exception.SLException;
import com.sl.transport.common.vo.TradeStatusMsg;
import java.util.List;
public interface CrudOrderService extends IService<OrderEntity> {
/**
* 新增订单
*
* @param order 订单信息
* @param orderCargo 订单
* @param orderLocation 位置
* @throws SLException 异常
*/
void saveOrder(OrderEntity order, OrderCargoEntity orderCargo, OrderLocationEntity orderLocation) throws SLException;
/**
* 获取订单分页数据
*
* @param page 页码
* @param pageSize 页尺寸
* @param order 查询条件
* @return 订单分页数据
*/
IPage<OrderEntity> findByPage(Integer page, Integer pageSize, OrderDTO order);
/**
* 获取订单列表
*
* @param ids 订单id列表
* @return 订单列表
*/
List<OrderEntity> findAll(List<Long> ids);
/**
* 统计各个状态的数量
*
* @param memberId 用户ID
* @return 状态数量数据
*/
List<OrderStatusCountDTO> groupByStatus(Long memberId);
/**
* 快递员取件更新订单和货物信息
*
* @param orderPickupDTO 订单和货物信息
*/
void orderPickup(OrderPickupDTO orderPickupDTO);
/**
* 状态更新
*
* @param orderId 订单ID
* @param code 状态码
*/
void updateStatus(List<Long> orderId, Integer code);
/**
* 更新支付状态
*
* @param ids 订单ID
* @param status 状态
*/
void updatePayStatus(List<Long> ids, Integer status);
/**
* 退款成功
*
* @param msgList 退款消息
*/
void updateRefundInfo(List<TradeStatusMsg> msgList);
/**
* 根据用户id查询订单
*
* @param memberId 用户id
* @return 订单信息
*/
List<OrderEntity> findByMemberId(Long memberId);
}

View File

@@ -0,0 +1,10 @@
package com.sl.ms.oms.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sl.ms.oms.entity.HotGoodEntity;
/**
*
*/
public interface HotGoodService extends IService<HotGoodEntity> {
}

View File

@@ -0,0 +1,48 @@
package com.sl.ms.oms.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sl.ms.oms.dto.OrderCargoDTO;
import com.sl.ms.oms.entity.OrderCargoEntity;
import java.util.List;
/**
* 货品总重量 服务类
*/
public interface OrderCargoService extends IService<OrderCargoEntity> {
/**
* 保存货物信息
*
* @param record 货物信息
* @return 货物信息
*/
OrderCargoEntity saveSelective(OrderCargoEntity record);
/**
* 获取货物列表
*
* @param tranOrderId 运单id
* @param orderId 订单id
* @return 货物列表
*/
List<OrderCargoEntity> findAll(Long tranOrderId, Long orderId);
/**
* 根据订单id查询货品信息
*
* @param id 订单id
* @return 货品信息
*/
OrderCargoDTO findByOrderId(Long id);
/**
* 最近寄递
*
* @param name 物品名称
* @param memberId 用户ID
* @return
*/
List<OrderCargoDTO> listRecent(String name, Long memberId);
}

View File

@@ -0,0 +1,13 @@
package com.sl.ms.oms.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sl.ms.oms.dto.OrderLocationDTO;
import com.sl.ms.oms.entity.OrderLocationEntity;
/**
* 位置信息 服务
*/
public interface OrderLocationService extends IService<OrderLocationEntity> {
OrderLocationDTO findOrderLocationByOrderId(Long orderId);
}

View File

@@ -0,0 +1,28 @@
package com.sl.ms.oms.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sl.ms.oms.dto.MailingSaveDTO;
import com.sl.ms.oms.dto.OrderCarriageDTO;
import com.sl.ms.oms.dto.OrderDTO;
import com.sl.ms.oms.entity.OrderEntity;
/**
* 订单状态 服务类
*/
public interface OrderService extends IService<OrderEntity> {
/**
* 下单
* @param mailingSaveDTO 下单信息
* @return 下单成功信息
* @throws Exception 异常
*/
OrderDTO mailingSave(MailingSaveDTO mailingSaveDTO) throws Exception;
/**
* 预估总价
* @param mailingSaveDTO 下单信息
* @return 运费预估信息
*/
OrderCarriageDTO totalPrice(MailingSaveDTO mailingSaveDTO);
}

View File

@@ -0,0 +1,287 @@
package com.sl.ms.oms.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sl.ms.oms.dto.OrderCargoDTO;
import com.sl.ms.oms.dto.OrderDTO;
import com.sl.ms.oms.dto.OrderPickupDTO;
import com.sl.ms.oms.dto.OrderStatusCountDTO;
import com.sl.ms.oms.entity.OrderCargoEntity;
import com.sl.ms.oms.entity.OrderEntity;
import com.sl.ms.oms.entity.OrderLocationEntity;
import com.sl.ms.oms.enums.MailType;
import com.sl.ms.oms.enums.OrderPaymentStatus;
import com.sl.ms.oms.enums.OrderPickupType;
import com.sl.ms.oms.enums.OrderStatus;
import com.sl.ms.oms.mapper.OrderMapper;
import com.sl.ms.oms.service.CrudOrderService;
import com.sl.ms.oms.service.OrderCargoService;
import com.sl.ms.oms.service.OrderLocationService;
import com.sl.ms.user.api.MemberFeign;
import com.sl.ms.user.domain.dto.MemberDTO;
import com.sl.ms.work.api.TransportOrderFeign;
import com.sl.ms.work.domain.dto.TransportOrderDTO;
import com.sl.transport.common.exception.SLException;
import com.sl.transport.common.vo.TradeStatusMsg;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 订单 服务实现类
*/
@Service
@Slf4j
public class CrudOrderServiceImpl extends ServiceImpl<OrderMapper, OrderEntity> implements CrudOrderService {
@Resource
private OrderCargoService orderCargoService;
@Resource
private OrderLocationService orderLocationService;
@Resource
private MemberFeign memberFeign;
@Resource
private TransportOrderFeign transportOrderFeign;
@Transactional
@Override
public void saveOrder(OrderEntity order, OrderCargoEntity orderCargo, OrderLocationEntity orderLocation) throws SLException {
order.setCreateTime(LocalDateTime.now());
order.setPaymentStatus(OrderPaymentStatus.UNPAID.getStatus());
if (OrderPickupType.NO_PICKUP.getCode().equals(order.getPickupType())) {
order.setStatus(OrderStatus.OUTLETS_SINCE_SENT.getCode());
} else {
order.setStatus(OrderStatus.PENDING.getCode());
}
// 保存订单
if (save(order)) {
// 保存货物
orderCargo.setOrderId(order.getId());
orderCargoService.saveSelective(orderCargo);
// 保存位置
orderLocation.setOrderId(order.getId());
orderLocationService.save(orderLocation);
return;
}
throw new SLException("保存订单失败");
}
@Override
public Page<OrderEntity> findByPage(Integer page, Integer pageSize, OrderDTO orderDTO) {
OrderEntity order = BeanUtil.toBean(orderDTO, OrderEntity.class);
Page<OrderEntity> iPage = new Page<>(page, pageSize);
LambdaQueryWrapper<OrderEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// 客户端搜索
if (ObjectUtil.isNotEmpty(orderDTO.getKeyword())) {
List<Long> orderIds = new ArrayList<>();
// 运单号
try {
TransportOrderDTO transportOrderDTO = transportOrderFeign.findById(orderDTO.getKeyword());
Long orderId = transportOrderDTO.getOrderId();
orderIds.add(orderId);
} catch (Exception ignored) {
log.info("Exception:{}", ignored.getMessage());
}
// 订单号
if (NumberUtil.isLong(orderDTO.getKeyword())) {
orderIds.add(Long.valueOf(orderDTO.getKeyword()));
}
// 搜索条件不满足
if (CollUtil.isEmpty(orderIds)) {
return iPage;
}
// 查询条件
lambdaQueryWrapper.in(CollUtil.isNotEmpty(orderIds), OrderEntity::getId, orderIds);
}
lambdaQueryWrapper
.like(ObjectUtil.isNotEmpty(order.getId()), OrderEntity::getId, order.getId())
.eq(ObjectUtil.isNotEmpty(order.getStatus()), OrderEntity::getStatus, order.getStatus())
.eq(ObjectUtil.isNotEmpty(order.getPaymentStatus()), OrderEntity::getPaymentStatus, order.getPaymentStatus())
//发件人信息
.like(ObjectUtil.isNotEmpty(order.getSenderName()), OrderEntity::getSenderName, order.getSenderName())
.like(StrUtil.isNotEmpty(order.getSenderPhone()), OrderEntity::getSenderPhone, order.getSenderPhone())
.eq(ObjectUtil.isNotEmpty(order.getSenderProvinceId()), OrderEntity::getSenderProvinceId, order.getSenderProvinceId())
.eq(ObjectUtil.isNotEmpty(order.getSenderCityId()), OrderEntity::getSenderCityId, order.getSenderCityId())
.eq(ObjectUtil.isNotEmpty(order.getSenderCountyId()), OrderEntity::getSenderCountyId, order.getSenderCountyId())
//收件人信息
.like(ObjectUtil.isNotEmpty(order.getReceiverName()), OrderEntity::getReceiverName, order.getReceiverName())
.eq(ObjectUtil.isNotEmpty(order.getReceiverProvinceId()), OrderEntity::getReceiverProvinceId, order.getReceiverProvinceId())
.eq(ObjectUtil.isNotEmpty(order.getReceiverCityId()), OrderEntity::getReceiverCityId, order.getReceiverCityId())
.eq(ObjectUtil.isNotEmpty(order.getReceiverCountyId()), OrderEntity::getReceiverCountyId, order.getReceiverCountyId())
// 不展示删除状态
.ne(OrderEntity::getStatus, OrderStatus.DEL.getCode());
// 是否客户端查询
boolean isQueryByCustom = ObjectUtil.isNotEmpty(orderDTO.getMailType());
// 收件人手机号查询 客户端、管理端共用
lambdaQueryWrapper
.eq(isQueryByCustom && StrUtil.isNotEmpty(order.getReceiverPhone()), OrderEntity::getReceiverPhone, order.getReceiverPhone())
.like(!isQueryByCustom && StrUtil.isNotEmpty(order.getReceiverPhone()), OrderEntity::getReceiverPhone, order.getReceiverPhone())
// 客户端非寄件列表 不展示这些状态
.notIn(isQueryByCustom && !MailType.SEND.getCode().equals(orderDTO.getMailType()), OrderEntity::getStatus, Arrays.asList(OrderStatus.CLOSE.getCode(), OrderStatus.CANCELLED.getCode(), OrderStatus.PENDING.getCode()));
// 客户端 寄件列表
lambdaQueryWrapper.eq(isQueryByCustom && MailType.SEND.getCode().equals(orderDTO.getMailType()), OrderEntity::getMemberId, order.getMemberId());
// 客户端 混合列表 客户端根据用户ID查询 或者用收件人手机号查询都可以
lambdaQueryWrapper.or(isQueryByCustom && MailType.ALL.getCode().equals(orderDTO.getMailType()))
.eq(isQueryByCustom && MailType.ALL.getCode().equals(orderDTO.getMailType()), OrderEntity::getMemberId, order.getMemberId())
.ne(isQueryByCustom && MailType.ALL.getCode().equals(orderDTO.getMailType()), OrderEntity::getStatus, OrderStatus.DEL.getCode());
lambdaQueryWrapper.orderBy(true, false, OrderEntity::getCreateTime);
return page(iPage, lambdaQueryWrapper);
}
@Override
public List<OrderEntity> findAll(List<Long> ids) {
LambdaQueryWrapper<OrderEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
if (ObjectUtil.isNotEmpty(ids) && ids.size() > 0) {
lambdaQueryWrapper.in(OrderEntity::getId, ids);
}
lambdaQueryWrapper.orderBy(true, false, OrderEntity::getCreateTime);
return list(lambdaQueryWrapper);
}
/**
* 统计各个状态的数量
*
* @param memberId 用户ID
* @return 状态数量数据
*/
@Override
public List<OrderStatusCountDTO> groupByStatus(Long memberId) {
List<OrderStatusCountDTO> list = new ArrayList<>();
MemberDTO detail = memberFeign.detail(memberId);
// 收件数量
long count = count(Wrappers.<OrderEntity>lambdaQuery()
.eq(OrderEntity::getReceiverPhone, detail.getPhone())
.ne(OrderEntity::getStatus, OrderStatus.DEL.getCode())
.notIn(OrderEntity::getStatus, Arrays.asList(OrderStatus.CLOSE.getCode(), OrderStatus.CANCELLED.getCode(), OrderStatus.PENDING.getCode()))
);
OrderStatusCountDTO orderStatusCountDTO = new OrderStatusCountDTO();
orderStatusCountDTO.setStatus(MailType.RECEIVE);
orderStatusCountDTO.setStatusCode(MailType.RECEIVE.getCode());
orderStatusCountDTO.setCount(count);
list.add(orderStatusCountDTO);
// 寄件数量
long sendCount = count(Wrappers.<OrderEntity>lambdaQuery()
.eq(OrderEntity::getMemberId, memberId)
.ne(OrderEntity::getStatus, OrderStatus.DEL.getCode())
);
OrderStatusCountDTO send = new OrderStatusCountDTO();
send.setStatus(MailType.SEND);
send.setStatusCode(MailType.SEND.getCode());
send.setCount(sendCount);
list.add(send);
return list;
}
/**
* 状态更新
*
* @param orderId 订单ID
* @param code 状态码
*/
@Override
public void updateStatus(List<Long> orderId, Integer code) {
update(Wrappers.<OrderEntity>lambdaUpdate()
.in(OrderEntity::getId, orderId)
.set(OrderEntity::getStatus, code));
}
/**
* 快递员取件更新订单和货物信息
*
* @param orderPickupDTO 订单和货物信息
*/
@Transactional
@Override
public void orderPickup(OrderPickupDTO orderPickupDTO) {
//5.更新订单
OrderEntity orderEntity = new OrderEntity();
orderEntity.setPaymentMethod(orderPickupDTO.getPayMethod());//付款方式,1.预结2到付
orderEntity.setPaymentStatus(OrderPaymentStatus.UNPAID.getStatus());//付款状态,1.未付2已付
orderEntity.setAmount(orderPickupDTO.getAmount());//金额
orderEntity.setStatus(OrderStatus.PICKED_UP.getCode());//订单状态
orderEntity.setMark(orderPickupDTO.getRemark());//备注
orderEntity.setId(orderPickupDTO.getId());
updateById(orderEntity);
//6.更新订单货品
BigDecimal volume = NumberUtil.round(orderPickupDTO.getVolume(), 4);
BigDecimal weight = NumberUtil.round(orderPickupDTO.getWeight(), 2);
OrderCargoDTO cargoDTO = orderCargoService.findByOrderId(orderPickupDTO.getId());
OrderCargoEntity orderCargoEntity = new OrderCargoEntity();
orderCargoEntity.setName(orderPickupDTO.getGoodName());//货物名称
orderCargoEntity.setVolume(volume);//货品体积单位m^3
orderCargoEntity.setWeight(weight);//货品重量单位kg
orderCargoEntity.setTotalVolume(volume);//货品总体积单位m^3
orderCargoEntity.setTotalWeight(weight);//货品总重量单位kg
orderCargoEntity.setId(cargoDTO.getId());
orderCargoService.saveOrUpdate(orderCargoEntity);
}
/**
* 更新支付状态
*
* @param ids 订单ID
* @param status 状态
*/
@Override
public void updatePayStatus(List<Long> ids, Integer status) {
LambdaUpdateWrapper<OrderEntity> updateWrapper = Wrappers.<OrderEntity>lambdaUpdate()
.set(OrderEntity::getPaymentStatus, status)
.in(OrderEntity::getId, ids);
update(updateWrapper);
}
/**
* 退款成功
*
* @param msgList 退款消息
*/
@Override
public void updateRefundInfo(List<TradeStatusMsg> msgList) {
// 退款功能暂不实现 涉及逻辑较多
}
/**
* 根据用户id查询订单
*
* @param memberId 用户id
* @return 订单信息
*/
@Override
public List<OrderEntity> findByMemberId(Long memberId) {
return list(Wrappers.<OrderEntity>lambdaQuery().eq(OrderEntity::getMemberId, memberId));
}
}

View File

@@ -0,0 +1,11 @@
package com.sl.ms.oms.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sl.ms.oms.entity.HotGoodEntity;
import com.sl.ms.oms.mapper.HotGoodMapper;
import com.sl.ms.oms.service.HotGoodService;
import org.springframework.stereotype.Service;
@Service
public class HotGoodServiceImpl extends ServiceImpl<HotGoodMapper, HotGoodEntity> implements HotGoodService {
}

View File

@@ -0,0 +1,85 @@
package com.sl.ms.oms.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sl.ms.oms.dto.OrderCargoDTO;
import com.sl.ms.oms.entity.OrderCargoEntity;
import com.sl.ms.oms.entity.OrderEntity;
import com.sl.ms.oms.mapper.OrderCargoMapper;
import com.sl.ms.oms.service.CrudOrderService;
import com.sl.ms.oms.service.OrderCargoService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 货品总重量 服务实现类
*/
@Service
public class OrderCargoServiceImpl extends ServiceImpl<OrderCargoMapper, OrderCargoEntity>
implements OrderCargoService {
@Resource
private CrudOrderService crudOrderService;
@Override
public OrderCargoEntity saveSelective(OrderCargoEntity record) {
super.saveOrUpdate(record);
return record;
}
@Override
public List<OrderCargoEntity> findAll(Long tranOrderId, Long orderId) {
LambdaQueryWrapper<OrderCargoEntity> queryWrapper = new LambdaQueryWrapper<>();
if (ObjectUtil.isNotEmpty(tranOrderId)) {
queryWrapper.eq(OrderCargoEntity::getTranOrderId, tranOrderId);
}
if (ObjectUtil.isNotEmpty(orderId)) {
queryWrapper.eq(OrderCargoEntity::getOrderId, orderId);
}
queryWrapper.orderBy(true, false, OrderCargoEntity::getCreated);
return super.list(queryWrapper);
}
/**
* 根据订单id查询货品信息
*
* @param id 订单id
* @return 货品信息
*/
@Override
public OrderCargoDTO findByOrderId(Long id) {
//构造查询条件
LambdaQueryWrapper<OrderCargoEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OrderCargoEntity::getOrderId,id);
//根据订单id查询
OrderCargoEntity orderCargo = getOne(queryWrapper);
return BeanUtil.toBean(orderCargo, OrderCargoDTO.class);
}
@Override
public List<OrderCargoDTO> listRecent(String name, Long memberId) {
List<Long> orderIds = crudOrderService.findByMemberId(memberId).parallelStream().map(OrderEntity::getId).collect(Collectors.toList());
if (CollUtil.isEmpty(orderIds)) {
return new ArrayList<>();
}
return list(Wrappers.<OrderCargoEntity>lambdaQuery()
.like(ObjectUtil.isNotEmpty(name), OrderCargoEntity::getName, name)
.in(OrderCargoEntity::getOrderId, orderIds)
.groupBy(ObjectUtil.isEmpty(name), OrderCargoEntity::getName)
.last("limit 20")
.orderByDesc(OrderCargoEntity::getCreated)
)
.stream()
.map(orderCargo -> BeanUtil.toBean(orderCargo, OrderCargoDTO.class))
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,30 @@
package com.sl.ms.oms.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sl.ms.oms.dto.OrderLocationDTO;
import com.sl.ms.oms.entity.OrderLocationEntity;
import com.sl.ms.oms.mapper.OrderLocationMapper;
import com.sl.ms.oms.service.OrderLocationService;
import org.springframework.stereotype.Service;
/**
* 位置信息服务实现
*/
@Service
public class OrderLocationServiceImpl extends ServiceImpl<OrderLocationMapper, OrderLocationEntity>
implements OrderLocationService {
@Override
public OrderLocationDTO findOrderLocationByOrderId(Long orderId) {
QueryWrapper<OrderLocationEntity> queryWrapper = new QueryWrapper<OrderLocationEntity>()
.eq("order_id", orderId).last(" limit 1");
OrderLocationEntity location = getOne(queryWrapper);
if (ObjectUtil.isNotEmpty(location)) {
return BeanUtil.toBean(location, OrderLocationDTO.class);
}
return null;
}
}

View File

@@ -0,0 +1,446 @@
package com.sl.ms.oms.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.em.sdk.EagleMapTemplate;
import com.itheima.em.sdk.enums.ProviderEnum;
import com.itheima.em.sdk.vo.Coordinate;
import com.itheima.em.sdk.vo.GeoResult;
import com.sl.ms.base.api.common.AreaFeign;
import com.sl.ms.base.api.common.MQFeign;
import com.sl.ms.base.domain.base.AreaDto;
import com.sl.ms.carriage.appi.CarriageFeign;
import com.sl.ms.carriage.domain.dto.CarriageDTO;
import com.sl.ms.carriage.domain.dto.WaybillDTO;
import com.sl.ms.oms.dto.MailingSaveDTO;
import com.sl.ms.oms.dto.OrderCarriageDTO;
import com.sl.ms.oms.dto.OrderDTO;
import com.sl.ms.oms.entity.OrderCargoEntity;
import com.sl.ms.oms.entity.OrderEntity;
import com.sl.ms.oms.entity.OrderLocationEntity;
import com.sl.ms.oms.enums.OrderPaymentStatus;
import com.sl.ms.oms.enums.OrderType;
import com.sl.ms.oms.mapper.OrderMapper;
import com.sl.ms.oms.service.CrudOrderService;
import com.sl.ms.oms.service.OrderService;
import com.sl.ms.scope.api.ServiceScopeFeign;
import com.sl.ms.scope.dto.ServiceScopeDTO;
import com.sl.ms.transport.api.TransportLineFeign;
import com.sl.ms.user.api.AddressBookFeign;
import com.sl.ms.user.domain.dto.AddressBookDTO;
import com.sl.ms.work.domain.enums.pickupDispatchtask.PickupDispatchTaskType;
import com.sl.transport.common.constant.Constants;
import com.sl.transport.common.exception.SLException;
import com.sl.transport.common.vo.OrderMsg;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
/**
* 订单 服务实现类
*/
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, OrderEntity> implements OrderService {
@Resource
private MQFeign mqFeign;
@Autowired
private AddressBookFeign addressBookFeign;
@Autowired
private CrudOrderService crudOrderService;
@Resource
AreaFeign areaFeign;
@Resource
ServiceScopeFeign agencyScopeFeign;
@Resource
private EagleMapTemplate eagleMapTemplate;
@Resource
private CarriageFeign carriageFeign;
@Resource
private TransportLineFeign transportLineFeign;
/**
* 下单
* @param mailingSaveDTO 下单信息
* @return 下单成功信息
* @throws SLException
*/
@Override
public OrderDTO mailingSave(MailingSaveDTO mailingSaveDTO) throws Exception {
// 获取地址详细信息
HashMap<Long, AddressBookDTO> orderAddress = getOrderAddress(mailingSaveDTO.getSendAddress(), mailingSaveDTO.getReceiptAddress());
AddressBookDTO sendAddress = orderAddress.get(mailingSaveDTO.getSendAddress());
AddressBookDTO receiptAddress = orderAddress.get(mailingSaveDTO.getReceiptAddress());
// 构建实体
OrderEntity order = buildOrder(mailingSaveDTO, sendAddress, receiptAddress);
log.info("订单信息入库:{}", order);
// 订单位置
OrderLocationEntity orderLocation = buildOrderLocation(order);
log.info("订单位置为:{}", orderLocation);
// 计算运费
CarriageDTO carriageDTO = computeCarriage(mailingSaveDTO, sendAddress.getCityId(), receiptAddress.getCityId());
order.setAmount(BigDecimal.valueOf(carriageDTO.getExpense()));
log.info("订单运费为:{}", carriageDTO);
// 货物
OrderCargoEntity orderCargo = buildOrderCargo(mailingSaveDTO);
// 距离 设置当前机构ID
appendOtherInfo(order, orderLocation);
// 执行保存
crudOrderService.saveOrder(order, orderCargo, orderLocation);
// 生成订单mq 调度服务用来调度 之后快递员服务处理
noticeOrderStatusChange(order, orderLocation);
// 返回下单成功页
OrderDTO orderDTO = BeanUtil.toBean(order, OrderDTO.class);
// 首重价格
orderDTO.setFirstWeight(carriageDTO.getFirstWeight());
// 续重价格
orderDTO.setContinuousWeight(carriageDTO.getContinuousWeight());
return orderDTO;
}
/**
* 获取订单地址信息
* @param sendAddressId 发送地址ID
* @param receiptAddressId 接收地址ID
* @return
*/
private HashMap<Long, AddressBookDTO> getOrderAddress(Long sendAddressId, Long receiptAddressId) {
AddressBookDTO sendAddress = addressBookFeign.detail(sendAddressId);
AddressBookDTO receiptAddress = addressBookFeign.detail(receiptAddressId);
log.info("sendAddress:{},{} receiptAddress:{},{}", receiptAddressId, sendAddress, receiptAddressId, receiptAddress);
if (ObjectUtil.isEmpty(sendAddress) || ObjectUtil.isEmpty(receiptAddress)) {
log.error("获取地址薄详细信息 失败 receiptAddressId receiptAddressId :{} {} ", sendAddressId, receiptAddressId);
throw new SLException("获取地址详细信息失败");
}
HashMap<Long, AddressBookDTO> map = new HashMap<>();
map.put(sendAddressId, sendAddress);
map.put(receiptAddressId, receiptAddress);
return map;
}
/**
* 预估总价
* @param mailingSaveDTO 下单信息
* @return 运费预估信息
*/
@Override
public OrderCarriageDTO totalPrice(MailingSaveDTO mailingSaveDTO) {
// 获取地址详细信息
// 获取地址详细信息
HashMap<Long, AddressBookDTO> orderAddress = getOrderAddress(mailingSaveDTO.getSendAddress(), mailingSaveDTO.getReceiptAddress());
AddressBookDTO sendAddress = orderAddress.get(mailingSaveDTO.getSendAddress());
AddressBookDTO receiptAddress = orderAddress.get(mailingSaveDTO.getReceiptAddress());
// 计算运费
CarriageDTO carriageDTO = computeCarriage(mailingSaveDTO, sendAddress.getCityId(), receiptAddress.getCityId());
return BeanUtil.toBean(carriageDTO, OrderCarriageDTO.class);
}
/**
* 运费计算
* @param mailingSaveDTO 下单信息
* @param senderCityId 发送城市ID
* @param receiverCityId 接收城市ID
* @return 计算结果
*/
private CarriageDTO computeCarriage(MailingSaveDTO mailingSaveDTO, Long senderCityId, Long receiverCityId) {
// 运费
WaybillDTO waybillDTO = WaybillDTO.builder()
.senderCityId(senderCityId)
.receiverCityId(receiverCityId)
.measureHigh(mailingSaveDTO.getMeasureHigh())
.measureLong(mailingSaveDTO.getMeasureLong())
.measureWidth(mailingSaveDTO.getMeasureWidth())
.volume(ObjectUtil.isEmpty(mailingSaveDTO.getTotalVolume()) ? null : mailingSaveDTO.getTotalVolume().intValue())
.weight(mailingSaveDTO.getTotalWeight().doubleValue())
.build();
CarriageDTO compute = carriageFeign.compute(waybillDTO);
if (ObjectUtil.isEmpty(compute)) {
throw new SLException(StrUtil.format("计算运费出错 mailingSaveDTO {}", mailingSaveDTO));
}
return compute;
}
/**
* 补充数据
* @param order 订单
* @param orderLocation 订单位置
*/
private void appendOtherInfo(OrderEntity order, OrderLocationEntity orderLocation) {
// 当前机构
order.setCurrentAgencyId(orderLocation.getSendAgentId());
//查询地图服务商
String[] sendLocation = orderLocation.getSendLocation().split(",");
double sendLnt = Double.parseDouble(sendLocation[0]);
double sendLat = Double.parseDouble(sendLocation[1]);
String[] receiveLocation = orderLocation.getReceiveLocation().split(",");
double receiveLnt = Double.parseDouble(receiveLocation[0]);
double receiveLat = Double.parseDouble(receiveLocation[1]);
Coordinate origin = new Coordinate(sendLnt, sendLat);
Coordinate destination = new Coordinate(receiveLnt, receiveLat);
//设置高德地图参数,默认是不返回预计耗时的,需要额外设置参数
Map<String, Object> param = MapUtil.<String, Object>builder().put("show_fields", "cost").build();
String driving = this.eagleMapTemplate.opsForDirection().driving(ProviderEnum.AMAP, origin, destination, param);
if (StrUtil.isEmpty(driving)) {
return;
}
JSONObject jsonObject = JSONUtil.parseObj(driving);
//距离,单位:米
Double distance = Convert.toDouble(jsonObject.getByPath("route.paths[0].distance"));
order.setDistance(distance);
//时间,单位:秒
Long duration = Convert.toLong(jsonObject.getByPath("route.paths[0].cost.duration"), -1L);
// 预计到达时间 这里根据地图大致估算时间 并非实际时间
order.setEstimatedArrivalTime(LocalDateTime.now().plus(duration, ChronoUnit.SECONDS));
}
/**
* 构建订单
*
* @param mailingSaveDTO 下单信息
* @param sendAddress 发送地址
* @param receiptAddress 接收地址
* @return
*/
private OrderEntity buildOrder(MailingSaveDTO mailingSaveDTO, AddressBookDTO sendAddress, AddressBookDTO receiptAddress) {
OrderEntity entity = OrderEntity.builder()
// 用户ID
.memberId(mailingSaveDTO.getMemberId())
.senderName(sendAddress.getName())
.senderPhone(sendAddress.getPhoneNumber())
.senderProvinceId(sendAddress.getProvinceId())
.senderCityId(sendAddress.getCityId())
.senderCountyId(sendAddress.getCountyId())
.senderAddress(sendAddress.getAddress())
.senderAddressId(mailingSaveDTO.getSendAddress())
.receiverName(receiptAddress.getName())
.receiverPhone(receiptAddress.getPhoneNumber())
.receiverProvinceId(receiptAddress.getProvinceId())
.receiverCityId(receiptAddress.getCityId())
.receiverCountyId(receiptAddress.getCountyId())
.receiverAddress(receiptAddress.getAddress())
.receiverAddressId(mailingSaveDTO.getReceiptAddress())
.paymentMethod(mailingSaveDTO.getPayMethod())
.paymentStatus(OrderPaymentStatus.UNPAID.getStatus()) // 默认未付款
.estimatedStartTime(mailingSaveDTO.getPickUpTime())
.pickupType(mailingSaveDTO.getPickupType())
.build();
entity.setOrderType(entity.getReceiverCityId().equals(entity.getSenderCityId()) ? OrderType.INCITY.getCode() : OrderType.OUTCITY.getCode());
return entity;
}
/**
* 根据地址计算网点
*
* @param address 地址
* @return
*/
private HashMap getAgencyId(String address) throws SLException {
if (ObjectUtil.isEmpty(address)) {
log.error("地址不能为空");
throw new SLException("下单时发货地址不能为空");
}
//根据详细地址查询坐标
GeoResult geoResult = this.eagleMapTemplate.opsForBase().geoCode(ProviderEnum.AMAP, address, null);
Coordinate coordinate = geoResult.getLocation();
log.info("地址和坐标-->" + address + "--" + coordinate);
if (ObjectUtil.isEmpty(coordinate)) {
log.error("地址无法定位");
throw new SLException("地址无法定位");
}
double lng = coordinate.getLongitude(); // 经度
double lat = coordinate.getLatitude(); // 纬度
DecimalFormat df = new DecimalFormat("#.######");
String lngStr = df.format(lng);
String latStr = df.format(lat);
String location = StrUtil.format("{},{}", lngStr, latStr);
List<ServiceScopeDTO> serviceScopeDTOS = agencyScopeFeign.queryListByLocation(1, coordinate.getLongitude(), coordinate.getLatitude());
if (CollectionUtils.isEmpty(serviceScopeDTOS)) {
log.error("地址不在服务范围");
throw new SLException("地址不在服务范围");
}
HashMap result = new HashMap();
result.put("agencyId", serviceScopeDTOS.get(0).getBid());
result.put("location", location);
return result;
}
/**
* 合并地址
* @param entity 订单
* @return 地址
*/
private String senderFullAddress(OrderEntity entity) {
Long province = entity.getSenderProvinceId();
Long city = entity.getSenderCityId();
Long county = entity.getSenderCountyId();
StringBuilder stringBuilder = areaAddress(province, city, county);
stringBuilder.append(entity.getSenderAddress());
return stringBuilder.toString();
}
/**
* 合并地址
* @param orderDTO 订单
* @return 地址
*/
private String receiverFullAddress(OrderEntity orderDTO) {
Long province = orderDTO.getReceiverProvinceId();
Long city = orderDTO.getReceiverCityId();
Long county = orderDTO.getReceiverCountyId();
StringBuilder stringBuilder = areaAddress(province, city, county);
stringBuilder.append(orderDTO.getReceiverAddress());
return stringBuilder.toString();
}
/**
* 合并地址
* @return 地址
*/
private StringBuilder areaAddress(Long province, Long city, Long county) {
StringBuilder stringBuffer = new StringBuilder();
Set<Long> areaIdSet = new HashSet<>();
areaIdSet.add(province);
areaIdSet.add(city);
areaIdSet.add(county);
List<AreaDto> result = areaFeign.findBatch(new ArrayList<>(areaIdSet));
Map<Long, AreaDto> areaMap = result.stream().collect(Collectors.toMap(AreaDto::getId, vo -> vo));
stringBuffer.append(areaMap.get(province).getName());
stringBuffer.append(areaMap.get(city).getName());
stringBuffer.append(areaMap.get(county).getName());
return stringBuffer;
}
/**
* 构建货物
*
* @param mailingSaveDTO 下单信息
* @return
*/
private OrderCargoEntity buildOrderCargo(MailingSaveDTO mailingSaveDTO) {
OrderCargoEntity cargoEntity = new OrderCargoEntity();
cargoEntity.setName(mailingSaveDTO.getGoodsName());
cargoEntity.setGoodsTypeId(mailingSaveDTO.getGoodsType());
// 数量
cargoEntity.setQuantity(mailingSaveDTO.getGoodNum());
// 重量
cargoEntity.setTotalWeight(mailingSaveDTO.getTotalWeight());
cargoEntity.setWeight(mailingSaveDTO.getTotalWeight());
// 体积
BigDecimal volume = ObjectUtil.isEmpty(mailingSaveDTO.getTotalVolume()) ? new BigDecimal("0.0001") : mailingSaveDTO.getTotalVolume().divide(new BigDecimal("1000000.00"));
cargoEntity.setTotalVolume(volume);
cargoEntity.setVolume(volume);
return cargoEntity;
}
/**
* 根据发收件人地址获取起止机构ID 调用机构范围微服务
*
* @param order 订单
* @return 位置信息
*/
private OrderLocationEntity buildOrderLocation(OrderEntity order) {
String address = senderFullAddress(order);
HashMap result = getAgencyId(address);
String sendAgentId = result.get("agencyId").toString();
String sendLocation = result.get("location").toString();
String receiverAddress = receiverFullAddress(order);
HashMap resultReceive = getAgencyId(receiverAddress);
String receiveAgentId = resultReceive.get("agencyId").toString();
String receiveAgentLocation = resultReceive.get("location").toString();
// 线路规划逻辑耗时较长,影响下单接口响应时间 下单时暂不进行判断是否存在线路
// if (ObjectUtil.notEqual(sendAgentId, receiveAgentId)) {
// //根据起始机构规划运输路线
// TransportLineNodeDTO transportLineNodeDTO = this.transportLineFeign.queryPathByDispatchMethod(Long.parseLong(sendAgentId), Long.parseLong(receiveAgentId));
// if (ObjectUtil.isEmpty(transportLineNodeDTO) || CollUtil.isEmpty(transportLineNodeDTO.getNodeList())) {
// throw new SLException("暂不支持寄件收件地址,没有对应的路线");
// }
// }
OrderLocationEntity orderLocationEntity = new OrderLocationEntity();
orderLocationEntity.setOrderId(order.getId());
orderLocationEntity.setSendLocation(sendLocation);
orderLocationEntity.setSendAgentId(Long.parseLong(sendAgentId));
orderLocationEntity.setReceiveLocation(receiveAgentLocation);
orderLocationEntity.setReceiveAgentId(Long.parseLong(receiveAgentId));
return orderLocationEntity;
}
/**
* 取件
*
* @param orderEntity 订单
* @param orderLocation 位置
*/
private void noticeOrderStatusChange(OrderEntity orderEntity, OrderLocationEntity orderLocation) {
//{"order":{"orderId":123, "agencyId": 8001, "taskType":1, "mark":"带包装", "longitude":116.111, "latitude":39.00, "created":1654224658728, "estimatedStartTime": 1654224658728}, "created":123456}
String[] split = orderLocation.getSendLocation().split(",");
double lnt = Double.parseDouble(split[0]);
double lat = Double.parseDouble(split[1]);
OrderMsg orderMsg = OrderMsg.builder()
.created(LocalDateTimeUtil.toEpochMilli(orderEntity.getCreateTime()))
.estimatedEndTime(orderEntity.getEstimatedStartTime())
.mark(orderEntity.getMark())
.taskType(PickupDispatchTaskType.PICKUP.getCode())
.latitude(lat)
.longitude(lnt)
.agencyId(orderEntity.getCurrentAgencyId())
.orderId(orderEntity.getId())
.build();
//发送消息
this.mqFeign.sendMsg(Constants.MQ.Exchanges.ORDER_DELAYED, Constants.MQ.RoutingKeys.ORDER_CREATE, orderMsg.toJson(), Constants.MQ.LOW_DELAY);
}
}

View File

@@ -0,0 +1,7 @@
_ ${spring.application.name} ${application.version}
___ | | ___ __ __ _ __ _ __ ___ ___ ___ Port: ${server.port}
/ __|| | _____ / _ \\ \/ /| '_ \ | '__|/ _ \/ __|/ __| Pid: ${pid} Profile(s): ${AnsiColor.GREEN}${spring.profiles.active}${AnsiColor.DEFAULT}
\__ \| ||_____|| __/ > < | |_) || | | __/\__ \\__ \
|___/|_| \___|/_/\_\| .__/ |_| \___||___/|___/ https://sl-express.itheima.net/
|_|

View File

@@ -0,0 +1,37 @@
server:
port: 18082
tomcat:
uri-encoding: UTF-8
threads:
max: 1000
min-spare: 30
spring:
cloud:
nacos:
username: nacos
password: nacos
server-addr: 192.168.150.101:8848
discovery:
namespace: ecae68ba-7b43-4473-a980-4ddeb6157bdc
ip: 192.168.150.1
config:
namespace: ecae68ba-7b43-4473-a980-4ddeb6157bdc
shared-configs: #共享配置
- data-id: shared-spring-seata.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mysql.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mybatis-plus.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-rabbitmq.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-redis.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-eaglemap.yml
group: SHARED_GROUP
refresh: false

View File

@@ -0,0 +1,36 @@
server:
port: 18082
tomcat:
uri-encoding: UTF-8
threads:
max: 1000
min-spare: 30
spring:
cloud:
nacos:
username: nacos
password: vO5/dZ9,iL
server-addr: nacos-service.yjy-public-slwl-java-prod.svc.cluster.local:8848
discovery:
namespace: 92312ba8-1119-440f-81af-c29618df303b
config:
namespace: 92312ba8-1119-440f-81af-c29618df303b
shared-configs: #共享配置
- data-id: shared-spring-seata.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mysql.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mybatis-plus.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-rabbitmq.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-redis.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-eaglemap.yml
group: SHARED_GROUP
refresh: false

View File

@@ -0,0 +1,36 @@
server:
port: 18082
tomcat:
uri-encoding: UTF-8
threads:
max: 1000
min-spare: 30
spring:
cloud:
nacos:
username: nacos
password: nacos
server-addr: 192.168.150.101:8848
discovery:
namespace: ecae68ba-7b43-4473-a980-4ddeb6157bdc
config:
namespace: ecae68ba-7b43-4473-a980-4ddeb6157bdc
shared-configs: #共享配置
- data-id: shared-spring-seata.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mysql.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mybatis-plus.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-rabbitmq.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-redis.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-eaglemap.yml
group: SHARED_GROUP
refresh: false

View File

@@ -0,0 +1,36 @@
server:
port: 18082
tomcat:
uri-encoding: UTF-8
threads:
max: 1000
min-spare: 30
spring:
cloud:
nacos:
username: nacos
password: nacos
server-addr: nacos-service.yjy-public-slwl-java.svc.cluster.local:8848
discovery:
namespace: 92312ba8-1119-440f-81af-c29618df303b
config:
namespace: 92312ba8-1119-440f-81af-c29618df303b
shared-configs: #共享配置
- data-id: shared-spring-seata.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mysql.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mybatis-plus.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-rabbitmq.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-redis.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-eaglemap.yml
group: SHARED_GROUP
refresh: false

View File

@@ -0,0 +1,25 @@
application:
version: v1.0
logging:
config: classpath:logback-spring.xml
spring:
application:
name: sl-express-ms-oms
main:
allow-circular-references: true #允许bean循环依赖
profiles:
active: local
mvc:
pathmatch:
#解决异常swagger Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
#因为Springfox使用的路径匹配是基于AntPathMatcher的而Spring Boot 2.6.X使用的是PathPatternMatcher
matching-strategy: ant_path_matcher
sl:
swagger:
package-path: com.sl.ms.oms.controller
title: 神领物流 - 订单微服务接口文档
description: 该微服务完成订单相关业务。
contact-name: 传智教育·研究院
contact-url: http://www.itcast.cn/
contact-email: yjy@itcast.cn
version: ${application.version}

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--scan: 当此属性设置为true时配置文件如果发生改变将会被重新加载默认值为true。-->
<!--scanPeriod: 设置监测配置文件是否有修改的时间间隔如果没有给出时间单位默认单位是毫秒。当scan为true时此属性生效。默认的时间间隔为1分钟。-->
<!--debug: 当此属性设置为true时将打印出logback内部日志信息实时查看logback运行状态。默认值为false。-->
<configuration debug="false" scan="false" scanPeriod="60 seconds">
<springProperty scope="context" name="appName" source="spring.application.name"/>
<!--文件名-->
<property name="logback.appname" value="${appName}"/>
<!--文件位置-->
<property name="logback.logdir" value="/data/logs"/>
<!-- 定义控制台输出 -->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} - [%thread] - %-5level - %logger{50} - %msg%n</pattern>
</layout>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<File>${logback.logdir}/${logback.appname}/${logback.appname}.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${logback.logdir}/${logback.appname}/${logback.appname}.%d{yyyy-MM-dd}.log.zip</FileNamePattern>
<maxHistory>90</maxHistory>
</rollingPolicy>
<encoder>
<charset>UTF-8</charset>
<pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>
</encoder>
</appender>
<!--evel:用来设置打印级别大小写无关TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF-->
<!--不能设置为INHERITED或者同义词NULL。默认是DEBUG。-->
<root level="INFO">
<appender-ref ref="stdout"/>
</root>
</configuration>

View File

@@ -0,0 +1,60 @@
package com.sl.ms.oms.service.impl;
import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONUtil;
import com.itheima.em.sdk.EagleMapTemplate;
import com.itheima.em.sdk.enums.ProviderEnum;
import com.itheima.em.sdk.vo.Coordinate;
import com.sl.ms.oms.dto.MailingSaveDTO;
import com.sl.ms.oms.dto.OrderDTO;
import com.sl.ms.oms.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.util.Map;
@Slf4j
@SpringBootTest
class OrderServiceImplTest {
@Resource
private OrderService orderService;
@Resource
private EagleMapTemplate eagleMapTemplate;
@Test
void mailingSave() throws Exception {
String json = "{\n" +
" \"goodsName\": \"食品\",\n" +
" \"goodsType\": \"1\",\n" +
" \"totalWeight\": \"1\",\n" +
" \"totalVolume\": \"1\",\n" +
" \"memberId\": 12323432453466712,\n" +
" \"payMethod\": 1,\n" +
" \"pickUpTime\": \"2022-07-25 13:59:25\",\n" +
" \"pickupType\": 2,\n" +
" \"receiptAddress\": 1,\n" +
" \"sendAddress\": 2\n" +
"}";
OrderDTO orderDTO = orderService.mailingSave(JSONUtil.toBean(json, MailingSaveDTO.class));
}
@Test
void eagleMap() {
double sendLnt = Double.parseDouble("121.95");
double sendLat = Double.parseDouble("30.88");
double receiveLnt = Double.parseDouble("121.71");
double receiveLat = Double.parseDouble("31.03");
Coordinate origin = new Coordinate(sendLnt, sendLat);
Coordinate destination = new Coordinate(receiveLnt, receiveLat);
//设置高德地图参数,默认是不返回预计耗时的,需要额外设置参数
Map<String, Object> param = MapUtil.<String, Object>builder().put("show_fields", "cost").build();
String driving = this.eagleMapTemplate.opsForDirection().driving(ProviderEnum.AMAP, origin, destination, param);
log.info(driving);
}
}