修复业务模块bug

This commit is contained in:
2026-08-13 14:06:53 +08:00
parent 2441fb3023
commit 31dbd731dd
12 changed files with 106 additions and 4 deletions
@@ -114,6 +114,9 @@ public class ShippingTemplate extends TenantEntity {
@Schema(description = "所属组织")
private String deptName;
@Schema(description = "基本信息备注")
private String basicRemark;
@Schema(description = "备注")
private String remark;
@@ -30,6 +30,7 @@ import org.springblade.core.tenant.mp.TenantEntity;
import java.io.Serial;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 运输计划实体类
@@ -114,6 +115,9 @@ public class TransportPlan extends TenantEntity {
@Schema(description = "货物信息")
private String goodsJson;
@Schema(description = "费用信息")
private String freightJson;
@Schema(description = "附件")
private String attachmentsJson;
@@ -123,6 +127,15 @@ public class TransportPlan extends TenantEntity {
@Schema(description = "业务状态")
private String businessStatus;
@Schema(description = "调度人ID")
private Long dispatcherUserId;
@Schema(description = "调度人姓名")
private String dispatcherUserName;
@Schema(description = "调度时间")
private LocalDateTime dispatchTime;
@Schema(description = "所属组织ID")
private Long deptId;
@@ -27,8 +27,10 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.transport.pojo.entity.TransportPlan;
import org.springblade.transport.pojo.entity.Waybill;
import java.io.Serial;
import java.util.List;
/**
* 运输计划视图实体类
@@ -62,5 +64,9 @@ public class TransportPlanVO extends TransportPlan {
@Schema(description = "业务状态名称")
private String businessStatusName;
@TableField(exist = false)
@Schema(description = "计划调度生成的运单")
private List<Waybill> dispatchRows;
}
@@ -186,7 +186,10 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
waybill.setEstimatedStartTime(date(dispatch, "estimatedStartTime")); waybill.setEstimatedEndTime(date(dispatch, "estimatedEndTime"));
waybill.setUnitPrice(unitPrice); waybill.setPriceUnit(string(dispatch, "priceUnit"));
waybill.setGoodsJson(JsonUtil.toJson(dispatches));
waybill.setFreightJson(JsonUtil.toJson(Map.of("weightTotal", quantity, "freightTotal", freightTotal))); waybill.setBusinessStatus("pending");
BigDecimal otherFeeTotal = nullableDecimal(dispatch, "otherFeeTotal");
waybill.setOtherFeeTotal(otherFeeTotal);
String freightJson = string(dispatch, "freightJson");
waybill.setFreightJson(Func.isNotEmpty(freightJson) ? freightJson : buildFreightJson(quantity, freightTotal, dispatch)); waybill.setBusinessStatus("pending");
waybill.setTaskEntryMode(string(dispatch, "documentType", "运单")); waybill.setRelationNo(string(dispatch, "relationNo")); waybill.setCarrierJson(JsonUtil.toJson(dispatch));
waybillService.submit(waybill);
}
@@ -204,7 +207,11 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
plan.setArrivalName(string(first, "arrivalName")); plan.setArrivalAddress(string(first, "arrivalAddress"));
plan.setArrivalContact(string(first, "arrivalContact")); plan.setArrivalPhone(string(first, "arrivalPhone"));
plan.setPlanStartDate(date(first, "estimatedStartTime")); plan.setPlanEndDate(date(first, "estimatedEndTime"));
plan.setGoodsJson(JsonUtil.toJson(dispatches)); plan.setDataSource("多联总单调度"); plan.setBusinessStatus("waiting_dispatch");
plan.setGoodsJson(JsonUtil.toJson(dispatches));
String freightJson = string(first, "freightJson");
BigDecimal freightTotal = dispatches.stream().map(item -> decimal(item, "quantity").multiply(decimal(item, "unitPrice"))).reduce(BigDecimal.ZERO, BigDecimal::add);
plan.setFreightJson(Func.isNotEmpty(freightJson) ? freightJson : buildFreightJson(null, freightTotal, first));
plan.setDataSource("多联总单调度"); plan.setBusinessStatus("waiting_dispatch");
plan.setRemark(string(first, "remark"));
transportPlanService.submit(plan);
}
@@ -308,6 +315,9 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
String key = goodsKey(dispatch);
BigDecimal quantity = decimal(dispatch, "quantity");
if (quantity.compareTo(BigDecimal.ZERO) <= 0) throw new ServiceException("本次数量必须大于0");
if (Func.isEmpty(string(dispatch, "quantityUnit"))) throw new ServiceException("数量单位不能为空");
if (Func.isEmpty(string(dispatch, "unitPrice"))) throw new ServiceException("单价不能为空");
if (Func.isEmpty(string(dispatch, "priceUnit"))) throw new ServiceException("单价单位不能为空");
if (!available.containsKey(key)) throw new ServiceException("调度货物必须来自总单配置");
LocalDate startDate = date(dispatch, "estimatedStartTime"); LocalDate endDate = date(dispatch, "estimatedEndTime");
if (startDate == null || endDate == null) throw new ServiceException("预计发货日期和预计完成日期不能为空");
@@ -354,9 +364,19 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
return result;
}
private BigDecimal totalQuantity(List<Map<String, Object>> goods) { return goods.stream().map(item -> decimal(item, "quantity")).reduce(BigDecimal.ZERO, BigDecimal::add); }
private String buildFreightJson(BigDecimal quantity, BigDecimal freightTotal, Map<String, Object> dispatch) {
Map<String, Object> freight = new LinkedHashMap<>();
if (quantity != null) freight.put("weightTotal", quantity);
freight.put("freightTotal", freightTotal);
freight.put("totalFreightAmount", freightTotal.add(Objects.requireNonNullElse(nullableDecimal(dispatch, "otherFeeTotal"), BigDecimal.ZERO)));
freight.put("otherFreightAmount", string(dispatch, "otherFeeTotal", ""));
freight.put("currency", string(dispatch, "currency", "CNY"));
return JsonUtil.toJson(freight);
}
private String waybillGroupKey(Map<String, Object> dispatch) { return String.join("\u0000", string(dispatch, "segmentNo", ""), string(dispatch, "carrierType", ""), string(dispatch, "carrierName", ""), string(dispatch, "driverName", ""), string(dispatch, "vehicleNo", "")); }
private String joinGoodsField(List<Map<String, Object>> dispatches, String field) { return dispatches.stream().map(item -> string(item, field, "")).filter(Func::isNotEmpty).distinct().reduce((left, right) -> left + "" + right).orElse(""); }
private BigDecimal decimal(Map<String, Object> values, String key) { try { return new BigDecimal(string(values, key, "0")); } catch (Exception exception) { return BigDecimal.ZERO; } }
private BigDecimal nullableDecimal(Map<String, Object> values, String key) { String value = string(values, key); if (Func.isEmpty(value)) return null; try { return new BigDecimal(value); } catch (Exception exception) { return null; } }
private String goodsKey(Map<String, Object> values) { return goodsKey(string(values, "cargoName"), string(values, "cargoType")); }
private String goodsKey(String cargoName, String cargoType) { return String.valueOf(cargoName) + "\u0000" + String.valueOf(cargoType); }
private LocalDate date(Map<String, Object> values, String key) { String value = string(values, key); if (Func.isEmpty(value)) return null; try { return LocalDate.parse(value.substring(0, 10)); } catch (Exception exception) { throw new ServiceException("日期格式不正确"); } }
@@ -160,6 +160,7 @@ public class ShippingTemplateServiceImpl extends BaseServiceImpl<ShippingTemplat
target.setGoodsJson(source.getGoodsJson());
target.setFreightJson(source.getFreightJson());
target.setAttachmentsJson(source.getAttachmentsJson());
target.setBasicRemark(source.getBasicRemark());
target.setRemark(source.getRemark());
target.setTemplateName(source.getTemplateName() + " - 副本");
target.setTemplateCode(nextCode());
@@ -266,6 +267,7 @@ public class ShippingTemplateServiceImpl extends BaseServiceImpl<ShippingTemplat
shippingTemplate.setFreightJson(TransportBusinessSupport.trimToNull(shippingTemplate.getFreightJson()));
shippingTemplate.setAttachmentsJson(TransportBusinessSupport.trimToNull(shippingTemplate.getAttachmentsJson()));
shippingTemplate.setDeptName(TransportBusinessSupport.trimToNull(shippingTemplate.getDeptName()));
shippingTemplate.setBasicRemark(TransportBusinessSupport.trimToNull(shippingTemplate.getBasicRemark()));
shippingTemplate.setRemark(TransportBusinessSupport.trimToNull(shippingTemplate.getRemark()));
if (Func.isEmpty(shippingTemplate.getDeptId())) {
Dept dept = TransportBusinessSupport.currentDept("发货模板");
@@ -302,6 +304,7 @@ public class ShippingTemplateServiceImpl extends BaseServiceImpl<ShippingTemplat
validateFreight(shippingTemplate);
TransportBusinessSupport.validateLength(shippingTemplate.getAttachmentsJson(), 8000, "附件不能超过8000字");
TransportBusinessSupport.validateLength(shippingTemplate.getDeptName(), 255, "所属组织不能超过255字");
TransportBusinessSupport.validateLength(shippingTemplate.getBasicRemark(), 200, "基本信息备注不能超过200字");
TransportBusinessSupport.validateLength(shippingTemplate.getRemark(), 500, "备注不能超过500字");
}
@@ -28,6 +28,8 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.jackson.JsonUtil;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
@@ -36,6 +38,7 @@ import org.springblade.system.pojo.entity.Dept;
import org.springblade.transport.excel.TransportPlanExcel;
import org.springblade.transport.excel.TransportPlanImportExcel;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.springblade.transport.mapper.TransportPlanMapper;
import org.springblade.transport.pojo.dto.TransportPlanDispatchRequest;
@@ -51,9 +54,12 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 运输计划 服务实现类
@@ -69,12 +75,16 @@ public class TransportPlanServiceImpl extends BaseServiceImpl<TransportPlanMappe
@Override
public IPage<TransportPlanVO> selectTransportPlanPage(IPage<TransportPlan> page, TransportPlanVO transportPlan) {
IPage<TransportPlan> entityPage = page(page, buildQuery(transportPlan));
return TransportPlanWrapper.build().pageVO(entityPage);
IPage<TransportPlanVO> resultPage = TransportPlanWrapper.build().pageVO(entityPage);
fillDispatchRows(resultPage.getRecords());
return resultPage;
}
@Override
public TransportPlanVO detail(Long id) {
return TransportPlanWrapper.build().entityVO(loadEditable(id, false));
TransportPlanVO transportPlan = TransportPlanWrapper.build().entityVO(loadEditable(id, false));
fillDispatchRows(Collections.singletonList(transportPlan));
return transportPlan;
}
@Override
@@ -321,6 +331,9 @@ public class TransportPlanServiceImpl extends BaseServiceImpl<TransportPlanMappe
waybillService.submit(waybill);
}
plan.setBusinessStatus("dispatching");
plan.setDispatcherUserId(AuthUtil.getUserId());
plan.setDispatcherUserName(AuthUtil.getUserName());
plan.setDispatchTime(LocalDateTime.now());
updateById(plan);
return request.getWaybills().size();
}
@@ -347,6 +360,25 @@ public class TransportPlanServiceImpl extends BaseServiceImpl<TransportPlanMappe
return updateById(transportPlan);
}
private void fillDispatchRows(List<TransportPlanVO> plans) {
if (Func.isEmpty(plans)) {
return;
}
List<Long> planIds = plans.stream().map(TransportPlanVO::getId).filter(Objects::nonNull).toList();
if (Func.isEmpty(planIds)) {
plans.forEach(plan -> plan.setDispatchRows(Collections.emptyList()));
return;
}
Map<Long, List<Waybill>> waybillsByPlanId = waybillService.list(Wrappers.<Waybill>lambdaQuery()
.eq(Waybill::getIsDeleted, 0)
.in(Waybill::getPlanId, planIds))
.stream()
.collect(Collectors.groupingBy(Waybill::getPlanId));
plans.forEach(plan -> plan.setDispatchRows(
waybillsByPlanId.getOrDefault(plan.getId(), Collections.emptyList())
));
}
private LambdaQueryWrapper<TransportPlan> buildQuery(TransportPlanVO transportPlan) {
TransportBusinessSupport.validateAllDept(transportPlan.getAllDept(), "运输计划");
LambdaQueryWrapper<TransportPlan> queryWrapper = Wrappers.<TransportPlan>lambdaQuery().eq(TransportPlan::getIsDeleted, 0);
@@ -422,6 +422,9 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
}
private void prepare(Waybill waybill) {
if (isSentinelMinusOne(waybill.getQuantity())) waybill.setQuantity(null);
if (isSentinelMinusOne(waybill.getMileage())) waybill.setMileage(null);
if (isSentinelMinusOne(waybill.getUnitPrice())) waybill.setUnitPrice(null);
waybill.setWaybillNo(TransportBusinessSupport.trimToNull(waybill.getWaybillNo()));
waybill.setProjectName(TransportBusinessSupport.trimToNull(waybill.getProjectName()));
waybill.setContractName(TransportBusinessSupport.trimToNull(waybill.getContractName()));
@@ -481,6 +484,10 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
if (Func.isEmpty(waybill.getBusinessStatus())) { waybill.setBusinessStatus("pending"); }
}
private boolean isSentinelMinusOne(BigDecimal value) {
return value != null && value.compareTo(BigDecimal.ONE.negate()) == 0;
}
private void validate(Waybill waybill) {
TransportBusinessSupport.validateRequired(waybill.getProjectName(), "项目不能为空");
TransportBusinessSupport.validateRequired(waybill.getContractName(), "客户合同不能为空");
@@ -0,0 +1,2 @@
ALTER TABLE `blade_shipping_template`
ADD COLUMN `basic_remark` varchar(200) DEFAULT NULL COMMENT '基本信息备注' AFTER `dept_name`;
+6
View File
@@ -144,6 +144,7 @@ CREATE TABLE `blade_shipping_template` (
`attachments_json` text DEFAULT NULL COMMENT '附件',
`dept_id` bigint(20) DEFAULT NULL COMMENT '所属组织ID',
`dept_name` varchar(100) DEFAULT NULL COMMENT '所属组织',
`basic_remark` varchar(200) DEFAULT NULL COMMENT '基本信息备注',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_shipping_template_dept` (`dept_id`) USING BTREE,
@@ -187,9 +188,13 @@ CREATE TABLE `blade_transport_plan` (
`arrival_contact` varchar(100) DEFAULT NULL COMMENT '收货联系人',
`arrival_phone` varchar(100) DEFAULT NULL COMMENT '收货联系方式',
`goods_json` text DEFAULT NULL COMMENT '货物信息',
`freight_json` text DEFAULT NULL COMMENT '费用信息',
`attachments_json` text DEFAULT NULL COMMENT '附件',
`data_source` varchar(100) DEFAULT NULL COMMENT '数据来源',
`business_status` varchar(100) DEFAULT NULL COMMENT '业务状态',
`dispatcher_user_id` bigint(20) DEFAULT NULL COMMENT '调度人ID',
`dispatcher_user_name` varchar(100) DEFAULT NULL COMMENT '调度人姓名',
`dispatch_time` datetime DEFAULT NULL COMMENT '调度时间',
`dept_id` bigint(20) DEFAULT NULL COMMENT '所属组织ID',
`dept_name` varchar(100) DEFAULT NULL COMMENT '所属组织',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
@@ -279,6 +284,7 @@ CREATE TABLE `blade_waybill` (
`remark` varchar(200) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_waybill_dept` (`dept_id`) USING BTREE,
KEY `idx_waybill_plan_id` (`plan_id`) USING BTREE,
KEY `idx_waybill_create_time` (`create_time`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='运单管理';
@@ -0,0 +1,5 @@
-- 运输计划计划调度记录调度人和调度时间
ALTER TABLE `blade_transport_plan`
ADD COLUMN `dispatcher_user_id` bigint(20) DEFAULT NULL COMMENT '调度人ID' AFTER `business_status`,
ADD COLUMN `dispatcher_user_name` varchar(100) DEFAULT NULL COMMENT '调度人姓名' AFTER `dispatcher_user_id`,
ADD COLUMN `dispatch_time` datetime DEFAULT NULL COMMENT '调度时间' AFTER `dispatcher_user_name`;
@@ -0,0 +1,3 @@
-- 多联总单调度生成运输计划费用信息
ALTER TABLE `blade_transport_plan`
ADD COLUMN `freight_json` text DEFAULT NULL COMMENT '费用信息' AFTER `goods_json`;
@@ -0,0 +1,2 @@
ALTER TABLE `blade_waybill`
ADD KEY `idx_waybill_plan_id` (`plan_id`) USING BTREE;