Merge branch 'dev-bms-260826' into test

# Conflicts:
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/XxlJobServiceFeign.java
#	mhd-common/mhd-common-core/src/main/java/com/mhd/common/core/feign/ThirdPartyServiceFeign.java
#	mhd_oms/src/main/resources/bootstrap.yml
This commit is contained in:
王奎兴
2026-09-14 14:44:29 +08:00
46 changed files with 3215 additions and 174 deletions
@@ -7,9 +7,16 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mhd.common.core.domain.dto.wlhy.TmsAddressMultiDTO;
import com.mhd.common.core.domain.dto.wlhy.TmsCargoInfoDTO;
import com.mhd.common.core.domain.dto.wlhy.TmsOrderAccount;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.oms.domain.businessDocumentAddressMulti.entity.BusinessDocumentAddressMulti;
import com.mhd.oms.domain.businessDocumentAddressMulti.repository.mapper.BusinessDocumentAddressMultiMapper;
import com.mhd.oms.domain.businessDocumentCargoMulti.entity.BusinessDocumentCargoMulti;
import com.mhd.oms.domain.businessDocumentCargoMulti.repository.mapper.BusinessDocumentCargoMultiMapper;
import com.mhd.oms.domain.businessDocumentOrder.entity.BusinessDocumentOrder;
import com.mhd.oms.domain.businessDocumentOrder.repository.mapper.BusinessDocumentOrderMapper;
import com.mhd.oms.domain.businessDocumentOrderAdjust.entity.BusinessDocumentOrderAdjust;
@@ -20,11 +27,13 @@ import com.mhd.oms.domain.businessOrderAccount.BusinessOrderAccount;
import com.mhd.oms.domain.businessOrderAccount.repository.mapper.BusinessOrderAccountMapper;
import com.mhd.oms.domain.executeOrder.entity.ExecuteOrder;
import com.mhd.oms.domain.executeOrder.repository.mapper.ExecuteOrderMapper;
import com.mhd.oms.interfaces.dto.businessDocumentAddressMulti.BusinessDocumentAddressMultiDTO;
import com.mhd.oms.interfaces.dto.businessDocumentOrderAdjust.BusinessDocumentOrderAdjustAuditDTO;
import com.mhd.oms.interfaces.dto.businessDocumentOrderAdjust.BusinessDocumentOrderAdjustDTO;
import com.mhd.oms.interfaces.dto.businessDocumentOrderAdjust.BusinessDocumentOrderAdjustQueryDTO;
import com.mhd.oms.interfaces.dto.businessDocumentOrderAdjust.BusinessDocumentOrderAdjustRecordDTO;
import com.mhd.system.api.WlhyServiceFeign;
import com.mhd.system.api.domain.TmsOrderAddDTO;
import com.mhd.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -36,6 +45,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@@ -46,16 +56,23 @@ import java.util.stream.Collectors;
* 2. 费用数据源 = 前端回传的费用明细 business_order_account(feeDetailList)
* 主表金额 deliveryFreight 为其 amount 合计(冗余汇总,后端自动算)。
* 3. 是否需审核:一旦任一「金额」发生变化
* = feeDetailList 明细 amount 变化,或主表金额列变化 -> 走业务主管审核;
* = feeDetailList 明细 amount 变化,或主表金额/费用列变化 -> 走业务主管审核;
* 否则(仅改非金额字段) -> 直通。
* 「金额/费用」字段涵盖: deliveryFreight / collectedFreight / uncollectedFreight /
* collectLessFreight / transportationUnitPrice / infoFee / freightUnitPrice /
* cargoInsuranceAmount / freightCharges / freightFee / unloadingFee / customsFee /
* shortageFee / miscellaneousFee / otherFee / detentionFee,以及 settlementCurrency /
* paymentAccountId / accountName / accountInformation(结算币种+收款账户任一变化即视为费用变更)。
* 判定口径: 以后端兜底比对为准(主表金额/费用列 + 明细 amount 合计)
* 前端 amountChanged 仅作提示;后端比对结果与前端 OR 运算,避免前端误传 false 绕过审核。
* 4. 涉及金额提交 -> 仅把业务单 review_status 置为「调整待审核(3)」;主记录 AUDIT_STATUS=0(待审核)
* 不更新业务单数据,不影响其它状态(order_status / execute_status 不动)。
* 5. 审核通过 -> 覆盖业务单(金额) + 替换费用明细;review_status 一律置为 1(已审核)
* 不影响 order_status / execute_status。
* 审核驳回 -> 不更新业务单数据,review_status 还原为调整前值(主记录 before_review_status),可再次调整。
* 审核驳回 -> 不更新业务单数据,review_status 置为「调整驳回(4)」,不影响 order_status/execute_status
* 可再次调整提交审核。
* 6. 直通(未改金额) -> 覆盖业务单可编辑字段 + deliveryFreight(明细合计),并替换 business_order_account
* (逻辑删旧 is_delete=1 + 插新 is_delete=0);不改动任何审核/执行状态。
* 7. 前端以 amountChanged 告知是否改金额(默认前端判定);未传时后端兜底比对。
*
* 说明:review_status 原枚举 0未审/1通过/2驳回,新增 3=调整待审核;不改变原有用例。
*
@@ -70,12 +87,22 @@ public class BusinessDocumentOrderAdjustService {
private static final Integer AUDIT_PASS = 1; // 调整记录:审核通过
private static final Integer AUDIT_REJECT = 2; // 调整记录:驳回
/** 主表金额(费用)字段,任一变化触发审核 */
/** 业务单 review_status:调整待审核(提交涉及金额时置) */
private static final Long REVIEW_ADJUST_WAIT = 3L;
/** 业务单 review_status:调整驳回(审核驳回时置,与普通驳回 2 区分) */
private static final Long REVIEW_ADJUST_REJECT = 4L;
/** 主表金额(费用)字段,任一变化触发审核
* 含: 运费相关 8 项 + 其他费用 8 项 + 结算币种 + 收款账户(3 字段)
* 任意一项变化即需要审核(对应前端"费用合计 / 运费 / 装卸费 / 仓租及柜租(走明细) /
* 保险 / 压车(走明细) / 运输处理费(走明细) / 报关费 / 其他 / 费用合计 / 结算币种 / 收款账户") */
private static final List<String> FEE_FIELDS = Arrays.asList(
"deliveryFreight", "collectedFreight", "uncollectedFreight", "collectLessFreight",
"transportationUnitPrice", "infoFee", "freightUnitPrice", "cargoInsuranceAmount",
"freightCharges", "freightFee", "unloadingFee", "customsFee", "shortageFee",
"miscellaneousFee", "otherFee", "detentionFee");
"miscellaneousFee", "otherFee", "detentionFee",
// 结算币种 + 收款账户 任一变化也视为费用变更,需审核
"settlementCurrency", "paymentAccountId", "accountName", "accountInformation");
/** 不允许被前端调整覆盖的系统字段 */
private static final List<String> PROTECTED_FIELDS = Arrays.asList(
@@ -83,7 +110,7 @@ public class BusinessDocumentOrderAdjustService {
"orderStatus", "reviewStatus", "reviewId", "review", "reviewTime", "reviewOpinion",
"salesManager", "auditStatus", "auditBy", "auditTime",
"executeStatus", "executeId", "executeTime", "executor",
"executeOrderId", "executeOrderNumber", "adjustStatus",
"executeOrderId", "executeOrderNumber",
"isDelete", "delFlag", "createBy", "createByName", "createTime",
"updateBy", "updateByName", "updateTime",
"pushStatus", "pushTime", "pushBy", "pushByName",
@@ -112,6 +139,12 @@ public class BusinessDocumentOrderAdjustService {
@Autowired
private ExecuteOrderMapper executeOrderMapper;
@Autowired
private BusinessDocumentCargoMultiMapper businessDocumentCargoMultiMapper;
@Autowired
private BusinessDocumentAddressMultiMapper businessDocumentAddressMultiMapper;
@Autowired
private WlhyServiceFeign wlhyServiceFeign;
@@ -136,12 +169,20 @@ public class BusinessDocumentOrderAdjustService {
.eq(BusinessOrderAccount::getOrderId, dbOrder.getId())
.eq(BusinessOrderAccount::getIsDelete, 0));
// 2. 调整后的费用明细(前端);为 null 则视为保持库中不变
// 2. 调整后的费用明细(前端);为 null 则视为保持库中不变
// 兼容前端两种传法:顶层 feeDetailList,或整单回传 order.businessOrderAccountList
List<BusinessOrderAccount> newFeeList = dto.getFeeDetailList();
if ((newFeeList == null || newFeeList.isEmpty()) && front.getBusinessOrderAccountList() != null) {
newFeeList = front.getBusinessOrderAccountList();
}
// 3. 生成"调整后"业务单对象:DB原值 + 前端可编辑字段覆盖(忽略null)
BusinessDocumentOrder afterOrder = buildAfterOrder(dbOrder, front);
// 3.1 地址兼容:前端把地址放在 shipment/receipt 或 loadingAddressList/unloadAddressList
// 映射到 loading*/unload* 扁平字段(与下单主流程 BusinessDocumentOrderDomainService 一致口径)
applyAddressMapping(afterOrder, front);
// 4. 若提供了费用明细,则 deliveryFreight(合计)=明细 amount 之和,并联动到 afterOrder
boolean hasFeeDetail = newFeeList != null && !newFeeList.isEmpty();
if (hasFeeDetail) {
@@ -149,14 +190,10 @@ public class BusinessDocumentOrderAdjustService {
afterOrder.setDeliveryFreight(sum);
}
// 5. 判定是否修改了金额:以前端 amountChanged 为准(前端整单回传已自行判定)
// 前端未传则后端兜底比对(主表金额列 或 明细 amount 变化)
boolean amountChanged;
if (dto.getAmountChanged() != null) {
amountChanged = dto.getAmountChanged();
} else {
amountChanged = isAmountChanged(dbOrder, front, hasFeeDetail, dbFeeList, newFeeList);
}
// 5. 判定是否修改了金额:以后端兜底比对为准,避免前端误传 false 绕过审核
// 前端传 true 也尊重;后端比对结果与前端 OR 运算(任一为真则需审核)。
boolean backendChanged = isAmountChanged(dbOrder, front, hasFeeDetail, dbFeeList, newFeeList);
boolean amountChanged = backendChanged || Boolean.TRUE.equals(dto.getAmountChanged());
// 6. 写主记录
LoginUser loginUser = SecurityUtils.getLoginUser();
@@ -188,7 +225,7 @@ public class BusinessDocumentOrderAdjustService {
// 8b. 涉及金额:仅把业务单 review_status 置为"调整待审核(3)",其余状态(exec/orderStatus)不动,不更新业务单数据
BusinessDocumentOrder statusOnly = new BusinessDocumentOrder();
statusOnly.setId(dbOrder.getId());
statusOnly.setReviewStatus(3L); // 调整待审核
statusOnly.setReviewStatus(REVIEW_ADJUST_WAIT); // 调整待审核
businessDocumentOrderMapper.updateById(statusOnly);
}
@@ -250,11 +287,27 @@ public class BusinessDocumentOrderAdjustService {
/**
* 按业务单查询调整记录(供订单详情页"调整记录"Tab用)
* 每条记录同时带出调整后明细快照(detail),前端可自包含展示,无需再单独调详情接口
*/
public List<BusinessDocumentOrderAdjustRecordDTO> listAdjustRecordByOrder(Long orderId) {
BusinessDocumentOrderAdjustQueryDTO query = new BusinessDocumentOrderAdjustQueryDTO();
query.setOrderId(orderId);
return listAdjustRecord(query);
List<BusinessDocumentOrderAdjustRecordDTO> list = listAdjustRecord(query);
if (list == null || list.isEmpty()) {
return list;
}
// 批量取明细快照按 adjust_id 一次性拼上,避免 N+1
List<Long> adjustIds = list.stream()
.map(BusinessDocumentOrderAdjustRecordDTO::getId)
.collect(Collectors.toList());
List<BusinessDocumentOrderAdjustDetail> details = adjustDetailMapper.selectList(
new LambdaQueryWrapper<BusinessDocumentOrderAdjustDetail>()
.in(BusinessDocumentOrderAdjustDetail::getAdjustId, adjustIds)
.eq(BusinessDocumentOrderAdjustDetail::getDelFlag, 1));
Map<Long, BusinessDocumentOrderAdjustDetail> detailMap = details.stream()
.collect(Collectors.toMap(BusinessDocumentOrderAdjustDetail::getAdjustId, d -> d, (a, b) -> a));
list.forEach(vo -> vo.setDetail(detailMap.get(vo.getId())));
return list;
}
/**
@@ -353,6 +406,7 @@ public class BusinessDocumentOrderAdjustService {
syncTmsAsync(order.getGoodsNumber(), toSave);
} else {
adjust.setAuditStatus(AUDIT_REJECT);
adjust.setIsAudit(1); // 走到审核即说明该调整需要审核,保持 is_audit 与 audit_status 语义一致
adjust.setAuditBy(auditBy);
adjust.setAuditByName(auditByName);
adjust.setAuditTime(now);
@@ -361,10 +415,11 @@ public class BusinessDocumentOrderAdjustService {
adjust.setUpdateTime(now);
adjustMapper.updateById(adjust);
// 驳回:不更新业务单数据,仅把 review_status 还原为调整前值(不影响其它状态)
// 驳回:不更新业务单数据,仅把 review_status 置为「调整驳回(4)」;
// 不影响 order_status / execute_status 等其它单据状态;可再次调整提交审核
BusinessDocumentOrder statusOnly = new BusinessDocumentOrder();
statusOnly.setId(adjust.getOrderId());
statusOnly.setReviewStatus(adjust.getBeforeReviewStatus() == null ? 0L : adjust.getBeforeReviewStatus());
statusOnly.setReviewStatus(REVIEW_ADJUST_REJECT);
businessDocumentOrderMapper.updateById(statusOnly);
}
return AjaxResult.success();
@@ -383,6 +438,50 @@ public class BusinessDocumentOrderAdjustService {
return after;
}
/**
* 地址兼容映射:前端整单回传时地址在 shipment/receipt 或 loadingAddressList/unloadAddressList
* 这里统一映射到 business_document_order 的 loading 与 unload 系列扁平字段。
* 口径与 BusinessDocumentOrderDomainService 下单主流程保持一致:
* 装货取第一条地址,卸货取最后一条地址。
*/
private void applyAddressMapping(BusinessDocumentOrder after, BusinessDocumentOrder front) {
BusinessDocumentAddressMultiDTO loading = null;
BusinessDocumentAddressMultiDTO unloading = null;
// 优先取 shipment/receipt 单对象,其次取 loadingAddressList/unloadAddressList 集合
if (front.getShipment() != null) {
loading = front.getShipment();
} else if (front.getLoadingAddressList() != null && !front.getLoadingAddressList().isEmpty()) {
loading = front.getLoadingAddressList().get(0);
}
if (front.getReceipt() != null) {
unloading = front.getReceipt();
} else if (front.getUnloadAddressList() != null && !front.getUnloadAddressList().isEmpty()) {
unloading = front.getUnloadAddressList().get(front.getUnloadAddressList().size() - 1);
}
if (loading != null) {
after.setLoadingAreaId(loading.getAreaCode());
after.setLoadingName(loading.getAreaName() != null ? loading.getAreaName() : loading.getAreaCode());
after.setLoadingAddress(loading.getAddress());
after.setLoadingLongitude(loading.getLongitude());
after.setLoadingLatitude(loading.getLatitude());
after.setFreighterName(loading.getContactName());
after.setLoadingPhone(loading.getContactPhone());
after.setLoadingDate(loading.getLayDate());
}
if (unloading != null) {
after.setUnloadAreaId(unloading.getAreaCode());
after.setUnloadName(unloading.getAreaName() != null ? unloading.getAreaName() : unloading.getAreaCode());
after.setUnloadAddress(unloading.getAddress());
after.setUnloadLongitude(unloading.getLongitude());
after.setUnloadLatitude(unloading.getLatitude());
after.setDischargerName(unloading.getContactName());
after.setUnloadPhone(unloading.getContactPhone());
after.setUnloadingData(unloading.getLayDate());
}
}
private BusinessDocumentOrderAdjust buildAdjust(BusinessDocumentOrder dbOrder, LoginUser u, Date now,
boolean amountChanged, String reason) {
BusinessDocumentOrderAdjust adjust = new BusinessDocumentOrderAdjust();
@@ -421,21 +520,25 @@ public class BusinessDocumentOrderAdjustService {
}
/**
* 是否修改了金额:主表金额列变化 或 明细 amount 变化
* 是否修改了金额:主表金额/费用列变化 或 明细 amount 变化
*/
private boolean isAmountChanged(BusinessDocumentOrder dbOrder, BusinessDocumentOrder front,
boolean hasFeeDetail, List<BusinessOrderAccount> dbFeeList,
List<BusinessOrderAccount> newFeeList) {
// a) 主表金额列比对
// a) 主表金额/费用列比对(金额列用 BigDecimal 比对,字符串列用 equals 比对)
boolean mainChanged = FEE_FIELDS.stream().anyMatch(field -> {
Object newVal = BeanUtil.getFieldValue(front, field);
if (newVal == null) {
return false;
}
Object oldVal = BeanUtil.getFieldValue(dbOrder, field);
BigDecimal old = oldVal == null ? BigDecimal.ZERO : (BigDecimal) oldVal;
BigDecimal now = (BigDecimal) newVal;
return old.compareTo(now) != 0;
if (newVal instanceof BigDecimal || oldVal instanceof BigDecimal) {
BigDecimal old = oldVal == null ? BigDecimal.ZERO : new BigDecimal(oldVal.toString());
BigDecimal now = new BigDecimal(newVal.toString());
return old.compareTo(now) != 0;
}
// 字符串字段(结算币种/收款账户等)
return !newVal.toString().equals(oldVal == null ? "" : oldVal.toString());
});
if (mainChanged) {
return true;
@@ -505,6 +608,74 @@ public class BusinessDocumentOrderAdjustService {
businessOrderAccountMapper.insert(acc);
}
}
// 同步地址明细表(business_document_address_multi):逻辑删旧 + 按调整后扁平字段插新
syncAddressDetail(orderId, toSave, loginUser, now);
}
/**
* 同步地址明细表:把「调整后业务单」的装/卸货扁平字段写回 business_document_address_multi。
* 与 applyAddressMapping 口径一致(装货取第一条、卸货取最后一条),此处各保留一条。
*/
private void syncAddressDetail(Long orderId, BusinessDocumentOrder toSave, LoginUser loginUser, Date now) {
// 逻辑删旧
List<BusinessDocumentAddressMulti> oldList = businessDocumentAddressMultiMapper.selectList(
new LambdaQueryWrapper<BusinessDocumentAddressMulti>()
.eq(BusinessDocumentAddressMulti::getOrderId, String.valueOf(orderId))
.eq(BusinessDocumentAddressMulti::getDelFlag, 1));
if (oldList != null) {
for (BusinessDocumentAddressMulti old : oldList) {
old.setDelFlag(0);
old.setUpdateBy(loginUser != null ? loginUser.getUserid() : null);
old.setUpdateTime(now);
businessDocumentAddressMultiMapper.updateById(old);
}
}
Long userId = loginUser != null ? loginUser.getUserid() : null;
// 装货
BusinessDocumentAddressMulti loading = new BusinessDocumentAddressMulti();
loading.setOrderId(String.valueOf(orderId));
loading.setAreaCode(toSave.getLoadingAreaId());
loading.setAreaName(toSave.getLoadingName());
loading.setAddress(toSave.getLoadingAddress());
loading.setLongitude(toSave.getLoadingLongitude());
loading.setLatitude(toSave.getLoadingLatitude());
loading.setContactName(toSave.getFreighterName());
loading.setContactPhone(toSave.getLoadingPhone());
loading.setLayDate(toSave.getLoadingDate());
loading.setLayType(1L);
loading.setDelFlag(1);
loading.setOrganizationId(toSave.getOrganizationId());
loading.setOrganizationName(toSave.getOrganizationName());
loading.setTopOrganizationId(toSave.getTopOrganizationId());
loading.setCreateBy(userId);
loading.setCreateTime(now);
loading.setUpdateBy(userId);
loading.setUpdateTime(now);
businessDocumentAddressMultiMapper.insert(loading);
// 卸货
BusinessDocumentAddressMulti unload = new BusinessDocumentAddressMulti();
unload.setOrderId(String.valueOf(orderId));
unload.setAreaCode(toSave.getUnloadAreaId());
unload.setAreaName(toSave.getUnloadName());
unload.setAddress(toSave.getUnloadAddress());
unload.setLongitude(toSave.getUnloadLongitude());
unload.setLatitude(toSave.getUnloadLatitude());
unload.setContactName(toSave.getDischargerName());
unload.setContactPhone(toSave.getUnloadPhone());
unload.setLayDate(toSave.getUnloadingData());
unload.setLayType(2L);
unload.setDelFlag(1);
unload.setOrganizationId(toSave.getOrganizationId());
unload.setOrganizationName(toSave.getOrganizationName());
unload.setTopOrganizationId(toSave.getTopOrganizationId());
unload.setCreateBy(userId);
unload.setCreateTime(now);
unload.setUpdateBy(userId);
unload.setUpdateTime(now);
businessDocumentAddressMultiMapper.insert(unload);
}
private void copySnapshot(BusinessDocumentOrder order, BusinessDocumentOrderAdjustDetail detail) {
@@ -545,10 +716,111 @@ public class BusinessDocumentOrderAdjustService {
if (executeOrders == null || executeOrders.isEmpty()) {
return;
}
log.info("业务单[{}]调整完成,关联执行单[{}]。如需回写TMS请接入TMS改费Feign。", goodsNumber,
executeOrders.stream().map(ExecuteOrder::getGoodsNumber).collect(Collectors.toList()));
for (ExecuteOrder executeOrder : executeOrders) {
// 仅已下发 TMS(存在 TMS 单号)的执行单需要同步修改
if (StrUtil.isBlank(executeOrder.getTmsOrderNumber())) {
continue;
}
syncTmsOrder(executeOrder, after);
}
} catch (Exception e) {
log.error("同步TMS失败,不影响主流程", e);
}
}
/**
* 同步修改单个 TMS 订单:按调整后业务单重新组装 TmsOrderAddDTO
* 带 executeOrderNumber 定位 TMS 订单,调用 TMS /feign/order/update 接口。
*/
private void syncTmsOrder(ExecuteOrder executeOrder, BusinessDocumentOrder after) {
TmsOrderAddDTO tmsOrderAddDTO = new TmsOrderAddDTO();
BeanUtil.copyProperties(after, tmsOrderAddDTO);
// id 传 OMS 业务单主键:TMS 侧用作 tms_order_account.order_id 口径;
// TMS 的 update 在覆盖前会保留 tms_order 真实主键,不会被污染
tmsOrderAddDTO.setId(String.valueOf(after.getId()));
// TMS 侧按执行单号定位订单
tmsOrderAddDTO.setExecuteOrderId(String.valueOf(executeOrder.getId()));
tmsOrderAddDTO.setExecuteOrderNumber(executeOrder.getGoodsNumber());
tmsOrderAddDTO.setGoodsNumber(after.getGoodsNumber());
tmsOrderAddDTO.setOrderSource("0");
// TMS 侧 update 按 appointShipperId(业务单货主) 定位货主,需显式带上,口径与下单一致
if (StrUtil.isNotBlank(after.getAppointShipperId())) {
tmsOrderAddDTO.setAppointShipperId(after.getAppointShipperId());
}
if (after.getAppointShipper() != null) {
tmsOrderAddDTO.setAppointShipper(after.getAppointShipper());
}
if (after.getSzwlUserId() != null) {
tmsOrderAddDTO.setSzwlUserId(after.getSzwlUserId());
}
// 货物信息
List<BusinessDocumentCargoMulti> cargoList = businessDocumentCargoMultiMapper.selectList(
new LambdaQueryWrapper<BusinessDocumentCargoMulti>()
.eq(BusinessDocumentCargoMulti::getOrderId, String.valueOf(after.getId()))
.eq(BusinessDocumentCargoMulti::getDelFlag, 1));
List<TmsCargoInfoDTO> cargoInfoList = new ArrayList<>();
if (cargoList != null) {
for (BusinessDocumentCargoMulti cargo : cargoList) {
TmsCargoInfoDTO dto = new TmsCargoInfoDTO();
BeanUtil.copyProperties(cargo, dto);
cargoInfoList.add(dto);
}
}
tmsOrderAddDTO.setCargoInfoList(cargoInfoList);
// 装货地址:统一以「调整后业务单」的扁平字段为准,避免明细表(business_document_address_multi)旧值覆盖
TmsAddressMultiDTO loadingDto = new TmsAddressMultiDTO();
loadingDto.setAreaCode(after.getLoadingAreaId());
loadingDto.setAreaName(after.getLoadingName());
loadingDto.setAddress(after.getLoadingAddress());
loadingDto.setLongitude(after.getLoadingLongitude());
loadingDto.setLatitude(after.getLoadingLatitude());
loadingDto.setContactName(after.getFreighterName());
loadingDto.setContactPhone(after.getLoadingPhone());
loadingDto.setLayDate(after.getLoadingDate());
loadingDto.setLayType(1);
List<TmsAddressMultiDTO> loadingAddressList = new ArrayList<>();
loadingAddressList.add(loadingDto);
tmsOrderAddDTO.setLoadingAddressList(loadingAddressList);
// 卸货地址:同样以「调整后业务单」的扁平字段为准
TmsAddressMultiDTO unloadDto = new TmsAddressMultiDTO();
unloadDto.setAreaCode(after.getUnloadAreaId());
unloadDto.setAreaName(after.getUnloadName());
unloadDto.setAddress(after.getUnloadAddress());
unloadDto.setLongitude(after.getUnloadLongitude());
unloadDto.setLatitude(after.getUnloadLatitude());
unloadDto.setContactName(after.getDischargerName());
unloadDto.setContactPhone(after.getUnloadPhone());
unloadDto.setLayDate(after.getUnloadingData());
unloadDto.setLayType(2);
List<TmsAddressMultiDTO> unloadAddressList = new ArrayList<>();
unloadAddressList.add(unloadDto);
tmsOrderAddDTO.setUnloadAddressList(unloadAddressList);
// 费用明细
List<BusinessOrderAccount> accountList = businessOrderAccountMapper.selectList(
new LambdaQueryWrapper<BusinessOrderAccount>()
.eq(BusinessOrderAccount::getOrderId, after.getId())
.eq(BusinessOrderAccount::getIsDelete, 0));
List<TmsOrderAccount> tmsOrderAccountList = new ArrayList<>();
if (accountList != null) {
for (BusinessOrderAccount acc : accountList) {
TmsOrderAccount dto = new TmsOrderAccount();
BeanUtil.copyProperties(acc, dto);
tmsOrderAccountList.add(dto);
}
}
tmsOrderAddDTO.setTmsOrderAccountList(tmsOrderAccountList);
AjaxResult result = wlhyServiceFeign.update(tmsOrderAddDTO);
if (result != null && "200".equals(String.valueOf(result.get("code")))) {
log.info("调整后同步修改TMS订单成功,执行单[{}],业务单[{}]", executeOrder.getGoodsNumber(), after.getGoodsNumber());
} else {
log.error("调整后同步修改TMS订单失败,执行单[{}],返回: {}", executeOrder.getGoodsNumber(),
result == null ? "null" : result.get("msg"));
}
}
}
@@ -8,6 +8,7 @@ import com.mhd.common.core.web.domain.BaseVOEntity;
import java.math.BigDecimal;
import lombok.Data;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
@@ -659,7 +660,7 @@ public class BusinessDocumentOrder extends BaseVOEntity{
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
private Date documentDate;
@ApiModelProperty( "审核状态 0-未审核 1-审核通过 2-已驳回 3-调整待审核")
@ApiModelProperty( "审核状态 0-未审核 1-审核通过 2-已驳回 3-调整待审核 4-调整驳回")
private Long reviewStatus;
@ApiModelProperty("审核时间")
@@ -826,6 +827,34 @@ public class BusinessDocumentOrder extends BaseVOEntity{
@Excel(name = "车次")
private String shuttleNo;
@ApiModelProperty("业务单调整状态 0-无 1-调整待审核 2-调整驳回 3-调整已通过")
private Integer adjustStatus;
/**
* 前端整单回传时携带的费用明细(business_order_account),非表字段,仅用于「订单调整」入参接收。
* 与顶层 feeDetailList 二选一,后端在 adjust() 中做回退兼容。
*/
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
private List<com.mhd.oms.domain.businessOrderAccount.BusinessOrderAccount> businessOrderAccountList;
/**
* 前端整单回传时的装货地址(单个),非表字段,仅用于「订单调整」入参接收与映射到 loading* 扁平字段。
*/
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
private com.mhd.oms.interfaces.dto.businessDocumentAddressMulti.BusinessDocumentAddressMultiDTO shipment;
/**
* 前端整单回传时的卸货地址(单个),非表字段,仅用于「订单调整」入参接收与映射到 unload* 扁平字段。
*/
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
private com.mhd.oms.interfaces.dto.businessDocumentAddressMulti.BusinessDocumentAddressMultiDTO receipt;
/**
* 前端整单回传时的装货地址集合,非表字段,仅用于「订单调整」入参接收与映射。
*/
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
private List<com.mhd.oms.interfaces.dto.businessDocumentAddressMulti.BusinessDocumentAddressMultiDTO> loadingAddressList;
/**
* 前端整单回传时的卸货地址集合,非表字段,仅用于「订单调整」入参接收与映射。
*/
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
private List<com.mhd.oms.interfaces.dto.businessDocumentAddressMulti.BusinessDocumentAddressMultiDTO> unloadAddressList;
}
@@ -3,8 +3,10 @@ package com.mhd.oms.domain.businessDocumentOrderAdjust.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
@@ -38,6 +40,8 @@ public class BusinessDocumentOrderAdjust implements Serializable {
private String adjustByName;
@ApiModelProperty("调整时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date adjustTime;
@ApiModelProperty("调整原因")
@@ -59,6 +63,8 @@ public class BusinessDocumentOrderAdjust implements Serializable {
private String auditByName;
@ApiModelProperty("审核时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date auditTime;
@ApiModelProperty("审核/驳回意见")
@@ -77,6 +83,8 @@ public class BusinessDocumentOrderAdjust implements Serializable {
private String createName;
@ApiModelProperty("创建时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@ApiModelProperty("更新人")
@@ -86,6 +94,8 @@ public class BusinessDocumentOrderAdjust implements Serializable {
private String updateName;
@ApiModelProperty("更新时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@ApiModelProperty("删除标记 1-正常 0-删除")
@@ -3,8 +3,12 @@ package com.mhd.oms.domain.businessDocumentOrderAdjustDetail.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.math.BigDecimal;
@@ -24,9 +28,11 @@ public class BusinessDocumentOrderAdjustDetail implements Serializable {
@ApiModelProperty("主键")
@TableId(type = IdType.ASSIGN_ID)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
@ApiModelProperty("关联调整主记录ID")
@JsonSerialize(using = ToStringSerializer.class)
private Long adjustId;
@ApiModelProperty("业务单ID")
@@ -51,6 +57,8 @@ public class BusinessDocumentOrderAdjustDetail implements Serializable {
private String loadingAddress;
@ApiModelProperty("装货时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date loadingDate;
@ApiModelProperty("卸货地")
@@ -60,6 +68,8 @@ public class BusinessDocumentOrderAdjustDetail implements Serializable {
private String unloadAddress;
@ApiModelProperty("卸货时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date unloadingData;
@ApiModelProperty("发货人")
@@ -81,6 +91,8 @@ public class BusinessDocumentOrderAdjustDetail implements Serializable {
private String route;
@ApiModelProperty("单据日期")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date documentDate;
@ApiModelProperty("组织ID")
@@ -154,12 +166,16 @@ public class BusinessDocumentOrderAdjustDetail implements Serializable {
private String createName;
@ApiModelProperty("创建时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@ApiModelProperty("更新人")
private String updateBy;
@ApiModelProperty("更新时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@ApiModelProperty("删除标记 1-正常 0-删除")
@@ -610,6 +610,12 @@ public class OmsAddressMultiService implements IOmsAddressMultiService {
List<OmsOrderAccount> tmsOrderAccountList = tmsOrderAddDTO.getTmsOrderAccountList();
if (ObjectUtil.isNotNull(tmsOrderAccountList) && tmsOrderAccountList.size() > 0) {
for (OmsOrderAccount tmsOrderAccount : tmsOrderAccountList) {
// 防御:account_id 为空或<=0 时跳过(避免唯一约束撞库 + 插入脏数据)
if (tmsOrderAccount.getAccountId() == null || tmsOrderAccount.getAccountId() <= 0) {
log.warn("订单费用科目 accountId 为空,已跳过该条, orderId={}, subjectName={}",
resevationOrder.getId(), tmsOrderAccount.getSubjectName());
continue;
}
tmsOrderAccount.setIsDelete(0);
tmsOrderAccount.setOrderId(String.valueOf(resevationOrder.getId()));
tmsOrderAccount.setCreateBy(String.valueOf(userPo.getUserId()));
@@ -1116,14 +1122,20 @@ public class OmsAddressMultiService implements IOmsAddressMultiService {
if (ObjectUtil.isNotNull(tmsOrderAccountList) && tmsOrderAccountList.size() > 0) {
// 先删除旧的费用科目信息
tmsOrderAccountMapper.delete(new LambdaQueryWrapper<OmsOrderAccount>().eq(OmsOrderAccount::getOrderId, String.valueOf(resevationOrder.getId())));
// 插入新的费用科目信息
for (OmsOrderAccount tmsOrderAccount : tmsOrderAccountList) {
// 防御:account_id 为空或<=0 时跳过
if (tmsOrderAccount.getAccountId() == null || tmsOrderAccount.getAccountId() <= 0) {
log.warn("订单费用科目 accountId 为空,已跳过该条, orderId={}, subjectName={}",
resevationOrder.getId(), tmsOrderAccount.getSubjectName());
continue;
}
tmsOrderAccount.setIsDelete(0);
tmsOrderAccount.setOrderId(String.valueOf(resevationOrder.getId()));
tmsOrderAccount.setCreateBy(String.valueOf(userPo.getUserId()));
tmsOrderAccount.setCreateTime(new Date());
// 设置组织信息
if (tmsOrderAddDTO.getOrganizationId() != null) {
tmsOrderAccount.setOrganizationId(tmsOrderAddDTO.getOrganizationId());
@@ -1134,7 +1146,7 @@ public class OmsAddressMultiService implements IOmsAddressMultiService {
if (tmsOrderAddDTO.getTopOrganizationId() != null) {
tmsOrderAccount.setTopOrganizationId(tmsOrderAddDTO.getTopOrganizationId());
}
tmsOrderAccountMapper.insert(tmsOrderAccount);
}
}
@@ -1,8 +1,12 @@
package com.mhd.oms.interfaces.dto.businessDocumentOrderAdjust;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.mhd.oms.domain.businessDocumentOrderAdjustDetail.entity.BusinessDocumentOrderAdjustDetail;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
@@ -16,6 +20,7 @@ public class BusinessDocumentOrderAdjustRecordDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主记录ID")
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
@ApiModelProperty("业务单ID")
@@ -31,6 +36,8 @@ public class BusinessDocumentOrderAdjustRecordDTO implements Serializable {
private String adjustByName;
@ApiModelProperty("调整时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date adjustTime;
@ApiModelProperty("调整原因")
@@ -49,6 +56,8 @@ public class BusinessDocumentOrderAdjustRecordDTO implements Serializable {
private String auditByName;
@ApiModelProperty("审核时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date auditTime;
@ApiModelProperty("审核/驳回意见")
+4 -4
View File
@@ -18,15 +18,15 @@ spring:
discovery:
# server-addr: 127.0.0.1:8848
# 线上测试环境配置 容器名+端口号
server-addr: 10.33.0.129:6010
# server-addr: 10.102.192.31:6848
# server-addr: 10.33.0.129:6010
server-addr: 10.102.192.31:6848
username: nacos
password: manhuoda@2023
config:
# server-addr: 127.0.0.1:8848
# 线上测试环境配置 容器名+端口号
server-addr: 10.33.0.129:6010
# server-addr: 10.102.192.31:6848
# server-addr: 10.33.0.129:6010
server-addr: 10.102.192.31:6848
username: nacos
password: manhuoda@2023
#线上正式环境