|
|
@@ -0,0 +1,333 @@
|
|
|
+package org.dromara.system.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.util.IdUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import org.dromara.common.core.service.UserService;
|
|
|
+import org.dromara.common.core.utils.MapstructUtils;
|
|
|
+import org.dromara.common.core.utils.StringUtils;
|
|
|
+import org.dromara.common.mybatis.core.page.PageQuery;
|
|
|
+import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
|
+import org.dromara.common.satoken.utils.LoginHelper;
|
|
|
+import org.dromara.system.domain.SysUser;
|
|
|
+import org.dromara.system.domain.TblDzbcCargoItem;
|
|
|
+import org.dromara.system.domain.TblDzbcCargoOrder;
|
|
|
+import org.dromara.system.domain.TblDzbcDriverTrip;
|
|
|
+import org.dromara.system.domain.TblDzbcSitePrice;
|
|
|
+import org.dromara.system.domain.bo.CargoItemBo;
|
|
|
+import org.dromara.system.domain.bo.CargoOrderSubmitBo;
|
|
|
+import org.dromara.system.domain.bo.TblDzbcCargoOrderBo;
|
|
|
+import org.dromara.system.domain.vo.SysUserVo;
|
|
|
+import org.dromara.system.domain.vo.TblDzbcCargoItemVo;
|
|
|
+import org.dromara.system.domain.vo.TblDzbcCargoOrderVo;
|
|
|
+import org.dromara.system.domain.vo.TblDzbcDriverTripVo;
|
|
|
+import org.dromara.system.mapper.TblDzbcCargoItemMapper;
|
|
|
+import org.dromara.system.mapper.TblDzbcCargoOrderMapper;
|
|
|
+import org.dromara.system.mapper.TblDzbcDriverTripMapper;
|
|
|
+import org.dromara.system.mapper.TblDzbcSitePriceMapper;
|
|
|
+import org.dromara.system.service.ISysUserService;
|
|
|
+import org.dromara.system.service.ITblDzbcCargoOrderService;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.util.Assert;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+
|
|
|
+import java.util.Collection;
|
|
|
+import java.util.List;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 货物订单Service业务层处理
|
|
|
+ *
|
|
|
+ * @author Claude
|
|
|
+ * @date 2026-01-15
|
|
|
+ */
|
|
|
+@RequiredArgsConstructor
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+public class TblDzbcCargoOrderServiceImpl implements ITblDzbcCargoOrderService {
|
|
|
+
|
|
|
+ private final TblDzbcCargoOrderMapper baseMapper;
|
|
|
+ private final TblDzbcCargoItemMapper cargoItemMapper;
|
|
|
+ private final TblDzbcDriverTripMapper driverTripMapper;
|
|
|
+ private final TblDzbcSitePriceMapper sitePriceMapper;
|
|
|
+ private final ISysUserService userService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询货物订单
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public TblDzbcCargoOrderVo queryById(Long id) {
|
|
|
+ TblDzbcCargoOrderVo vo = baseMapper.selectVoById(id);
|
|
|
+ if (vo != null) {
|
|
|
+ fillCargoItems(vo);
|
|
|
+ }
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询货物订单列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public TableDataInfo<TblDzbcCargoOrderVo> queryPageList(TblDzbcCargoOrderBo bo, PageQuery pageQuery) {
|
|
|
+ LambdaQueryWrapper<TblDzbcCargoOrder> lqw = buildQueryWrapper(bo);
|
|
|
+ Page<TblDzbcCargoOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
|
|
+ result.getRecords().forEach(this::fillCargoItems);
|
|
|
+ return TableDataInfo.build(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询货物订单列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<TblDzbcCargoOrderVo> queryList(TblDzbcCargoOrderBo bo) {
|
|
|
+ LambdaQueryWrapper<TblDzbcCargoOrder> lqw = buildQueryWrapper(bo);
|
|
|
+ List<TblDzbcCargoOrderVo> list = baseMapper.selectVoList(lqw);
|
|
|
+ list.forEach(this::fillCargoItems);
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据司机任务ID查询订单列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<TblDzbcCargoOrderVo> queryByTripId(Long tripId) {
|
|
|
+ // 使用 LambdaQueryWrapper 替代未实现的 XML 方法 selectByTripId
|
|
|
+ List<TblDzbcCargoOrderVo> list = baseMapper.selectVoList(new LambdaQueryWrapper<TblDzbcCargoOrder>()
|
|
|
+ .eq(TblDzbcCargoOrder::getTripId, tripId));
|
|
|
+ list.forEach(this::fillCargoItems);
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据用户ID查询订单列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<TblDzbcCargoOrderVo> queryByUserId(Long userId) {
|
|
|
+ // 使用 LambdaQueryWrapper 替代未实现的 XML 方法 selectByUserId
|
|
|
+ List<TblDzbcCargoOrderVo> list = baseMapper.selectVoList(new LambdaQueryWrapper<TblDzbcCargoOrder>()
|
|
|
+ .eq(TblDzbcCargoOrder::getUserId, userId));
|
|
|
+ list.forEach(this::fillCargoItems);
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 提交货物订单
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public TblDzbcCargoOrderVo submitOrder(CargoOrderSubmitBo bo) {
|
|
|
+ // 验证司机任务
|
|
|
+ TblDzbcDriverTripVo trip = driverTripMapper.selectByTripNo(bo.getTripNo());
|
|
|
+ Assert.notNull(trip, "司机任务不存在");
|
|
|
+ Assert.isTrue(trip.getStatus() != null && trip.getStatus() == 1, "任务未开始或已结束");
|
|
|
+
|
|
|
+ // 创建订单
|
|
|
+ TblDzbcCargoOrder order = new TblDzbcCargoOrder();
|
|
|
+ order.setOrderNo(generateOrderNo());
|
|
|
+ order.setTripId(trip.getId());
|
|
|
+ order.setTripNo(bo.getTripNo());
|
|
|
+ order.setUserId(LoginHelper.getUserId());
|
|
|
+
|
|
|
+ SysUserVo user = userService.selectUserById(order.getUserId());
|
|
|
+ Assert.notNull(user, "用户不存在");
|
|
|
+
|
|
|
+ // 设置用户信息(这里假设从登录信息获取,实际可能需要查询用户表)
|
|
|
+ order.setUserName(user.getUserName());
|
|
|
+ order.setUserPhone(user.getPhonenumber());
|
|
|
+
|
|
|
+ order.setSenderName(bo.getSenderName());
|
|
|
+ order.setSenderPhone(bo.getSenderPhone());
|
|
|
+ order.setReceiverName(bo.getReceiverName());
|
|
|
+ order.setReceiverPhone(bo.getReceiverPhone());
|
|
|
+ order.setFromSiteId(bo.getFromSiteId());
|
|
|
+ order.setToSiteId(bo.getToSiteId());
|
|
|
+
|
|
|
+ // 设置货物信息
|
|
|
+ if (bo.getItems() != null && !bo.getItems().isEmpty()) {
|
|
|
+ order.setCargoCount(bo.getItems().size());
|
|
|
+ // 计算总重量和总价值
|
|
|
+ double totalWeight = 0;
|
|
|
+ double totalValue = 0;
|
|
|
+ for (CargoItemBo item : bo.getItems()) {
|
|
|
+ if (item.getWeight() != null) {
|
|
|
+ totalWeight += item.getWeight().doubleValue();
|
|
|
+ }
|
|
|
+ if (item.getValue() != null) {
|
|
|
+ totalValue += item.getValue().doubleValue();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ order.setCargoWeight(new java.math.BigDecimal(totalWeight));
|
|
|
+ order.setCargoValue(new java.math.BigDecimal(totalValue));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算价格 - 根据起始站点和送达站点从价格表 ext2 获取带货价格
|
|
|
+ TblDzbcSitePrice sitePrice = sitePriceMapper.selectOne(new LambdaQueryWrapper<TblDzbcSitePrice>()
|
|
|
+ .eq(TblDzbcSitePrice::getPathId, trip.getPathId())
|
|
|
+ .eq(TblDzbcSitePrice::getFromSiteId, bo.getFromSiteId())
|
|
|
+ .eq(TblDzbcSitePrice::getToSiteId, bo.getToSiteId())
|
|
|
+ .last("LIMIT 1"));
|
|
|
+
|
|
|
+ int freightPrice = 0;
|
|
|
+ if (sitePrice != null && StrUtil.isNotBlank(sitePrice.getExt2())) {
|
|
|
+ try {
|
|
|
+ // ext2 是 JSON 格式,需要解析获取 cargoPrice
|
|
|
+ cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(sitePrice.getExt2());
|
|
|
+ if (jsonObject.containsKey("cargoPrice")) {
|
|
|
+ freightPrice = jsonObject.getInt("cargoPrice", 0);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("Failed to parse cargoPrice from ext2 JSON for site price id: {}", sitePrice.getId(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ order.setPrice(freightPrice);
|
|
|
+
|
|
|
+ order.setPayStatus(0); // 待支付
|
|
|
+ order.setStatus(0); // 待发货
|
|
|
+ order.setRemark(bo.getRemark());
|
|
|
+
|
|
|
+ // 保存订单
|
|
|
+ baseMapper.insert(order);
|
|
|
+
|
|
|
+ // 保存货物明细
|
|
|
+ if (bo.getItems() != null && !bo.getItems().isEmpty()) {
|
|
|
+ for (CargoItemBo itemBo : bo.getItems()) {
|
|
|
+ TblDzbcCargoItem item = new TblDzbcCargoItem();
|
|
|
+ item.setOrderId(order.getId());
|
|
|
+ item.setOrderNo(order.getOrderNo());
|
|
|
+ item.setCargoName(itemBo.getCargoName());
|
|
|
+ item.setCargoType(itemBo.getCargoType());
|
|
|
+ item.setQuantity(itemBo.getQuantity());
|
|
|
+ item.setUnit(itemBo.getUnit());
|
|
|
+ item.setWeight(itemBo.getWeight());
|
|
|
+ item.setLength(itemBo.getLength());
|
|
|
+ item.setWidth(itemBo.getWidth());
|
|
|
+ item.setHeight(itemBo.getHeight());
|
|
|
+ item.setValue(itemBo.getValue());
|
|
|
+ if (itemBo.getImages() != null && !itemBo.getImages().isEmpty()) {
|
|
|
+ item.setImageUrls(JSONUtil.toJsonStr(itemBo.getImages()));
|
|
|
+ }
|
|
|
+ item.setRemark(itemBo.getRemark());
|
|
|
+ cargoItemMapper.insert(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新司机任务的货物统计
|
|
|
+ updateTripCargoStats(trip.getId());
|
|
|
+
|
|
|
+ // 返回完整订单信息
|
|
|
+ return queryById(order.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 修改货物订单
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Boolean updateByBo(TblDzbcCargoOrderBo bo) {
|
|
|
+ TblDzbcCargoOrder update = MapstructUtils.convert(bo, TblDzbcCargoOrder.class);
|
|
|
+ validEntityBeforeSave(update);
|
|
|
+ return baseMapper.updateById(update) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新订单状态
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Boolean updateStatus(Long id, Integer status) {
|
|
|
+ TblDzbcCargoOrder order = new TblDzbcCargoOrder();
|
|
|
+ order.setId(id);
|
|
|
+ order.setStatus(status);
|
|
|
+ return baseMapper.updateById(order) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量删除货物订单
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
|
|
+ if (isValid) {
|
|
|
+ // TODO 做一些业务上的校验,判断是否需要校验
|
|
|
+ }
|
|
|
+ return baseMapper.deleteBatchIds(ids) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建查询条件
|
|
|
+ */
|
|
|
+ private LambdaQueryWrapper<TblDzbcCargoOrder> buildQueryWrapper(TblDzbcCargoOrderBo bo) {
|
|
|
+ LambdaQueryWrapper<TblDzbcCargoOrder> lqw = Wrappers.lambdaQuery();
|
|
|
+ lqw.eq(bo.getId() != null, TblDzbcCargoOrder::getId, bo.getId());
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), TblDzbcCargoOrder::getOrderNo, bo.getOrderNo());
|
|
|
+ lqw.eq(bo.getTripId() != null, TblDzbcCargoOrder::getTripId, bo.getTripId());
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getTripNo()), TblDzbcCargoOrder::getTripNo, bo.getTripNo());
|
|
|
+ lqw.eq(bo.getUserId() != null, TblDzbcCargoOrder::getUserId, bo.getUserId());
|
|
|
+ lqw.eq(bo.getFromSiteId() != null, TblDzbcCargoOrder::getFromSiteId, bo.getFromSiteId());
|
|
|
+ lqw.eq(bo.getToSiteId() != null, TblDzbcCargoOrder::getToSiteId, bo.getToSiteId());
|
|
|
+ lqw.eq(bo.getPayStatus() != null, TblDzbcCargoOrder::getPayStatus, bo.getPayStatus());
|
|
|
+ lqw.eq(bo.getStatus() != null, TblDzbcCargoOrder::getStatus, bo.getStatus());
|
|
|
+
|
|
|
+ if (bo.getParams() != null) {
|
|
|
+ // 处理时间范围查询等额外参数
|
|
|
+ if (bo.getParams().containsKey("beginTime")) {
|
|
|
+ lqw.ge(TblDzbcCargoOrder::getCreateTime, bo.getParams().get("beginTime"));
|
|
|
+ }
|
|
|
+ if (bo.getParams().containsKey("endTime")) {
|
|
|
+ lqw.le(TblDzbcCargoOrder::getCreateTime, bo.getParams().get("endTime"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ lqw.orderByDesc(TblDzbcCargoOrder::getCreateTime);
|
|
|
+ return lqw;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存前的数据校验
|
|
|
+ */
|
|
|
+ private void validEntityBeforeSave(TblDzbcCargoOrder entity) {
|
|
|
+ // TODO 做一些数据校验,如唯一约束
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 填充货物明细
|
|
|
+ */
|
|
|
+ private void fillCargoItems(TblDzbcCargoOrderVo vo) {
|
|
|
+ if (vo == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 使用 LambdaQueryWrapper 替代未实现的 XML 方法 selectByOrderId
|
|
|
+ List<TblDzbcCargoItemVo> items = cargoItemMapper.selectVoList(new LambdaQueryWrapper<TblDzbcCargoItem>()
|
|
|
+ .eq(TblDzbcCargoItem::getOrderId, vo.getId()));
|
|
|
+ vo.setItems(items);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新司机任务的货物统计
|
|
|
+ */
|
|
|
+ private void updateTripCargoStats(Long tripId) {
|
|
|
+ // 使用 LambdaQueryWrapper 替代未实现的 XML 方法 selectByTripId
|
|
|
+ List<TblDzbcCargoOrderVo> orders = baseMapper.selectVoList(new LambdaQueryWrapper<TblDzbcCargoOrder>()
|
|
|
+ .eq(TblDzbcCargoOrder::getTripId, tripId));
|
|
|
+ int cargoCount = orders.size();
|
|
|
+ int totalPrice = orders.stream()
|
|
|
+ .mapToInt(order -> order.getPrice() != null ? order.getPrice() : 0)
|
|
|
+ .sum();
|
|
|
+
|
|
|
+ TblDzbcDriverTrip trip = new TblDzbcDriverTrip();
|
|
|
+ trip.setId(tripId);
|
|
|
+ trip.setCargoCount(cargoCount);
|
|
|
+ trip.setCargoTotalPrice(totalPrice);
|
|
|
+ driverTripMapper.updateById(trip);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成订单编号
|
|
|
+ */
|
|
|
+ private String generateOrderNo() {
|
|
|
+ return "CARGO" + cn.hutool.core.date.DateUtil.format(cn.hutool.core.date.DateUtil.date(), "yyyyMMddHHmmss")
|
|
|
+ + IdUtil.getSnowflakeNextIdStr().substring(8);
|
|
|
+ }
|
|
|
+}
|