Merge branch 'dev' into dev-bms-260826
This commit is contained in:
@@ -19,7 +19,7 @@ import java.util.Set;
|
||||
/**
|
||||
* bms财务结算系统feign调用接口
|
||||
*/
|
||||
@FeignClient(contextId = "BmsService", value = ServiceNameConstants.BMS_SERVICE, url = "http://10.33.0.109:8012",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(contextId = "BmsService", value = ServiceNameConstants.BMS_SERVICE, url = "http://10.102.192.32:8012",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
public interface BmsServiceFeign {
|
||||
|
||||
|
||||
|
||||
@@ -12,11 +12,12 @@ import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@FeignClient(contextId = "OmsService", value = ServiceNameConstants.OMS_SERVICE,url = "http://10.33.0.99:8017",fallbackFactory = RemoteOmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(contextId = "OmsService", value = ServiceNameConstants.OMS_SERVICE,url = "http://10.102.192.33:8017",fallbackFactory = RemoteOmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
public interface OmsServiceFeign {
|
||||
|
||||
|
||||
@@ -28,6 +29,10 @@ public interface OmsServiceFeign {
|
||||
@PostMapping(value = "/reservationStockInOrderApi/pushInOrderDetail")
|
||||
public AjaxResult pushInOrderDetail(@RequestBody InMaterialDetailTZPD inMaterialDetail);
|
||||
|
||||
@ApiOperation("wms回传入库结果:按入库单号同步入库状态(3-收货中 4-上架中 5-已入库)到OMS入库业务单,type非1为入库")
|
||||
@GetMapping(value = "/executionStockInOrderApi/returnResult")
|
||||
public AjaxResult returnInResult(@RequestParam("orderNumber") String orderNumber, @RequestParam("status") Long status, @RequestParam("type") String type);
|
||||
|
||||
|
||||
@ApiOperation("wms推送入库单")
|
||||
@PostMapping(value = "/reservationStockOutOrderApi/pushOutOrder")
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@FeignClient(contextId = "commonWlhyServiceFeign",value = ServiceNameConstants.WLHY_SERVICE,url = "http://10.33.0.129:8014",configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(contextId = "commonWlhyServiceFeign",value = ServiceNameConstants.WLHY_SERVICE,url = "http://10.102.192.31:8014",configuration = FeignAutoConfiguration.class)
|
||||
public interface WlhyServiceFeign {
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.Map;
|
||||
* @description: TODO
|
||||
* @date 2024/5/10 8:58
|
||||
**/
|
||||
@FeignClient(contextId = "remoteWmsServiceFeign",value = ServiceNameConstants.WMS_SERVICE, url = "http://10.33.0.109:8016",fallbackFactory = RemoteWmsFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(contextId = "remoteWmsServiceFeign",value = ServiceNameConstants.WMS_SERVICE,url = "http://10.102.192.32:8016",fallbackFactory = RemoteWmsFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
public interface WmsServiceFeign {
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,7 +9,7 @@ import com.mhd.system.api.feign.FeignAutoConfiguration;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@FeignClient(contextId = "YmsService", value = ServiceNameConstants.YMS_SERVICE,url = "http://10.33.0.99:8018",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(contextId = "YmsService", value = ServiceNameConstants.YMS_SERVICE,url = "http://10.102.192.33:8018",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
public interface YmsServiceFeign {
|
||||
|
||||
/**
|
||||
|
||||
+5
@@ -41,6 +41,11 @@ public class RemoteOmsFeignFallbackFactory implements FallbackFactory<OmsService
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult returnInResult(String orderNumber, Long status, String type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult pushOutOrder(StockOutOrderTZPD stockOutOrder) {
|
||||
return null;
|
||||
|
||||
+13
-1
@@ -7,6 +7,9 @@ import com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskLoadPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealBusinessTypeStatPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealPlatformFloorStatPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealPlatformInfoPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealOnTimeStatPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskTypeStatPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealMonthlyTaskDurationPO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -32,12 +35,21 @@ public interface BiPlatformRealDataMapper {
|
||||
/** 本月任务量 */
|
||||
Long countMonthTasks();
|
||||
|
||||
/** 本月任务平均时长 / 完成率统计 */
|
||||
RealMonthlyTaskDurationPO queryMonthTaskStats();
|
||||
|
||||
/** 任务负荷(今日 24 小时) */
|
||||
List<RealTaskLoadPO> queryTaskLoadToday();
|
||||
|
||||
/** 今日预约-业务类型统计(按 businessName 分组统计今日预约数量) */
|
||||
/** 今日预约-租户统计(按 tenantName 分组统计今日预约数量) */
|
||||
List<RealBusinessTypeStatPO> queryTodayBusinessTypeStats();
|
||||
|
||||
/** 今日作业准时率统计(total 今日预约总数;onTimeCount 今日准时车辆数) */
|
||||
RealOnTimeStatPO queryTodayOnTimeStats();
|
||||
|
||||
/** 任务类型统计(当月 OMS 运输订单按业务类型分组:1-跨境 2-国内) */
|
||||
List<RealTaskTypeStatPO> queryMonthTransportOrderByType();
|
||||
|
||||
/** 月台监控-按楼层统计月台车辆(楼层、月台数量、今日预约车辆、当前作业车辆) */
|
||||
List<RealPlatformFloorStatPO> queryPlatformFloorStats();
|
||||
|
||||
|
||||
+4
-4
@@ -5,15 +5,15 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 今日预约-业务类型统计(真实数据,来自 TEST_NGWL_YMS.QMS_MAIN_BUSINESS)
|
||||
* 按业务类型分组统计今日预约数量
|
||||
* 今日预约-租户统计(真实数据,来自 TEST_NGWL_YMS.QMS_MAIN_BUSINESS)
|
||||
* 按租户名称分组统计今日预约数量
|
||||
*/
|
||||
@Data
|
||||
public class RealBusinessTypeStatPO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 业务类型名称(qms_main_business.businessName) */
|
||||
private String businessName;
|
||||
/** 租户名称(qms_main_business.tenantName) */
|
||||
private String tenantName;
|
||||
|
||||
/** 今日预约数量 */
|
||||
private Long count;
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.mhd.bi.domain.biPlatformRealData.repository.po;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 本月任务平均时长 / 完成率统计(真实数据,来自 TEST_NGWL_YMS.QMS_MAIN_BUSINESS)
|
||||
* avgDurationHours:累计 (EXIT_TIME - ENTRY_TIME) 小时数(仅 ENTRY_TIME/EXIT_TIME 都不为空时参与)
|
||||
* durationCount:参与平均时长统计的有效条数
|
||||
* completedCount:已出场(EXIT_TIME IS NOT NULL)且预约日期在本月的数量
|
||||
* totalCount:本月(TARGET_DATE)预约总数量
|
||||
*/
|
||||
@Data
|
||||
public class RealMonthlyTaskDurationPO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 平均作业时长(小时) */
|
||||
private Double avgDurationHours;
|
||||
|
||||
/** 参与平均时长统计的有效条数 */
|
||||
private Long durationCount;
|
||||
|
||||
/** 本月已出场数量 */
|
||||
private Long completedCount;
|
||||
|
||||
/** 本月预约总数量(按 TARGET_DATE 统计) */
|
||||
private Long totalCount;
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.mhd.bi.domain.biPlatformRealData.repository.po;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 今日作业准时率统计(真实数据,来自 TEST_NGWL_YMS.QMS_MAIN_BUSINESS)
|
||||
* 准时率 = 今日实际进场时间在预约日期当天的车辆数 / 今日预约总车辆数 × 100%
|
||||
*/
|
||||
@Data
|
||||
public class RealOnTimeStatPO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 今日预约总车辆数 */
|
||||
private Long total;
|
||||
|
||||
/** 今日准时车辆数(已进场且实际进场日期 = 预约日期) */
|
||||
private Long onTimeCount;
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.mhd.bi.domain.biPlatformRealData.repository.po;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 任务类型统计(真实数据,来自 NGWL_TEST_OMS.BUSINESS_DOCUMENT_ORDER 运输订单)
|
||||
* 按业务类型 businessCategory 分组统计当月数量:1-跨境运输 2-国内运输
|
||||
*/
|
||||
@Data
|
||||
public class RealTaskTypeStatPO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 业务类型:1-跨境 2-国内 */
|
||||
private Integer businessCategory;
|
||||
|
||||
/** 该类型当月单量 */
|
||||
private Long count;
|
||||
}
|
||||
+3
@@ -16,6 +16,9 @@ public class RealVehicleStatusPO implements Serializable {
|
||||
/** 当前未签到 */
|
||||
private Long notCheckedIn;
|
||||
|
||||
/** 当前等待作业(FLOW_STATUS IN '1','2','3' 已预约/已签到/已叫号) */
|
||||
private Long waiting;
|
||||
|
||||
/** 当前作业中 */
|
||||
private Long operatingVehicles;
|
||||
|
||||
|
||||
+147
-9
@@ -9,12 +9,17 @@ import com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskLoadPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealBusinessTypeStatPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealPlatformFloorStatPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealPlatformInfoPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealOnTimeStatPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskTypeStatPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealMonthlyTaskDurationPO;
|
||||
import com.mhd.bi.domain.biPlatformSurveillance.repository.mapper.BiPlatformSurveillanceReportMapper;
|
||||
import com.mhd.bi.domain.biSnapshotSync.repository.mapper.BiSnapshotWriteMapper;
|
||||
import com.mhd.bi.domain.biSnapshotSync.support.BiSnapshotWeeklyRandomDataBuilder;
|
||||
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.PlatformSurveillanceVO;
|
||||
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.PlatformVehicleItemVO;
|
||||
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.TaskLoadItemVO;
|
||||
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.TaskTypeStatisticsVO;
|
||||
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.TaskTypeCountItemVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -91,16 +96,23 @@ public class BiPlatformRealDataService {
|
||||
if (vo.getPlatformOverview() != null) {
|
||||
fp.put("totalPlatforms", vo.getPlatformOverview().getTotalPlatforms());
|
||||
fp.put("operatingPlatforms", vo.getPlatformOverview().getOperatingPlatforms());
|
||||
fp.put("currentOccupancyRate", vo.getPlatformOverview().getCurrentOccupancyRate());
|
||||
fp.put("todayTasks", vo.getPlatformOverview().getTodayTasks());
|
||||
}
|
||||
if (vo.getEfficiencyStatistics() != null) {
|
||||
fp.put("platformOnTimeRate", vo.getEfficiencyStatistics().getPlatformOnTimeRate());
|
||||
}
|
||||
if (vo.getVehicleStatus() != null) {
|
||||
fp.put("todayReservedVehicles", vo.getVehicleStatus().getTodayReservedVehicles());
|
||||
fp.put("notCheckedIn", vo.getVehicleStatus().getNotCheckedIn());
|
||||
fp.put("waiting", vo.getVehicleStatus().getWaiting());
|
||||
fp.put("operatingVehicles", vo.getVehicleStatus().getOperatingVehicles());
|
||||
fp.put("completedVehicles", vo.getVehicleStatus().getCompletedVehicles());
|
||||
}
|
||||
if (vo.getMonthlyTaskStatistics() != null) {
|
||||
fp.put("taskTotal", vo.getMonthlyTaskStatistics().getTaskTotal());
|
||||
fp.put("avgTaskDuration", vo.getMonthlyTaskStatistics().getAvgTaskDuration());
|
||||
fp.put("taskCompletionRate", vo.getMonthlyTaskStatistics().getTaskCompletionRate());
|
||||
}
|
||||
if (vo.getVehicles() != null) {
|
||||
List<Map<String, Object>> vehicles = new ArrayList<>();
|
||||
@@ -126,6 +138,21 @@ public class BiPlatformRealDataService {
|
||||
}
|
||||
fp.put("taskLoadStatistics", loads);
|
||||
}
|
||||
if (vo.getTaskTypeStatistics() != null) {
|
||||
Map<String, Object> m = new LinkedHashMap<>();
|
||||
m.put("totalTasks", vo.getTaskTypeStatistics().getTotalTasks());
|
||||
if (vo.getTaskTypeStatistics().getTaskTypes() != null) {
|
||||
List<Map<String, Object>> types = new ArrayList<>();
|
||||
for (TaskTypeCountItemVO it : vo.getTaskTypeStatistics().getTaskTypes()) {
|
||||
Map<String, Object> tm = new LinkedHashMap<>();
|
||||
tm.put("type", it.getType());
|
||||
tm.put("count", it.getCount());
|
||||
types.add(tm);
|
||||
}
|
||||
m.put("taskTypes", types);
|
||||
}
|
||||
fp.put("taskTypeStatistics", m);
|
||||
}
|
||||
return objectMapper.writeValueAsString(fp);
|
||||
}
|
||||
|
||||
@@ -166,12 +193,34 @@ public class BiPlatformRealDataService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 今日作业准时率 = 准时车辆数 / 今日预约车辆总数 × 100%
|
||||
* 准时:今日(TARGET_DATE=今天)已进场且实际进场时间不超过该预约的预约结束时间 bookingEndTime;
|
||||
* 实际进场时间超过 bookingEndTime 视为不准时。
|
||||
* 今日预约总数为 0 时返回 0。
|
||||
*/
|
||||
public int calcTodayOnTimeRate() {
|
||||
try {
|
||||
RealOnTimeStatPO po = biPlatformRealDataMapper.queryTodayOnTimeStats();
|
||||
if (po == null) return 0;
|
||||
long total = po.getTotal() == null ? 0L : po.getTotal();
|
||||
long onTime = po.getOnTimeCount() == null ? 0L : po.getOnTimeCount();
|
||||
if (total <= 0) return 0;
|
||||
// 四舍五入到整数百分比
|
||||
return (int) Math.round(((double) onTime / (double) total) * 100.0);
|
||||
} catch (Exception e) {
|
||||
log.error("【YMS】计算今日作业准时率失败: {}", e.getMessage(), e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public RealVehicleStatusPO queryVehicleStatusToday() {
|
||||
try {
|
||||
RealVehicleStatusPO po = biPlatformRealDataMapper.queryVehicleStatusToday();
|
||||
if (po == null) po = new RealVehicleStatusPO();
|
||||
if (po.getTodayReservedVehicles() == null) po.setTodayReservedVehicles(0L);
|
||||
if (po.getNotCheckedIn() == null) po.setNotCheckedIn(0L);
|
||||
if (po.getWaiting() == null) po.setWaiting(0L);
|
||||
if (po.getOperatingVehicles() == null) po.setOperatingVehicles(0L);
|
||||
if (po.getCompletedVehicles() == null) po.setCompletedVehicles(0L);
|
||||
return po;
|
||||
@@ -180,6 +229,7 @@ public class BiPlatformRealDataService {
|
||||
RealVehicleStatusPO po = new RealVehicleStatusPO();
|
||||
po.setTodayReservedVehicles(0L);
|
||||
po.setNotCheckedIn(0L);
|
||||
po.setWaiting(0L);
|
||||
po.setOperatingVehicles(0L);
|
||||
po.setCompletedVehicles(0L);
|
||||
return po;
|
||||
@@ -196,6 +246,21 @@ public class BiPlatformRealDataService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 本月任务平均时长 / 完成率统计:
|
||||
* - avgDurationHours:累计(EXIT_TIME - ENTRY_TIME)小时数 / 参与数;任一为空的行不参与
|
||||
* - taskCompletionRate:已完成(EXIT_TIME 不为空 且 预约日期在本月)/ 本月预约总数量 ×100
|
||||
* 任一查询失败均返回 null,由调用方决定是否覆盖模板值。
|
||||
*/
|
||||
public RealMonthlyTaskDurationPO queryMonthTaskStats() {
|
||||
try {
|
||||
return biPlatformRealDataMapper.queryMonthTaskStats();
|
||||
} catch (Exception e) {
|
||||
log.error("【YMS】统计本月任务平均时长/完成率失败: {}", e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public List<RealTaskLoadPO> queryTaskLoadToday() {
|
||||
try {
|
||||
return biPlatformRealDataMapper.queryTaskLoadToday();
|
||||
@@ -206,14 +271,50 @@ public class BiPlatformRealDataService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 今日预约-业务类型统计:按业务类型分组统计今日预约数量。
|
||||
* 例:今日预约航空打板 3 条 → 返回 {businessName:"航空打板", count:3}
|
||||
* 任务类型统计:当月 OMS 运输订单按业务类型分组(1-跨境运输,2-国内运输)。
|
||||
* 返回 {totalTasks: 当月跨境+国内运输总单量, taskTypes: [{type, count}]}
|
||||
* 查询失败时返回空结构,不影响写死字段。
|
||||
*/
|
||||
/**
|
||||
* 任务类型统计:固定输出「跨境运输」「国内运输」两类,count 取当月 OMS 业务单真实单量;
|
||||
* 当月无数据或查询失败时仍返回两类、count=0(不使用写死模板兜底)。
|
||||
*/
|
||||
public TaskTypeStatisticsVO queryMonthTransportOrderByType() {
|
||||
int crossBorder = 0; // 跨境运输 BUSINESS_CATEGORY=1
|
||||
int domestic = 0; // 国内运输 BUSINESS_CATEGORY=2
|
||||
try {
|
||||
List<RealTaskTypeStatPO> rows = biPlatformRealDataMapper.queryMonthTransportOrderByType();
|
||||
if (rows != null) {
|
||||
for (RealTaskTypeStatPO r : rows) {
|
||||
if (r == null || r.getBusinessCategory() == null || r.getCount() == null) {
|
||||
continue;
|
||||
}
|
||||
if (r.getBusinessCategory() == 1) {
|
||||
crossBorder = r.getCount().intValue();
|
||||
} else if (r.getBusinessCategory() == 2) {
|
||||
domestic = r.getCount().intValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("【OMS】统计当月运输订单业务类型失败: {}", e.getMessage(), e);
|
||||
// 失败时不回退写死模板,保持两类 count=0
|
||||
}
|
||||
List<TaskTypeCountItemVO> items = new ArrayList<>();
|
||||
items.add(TaskTypeCountItemVO.builder().type("跨境运输").count(crossBorder).build());
|
||||
items.add(TaskTypeCountItemVO.builder().type("国内运输").count(domestic).build());
|
||||
return TaskTypeStatisticsVO.builder().totalTasks(crossBorder + domestic).taskTypes(items).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 今日预约-租户统计:按租户名称分组统计今日预约数量。
|
||||
* 例:今日预约某租户 3 条 → 返回 {tenantName:"某租户", count:3}
|
||||
*/
|
||||
public List<RealBusinessTypeStatPO> queryTodayBusinessTypeStats() {
|
||||
try {
|
||||
return biPlatformRealDataMapper.queryTodayBusinessTypeStats();
|
||||
} catch (Exception e) {
|
||||
log.error("【YMS】统计今日业务类型失败: {}", e.getMessage(), e);
|
||||
log.error("【YMS】统计今日租户预约失败: {}", e.getMessage(), e);
|
||||
return java.util.Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -271,29 +372,63 @@ public class BiPlatformRealDataService {
|
||||
template.setVehicles(vehicleVos);
|
||||
|
||||
// 月台实时概览:真实数据源,无条件覆盖
|
||||
// 总月台 / 占用月台 来源:YMS 月台管理列表 QMS_WINDOW_INFO(JOB_STATUS=1 表示占用)
|
||||
// 月台占用率 = 占用 / 全部月台
|
||||
// 今日作业任务 来源:QMS_MAIN_BUSINESS 按预约时间 TARGET_DATE = 今天 的全部数量
|
||||
// 作业准时率 = 今日(实际进场时间在预约日期当天的车辆数) / 今日预约车辆总数 × 100%
|
||||
if (template.getPlatformOverview() != null) {
|
||||
RealPlatformOverviewPO ov = queryPlatformOverview();
|
||||
int total = ov.getTotalPlatforms().intValue();
|
||||
int occ = ov.getOperatingPlatforms().intValue();
|
||||
List<RealPlatformInfoPO> platformList = queryPlatformInfoList();
|
||||
int total = platformList == null ? 0 : platformList.size();
|
||||
int occ = 0;
|
||||
if (platformList != null) {
|
||||
for (RealPlatformInfoPO p : platformList) {
|
||||
if (p != null && p.getJobStatus() != null && p.getJobStatus() == 1) {
|
||||
occ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
double rate = total > 0 ? Math.round(((double) occ / total) * 100.0 * 100.0) / 100.0 : 0d;
|
||||
int todayTasks = (int) countTodayTasks();
|
||||
template.getPlatformOverview().setTotalPlatforms(total);
|
||||
template.getPlatformOverview().setOperatingPlatforms(occ);
|
||||
template.getPlatformOverview().setCurrentOccupancyRate(rate);
|
||||
template.getPlatformOverview().setTodayTasks((int) countTodayTasks());
|
||||
template.getPlatformOverview().setTodayTasks(todayTasks);
|
||||
|
||||
// 作业准时率:准时车辆数 / 今日预约总数 × 100%(今日总数为 0 时返回 0)
|
||||
if (template.getEfficiencyStatistics() != null) {
|
||||
template.getEfficiencyStatistics().setPlatformOnTimeRate(calcTodayOnTimeRate());
|
||||
}
|
||||
}
|
||||
|
||||
// 作业车辆状态统计:真实数据源,无条件覆盖
|
||||
// 作业车辆状态统计:真实数据源,无条件覆盖(含等待作业 waiting = 今日预约且 已预约/已签到/已叫号)
|
||||
if (template.getVehicleStatus() != null) {
|
||||
RealVehicleStatusPO vs = queryVehicleStatusToday();
|
||||
template.getVehicleStatus().setTodayReservedVehicles(vs.getTodayReservedVehicles().intValue());
|
||||
template.getVehicleStatus().setNotCheckedIn(vs.getNotCheckedIn().intValue());
|
||||
template.getVehicleStatus().setWaiting(vs.getWaiting().intValue());
|
||||
template.getVehicleStatus().setOperatingVehicles(vs.getOperatingVehicles().intValue());
|
||||
template.getVehicleStatus().setCompletedVehicles(vs.getCompletedVehicles().intValue());
|
||||
}
|
||||
|
||||
// 本月任务统计:taskTotal 有真实数据源无条件覆盖;YoY 等无真实数据源保留模板写死值
|
||||
// 本月任务统计:taskTotal / avgTaskDuration / taskCompletionRate 均有真实数据源,无条件覆盖;YoY 保留模板写死值
|
||||
if (template.getMonthlyTaskStatistics() != null) {
|
||||
template.getMonthlyTaskStatistics().setTaskTotal((int) countMonthTasks());
|
||||
RealMonthlyTaskDurationPO monthStats = queryMonthTaskStats();
|
||||
if (monthStats != null) {
|
||||
if (monthStats.getAvgDurationHours() != null) {
|
||||
// 保留两位小数
|
||||
double v = monthStats.getAvgDurationHours();
|
||||
template.getMonthlyTaskStatistics().setAvgTaskDuration(Math.round(v * 100.0) / 100.0);
|
||||
}
|
||||
Long total = monthStats.getTotalCount();
|
||||
Long completed = monthStats.getCompletedCount();
|
||||
if (total != null && total > 0 && completed != null) {
|
||||
int rate = (int) Math.round(((double) completed.longValue() / total.longValue()) * 100.0);
|
||||
template.getMonthlyTaskStatistics().setTaskCompletionRate(rate);
|
||||
} else {
|
||||
template.getMonthlyTaskStatistics().setTaskCompletionRate(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 任务负荷:有真实数据源;真实为空则清空不用模板模拟,有数据则按真实小时覆盖
|
||||
@@ -313,6 +448,9 @@ public class BiPlatformRealDataService {
|
||||
}
|
||||
}
|
||||
|
||||
// 任务类型统计:当月 OMS 业务单真实数据(固定跨境运输/国内运输两类,不使用写死模板兜底)
|
||||
template.setTaskTypeStatistics(queryMonthTransportOrderByType());
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ public final class BiReportSnapshotMapperSupport {
|
||||
.platformOverview(PlatformOverviewVO.builder()
|
||||
.totalPlatforms(0).currentOccupancyRate(0d).operatingPlatforms(0).todayTasks(0).build())
|
||||
.vehicleStatus(VehicleStatusVO.builder()
|
||||
.todayReservedVehicles(0).notCheckedIn(0).operatingVehicles(0).completedVehicles(0).build())
|
||||
.todayReservedVehicles(0).notCheckedIn(0).waiting(0).operatingVehicles(0).completedVehicles(0).build())
|
||||
.avgOperationDurationTrend(Collections.emptyList())
|
||||
.monthlyTaskStatistics(MonthlyTaskStatisticsVO.builder()
|
||||
.taskTotal(0).taskTotalYoY(0).avgTaskDuration(0d).avgDurationYoY(0)
|
||||
|
||||
+46
-11
@@ -16,7 +16,7 @@ import com.mhd.bi.interfaces.facadeApi.biReport.vo.warehouseZone.WarehouseOperat
|
||||
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.PlatformVehicleItemVO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.service.BiPlatformRealDataService;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealPlatformVehiclePO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealPlatformOverviewPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealPlatformInfoPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealVehicleStatusPO;
|
||||
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskLoadPO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -173,18 +173,33 @@ public class BiReportSnapshotSyncService {
|
||||
}
|
||||
|
||||
// ====== 真实数据:月台实时概览 ======
|
||||
RealPlatformOverviewPO ov = biPlatformRealDataService.queryPlatformOverview();
|
||||
// 总月台 / 占用月台 来源:YMS 月台管理列表 QMS_WINDOW_INFO(JOB_STATUS=1 表示占用)
|
||||
// 月台占用率 = 占用 / 全部月台
|
||||
// 今日作业任务 来源:QMS_MAIN_BUSINESS 按预约时间 TARGET_DATE = 今天 的全部数量
|
||||
if (template.getPlatformOverview() != null) {
|
||||
template.getPlatformOverview().setTotalPlatforms(ov.getTotalPlatforms().intValue());
|
||||
template.getPlatformOverview().setOperatingPlatforms(ov.getOperatingPlatforms().intValue());
|
||||
int total = ov.getTotalPlatforms().intValue();
|
||||
int occ = ov.getOperatingPlatforms().intValue();
|
||||
List<RealPlatformInfoPO> platformList = biPlatformRealDataService.queryPlatformInfoList();
|
||||
int total = platformList == null ? 0 : platformList.size();
|
||||
int occ = 0;
|
||||
if (platformList != null) {
|
||||
for (RealPlatformInfoPO p : platformList) {
|
||||
if (p != null && p.getJobStatus() != null && p.getJobStatus() == 1) {
|
||||
occ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
double rate = total > 0 ? Math.round(((double) occ / total) * 100.0 * 100.0) / 100.0 : 0d;
|
||||
int todayTasks = (int) biPlatformRealDataService.countTodayTasks();
|
||||
template.getPlatformOverview().setTotalPlatforms(total);
|
||||
template.getPlatformOverview().setOperatingPlatforms(occ);
|
||||
template.getPlatformOverview().setCurrentOccupancyRate(rate);
|
||||
}
|
||||
long todayTasks = biPlatformRealDataService.countTodayTasks();
|
||||
if (template.getPlatformOverview() != null) {
|
||||
template.getPlatformOverview().setTodayTasks((int) todayTasks);
|
||||
template.getPlatformOverview().setTodayTasks(todayTasks);
|
||||
|
||||
// 作业准时率 = 准时车辆数 / 今日预约总数 × 100%
|
||||
// 准时:今日(TARGET_DATE=今天)已进场且 ENTRY_TIME <= bookingEndTime(预约结束时间),超过视为不准时
|
||||
// 今日预约总数 = 0 时返回 0
|
||||
if (template.getEfficiencyStatistics() != null) {
|
||||
template.getEfficiencyStatistics().setPlatformOnTimeRate(biPlatformRealDataService.calcTodayOnTimeRate());
|
||||
}
|
||||
}
|
||||
|
||||
// ====== 真实数据:作业车辆状态统计 ======
|
||||
@@ -192,14 +207,31 @@ public class BiReportSnapshotSyncService {
|
||||
if (template.getVehicleStatus() != null) {
|
||||
template.getVehicleStatus().setTodayReservedVehicles(vs.getTodayReservedVehicles().intValue());
|
||||
template.getVehicleStatus().setNotCheckedIn(vs.getNotCheckedIn().intValue());
|
||||
template.getVehicleStatus().setWaiting(vs.getWaiting().intValue());
|
||||
template.getVehicleStatus().setOperatingVehicles(vs.getOperatingVehicles().intValue());
|
||||
template.getVehicleStatus().setCompletedVehicles(vs.getCompletedVehicles().intValue());
|
||||
}
|
||||
|
||||
// ====== 真实数据:本月任务统计 taskTotal ======
|
||||
// ====== 真实数据:本月任务统计 taskTotal / avgTaskDuration / taskCompletionRate ======
|
||||
long monthTasks = biPlatformRealDataService.countMonthTasks();
|
||||
if (template.getMonthlyTaskStatistics() != null) {
|
||||
template.getMonthlyTaskStatistics().setTaskTotal((int) monthTasks);
|
||||
com.mhd.bi.domain.biPlatformRealData.repository.po.RealMonthlyTaskDurationPO monthStats =
|
||||
biPlatformRealDataService.queryMonthTaskStats();
|
||||
if (monthStats != null) {
|
||||
if (monthStats.getAvgDurationHours() != null) {
|
||||
double v = monthStats.getAvgDurationHours();
|
||||
template.getMonthlyTaskStatistics().setAvgTaskDuration(Math.round(v * 100.0) / 100.0);
|
||||
}
|
||||
Long total = monthStats.getTotalCount();
|
||||
Long completed = monthStats.getCompletedCount();
|
||||
if (total != null && total > 0 && completed != null) {
|
||||
int rate = (int) Math.round(((double) completed.longValue() / total.longValue()) * 100.0);
|
||||
template.getMonthlyTaskStatistics().setTaskCompletionRate(rate);
|
||||
} else {
|
||||
template.getMonthlyTaskStatistics().setTaskCompletionRate(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ====== 真实数据:任务负荷(今日 24 小时) ======
|
||||
@@ -218,6 +250,9 @@ public class BiReportSnapshotSyncService {
|
||||
}
|
||||
}
|
||||
|
||||
// ====== 真实数据:任务类型统计(当月 OMS 业务单,固定跨境运输/国内运输两类,不使用写死模板兜底) ======
|
||||
template.setTaskTypeStatistics(biPlatformRealDataService.queryMonthTransportOrderByType());
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -415,6 +415,7 @@ public final class BiSnapshotWeeklyRandomDataBuilder {
|
||||
static final int P_TASKS = 418;
|
||||
static final int P_RESV = 2_850;
|
||||
static final int P_NC = 920;
|
||||
static final int P_WAIT = 680;
|
||||
static final int P_OPV = 1_180;
|
||||
static final int P_DONE = 1_420;
|
||||
static final String[] P_MO_LABELS = {"5月", "6月", "7月"};
|
||||
|
||||
@@ -122,9 +122,9 @@ public class BiReportApi extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 今日预约-业务类型统计(实时查 YMS 库,不落库)
|
||||
* 今日预约-租户统计(实时查 YMS 库,不落库)
|
||||
*/
|
||||
@ApiOperation(value = "今日预约业务类型统计", notes = "按业务类型分组统计今日预约数量,实时查询 YMS 库,不落库;例:航空打板 3 条")
|
||||
@ApiOperation(value = "今日预约租户统计", notes = "按租户名称分组统计今日预约数量,实时查询 YMS 库,不落库;例:某租户 3 条")
|
||||
@GetMapping("/businessTypeStats")
|
||||
public BiApiResult<List<RealBusinessTypeStatPO>> businessTypeStats() {
|
||||
List<RealBusinessTypeStatPO> data = biPlatformRealDataService.queryTodayBusinessTypeStats();
|
||||
|
||||
+3
@@ -20,6 +20,9 @@ public class VehicleStatusVO {
|
||||
@ApiModelProperty("当前未签到,单位:辆")
|
||||
private Integer notCheckedIn;
|
||||
|
||||
@ApiModelProperty("当前等待作业(已预约/已签到/已叫号),单位:辆")
|
||||
private Integer waiting;
|
||||
|
||||
@ApiModelProperty("当前作业中,单位:辆")
|
||||
private Integer operatingVehicles;
|
||||
|
||||
|
||||
@@ -40,43 +40,86 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
FROM NGWL_TEST_YMS.QMS_WINDOW_INFO
|
||||
</select>
|
||||
|
||||
<!-- 今日作业任务:实际进入时间是今日的 -->
|
||||
<!-- 今日作业任务:按预约时间 TARGET_DATE(今日)统计主业务记录数 -->
|
||||
<select id="countTodayTasks" resultType="java.lang.Long">
|
||||
SELECT COUNT(1)
|
||||
FROM NGWL_TEST_YMS.QMS_MAIN_BUSINESS
|
||||
WHERE ENTRY_TIME IS NOT NULL
|
||||
AND TRUNC(ENTRY_TIME) = TRUNC(SYSDATE)
|
||||
WHERE TARGET_DATE IS NOT NULL
|
||||
AND TRUNC(TARGET_DATE) = TRUNC(SYSDATE)
|
||||
</select>
|
||||
|
||||
<!-- 今日作业准时率统计:
|
||||
total 今日预约总车辆数(TARGET_DATE = 今天)
|
||||
onTimeCount 今日准时车辆数(已进场且实际进场时间不超过该预约的预约结束时间 BOOKING_END_TIME)
|
||||
「准时」= 今日(TARGET_DATE=今天)已进场且 ENTRY_TIME <= BOOKING_END_TIME;超过则视为不准时
|
||||
准时率 = onTimeCount / total × 100%
|
||||
-->
|
||||
<select id="queryTodayOnTimeStats" resultType="com.mhd.bi.domain.biPlatformRealData.repository.po.RealOnTimeStatPO">
|
||||
SELECT
|
||||
SUM(CASE WHEN TARGET_DATE IS NOT NULL AND TRUNC(TARGET_DATE) = TRUNC(SYSDATE) THEN 1 ELSE 0 END) AS total,
|
||||
SUM(CASE WHEN ENTRY_TIME IS NOT NULL
|
||||
AND TRUNC(TARGET_DATE) = TRUNC(SYSDATE)
|
||||
AND ENTRY_TIME <= BOOKING_END_TIME
|
||||
THEN 1 ELSE 0 END) AS onTimeCount
|
||||
FROM NGWL_TEST_YMS.QMS_MAIN_BUSINESS
|
||||
</select>
|
||||
|
||||
<!-- 车辆状态统计:今日的统计(按创建时间 CREATE_TIME / 流程状态)
|
||||
todayReservedVehicles 改为按预约日期 TARGET_DATE(其它 3 项保持 CREATE_TIME)
|
||||
waiting 等待作业:FLOW_STATUS IN ('1','2','3') 已预约/已签到/已叫号 且 预约日期 = 今天
|
||||
FLOW_STATUS: 1已预约 2已签到 3已叫号 4已过号 5已进场 6已称重 7已装车 8二次称重 9已结算 10已还卡 11已出场 12已取消 -->
|
||||
<select id="queryVehicleStatusToday" resultType="com.mhd.bi.domain.biPlatformRealData.repository.po.RealVehicleStatusPO">
|
||||
SELECT
|
||||
SUM(CASE WHEN TRUNC(TARGET_DATE) = TRUNC(SYSDATE) THEN 1 ELSE 0 END) AS todayReservedVehicles,
|
||||
SUM(CASE WHEN FLOW_STATUS = '1' AND TRUNC(CREATE_TIME) = TRUNC(SYSDATE) THEN 1 ELSE 0 END) AS notCheckedIn,
|
||||
SUM(CASE WHEN FLOW_STATUS IN ('1','2','3') AND TRUNC(TARGET_DATE) = TRUNC(SYSDATE) THEN 1 ELSE 0 END) AS waiting,
|
||||
SUM(CASE WHEN FLOW_STATUS IN ('5','6','7','8','9','10') AND TRUNC(CREATE_TIME) = TRUNC(SYSDATE) THEN 1 ELSE 0 END) AS operatingVehicles,
|
||||
SUM(CASE WHEN FLOW_STATUS = '11' AND TRUNC(CREATE_TIME) = TRUNC(SYSDATE) THEN 1 ELSE 0 END) AS completedVehicles
|
||||
FROM NGWL_TEST_YMS.QMS_MAIN_BUSINESS
|
||||
</select>
|
||||
|
||||
<!-- 本月任务量:实际进入时间是本月的 -->
|
||||
<!-- 本月任务量:按预约日期 TARGET_DATE(Y预约日期)统计本月预约总数量 -->
|
||||
<select id="countMonthTasks" resultType="java.lang.Long">
|
||||
SELECT COUNT(1)
|
||||
FROM NGWL_TEST_YMS.QMS_MAIN_BUSINESS
|
||||
WHERE ENTRY_TIME IS NOT NULL
|
||||
AND TO_CHAR(ENTRY_TIME, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
|
||||
WHERE TARGET_DATE IS NOT NULL
|
||||
AND TO_CHAR(TARGET_DATE, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
|
||||
</select>
|
||||
|
||||
<!-- 今日预约-业务名称统计:按 BUSINESS_NAME(业务名称)分组统计今日预约数量,按预约日期 TARGET_DATE 过滤 -->
|
||||
<!-- 本月任务平均作业时长 / 完成率统计:
|
||||
avgDurationHours 平均时长(小时)= AVG((EXIT_TIME - ENTRY_TIME) * 24)
|
||||
仅 ENTRY_TIME 与 EXIT_TIME 都不为空时参与;
|
||||
durationCount 参与平均时长统计的有效条数;
|
||||
completedCount 本月(TARGET_DATE)已出场(EXIT_TIME IS NOT NULL)的数量;
|
||||
totalCount 本月(TARGET_DATE)预约总数量。
|
||||
-->
|
||||
<select id="queryMonthTaskStats" resultType="com.mhd.bi.domain.biPlatformRealData.repository.po.RealMonthlyTaskDurationPO">
|
||||
SELECT
|
||||
AVG(CASE WHEN ENTRY_TIME IS NOT NULL AND EXIT_TIME IS NOT NULL
|
||||
THEN (EXIT_TIME - ENTRY_TIME) * 24
|
||||
END) AS avgDurationHours,
|
||||
SUM(CASE WHEN ENTRY_TIME IS NOT NULL AND EXIT_TIME IS NOT NULL
|
||||
AND TO_CHAR(ENTRY_TIME, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
|
||||
THEN 1 ELSE 0 END) AS durationCount,
|
||||
SUM(CASE WHEN EXIT_TIME IS NOT NULL
|
||||
AND TARGET_DATE IS NOT NULL
|
||||
AND TO_CHAR(TARGET_DATE, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
|
||||
THEN 1 ELSE 0 END) AS completedCount,
|
||||
SUM(CASE WHEN TARGET_DATE IS NOT NULL
|
||||
AND TO_CHAR(TARGET_DATE, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
|
||||
THEN 1 ELSE 0 END) AS totalCount
|
||||
FROM NGWL_TEST_YMS.QMS_MAIN_BUSINESS
|
||||
</select>
|
||||
|
||||
<!-- 今日预约-租户统计:按 TENANT_NAME(租户名称)分组统计今日预约数量,按预约日期 TARGET_DATE 过滤 -->
|
||||
<select id="queryTodayBusinessTypeStats" resultType="com.mhd.bi.domain.biPlatformRealData.repository.po.RealBusinessTypeStatPO">
|
||||
SELECT
|
||||
BUSINESS_NAME AS businessName,
|
||||
COUNT(1) AS count
|
||||
TENANT_NAME AS tenantName,
|
||||
COUNT(1) AS count
|
||||
FROM NGWL_TEST_YMS.QMS_MAIN_BUSINESS
|
||||
WHERE BUSINESS_NAME IS NOT NULL
|
||||
WHERE TENANT_NAME IS NOT NULL
|
||||
AND TRUNC(TARGET_DATE) = TRUNC(SYSDATE)
|
||||
GROUP BY BUSINESS_NAME
|
||||
GROUP BY TENANT_NAME
|
||||
ORDER BY COUNT(1) DESC
|
||||
</select>
|
||||
|
||||
@@ -102,6 +145,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
ORDER BY 1 DESC
|
||||
</select>
|
||||
|
||||
<!-- 任务类型统计(运输订单,来自 NGWL_TEST_OMS.BUSINESS_DOCUMENT_ORDER):
|
||||
当月(CREATE_TIME 在当前月)按业务类型 BUSINESS_CATEGORY 分组统计
|
||||
BUSINESS_CATEGORY: 1-跨境运输 2-国内运输 -->
|
||||
<select id="queryMonthTransportOrderByType" resultType="com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskTypeStatPO">
|
||||
SELECT
|
||||
BUSINESS_CATEGORY AS businessCategory,
|
||||
COUNT(1) AS count
|
||||
FROM NGWL_TEST_OMS.BUSINESS_DOCUMENT_ORDER
|
||||
WHERE BUSINESS_CATEGORY IN (1, 2)
|
||||
AND CREATE_TIME IS NOT NULL
|
||||
AND TO_CHAR(CREATE_TIME, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
|
||||
GROUP BY BUSINESS_CATEGORY
|
||||
ORDER BY BUSINESS_CATEGORY
|
||||
</select>
|
||||
|
||||
<!-- 任务负荷(今日 24 小时时段):按 EXTRACT(HOUR FROM ENTRY_TIME) 统计 -->
|
||||
<select id="queryTaskLoadToday" resultType="com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskLoadPO">
|
||||
SELECT
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@FeignClient(value = "mhd-third-party-service",url = "http://10.33.0.129:8012",configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(value = "mhd-third-party-service",url = "http://10.102.192.31:8012", configuration = FeignAutoConfiguration.class)
|
||||
public interface ThirdPartyServiceFeign {
|
||||
|
||||
//查询当前组织所有三方接口信息
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.mhd.user.interfaces.facade;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.mhd.common.core.domain.entity.R;
|
||||
import com.mhd.common.core.utils.bean.BeanUtils;
|
||||
import com.mhd.common.core.utils.poi.ExcelUtil;
|
||||
import com.mhd.common.log.annotation.Log;
|
||||
import com.mhd.common.log.enums.BusinessType;
|
||||
import com.mhd.common.security.utils.SecurityUtils;
|
||||
@@ -24,6 +25,7 @@ import com.mhd.user.application.service.WechatMiniAppService;
|
||||
import com.mhd.user.interfaces.dto.updateDTO.SettlementInfoUpdateDTO;
|
||||
import com.mhd.user.interfaces.vo.SettlementInfoQueryVo;
|
||||
import com.mhd.user.interfaces.vo.ShipperMasterDataSyncTimeVo;
|
||||
import com.mhd.user.interfaces.vo.UserShipperExportVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -31,6 +33,9 @@ import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
|
||||
@Api(tags = "用户中台管理-托运人管理")
|
||||
@@ -128,6 +133,33 @@ public class UserShipperAPI extends BaseController {
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@Log(title = "托运人管理-导出", description ="导出托运人列表",businessType = BusinessType.EXPORT)
|
||||
@ApiOperation("导出托运人列表")
|
||||
@GetMapping(value = "/exportUserShipper", produces = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
public void exportUserShipper(UserShipperDTO userShipperDTO, HttpServletResponse response) throws IOException {
|
||||
//转换实体
|
||||
UserShipperDO userShipperDO = userShipperAssember.toUserShipperDO(userShipperDTO);
|
||||
//查询全量(不分页),复用列表查询逻辑(含数据权限过滤)
|
||||
List<UserShipperPo> list = userShipperApplicationService.userShipperList(userShipperDO);
|
||||
|
||||
List<UserShipperExportVO> exportList = new ArrayList<>();
|
||||
if (list != null) {
|
||||
for (UserShipperPo po : list) {
|
||||
UserShipperExportVO vo = new UserShipperExportVO();
|
||||
BeanUtils.copyProperties(po, vo);
|
||||
exportList.add(vo);
|
||||
}
|
||||
}
|
||||
|
||||
//设置下载头,防止浏览器乱码
|
||||
String fileName = URLEncoder.encode("托运人列表", "UTF-8").replaceAll("\\+", "%20");
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
|
||||
|
||||
ExcelUtil<UserShipperExportVO> util = new ExcelUtil<>(UserShipperExportVO.class);
|
||||
util.exportExcel(response, exportList, "托运人列表");
|
||||
}
|
||||
|
||||
@ApiOperation("查询托运人列表统计表单")
|
||||
@GetMapping("/userShipperCount")
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.mhd.user.interfaces.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.mhd.common.core.annotation.Excel;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 托运人(委托方)列表导出对象
|
||||
*
|
||||
* @author gen
|
||||
*/
|
||||
@Data
|
||||
@ApiModel(value = "托运人列表导出对象", description = "托运人列表导出对象")
|
||||
public class UserShipperExportVO {
|
||||
|
||||
@Excel(name = "登录账号", sort = 1, width = 20)
|
||||
@ApiModelProperty(value = "登录账号")
|
||||
private String userAccount;
|
||||
|
||||
@Excel(name = "公司名称", sort = 2, width = 30)
|
||||
@ApiModelProperty(value = "公司名称")
|
||||
private String shipperEnterpriseName;
|
||||
|
||||
@Excel(name = "联系人", sort = 3, width = 15)
|
||||
@ApiModelProperty(value = "联系人")
|
||||
private String emergencyContactName;
|
||||
|
||||
@Excel(name = "联系电话", sort = 4, width = 18)
|
||||
@ApiModelProperty(value = "联系电话")
|
||||
private String emergencyContactPhone;
|
||||
|
||||
@Excel(name = "地址", sort = 5, width = 30)
|
||||
@ApiModelProperty(value = "企业注册地址")
|
||||
private String shipperEnterpriseAddress;
|
||||
|
||||
@Excel(name = "详细地址", sort = 6, width = 30)
|
||||
@ApiModelProperty(value = "详细地址")
|
||||
private String userAreaAddressShipper;
|
||||
|
||||
@Excel(name = "备注", sort = 7, width = 25)
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
@Excel(name = "结算币种", sort = 8, width = 12)
|
||||
@ApiModelProperty(value = "结算币种")
|
||||
private String settlementCurrency;
|
||||
|
||||
@Excel(name = "信用额度", sort = 9, width = 15)
|
||||
@ApiModelProperty(value = "信用额度(授权额度)")
|
||||
private BigDecimal authorizedQuota;
|
||||
|
||||
@Excel(name = "信用占用", sort = 10, width = 15)
|
||||
@ApiModelProperty(value = "信用占用")
|
||||
private BigDecimal authorizedUsedAmount;
|
||||
|
||||
@Excel(name = "信用余额", sort = 11, width = 15)
|
||||
@ApiModelProperty(value = "信用余额")
|
||||
private BigDecimal creditAmount;
|
||||
|
||||
@Excel(name = "客户协议", sort = 12, width = 12)
|
||||
@ApiModelProperty(value = "客户协议数量")
|
||||
private BigDecimal agreementCount;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
@Excel(name = "最近同步信用时间", sort = 13, width = 22, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
@ApiModelProperty(value = "最近同步信用时间")
|
||||
private Date limitTime;
|
||||
}
|
||||
+554
@@ -0,0 +1,554 @@
|
||||
package com.mhd.oms.application.service.businessDocumentOrder;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
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.exception.ServiceException;
|
||||
import com.mhd.common.core.web.domain.AjaxResult;
|
||||
import com.mhd.common.security.utils.SecurityUtils;
|
||||
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;
|
||||
import com.mhd.oms.domain.businessDocumentOrderAdjust.repository.mapper.BusinessDocumentOrderAdjustMapper;
|
||||
import com.mhd.oms.domain.businessDocumentOrderAdjustDetail.entity.BusinessDocumentOrderAdjustDetail;
|
||||
import com.mhd.oms.domain.businessDocumentOrderAdjustDetail.repository.mapper.BusinessDocumentOrderAdjustDetailMapper;
|
||||
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.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.model.LoginUser;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 运输业务单「订单调整」应用服务
|
||||
*
|
||||
* 规则(定稿):
|
||||
* 1. 每次调整都生成:1 条主记录 + 1 条明细快照
|
||||
* 2. 费用数据源 = 前端回传的费用明细 business_order_account(feeDetailList);
|
||||
* 主表金额 deliveryFreight 为其 amount 合计(冗余汇总,后端自动算)。
|
||||
* 3. 是否需审核:一旦任一「金额」发生变化
|
||||
* = feeDetailList 明细 amount 变化,或主表金额列变化 -> 走业务主管审核;
|
||||
* 否则(仅改非金额字段) -> 直通。
|
||||
* 4. 涉及金额提交 -> 仅把业务单 review_status 置为「调整待审核(3)」;主记录 AUDIT_STATUS=0(待审核);
|
||||
* 不更新业务单数据,不影响其它状态(order_status / execute_status 不动)。
|
||||
* 5. 审核通过 -> 覆盖业务单(金额) + 替换费用明细;review_status 一律置为 1(已审核),
|
||||
* 不影响 order_status / execute_status。
|
||||
* 审核驳回 -> 不更新业务单数据,review_status 还原为调整前值(主记录 before_review_status),可再次调整。
|
||||
* 6. 直通(未改金额) -> 覆盖业务单可编辑字段 + deliveryFreight(明细合计),并替换 business_order_account
|
||||
* (逻辑删旧 is_delete=1 + 插新 is_delete=0);不改动任何审核/执行状态。
|
||||
* 7. 前端以 amountChanged 告知是否改金额(默认前端判定);未传时后端兜底比对。
|
||||
*
|
||||
* 说明:review_status 原枚举 0未审/1通过/2驳回,新增 3=调整待审核;不改变原有用例。
|
||||
*
|
||||
* @author dev
|
||||
* @date 2026-09-09
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class BusinessDocumentOrderAdjustService {
|
||||
|
||||
private static final Integer AUDIT_WAIT = 0; // 调整记录:待审核
|
||||
private static final Integer AUDIT_PASS = 1; // 调整记录:审核通过
|
||||
private static final Integer AUDIT_REJECT = 2; // 调整记录:驳回
|
||||
|
||||
/** 主表金额(费用)字段,任一变化触发审核 */
|
||||
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");
|
||||
|
||||
/** 不允许被前端调整覆盖的系统字段 */
|
||||
private static final List<String> PROTECTED_FIELDS = Arrays.asList(
|
||||
"id", "goodsNumber",
|
||||
"orderStatus", "reviewStatus", "reviewId", "review", "reviewTime", "reviewOpinion",
|
||||
"salesManager", "auditStatus", "auditBy", "auditTime",
|
||||
"executeStatus", "executeId", "executeTime", "executor",
|
||||
"executeOrderId", "executeOrderNumber", "adjustStatus",
|
||||
"isDelete", "delFlag", "createBy", "createByName", "createTime",
|
||||
"updateBy", "updateByName", "updateTime",
|
||||
"pushStatus", "pushTime", "pushBy", "pushByName",
|
||||
"reviseApplyType", "reviseApplyStatus", "reviseApplyBy", "reviseApplyByName",
|
||||
"reviseApplyReason", "reviseApplyTime",
|
||||
"reservationOrderId", "reservationOrderNumber",
|
||||
"mainOrderId", "mainOrderNum", "mergeOrderId", "mergeOrderNum",
|
||||
"splicingOrderType", "splicingStatus", "deliveryProgress",
|
||||
"orgId", "orgName", "organizationId", "organizationName", "topOrganizationId",
|
||||
"realCreateBy", "realCreateName", "createCompanyId", "createUserId",
|
||||
"szwlUserId"
|
||||
);
|
||||
|
||||
@Autowired
|
||||
private BusinessDocumentOrderMapper businessDocumentOrderMapper;
|
||||
|
||||
@Autowired
|
||||
private BusinessOrderAccountMapper businessOrderAccountMapper;
|
||||
|
||||
@Autowired
|
||||
private BusinessDocumentOrderAdjustMapper adjustMapper;
|
||||
|
||||
@Autowired
|
||||
private BusinessDocumentOrderAdjustDetailMapper adjustDetailMapper;
|
||||
|
||||
@Autowired
|
||||
private ExecuteOrderMapper executeOrderMapper;
|
||||
|
||||
@Autowired
|
||||
private WlhyServiceFeign wlhyServiceFeign;
|
||||
|
||||
/**
|
||||
* 提交调整
|
||||
* 返回 data = [是否需审核, 调整记录ID]
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public AjaxResult adjust(BusinessDocumentOrderAdjustDTO dto) {
|
||||
if (dto == null || dto.getOrder() == null || dto.getOrder().getId() == null) {
|
||||
throw new ServiceException("参数错误:缺少业务单ID(order.id)");
|
||||
}
|
||||
BusinessDocumentOrder dbOrder = businessDocumentOrderMapper.selectById(dto.getOrder().getId());
|
||||
if (ObjectUtil.isNull(dbOrder)) {
|
||||
throw new ServiceException("业务单不存在或已被删除");
|
||||
}
|
||||
BusinessDocumentOrder front = dto.getOrder();
|
||||
|
||||
// 1. 当前库中费用明细
|
||||
List<BusinessOrderAccount> dbFeeList = businessOrderAccountMapper.selectList(
|
||||
new LambdaQueryWrapper<BusinessOrderAccount>()
|
||||
.eq(BusinessOrderAccount::getOrderId, dbOrder.getId())
|
||||
.eq(BusinessOrderAccount::getIsDelete, 0));
|
||||
|
||||
// 2. 调整后的费用明细(前端);为 null 则视为保持库中不变
|
||||
List<BusinessOrderAccount> newFeeList = dto.getFeeDetailList();
|
||||
|
||||
// 3. 生成"调整后"业务单对象:DB原值 + 前端可编辑字段覆盖(忽略null)
|
||||
BusinessDocumentOrder afterOrder = buildAfterOrder(dbOrder, front);
|
||||
|
||||
// 4. 若提供了费用明细,则 deliveryFreight(合计)=明细 amount 之和,并联动到 afterOrder
|
||||
boolean hasFeeDetail = newFeeList != null && !newFeeList.isEmpty();
|
||||
if (hasFeeDetail) {
|
||||
BigDecimal sum = sumAmount(newFeeList);
|
||||
afterOrder.setDeliveryFreight(sum);
|
||||
}
|
||||
|
||||
// 5. 判定是否修改了金额:以前端 amountChanged 为准(前端整单回传已自行判定);
|
||||
// 若前端未传则后端兜底比对(主表金额列 或 明细 amount 变化)
|
||||
boolean amountChanged;
|
||||
if (dto.getAmountChanged() != null) {
|
||||
amountChanged = dto.getAmountChanged();
|
||||
} else {
|
||||
amountChanged = isAmountChanged(dbOrder, front, hasFeeDetail, dbFeeList, newFeeList);
|
||||
}
|
||||
|
||||
// 6. 写主记录
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
Date now = new Date();
|
||||
BusinessDocumentOrderAdjust adjust = buildAdjust(dbOrder, loginUser, now, amountChanged, dto.getAdjustReason());
|
||||
adjustMapper.insert(adjust);
|
||||
|
||||
// 7. 写明细快照(调整后业务单整行 + 费用明细JSON)
|
||||
BusinessDocumentOrderAdjustDetail detail = new BusinessDocumentOrderAdjustDetail();
|
||||
copySnapshot(afterOrder, detail);
|
||||
if (hasFeeDetail) {
|
||||
detail.setFeeDetailJson(JSONUtil.toJsonStr(newFeeList));
|
||||
}
|
||||
detail.setAdjustId(adjust.getId());
|
||||
detail.setOrderId(dbOrder.getId());
|
||||
detail.setGoodsNumber(dbOrder.getGoodsNumber());
|
||||
detail.setCreateBy(adjust.getAdjustBy());
|
||||
detail.setCreateName(adjust.getAdjustByName());
|
||||
detail.setCreateTime(now);
|
||||
detail.setDelFlag(1);
|
||||
adjustDetailMapper.insert(detail);
|
||||
|
||||
if (!amountChanged) {
|
||||
// 8a. 直通:覆盖主表可编辑字段(含 deliveryFreight 合计) + 替换费用明细;不改动任何审核/执行状态
|
||||
saveOrderAndFee(dbOrder.getId(), afterOrder, hasFeeDetail ? newFeeList : dbFeeList, loginUser, now, false, null);
|
||||
updateAdjustPass(adjust.getId(), adjust.getAdjustBy(), adjust.getAdjustByName(), now, null);
|
||||
syncTmsAsync(dbOrder.getGoodsNumber(), afterOrder);
|
||||
} else {
|
||||
// 8b. 涉及金额:仅把业务单 review_status 置为"调整待审核(3)",其余状态(exec/orderStatus)不动,不更新业务单数据
|
||||
BusinessDocumentOrder statusOnly = new BusinessDocumentOrder();
|
||||
statusOnly.setId(dbOrder.getId());
|
||||
statusOnly.setReviewStatus(3L); // 调整待审核
|
||||
businessDocumentOrderMapper.updateById(statusOnly);
|
||||
}
|
||||
|
||||
return AjaxResult.success(new Object[]{amountChanged, adjust.getId()});
|
||||
}
|
||||
|
||||
/**
|
||||
* 调整记录列表(管理页:查全部,可选按订单/业务单号/审核状态等筛选,配合分页使用)
|
||||
*/
|
||||
public List<BusinessDocumentOrderAdjustRecordDTO> listAdjustRecord(BusinessDocumentOrderAdjustQueryDTO query) {
|
||||
LambdaQueryWrapper<BusinessDocumentOrderAdjust> wrapper = new LambdaQueryWrapper<BusinessDocumentOrderAdjust>()
|
||||
.eq(BusinessDocumentOrderAdjust::getDelFlag, 1);
|
||||
|
||||
// ===== 组织隔离(参考业务单 queryList 口径) =====
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
if (loginUser != null && loginUser.getUserPo() != null) {
|
||||
Long loginOrgId = loginUser.getUserPo().getOrganizationId();
|
||||
Long loginTopOrgId = loginUser.getUserPo().getTopOrganizationId();
|
||||
// 一级组织非1(集团)时,按一级组织过滤(可看本一级组织下所有)
|
||||
if (loginTopOrgId != null && loginTopOrgId != 1) {
|
||||
wrapper.eq(BusinessDocumentOrderAdjust::getTopOrgId, String.valueOf(loginTopOrgId));
|
||||
} else if (loginOrgId != null) {
|
||||
// 否则按当前组织过滤;若查询方显式指定了 organizationId 则以其为准
|
||||
Long effOrgId = (query != null && query.getOrganizationId() != null)
|
||||
? query.getOrganizationId() : loginOrgId;
|
||||
if (effOrgId != null) {
|
||||
wrapper.eq(BusinessDocumentOrderAdjust::getOrgId, String.valueOf(effOrgId));
|
||||
}
|
||||
}
|
||||
} else if (query != null && query.getOrganizationId() != null) {
|
||||
wrapper.eq(BusinessDocumentOrderAdjust::getOrgId, String.valueOf(query.getOrganizationId()));
|
||||
}
|
||||
|
||||
if (query != null) {
|
||||
if (query.getOrderId() != null) {
|
||||
wrapper.eq(BusinessDocumentOrderAdjust::getOrderId, query.getOrderId());
|
||||
}
|
||||
if (StrUtil.isNotBlank(query.getGoodsNumber())) {
|
||||
wrapper.like(BusinessDocumentOrderAdjust::getGoodsNumber, query.getGoodsNumber());
|
||||
}
|
||||
if (query.getIsAudit() != null) {
|
||||
wrapper.eq(BusinessDocumentOrderAdjust::getIsAudit, query.getIsAudit());
|
||||
}
|
||||
if (query.getAuditStatus() != null) {
|
||||
wrapper.eq(BusinessDocumentOrderAdjust::getAuditStatus, query.getAuditStatus());
|
||||
}
|
||||
if (StrUtil.isNotBlank(query.getAdjustByName())) {
|
||||
wrapper.like(BusinessDocumentOrderAdjust::getAdjustByName, query.getAdjustByName());
|
||||
}
|
||||
}
|
||||
wrapper.orderByDesc(BusinessDocumentOrderAdjust::getAdjustTime);
|
||||
List<BusinessDocumentOrderAdjust> list = adjustMapper.selectList(wrapper);
|
||||
return list.stream().map(a -> {
|
||||
BusinessDocumentOrderAdjustRecordDTO vo = new BusinessDocumentOrderAdjustRecordDTO();
|
||||
BeanUtil.copyProperties(a, vo);
|
||||
return vo;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 按业务单查询调整记录(供订单详情页"调整记录"Tab用)
|
||||
*/
|
||||
public List<BusinessDocumentOrderAdjustRecordDTO> listAdjustRecordByOrder(Long orderId) {
|
||||
BusinessDocumentOrderAdjustQueryDTO query = new BusinessDocumentOrderAdjustQueryDTO();
|
||||
query.setOrderId(orderId);
|
||||
return listAdjustRecord(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调整记录详情(主记录 + 调整后明细快照)
|
||||
*/
|
||||
public BusinessDocumentOrderAdjustRecordDTO getAdjustRecord(Long adjustId) {
|
||||
BusinessDocumentOrderAdjust adjust = adjustMapper.selectById(adjustId);
|
||||
if (adjust == null) {
|
||||
throw new ServiceException("调整记录不存在");
|
||||
}
|
||||
BusinessDocumentOrderAdjustRecordDTO vo = new BusinessDocumentOrderAdjustRecordDTO();
|
||||
BeanUtil.copyProperties(adjust, vo);
|
||||
BusinessDocumentOrderAdjustDetail detail = adjustDetailMapper.selectOne(
|
||||
new LambdaQueryWrapper<BusinessDocumentOrderAdjustDetail>()
|
||||
.eq(BusinessDocumentOrderAdjustDetail::getAdjustId, adjustId)
|
||||
.eq(BusinessDocumentOrderAdjustDetail::getDelFlag, 1)
|
||||
.last("LIMIT 1"));
|
||||
vo.setDetail(detail);
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调整审核(通过/驳回),业务主管操作
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public AjaxResult auditAdjust(BusinessDocumentOrderAdjustAuditDTO auditDTO) {
|
||||
if (auditDTO == null || auditDTO.getAdjustId() == null) {
|
||||
throw new ServiceException("参数错误:缺少调整记录ID");
|
||||
}
|
||||
BusinessDocumentOrderAdjust adjust = adjustMapper.selectById(auditDTO.getAdjustId());
|
||||
if (adjust == null) {
|
||||
throw new ServiceException("调整记录不存在");
|
||||
}
|
||||
if (adjust.getAuditStatus() == null || adjust.getAuditStatus() != AUDIT_WAIT) {
|
||||
throw new ServiceException("该调整记录非待审核状态,无法审核");
|
||||
}
|
||||
Integer result = auditDTO.getAuditResult();
|
||||
if (result == null || (result != AUDIT_PASS && result != AUDIT_REJECT)) {
|
||||
throw new ServiceException("审核结果非法");
|
||||
}
|
||||
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
String auditBy = loginUser != null ? String.valueOf(loginUser.getUserid()) : null;
|
||||
String auditByName = loginUser != null && loginUser.getWlhyLoginUser() != null ? loginUser.getWlhyLoginUser().getRealname() : null;
|
||||
Date now = new Date();
|
||||
|
||||
if (result == AUDIT_PASS) {
|
||||
BusinessDocumentOrder order = businessDocumentOrderMapper.selectById(adjust.getOrderId());
|
||||
if (ObjectUtil.isNull(order)) {
|
||||
throw new ServiceException("业务单不存在");
|
||||
}
|
||||
BusinessDocumentOrderAdjustDetail detail = adjustDetailMapper.selectOne(
|
||||
new LambdaQueryWrapper<BusinessDocumentOrderAdjustDetail>()
|
||||
.eq(BusinessDocumentOrderAdjustDetail::getAdjustId, adjust.getId())
|
||||
.eq(BusinessDocumentOrderAdjustDetail::getDelFlag, 1)
|
||||
.last("LIMIT 1"));
|
||||
|
||||
// 还原调整后业务单(从JSON整行快照)
|
||||
BusinessDocumentOrder snapshot = null;
|
||||
if (detail != null && StrUtil.isNotBlank(detail.getOrderSnapshotJson())) {
|
||||
try {
|
||||
snapshot = JSONUtil.toBean(detail.getOrderSnapshotJson(), BusinessDocumentOrder.class);
|
||||
} catch (Exception e) {
|
||||
log.warn("解析调整快照JSON失败", e);
|
||||
}
|
||||
}
|
||||
BusinessDocumentOrder toSave = new BusinessDocumentOrder();
|
||||
toSave.setId(order.getId());
|
||||
if (snapshot != null) {
|
||||
BeanUtil.copyProperties(snapshot, toSave, CopyOptions.create().setIgnoreNullValue(true)
|
||||
.setIgnoreProperties(toArray()));
|
||||
} else if (detail != null) {
|
||||
BeanUtil.copyProperties(detail, toSave, CopyOptions.create().setIgnoreNullValue(true)
|
||||
.setIgnoreProperties(toArray()));
|
||||
}
|
||||
|
||||
// 还原调整后费用明细(从 feeDetailJson)
|
||||
List<BusinessOrderAccount> newFeeList = new ArrayList<>();
|
||||
if (detail != null && StrUtil.isNotBlank(detail.getFeeDetailJson())) {
|
||||
try {
|
||||
newFeeList = JSONUtil.toList(detail.getFeeDetailJson(), BusinessOrderAccount.class);
|
||||
} catch (Exception e) {
|
||||
log.warn("解析调整费用明细JSON失败", e);
|
||||
}
|
||||
}
|
||||
// 若快照中有明细合计则保证 deliveryFreight 一致
|
||||
if (!newFeeList.isEmpty()) {
|
||||
toSave.setDeliveryFreight(sumAmount(newFeeList));
|
||||
}
|
||||
// 审核通过后 review_status 一律置为 1(已审核);不影响 order_status / execute_status
|
||||
toSave.setReviewStatus(1L);
|
||||
// 覆盖业务单 + 替换费用明细
|
||||
saveOrderAndFee(order.getId(), toSave, newFeeList, loginUser, now, false, null);
|
||||
|
||||
updateAdjustPass(adjust.getId(), auditBy, auditByName, now, auditDTO.getAuditRemark());
|
||||
syncTmsAsync(order.getGoodsNumber(), toSave);
|
||||
} else {
|
||||
adjust.setAuditStatus(AUDIT_REJECT);
|
||||
adjust.setAuditBy(auditBy);
|
||||
adjust.setAuditByName(auditByName);
|
||||
adjust.setAuditTime(now);
|
||||
adjust.setAuditRemark(auditDTO.getAuditRemark());
|
||||
adjust.setUpdateBy(auditBy);
|
||||
adjust.setUpdateTime(now);
|
||||
adjustMapper.updateById(adjust);
|
||||
|
||||
// 驳回:不更新业务单数据,仅把 review_status 还原为调整前值(不影响其它状态)
|
||||
BusinessDocumentOrder statusOnly = new BusinessDocumentOrder();
|
||||
statusOnly.setId(adjust.getOrderId());
|
||||
statusOnly.setReviewStatus(adjust.getBeforeReviewStatus() == null ? 0L : adjust.getBeforeReviewStatus());
|
||||
businessDocumentOrderMapper.updateById(statusOnly);
|
||||
}
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// 私有工具
|
||||
// =====================================================
|
||||
|
||||
private BusinessDocumentOrder buildAfterOrder(BusinessDocumentOrder dbOrder, BusinessDocumentOrder front) {
|
||||
BusinessDocumentOrder after = new BusinessDocumentOrder();
|
||||
BeanUtil.copyProperties(dbOrder, after, CopyOptions.create().setIgnoreNullValue(true));
|
||||
BeanUtil.copyProperties(front, after, CopyOptions.create().setIgnoreNullValue(true)
|
||||
.setIgnoreProperties(toArray()));
|
||||
after.setId(dbOrder.getId());
|
||||
return after;
|
||||
}
|
||||
|
||||
private BusinessDocumentOrderAdjust buildAdjust(BusinessDocumentOrder dbOrder, LoginUser u, Date now,
|
||||
boolean amountChanged, String reason) {
|
||||
BusinessDocumentOrderAdjust adjust = new BusinessDocumentOrderAdjust();
|
||||
adjust.setOrderId(dbOrder.getId());
|
||||
adjust.setGoodsNumber(dbOrder.getGoodsNumber());
|
||||
adjust.setAdjustBy(u != null ? String.valueOf(u.getUserid()) : null);
|
||||
adjust.setAdjustByName(u != null && u.getWlhyLoginUser() != null ? u.getWlhyLoginUser().getRealname() : null);
|
||||
adjust.setAdjustTime(now);
|
||||
adjust.setAdjustReason(reason);
|
||||
adjust.setIsAudit(amountChanged ? 1 : 0);
|
||||
adjust.setAuditStatus(amountChanged ? AUDIT_WAIT : AUDIT_PASS);
|
||||
adjust.setBeforeReviewStatus(dbOrder.getReviewStatus());
|
||||
// 组织信息:参考业务单口径,取当前登录用户所属组织(调整人归属)
|
||||
if (u != null && u.getUserPo() != null) {
|
||||
if (u.getUserPo().getOrganizationId() != null) {
|
||||
adjust.setOrgId(String.valueOf(u.getUserPo().getOrganizationId()));
|
||||
} else {
|
||||
adjust.setOrgId(dbOrder.getOrgId());
|
||||
}
|
||||
if (u.getUserPo().getTopOrganizationId() != null) {
|
||||
adjust.setTopOrgId(String.valueOf(u.getUserPo().getTopOrganizationId()));
|
||||
} else if (dbOrder.getTopOrganizationId() != null) {
|
||||
adjust.setTopOrgId(String.valueOf(dbOrder.getTopOrganizationId()));
|
||||
}
|
||||
} else {
|
||||
adjust.setOrgId(dbOrder.getOrgId());
|
||||
if (dbOrder.getTopOrganizationId() != null) {
|
||||
adjust.setTopOrgId(String.valueOf(dbOrder.getTopOrganizationId()));
|
||||
}
|
||||
}
|
||||
adjust.setCreateBy(adjust.getAdjustBy());
|
||||
adjust.setCreateName(adjust.getAdjustByName());
|
||||
adjust.setCreateTime(now);
|
||||
adjust.setDelFlag(1);
|
||||
return adjust;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否修改了金额:主表金额列变化 或 明细 amount 变化
|
||||
*/
|
||||
private boolean isAmountChanged(BusinessDocumentOrder dbOrder, BusinessDocumentOrder front,
|
||||
boolean hasFeeDetail, List<BusinessOrderAccount> dbFeeList,
|
||||
List<BusinessOrderAccount> newFeeList) {
|
||||
// a) 主表金额列比对
|
||||
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 (mainChanged) {
|
||||
return true;
|
||||
}
|
||||
// b) 若前端未传明细,则只看主表;若传了明细,比较明细金额
|
||||
if (!hasFeeDetail) {
|
||||
return false;
|
||||
}
|
||||
// 明细合计对比
|
||||
BigDecimal oldSum = sumAmount(dbFeeList);
|
||||
BigDecimal newSum = sumAmount(newFeeList);
|
||||
return oldSum.compareTo(newSum) != 0;
|
||||
}
|
||||
|
||||
private BigDecimal sumAmount(List<BusinessOrderAccount> list) {
|
||||
BigDecimal sum = BigDecimal.ZERO;
|
||||
if (list == null) {
|
||||
return sum;
|
||||
}
|
||||
for (BusinessOrderAccount acc : list) {
|
||||
if (acc.getAmount() != null) {
|
||||
sum = sum.add(acc.getAmount());
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* 覆盖业务单可编辑字段 + 替换费用明细(逻辑删旧 + 插新)
|
||||
*/
|
||||
/**
|
||||
* 覆盖业务单可编辑字段 + 替换费用明细(逻辑删旧 + 插新)
|
||||
* @param restoreReview 是否还原审核状态(审核通过/驳回后 true;直通 false 不改任何审核状态)
|
||||
* @param beforeReviewStatus 调整前 review_status,用于还原
|
||||
*/
|
||||
private void saveOrderAndFee(Long orderId, BusinessDocumentOrder toSave,
|
||||
List<BusinessOrderAccount> newFeeList,
|
||||
LoginUser loginUser, Date now,
|
||||
boolean restoreReview, Long beforeReviewStatus) {
|
||||
if (restoreReview) {
|
||||
// 仅还原 review_status 到调整前值;不影响 order_status / execute_status 等其它状态
|
||||
toSave.setReviewStatus(beforeReviewStatus == null ? 0L : beforeReviewStatus);
|
||||
}
|
||||
businessDocumentOrderMapper.updateById(toSave);
|
||||
|
||||
// 逻辑删旧明细
|
||||
List<BusinessOrderAccount> oldFeeList = businessOrderAccountMapper.selectList(
|
||||
new LambdaQueryWrapper<BusinessOrderAccount>()
|
||||
.eq(BusinessOrderAccount::getOrderId, orderId)
|
||||
.eq(BusinessOrderAccount::getIsDelete, 0));
|
||||
if (oldFeeList != null) {
|
||||
for (BusinessOrderAccount oldAcc : oldFeeList) {
|
||||
oldAcc.setIsDelete(1);
|
||||
oldAcc.setUpdateBy(loginUser != null ? String.valueOf(loginUser.getUserid()) : null);
|
||||
oldAcc.setUpdateTime(now);
|
||||
businessOrderAccountMapper.updateById(oldAcc);
|
||||
}
|
||||
}
|
||||
// 插新明细
|
||||
if (newFeeList != null && !newFeeList.isEmpty()) {
|
||||
for (BusinessOrderAccount acc : newFeeList) {
|
||||
acc.setId(IdUtil.randomUUID());
|
||||
acc.setOrderId(String.valueOf(orderId));
|
||||
acc.setIsDelete(0);
|
||||
acc.setCreateBy(loginUser != null ? String.valueOf(loginUser.getUserid()) : null);
|
||||
acc.setCreateTime(now);
|
||||
businessOrderAccountMapper.insert(acc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void copySnapshot(BusinessDocumentOrder order, BusinessDocumentOrderAdjustDetail detail) {
|
||||
BeanUtil.copyProperties(order, detail, CopyOptions.create().setIgnoreNullValue(true)
|
||||
.setIgnoreProperties("id", "adjustId", "orderId", "createBy", "createName",
|
||||
"createTime", "updateBy", "updateTime", "delFlag",
|
||||
"orderSnapshotJson", "feeDetailJson"));
|
||||
try {
|
||||
detail.setOrderSnapshotJson(JSONUtil.toJsonStr(order));
|
||||
} catch (Exception e) {
|
||||
log.warn("生成调整快照JSON失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAdjustPass(Long adjustId, String auditBy, String auditByName, Date auditTime, String remark) {
|
||||
BusinessDocumentOrderAdjust adjust = new BusinessDocumentOrderAdjust();
|
||||
adjust.setId(adjustId);
|
||||
adjust.setAuditStatus(AUDIT_PASS);
|
||||
adjust.setAuditBy(auditBy);
|
||||
adjust.setAuditByName(auditByName);
|
||||
adjust.setAuditTime(auditTime);
|
||||
adjust.setAuditRemark(remark);
|
||||
adjust.setUpdateBy(auditBy);
|
||||
adjust.setUpdateTime(auditTime);
|
||||
adjustMapper.updateById(adjust);
|
||||
}
|
||||
|
||||
private String[] toArray() {
|
||||
return PROTECTED_FIELDS.toArray(new String[0]);
|
||||
}
|
||||
|
||||
private void syncTmsAsync(String goodsNumber, BusinessDocumentOrder after) {
|
||||
try {
|
||||
List<ExecuteOrder> executeOrders = executeOrderMapper.selectList(
|
||||
new LambdaQueryWrapper<ExecuteOrder>()
|
||||
.eq(ExecuteOrder::getGoodsNumber, goodsNumber)
|
||||
.eq(ExecuteOrder::getDelFlag, 1));
|
||||
if (executeOrders == null || executeOrders.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
log.info("业务单[{}]调整完成,关联执行单[{}]。如需回写TMS请接入TMS改费Feign。", goodsNumber,
|
||||
executeOrders.stream().map(ExecuteOrder::getGoodsNumber).collect(Collectors.toList()));
|
||||
} catch (Exception e) {
|
||||
log.error("同步TMS失败,不影响主流程", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -659,7 +659,7 @@ public class BusinessDocumentOrder extends BaseVOEntity{
|
||||
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
|
||||
private Date documentDate;
|
||||
|
||||
@ApiModelProperty( "审核状态 0-未审核 1-审核通过 2-已驳回")
|
||||
@ApiModelProperty( "审核状态 0-未审核 1-审核通过 2-已驳回 3-调整待审核")
|
||||
private Long reviewStatus;
|
||||
|
||||
@ApiModelProperty("审核时间")
|
||||
@@ -825,4 +825,7 @@ public class BusinessDocumentOrder extends BaseVOEntity{
|
||||
@ApiModelProperty("车次")
|
||||
@Excel(name = "车次")
|
||||
private String shuttleNo;
|
||||
|
||||
@ApiModelProperty("业务单调整状态 0-无 1-调整待审核 2-调整驳回 3-调整已通过")
|
||||
private Integer adjustStatus;
|
||||
}
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
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 io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 运输业务单 调整主记录
|
||||
*
|
||||
* @author dev
|
||||
* @date 2026-09-09
|
||||
*/
|
||||
@Data
|
||||
@TableName("business_document_order_adjust")
|
||||
public class BusinessDocumentOrderAdjust implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("主键")
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("业务单ID")
|
||||
private Long orderId;
|
||||
|
||||
@ApiModelProperty("业务单号")
|
||||
private String goodsNumber;
|
||||
|
||||
@ApiModelProperty("调整人账号")
|
||||
private String adjustBy;
|
||||
|
||||
@ApiModelProperty("调整人姓名")
|
||||
private String adjustByName;
|
||||
|
||||
@ApiModelProperty("调整时间")
|
||||
private Date adjustTime;
|
||||
|
||||
@ApiModelProperty("调整原因")
|
||||
private String adjustReason;
|
||||
|
||||
@ApiModelProperty("是否需要审核 0-否 1-是")
|
||||
private Integer isAudit;
|
||||
|
||||
@ApiModelProperty("调整前业务单审核状态(review_status原值,用于调整审核通过/驳回后还原,避免影响其它)")
|
||||
private Long beforeReviewStatus;
|
||||
|
||||
@ApiModelProperty("审核状态 0-待审核 1-审核通过 2-驳回")
|
||||
private Integer auditStatus;
|
||||
|
||||
@ApiModelProperty("审核人账号")
|
||||
private String auditBy;
|
||||
|
||||
@ApiModelProperty("审核人姓名")
|
||||
private String auditByName;
|
||||
|
||||
@ApiModelProperty("审核时间")
|
||||
private Date auditTime;
|
||||
|
||||
@ApiModelProperty("审核/驳回意见")
|
||||
private String auditRemark;
|
||||
|
||||
@ApiModelProperty("组织ID")
|
||||
private String orgId;
|
||||
|
||||
@ApiModelProperty("一级组织ID")
|
||||
private String topOrgId;
|
||||
|
||||
@ApiModelProperty("创建人")
|
||||
private String createBy;
|
||||
|
||||
@ApiModelProperty("创建人姓名")
|
||||
private String createName;
|
||||
|
||||
@ApiModelProperty("创建时间")
|
||||
private Date createTime;
|
||||
|
||||
@ApiModelProperty("更新人")
|
||||
private String updateBy;
|
||||
|
||||
@ApiModelProperty("更新人姓名")
|
||||
private String updateName;
|
||||
|
||||
@ApiModelProperty("更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
@ApiModelProperty("删除标记 1-正常 0-删除")
|
||||
private Integer delFlag;
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.mhd.oms.domain.businessDocumentOrderAdjust.repository.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.mhd.oms.domain.businessDocumentOrderAdjust.entity.BusinessDocumentOrderAdjust;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 运输业务单 调整主记录 Mapper
|
||||
*/
|
||||
@Mapper
|
||||
public interface BusinessDocumentOrderAdjustMapper extends BaseMapper<BusinessDocumentOrderAdjust> {
|
||||
}
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
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 io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 运输业务单 调整明细(调整后业务单整行快照)
|
||||
*
|
||||
* @author dev
|
||||
* @date 2026-09-09
|
||||
*/
|
||||
@Data
|
||||
@TableName("business_document_order_adjust_detail")
|
||||
public class BusinessDocumentOrderAdjustDetail implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("主键")
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("关联调整主记录ID")
|
||||
private Long adjustId;
|
||||
|
||||
@ApiModelProperty("业务单ID")
|
||||
private Long orderId;
|
||||
|
||||
@ApiModelProperty("业务单号")
|
||||
private String goodsNumber;
|
||||
|
||||
@ApiModelProperty("货物类型ID")
|
||||
private String goodsTypeId;
|
||||
|
||||
@ApiModelProperty("货物名称")
|
||||
private String goodsName;
|
||||
|
||||
@ApiModelProperty("车型")
|
||||
private String carType;
|
||||
|
||||
@ApiModelProperty("装货地")
|
||||
private String loadingName;
|
||||
|
||||
@ApiModelProperty("装货地址")
|
||||
private String loadingAddress;
|
||||
|
||||
@ApiModelProperty("装货时间")
|
||||
private Date loadingDate;
|
||||
|
||||
@ApiModelProperty("卸货地")
|
||||
private String unloadName;
|
||||
|
||||
@ApiModelProperty("卸货地址")
|
||||
private String unloadAddress;
|
||||
|
||||
@ApiModelProperty("卸货时间")
|
||||
private Date unloadingData;
|
||||
|
||||
@ApiModelProperty("发货人")
|
||||
private String freighterName;
|
||||
|
||||
@ApiModelProperty("装货电话")
|
||||
private String loadingPhone;
|
||||
|
||||
@ApiModelProperty("收货人")
|
||||
private String dischargerName;
|
||||
|
||||
@ApiModelProperty("卸货电话")
|
||||
private String unloadPhone;
|
||||
|
||||
@ApiModelProperty("备注")
|
||||
private String remarks;
|
||||
|
||||
@ApiModelProperty("线路")
|
||||
private String route;
|
||||
|
||||
@ApiModelProperty("单据日期")
|
||||
private Date documentDate;
|
||||
|
||||
@ApiModelProperty("组织ID")
|
||||
private String orgId;
|
||||
|
||||
@ApiModelProperty("组织ID")
|
||||
private Long organizationId;
|
||||
|
||||
@ApiModelProperty("组织名称")
|
||||
private String organizationName;
|
||||
|
||||
@ApiModelProperty("一级组织ID")
|
||||
private Long topOrganizationId;
|
||||
|
||||
// ==================== 金额/费用快照 ====================
|
||||
@ApiModelProperty("发货运费")
|
||||
private BigDecimal deliveryFreight;
|
||||
|
||||
@ApiModelProperty("已收运费")
|
||||
private BigDecimal collectedFreight;
|
||||
|
||||
@ApiModelProperty("未收运费")
|
||||
private BigDecimal uncollectedFreight;
|
||||
|
||||
@ApiModelProperty("少收运费")
|
||||
private BigDecimal collectLessFreight;
|
||||
|
||||
@ApiModelProperty("运费单价(元/吨)")
|
||||
private BigDecimal transportationUnitPrice;
|
||||
|
||||
@ApiModelProperty("信息费")
|
||||
private BigDecimal infoFee;
|
||||
|
||||
@ApiModelProperty("计费单价")
|
||||
private BigDecimal freightUnitPrice;
|
||||
|
||||
@ApiModelProperty("货物保险金额")
|
||||
private BigDecimal cargoInsuranceAmount;
|
||||
|
||||
@ApiModelProperty("运费")
|
||||
private BigDecimal freightCharges;
|
||||
|
||||
@ApiModelProperty("运费")
|
||||
private BigDecimal freightFee;
|
||||
|
||||
@ApiModelProperty("卸货费")
|
||||
private BigDecimal unloadingFee;
|
||||
|
||||
@ApiModelProperty("报关费")
|
||||
private BigDecimal customsFee;
|
||||
|
||||
@ApiModelProperty("差货费")
|
||||
private BigDecimal shortageFee;
|
||||
|
||||
@ApiModelProperty("杂费")
|
||||
private BigDecimal miscellaneousFee;
|
||||
|
||||
@ApiModelProperty("其他费用")
|
||||
private BigDecimal otherFee;
|
||||
|
||||
@ApiModelProperty("滞车费")
|
||||
private BigDecimal detentionFee;
|
||||
|
||||
@ApiModelProperty("税率")
|
||||
private BigDecimal taxRate;
|
||||
|
||||
@ApiModelProperty("创建人")
|
||||
private String createBy;
|
||||
|
||||
@ApiModelProperty("创建人姓名")
|
||||
private String createName;
|
||||
|
||||
@ApiModelProperty("创建时间")
|
||||
private Date createTime;
|
||||
|
||||
@ApiModelProperty("更新人")
|
||||
private String updateBy;
|
||||
|
||||
@ApiModelProperty("更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
@ApiModelProperty("删除标记 1-正常 0-删除")
|
||||
private Integer delFlag;
|
||||
|
||||
@ApiModelProperty("调整后业务单整行JSON快照(用于全字段精确还原)")
|
||||
private String orderSnapshotJson;
|
||||
|
||||
@ApiModelProperty("调整后费用明细JSON快照(business_order_account列表)")
|
||||
private String feeDetailJson;
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.mhd.oms.domain.businessDocumentOrderAdjustDetail.repository.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.mhd.oms.domain.businessDocumentOrderAdjustDetail.entity.BusinessDocumentOrderAdjustDetail;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 运输业务单 调整明细 Mapper
|
||||
*/
|
||||
@Mapper
|
||||
public interface BusinessDocumentOrderAdjustDetailMapper extends BaseMapper<BusinessDocumentOrderAdjustDetail> {
|
||||
}
|
||||
+10
-5
@@ -78,6 +78,16 @@ public class ExecutionStockInOrderAssembler {
|
||||
// 最后使用username(账号)作为兜底
|
||||
userRealName = loginUser.getUsername();
|
||||
}
|
||||
// 单据类型跟随业务类型:页面唯一的类型选择项是"业务类型"(只提交businessType),
|
||||
// 编辑时前端回显提交的orderTypeCode/orderTypeName是旧值,若以回显值为准会导致编辑改类型不生效;
|
||||
// 系统内businessType与orderTypeCode同值域(pu_tong_ru_ku/tui_huo_ru_ku),以businessType为准保持三者一致
|
||||
if (stockInOrderDO.getBusinessType() != null && stockInOrderDO.getBusinessType().trim().length() > 0) {
|
||||
stockInOrderDO.setOrderTypeCode(stockInOrderDO.getBusinessType().trim());
|
||||
} else if (stockInOrderDTO.getInOrderId() == null
|
||||
&& (stockInOrderDO.getOrderTypeCode() == null || stockInOrderDO.getOrderTypeCode().trim().length() == 0)) {
|
||||
// 仅新增且无业务类型时兜底普通入库;编辑时两字段都为空则不覆盖(updateById跳过null字段)
|
||||
stockInOrderDO.setOrderTypeCode("pu_tong_ru_ku");
|
||||
}
|
||||
if(stockInOrderDTO.getInOrderId() != null){
|
||||
stockInOrderDO.setUpdateBy(userId);
|
||||
stockInOrderDO.setUpdateByName(userRealName);
|
||||
@@ -91,11 +101,6 @@ public class ExecutionStockInOrderAssembler {
|
||||
stockInOrderDO.setCreateByName(userRealName);
|
||||
stockInOrderDO.setCreateTime(new Date());
|
||||
stockInOrderDO.setDelFlag(1);
|
||||
// 新增入库单时,如果入库单类型为空,默认设置为普通入库
|
||||
String orderTypeCode = stockInOrderDO.getOrderTypeCode();
|
||||
if (orderTypeCode == null || orderTypeCode.trim().length() == 0) {
|
||||
stockInOrderDO.setOrderTypeCode("pu_tong_ru_ku");
|
||||
}
|
||||
String orderTypeName = stockInOrderDO.getOrderTypeName();
|
||||
if (orderTypeName == null || orderTypeName.trim().length() == 0) {
|
||||
stockInOrderDO.setOrderTypeName("普通入库单");
|
||||
|
||||
+91
-16
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.mhd.common.core.exception.ServiceException;
|
||||
import com.mhd.common.core.utils.OrderSequence;
|
||||
@@ -32,6 +33,8 @@ import com.mhd.oms.domain.executionStockInOrder.repository.po.ExecutionStockInOr
|
||||
import com.mhd.oms.domain.executionStockInOrder.repository.todo.ExecutionStockInOrderDO;
|
||||
import com.mhd.oms.domain.executionStockOutOrder.entity.ExecutionStockOutOrder;
|
||||
import com.mhd.oms.domain.executionStockOutOrder.repository.facade.IExecutionStockOutOrderService;
|
||||
import com.mhd.oms.domain.reservationStockInOrder.entity.ReservationStockInOrder;
|
||||
import com.mhd.oms.domain.reservationStockInOrder.repository.facade.IReservationStockInOrderService;
|
||||
import com.mhd.oms.domain.reservationStockInOrder.repository.mapper.ReservationStockInOrderMapper;
|
||||
import com.mhd.oms.domain.reserveStockInOrder.repository.mapper.ReserveStockInOrderMapper;
|
||||
import com.mhd.system.api.SystemServiceFeign;
|
||||
@@ -70,6 +73,8 @@ public class ExecutionStockInOrderDomainService {
|
||||
private IExecutionInMaterialDetailService materialDetailService;
|
||||
@Autowired
|
||||
private IExecutionStockOutOrderService stockOutOrderService;
|
||||
@Autowired
|
||||
private IReservationStockInOrderService reservationStockInOrderService;
|
||||
// @Autowired
|
||||
// private ReservationStockReceiptOrderDomainService stockReceiptOrderDomainService;
|
||||
// @Autowired
|
||||
@@ -613,9 +618,15 @@ public class ExecutionStockInOrderDomainService {
|
||||
}
|
||||
// 入参去重:同一请求内重复ID会导致同一执行单被多次推送WMS
|
||||
List<Long> distinctInOrderIds = inOrderIds.stream().distinct().collect(Collectors.toList());
|
||||
// 只校验有效单据:已删除(软删)执行单混入ID(过期页面提交)时在此拦截,
|
||||
// 此前list/getById均不过滤del_flag,软删单照样被推到WMS形成"幽灵单"
|
||||
List<ExecutionStockInOrder> checkOrders = stockInOrderService.list(
|
||||
new QueryWrapper<ExecutionStockInOrder>().lambda()
|
||||
.in(ExecutionStockInOrder::getInOrderId, distinctInOrderIds));
|
||||
.in(ExecutionStockInOrder::getInOrderId, distinctInOrderIds)
|
||||
.eq(ExecutionStockInOrder::getDelFlag, 1));
|
||||
if (checkOrders.size() != distinctInOrderIds.size()) {
|
||||
throw new ServiceException("下发失败:存在已删除的单据,请刷新后重新选择");
|
||||
}
|
||||
for (ExecutionStockInOrder order : checkOrders) {
|
||||
if (order.getIssueTime() != null) {
|
||||
throw new ServiceException("下发失败:单据[" + order.getInOrderNumber() + "]已下发,不可重复下发;如需重新下发请先取消下发");
|
||||
@@ -704,24 +715,88 @@ public class ExecutionStockInOrderDomainService {
|
||||
* @return Boolean
|
||||
*/
|
||||
public Boolean returnResult(String orderNumber, Long status, String type) {
|
||||
// WMS内部Feign回传可能无登录上下文(如PDA异步完成上架),SecurityUtils.getLoginUser()会返回null,
|
||||
// 更新人信息判空兜底:无用户时只更新状态,不覆盖原有更新人字段
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
String userRealName = loginUser.getUserPo() != null && loginUser.getUserPo().getUserName() != null
|
||||
? loginUser.getUserPo().getUserName()
|
||||
: (loginUser.getRealname() != null ? loginUser.getRealname() : loginUser.getUsername());
|
||||
String userRealName = null;
|
||||
Long updateBy = null;
|
||||
if (loginUser != null) {
|
||||
userRealName = loginUser.getUserPo() != null && loginUser.getUserPo().getUserName() != null
|
||||
? loginUser.getUserPo().getUserName()
|
||||
: (loginUser.getRealname() != null ? loginUser.getRealname() : loginUser.getUsername());
|
||||
updateBy = loginUser.getUserid();
|
||||
}
|
||||
if (type != null && type.equals("1")) {
|
||||
return stockOutOrderService.update(null, new UpdateWrapper<ExecutionStockOutOrder>().lambda()
|
||||
.set(ExecutionStockOutOrder::getStatus, status)
|
||||
.set(ExecutionStockOutOrder::getUpdateBy, loginUser.getUserid())
|
||||
.set(ExecutionStockOutOrder::getUpdateByName, userRealName)
|
||||
.set(ExecutionStockOutOrder::getUpdateTime, new Date())
|
||||
.in(ExecutionStockOutOrder::getOutOrderNumber, orderNumber));
|
||||
LambdaUpdateWrapper<ExecutionStockOutOrder> wrapper = new LambdaUpdateWrapper<ExecutionStockOutOrder>()
|
||||
.set(ExecutionStockOutOrder::getStatus, status);
|
||||
if (updateBy != null) {
|
||||
wrapper.set(ExecutionStockOutOrder::getUpdateBy, updateBy)
|
||||
.set(ExecutionStockOutOrder::getUpdateByName, userRealName)
|
||||
.set(ExecutionStockOutOrder::getUpdateTime, new Date());
|
||||
}
|
||||
wrapper.in(ExecutionStockOutOrder::getOutOrderNumber, orderNumber);
|
||||
return stockOutOrderService.update(null, wrapper);
|
||||
} else {
|
||||
return stockInOrderService.update(null, new UpdateWrapper<ExecutionStockInOrder>().lambda()
|
||||
.set(ExecutionStockInOrder::getStatus, status)
|
||||
.set(ExecutionStockInOrder::getUpdateBy, loginUser.getUserid())
|
||||
.set(ExecutionStockInOrder::getUpdateByName, userRealName)
|
||||
.set(ExecutionStockInOrder::getUpdateTime, new Date())
|
||||
.in(ExecutionStockInOrder::getInOrderNumber, orderNumber));
|
||||
LambdaUpdateWrapper<ExecutionStockInOrder> wrapper = new LambdaUpdateWrapper<ExecutionStockInOrder>()
|
||||
.set(ExecutionStockInOrder::getStatus, status);
|
||||
// 已入库(5)时同步issueStatus=4,供前端"入库执行单"列表入库状态列展示"已入库"
|
||||
if (status != null && status == 5L) {
|
||||
wrapper.set(ExecutionStockInOrder::getIssueStatus, 4);
|
||||
}
|
||||
if (updateBy != null) {
|
||||
wrapper.set(ExecutionStockInOrder::getUpdateBy, updateBy)
|
||||
.set(ExecutionStockInOrder::getUpdateByName, userRealName)
|
||||
.set(ExecutionStockInOrder::getUpdateTime, new Date());
|
||||
}
|
||||
wrapper.in(ExecutionStockInOrder::getInOrderNumber, orderNumber);
|
||||
boolean updated = stockInOrderService.update(null, wrapper);
|
||||
// 同步预约入库单(前端"入库业务单"列表)状态
|
||||
syncReservationStatus(orderNumber, status, updateBy, userRealName);
|
||||
return updated;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 入库执行单状态回传后同步预约入库单:
|
||||
* 执行单通过business_in_order_number关联预约单,已入库(5)且该预约单名下关联执行单全部完成时,
|
||||
* 预约单同步置为已入库;同步失败只记日志,不影响执行单状态更新结果
|
||||
*/
|
||||
private void syncReservationStatus(String orderNumber, Long status, Long updateBy, String userRealName) {
|
||||
try {
|
||||
if (status == null || status != 5L) {
|
||||
return;
|
||||
}
|
||||
ExecutionStockInOrder execution = stockInOrderService.getOne(new QueryWrapper<ExecutionStockInOrder>().lambda()
|
||||
.eq(ExecutionStockInOrder::getInOrderNumber, orderNumber)
|
||||
.eq(ExecutionStockInOrder::getDelFlag, 1)
|
||||
.last("limit 1"));
|
||||
if (execution == null || execution.getBusinessInOrderNumber() == null
|
||||
|| execution.getBusinessInOrderNumber().trim().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// 多仓库拆单时存在多个关联执行单,全部已入库才同步预约单
|
||||
long unfinished = stockInOrderService.count(new QueryWrapper<ExecutionStockInOrder>().lambda()
|
||||
.eq(ExecutionStockInOrder::getBusinessInOrderNumber, execution.getBusinessInOrderNumber())
|
||||
.eq(ExecutionStockInOrder::getDelFlag, 1)
|
||||
.and(w -> w.isNull(ExecutionStockInOrder::getStatus).or().lt(ExecutionStockInOrder::getStatus, 5)));
|
||||
if (unfinished > 0) {
|
||||
log.info("预约入库单[{}]名下仍有{}张执行单未完成,暂不同步已入库状态", execution.getBusinessInOrderNumber(), unfinished);
|
||||
return;
|
||||
}
|
||||
LambdaUpdateWrapper<ReservationStockInOrder> reservationWrapper = new LambdaUpdateWrapper<ReservationStockInOrder>()
|
||||
.set(ReservationStockInOrder::getStatus, 5)
|
||||
// issueStatus=4 为前端"入库业务单"列表入库状态列的"已入库"展示值
|
||||
.set(ReservationStockInOrder::getIssueStatus, 4);
|
||||
if (updateBy != null) {
|
||||
reservationWrapper.set(ReservationStockInOrder::getUpdateBy, updateBy)
|
||||
.set(ReservationStockInOrder::getUpdateByName, userRealName)
|
||||
.set(ReservationStockInOrder::getUpdateTime, new Date());
|
||||
}
|
||||
reservationWrapper.in(ReservationStockInOrder::getInOrderNumber, execution.getBusinessInOrderNumber());
|
||||
reservationStockInOrderService.update(reservationWrapper);
|
||||
log.info("预约入库单[{}]已同步为已入库", execution.getBusinessInOrderNumber());
|
||||
} catch (Exception e) {
|
||||
log.warn("同步预约入库单状态失败: orderNumber={}, status={}", orderNumber, status, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
@@ -336,6 +336,12 @@ public class ReservationStockInOrderImpl extends ServiceImpl<ReservationStockInO
|
||||
if (productDetailList.isEmpty()) {
|
||||
throw new Exception("未解析到产品明细数据,请检查模板中是否填写了產品編號");
|
||||
}
|
||||
// 行级必填校验:支数缺失的行直接给出明确提示,避免后续 new BigDecimal(null) 抛无信息的NPE
|
||||
for (ProductDetail productDetail : productDetailList) {
|
||||
if (productDetail.getPieceCount() == null) {
|
||||
throw new Exception("产品[" + productDetail.getProductCode() + "]的【支/件数】未填写,请补全后重新导入");
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.info("页签[{}]解析完成,货品明细{}条,客户配送明细{}条",
|
||||
sheetName, productDetailList.size(), customerDeliveryDetailList.size());
|
||||
@@ -658,6 +664,9 @@ public class ReservationStockInOrderImpl extends ServiceImpl<ReservationStockInO
|
||||
preparedOrders.add(prepared); // null=空页签,跳过
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 完整堆栈进服务端日志,便于定位页签内解析异常的具体行号
|
||||
LOGGER.error("页签[{}]入库导入解析失败", name, e);
|
||||
// 非模板页签的解析异常(如NPE)message 可能为空,兜底用异常类名,避免报错显示"页签[x]:null"
|
||||
sheetProblems.add("页签[" + name + "]:" + (e.getMessage() == null ? e.toString() : e.getMessage()));
|
||||
}
|
||||
}
|
||||
@@ -710,6 +719,15 @@ public class ReservationStockInOrderImpl extends ServiceImpl<ReservationStockInO
|
||||
if (productDetailList == null || productDetailList.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
// 行级必填校验:编号/支数缺失的行直接给出明确提示,避免后续 new BigDecimal(null) 抛无信息的NPE
|
||||
for (StockInProductDetail productDetail : productDetailList) {
|
||||
if (productDetail.getProductCode() == null || productDetail.getProductCode().trim().isEmpty()) {
|
||||
throw new ServiceException("存在未填写【產品編號】的明细行,请补全后重新导入");
|
||||
}
|
||||
if (productDetail.getPieceCount() == null) {
|
||||
throw new ServiceException("产品[" + productDetail.getProductCode() + "]的【支/件数】未填写,请补全后重新导入");
|
||||
}
|
||||
}
|
||||
StockInHeader stockInHeader = resultDTO.getStockInHeader();
|
||||
// ====== 第一步:物料编号存在性校验(模板只填物料编号即可,名称按编号自动匹配) ======
|
||||
// 查询结果为空说明库中没有该物料,先收集全部缺失编号,不立即报错
|
||||
|
||||
-1
@@ -1948,7 +1948,6 @@ public class ReservationStockInOrderApplicationService {
|
||||
}
|
||||
stockInOrderDO.setOrderTypeName(documentTypeData.getDictLabel());
|
||||
}
|
||||
|
||||
//翻译优先级别类型
|
||||
if (StringUtils.isNotBlank(stockInOrderDO.getPriorityLevelCode())){
|
||||
AjaxResult priorityLevelResult = systemServiceFeign.selectListByDictType(DictCode.PRIORITY_LEVEL.getCode());
|
||||
|
||||
+10
-5
@@ -78,6 +78,16 @@ public class ReservationStockInOrderAssembler {
|
||||
// 最后使用username(账号)作为兜底
|
||||
userRealName = loginUser.getUsername();
|
||||
}
|
||||
// 单据类型跟随业务类型:页面唯一的类型选择项是"业务类型"(只提交businessType),
|
||||
// 编辑时前端回显提交的orderTypeCode/orderTypeName是旧值,若以回显值为准会导致编辑改类型不生效;
|
||||
// 系统内businessType与orderTypeCode同值域(pu_tong_ru_ku/tui_huo_ru_ku),以businessType为准保持三者一致
|
||||
if (stockInOrderDO.getBusinessType() != null && stockInOrderDO.getBusinessType().trim().length() > 0) {
|
||||
stockInOrderDO.setOrderTypeCode(stockInOrderDO.getBusinessType().trim());
|
||||
} else if (stockInOrderDTO.getInOrderId() == null
|
||||
&& (stockInOrderDO.getOrderTypeCode() == null || stockInOrderDO.getOrderTypeCode().trim().length() == 0)) {
|
||||
// 仅新增且无业务类型时兜底普通入库;编辑时两字段都为空则不覆盖(updateById跳过null字段)
|
||||
stockInOrderDO.setOrderTypeCode("pu_tong_ru_ku");
|
||||
}
|
||||
if(stockInOrderDTO.getInOrderId() != null){
|
||||
stockInOrderDO.setUpdateBy(userId);
|
||||
stockInOrderDO.setUpdateByName(userRealName);
|
||||
@@ -91,11 +101,6 @@ public class ReservationStockInOrderAssembler {
|
||||
stockInOrderDO.setCreateByName(userRealName);
|
||||
stockInOrderDO.setCreateTime(new Date());
|
||||
stockInOrderDO.setDelFlag(1);
|
||||
// 新增入库单时,如果入库单类型为空,默认设置为普通入库
|
||||
String orderTypeCode = stockInOrderDO.getOrderTypeCode();
|
||||
if (orderTypeCode == null || orderTypeCode.trim().length() == 0) {
|
||||
stockInOrderDO.setOrderTypeCode("pu_tong_ru_ku");
|
||||
}
|
||||
String orderTypeName = stockInOrderDO.getOrderTypeName();
|
||||
if (orderTypeName == null || orderTypeName.trim().length() == 0) {
|
||||
stockInOrderDO.setOrderTypeName("普通入库单");
|
||||
|
||||
+37
-51
@@ -525,9 +525,14 @@ public class ReservationStockInOrderDomainService {
|
||||
if (inOrderIds == null || inOrderIds.isEmpty()) {
|
||||
throw new ServiceException("下发失败:未选择单据");
|
||||
}
|
||||
// 只校验有效单据:软删单混入ID(过期页面提交)时在此拦截
|
||||
List<ReservationStockInOrder> checkOrders = stockInOrderService.list(
|
||||
new QueryWrapper<ReservationStockInOrder>().lambda()
|
||||
.in(ReservationStockInOrder::getInOrderId, inOrderIds));
|
||||
.in(ReservationStockInOrder::getInOrderId, inOrderIds)
|
||||
.eq(ReservationStockInOrder::getDelFlag, 1));
|
||||
if (checkOrders.size() != inOrderIds.stream().distinct().count()) {
|
||||
throw new ServiceException("下发失败:存在已删除的单据,请刷新后重新选择");
|
||||
}
|
||||
for (ReservationStockInOrder order : checkOrders) {
|
||||
// 校验1:必须已审核(issueStatus==2 表示审核成功)
|
||||
if (order.getIssueStatus() == null || order.getIssueStatus() != 2) {
|
||||
@@ -560,50 +565,12 @@ public class ReservationStockInOrderDomainService {
|
||||
.set(ReservationStockInOrder::getUpdateTime, new Date())
|
||||
.in(ReservationStockInOrder::getInOrderId, stockInOrderDO.getInOrderIds()));
|
||||
|
||||
//todo下发推送到wms
|
||||
for (Long inOrderId : inOrderIds) {
|
||||
ReservationStockInOrder byId = stockInOrderService.getById(inOrderId);
|
||||
StockInOrder stockInOrder = new StockInOrder();
|
||||
BeanUtils.copyProperties(byId, stockInOrder, "inOrderId");
|
||||
stockInOrder.setOmsStockInOrderId(String.valueOf(byId.getInOrderId()));
|
||||
// 业务链路(2026-09与业务确认,生产验证):预约单下发→生成执行单→执行单下发时才推送WMS。
|
||||
// 预约单下发此前会先把预约单自身推到WMS(omsInOrderAdd/omsInOrderAddDetail),执行单下发又推一次,
|
||||
// 导致WMS入库管理出现预约单号(R260907001)+执行单号(RK260907001)两张单、仓库收两道货。
|
||||
// 已移除预约单的WMS推送,WMS推送唯一入口收敛到 ExecutionStockInOrderDomainService.issueOrder。
|
||||
// 历史已推送的预约单数据由"取消下发"(cancelIssueOrder→omsCancelInOrder,幂等)负责清理。
|
||||
|
||||
try {
|
||||
//WMS保存结果必须校验:此前接口返回void、Feign降级被静默吞掉,OMS标记已下发但WMS无数据/缺明细,
|
||||
//收货流程无从进行(流程阻断);失败抛错回滚下发标记,WMS侧幂等(主单/明细判重),重下发安全
|
||||
AjaxResult addResult = wmsServiceFeign.omsInOrderAdd(stockInOrder); // 推主单
|
||||
if (addResult == null || !"200".equals(String.valueOf(addResult.get("code")))) {
|
||||
throw new ServiceException("下发到WMS失败:入库单[" + stockInOrder.getInOrderNumber() + "]保存主单失败:"
|
||||
+ (addResult == null ? "WMS服务不可用或已降级" : addResult.get("msg")));
|
||||
}
|
||||
|
||||
String inOrderNumber = stockInOrder.getInOrderNumber();
|
||||
List<ReservationInMaterialDetail> materialDetailList = materialDetailService.list(
|
||||
new QueryWrapper<ReservationInMaterialDetail>().lambda()
|
||||
.eq(ReservationInMaterialDetail::getInOrderNumber, inOrderNumber)
|
||||
.eq(ReservationInMaterialDetail::getDelFlag, 1));
|
||||
List<InMaterialDetail> inMaterialDetailList = new ArrayList<>();
|
||||
for (ReservationInMaterialDetail reservationInMaterialDetail : materialDetailList) {
|
||||
InMaterialDetail inMaterialDetail = new InMaterialDetail();
|
||||
BeanUtils.copyProperties(reservationInMaterialDetail, inMaterialDetail, "materialDetailId");
|
||||
inMaterialDetail.setOmsInMaterialDetail(String.valueOf(reservationInMaterialDetail.getMaterialDetailId()));
|
||||
// 过期日期为空且饮用日期有值时,用饮用日期补齐过期日期(食品业务饮用日期即效期),
|
||||
// 确保下发WMS后入库/收货/库存链路的过期日期能正常回显
|
||||
if (inMaterialDetail.getExpiryDate() == null && inMaterialDetail.getDrinkDate() != null) {
|
||||
inMaterialDetail.setExpiryDate(inMaterialDetail.getDrinkDate());
|
||||
}
|
||||
inMaterialDetailList.add(inMaterialDetail);
|
||||
}
|
||||
AjaxResult detailResult = wmsServiceFeign.omsInOrderAddDetail(inMaterialDetailList); // 推明细(会触发WMS自动审核)
|
||||
if (detailResult == null || !"200".equals(String.valueOf(detailResult.get("code")))) {
|
||||
throw new ServiceException("下发到WMS失败:入库单[" + inOrderNumber + "]保存明细失败:"
|
||||
+ (detailResult == null ? "WMS服务不可用或已降级" : detailResult.get("msg")));
|
||||
}
|
||||
log.info("下发到WMS成功,单据号:{}", byId.getInOrderNumber());
|
||||
} catch (Exception e) {
|
||||
log.error("下发到WMS失败,单据号:{}", byId.getInOrderNumber(), e);
|
||||
throw new ServiceException("下发到WMS失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
//todo下发推送到入库业务单
|
||||
for (Long inOrderId : inOrderIds) {
|
||||
// Long inOrderId = stockInOrderDO.getInOrderId();
|
||||
@@ -630,9 +597,16 @@ public class ReservationStockInOrderDomainService {
|
||||
// 执行单"运输业务单号"列永远显示入库业务单号(未选运输也显示)
|
||||
BeanUtils.copyProperties(byId, reservationStockInOrder,"inOrderId","issueStatus","issueTime","issueId","issueName","reservationAuditId","reservationAuditName","reservationAuditTime","businessOrderNo","businessNumber","tmsOrderNumber");
|
||||
reservationStockInOrder.setIssueStatus(0);
|
||||
reservationStockInOrder.setOrderTypeCode("pu_tong_ru_ku");
|
||||
reservationStockInOrder.setOrderTypeName("普通入库");
|
||||
reservationStockInOrder.setBusinessType("pu_tong_ru_ku");
|
||||
// 退货入库单下发时类型跟随预约单,避免执行入库单被固定写成普通入库
|
||||
if ("tui_huo_ru_ku".equals(byId.getOrderTypeCode()) || "退货入库".equals(byId.getOrderTypeName())) {
|
||||
reservationStockInOrder.setOrderTypeCode("tui_huo_ru_ku");
|
||||
reservationStockInOrder.setOrderTypeName("退货入库");
|
||||
reservationStockInOrder.setBusinessType("tui_huo_ru_ku");
|
||||
} else {
|
||||
reservationStockInOrder.setOrderTypeCode("pu_tong_ru_ku");
|
||||
reservationStockInOrder.setOrderTypeName("普通入库");
|
||||
reservationStockInOrder.setBusinessType("pu_tong_ru_ku");
|
||||
}
|
||||
reservationStockInOrder.setReservationOrderSource("客户预约");
|
||||
reservationStockInOrder.setWarehouseId(warehouseId);
|
||||
if (warehouseId == null || warehouseId == 0L){
|
||||
@@ -801,9 +775,14 @@ public class ReservationStockInOrderDomainService {
|
||||
if (inOrderIds == null || inOrderIds.isEmpty()) {
|
||||
throw new ServiceException("执行失败:未选择单据");
|
||||
}
|
||||
// 只校验有效单据:软删单混入ID(过期页面提交)时在此拦截(与 issueOrder 校验口径一致)
|
||||
List<ReservationStockInOrder> checkOrders = stockInOrderService.list(
|
||||
new QueryWrapper<ReservationStockInOrder>().lambda()
|
||||
.in(ReservationStockInOrder::getInOrderId, inOrderIds));
|
||||
.in(ReservationStockInOrder::getInOrderId, inOrderIds)
|
||||
.eq(ReservationStockInOrder::getDelFlag, 1));
|
||||
if (checkOrders.size() != inOrderIds.stream().distinct().count()) {
|
||||
throw new ServiceException("执行失败:存在已删除的单据,请刷新后重新选择");
|
||||
}
|
||||
for (ReservationStockInOrder order : checkOrders) {
|
||||
if (order.getIssueTime() != null) {
|
||||
throw new ServiceException("执行失败:单据[" + order.getInOrderNumber() + "]已下发,不可重复执行;如需重新下发请先取消下发");
|
||||
@@ -881,9 +860,16 @@ public class ReservationStockInOrderDomainService {
|
||||
// 运输业务单号不直接从业务单头复制,避免历史已取消运输单号残留下发到执行单
|
||||
BeanUtils.copyProperties(byId, reservationStockInOrder,"inOrderId","issueStatus","issueTime","issueId","issueName","reservationAuditId","reservationAuditName","reservationAuditTime","businessOrderNo","businessNumber","tmsOrderNumber");
|
||||
reservationStockInOrder.setIssueStatus(0);
|
||||
reservationStockInOrder.setOrderTypeCode("pu_tong_ru_ku");
|
||||
reservationStockInOrder.setOrderTypeName("普通入库");
|
||||
reservationStockInOrder.setBusinessType("pu_tong_ru_ku");
|
||||
// 退货入库单下发时类型跟随预约单,避免执行入库单被固定写成普通入库
|
||||
if ("tui_huo_ru_ku".equals(byId.getOrderTypeCode()) || "退货入库".equals(byId.getOrderTypeName())) {
|
||||
reservationStockInOrder.setOrderTypeCode("tui_huo_ru_ku");
|
||||
reservationStockInOrder.setOrderTypeName("退货入库");
|
||||
reservationStockInOrder.setBusinessType("tui_huo_ru_ku");
|
||||
} else {
|
||||
reservationStockInOrder.setOrderTypeCode("pu_tong_ru_ku");
|
||||
reservationStockInOrder.setOrderTypeName("普通入库");
|
||||
reservationStockInOrder.setBusinessType("pu_tong_ru_ku");
|
||||
}
|
||||
reservationStockInOrder.setReservationOrderSource("客户预约");
|
||||
reservationStockInOrder.setWarehouseId(warehouseId);
|
||||
// reservationStockInOrder.setOrganizationId(orgId);
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.Map;
|
||||
/**
|
||||
* 三方服务 Feign
|
||||
*/
|
||||
@FeignClient(contextId = "thirdPartyServiceFeign",url = "http://10.33.0.129:8012", value = ServiceNameConstants.THIRDPARTY_CENTER, configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(contextId = "thirdPartyServiceFeign",url = "http://10.102.192.31:8012", value = ServiceNameConstants.THIRDPARTY_CENTER, configuration = FeignAutoConfiguration.class)
|
||||
public interface ThirdPartyServiceFeign {
|
||||
|
||||
//查询当前组织所有三方接口信息
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.mhd.oms.interfaces.dto.businessDocumentOrderAdjust;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 运输业务单 调整 审核入参
|
||||
*/
|
||||
@Data
|
||||
public class BusinessDocumentOrderAdjustAuditDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("调整记录ID(必传)")
|
||||
private Long adjustId;
|
||||
|
||||
@ApiModelProperty("审核结果 1-通过 2-驳回")
|
||||
private Integer auditResult;
|
||||
|
||||
@ApiModelProperty("审核/驳回意见")
|
||||
private String auditRemark;
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.mhd.oms.interfaces.dto.businessDocumentOrderAdjust;
|
||||
|
||||
import com.mhd.oms.domain.businessDocumentOrder.entity.BusinessDocumentOrder;
|
||||
import com.mhd.oms.domain.businessOrderAccount.BusinessOrderAccount;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 运输业务单 调整提交入参
|
||||
*
|
||||
* 前端整单回传 business_document_order 全部字段 + 费用明细 business_order_account:
|
||||
* - amountChanged=true (本次修改了金额) -> 需要业务主管审核
|
||||
* - amountChanged=false (仅改其它字段) -> 无需审核,直接更新
|
||||
*
|
||||
* order: 前端把「调整后」业务单整单字段回传(含 id 定位;deliveryFreight 合计可由后端按明细自动算)。
|
||||
* feeDetailList: 调整后费用明细(business_order_account),其 amount 之和 = 主表 deliveryFreight。
|
||||
*/
|
||||
@Data
|
||||
public class BusinessDocumentOrderAdjustDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("调整后业务单(整单字段,含 id 定位;金额合计 deliveryFreight 可由后端按明细自动算)")
|
||||
private BusinessDocumentOrder order;
|
||||
|
||||
@ApiModelProperty("调整后费用明细(business_order_account),amount 之和作为主表 deliveryFreight 合计")
|
||||
private List<BusinessOrderAccount> feeDetailList;
|
||||
|
||||
@ApiModelProperty("是否修改了金额(前端判定传入):true-需审核,false-直通")
|
||||
private Boolean amountChanged;
|
||||
|
||||
@ApiModelProperty("调整原因")
|
||||
private String adjustReason;
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.mhd.oms.interfaces.dto.businessDocumentOrderAdjust;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 运输业务单 调整记录 查询条件(管理列表用,可不按订单、查全部)
|
||||
*/
|
||||
@Data
|
||||
public class BusinessDocumentOrderAdjustQueryDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("业务单号(模糊)")
|
||||
private String goodsNumber;
|
||||
|
||||
@ApiModelProperty("业务单ID")
|
||||
private Long orderId;
|
||||
|
||||
@ApiModelProperty("是否需要审核 0-否 1-是")
|
||||
private Integer isAudit;
|
||||
|
||||
@ApiModelProperty("审核状态 0-待审核 1-审核通过 2-驳回")
|
||||
private Integer auditStatus;
|
||||
|
||||
@ApiModelProperty("调整人姓名(模糊)")
|
||||
private String adjustByName;
|
||||
|
||||
@ApiModelProperty("所属组织ID(调整人/业务单所属组织)")
|
||||
private Long organizationId;
|
||||
|
||||
@ApiModelProperty("一级组织ID(组织隔离用)")
|
||||
private Long topOrganizationId;
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package com.mhd.oms.interfaces.dto.businessDocumentOrderAdjust;
|
||||
|
||||
import com.mhd.oms.domain.businessDocumentOrderAdjustDetail.entity.BusinessDocumentOrderAdjustDetail;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 运输业务单 调整记录(主记录) 列表/详情返回 VO
|
||||
*/
|
||||
@Data
|
||||
public class BusinessDocumentOrderAdjustRecordDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("主记录ID")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("业务单ID")
|
||||
private Long orderId;
|
||||
|
||||
@ApiModelProperty("业务单号")
|
||||
private String goodsNumber;
|
||||
|
||||
@ApiModelProperty("调整人账号")
|
||||
private String adjustBy;
|
||||
|
||||
@ApiModelProperty("调整人姓名")
|
||||
private String adjustByName;
|
||||
|
||||
@ApiModelProperty("调整时间")
|
||||
private Date adjustTime;
|
||||
|
||||
@ApiModelProperty("调整原因")
|
||||
private String adjustReason;
|
||||
|
||||
@ApiModelProperty("是否需要审核 0-否 1-是")
|
||||
private Integer isAudit;
|
||||
|
||||
@ApiModelProperty("审核状态 0-待审核 1-审核通过 2-驳回")
|
||||
private Integer auditStatus;
|
||||
|
||||
@ApiModelProperty("审核人账号")
|
||||
private String auditBy;
|
||||
|
||||
@ApiModelProperty("审核人姓名")
|
||||
private String auditByName;
|
||||
|
||||
@ApiModelProperty("审核时间")
|
||||
private Date auditTime;
|
||||
|
||||
@ApiModelProperty("审核/驳回意见")
|
||||
private String auditRemark;
|
||||
|
||||
@ApiModelProperty("调整后整行快照明细(详情查询时带出)")
|
||||
private BusinessDocumentOrderAdjustDetail detail;
|
||||
}
|
||||
+65
@@ -10,7 +10,12 @@ import org.springframework.web.bind.annotation.*;
|
||||
import com.mhd.oms.interfaces.dto.businessDocumentOrder.BusinessDocumentOrderDTO;
|
||||
import com.mhd.oms.domain.businessDocumentOrder.repository.todo.BusinessDocumentOrderDO;
|
||||
import com.mhd.oms.domain.businessDocumentOrder.repository.po.BusinessDocumentOrderPO;
|
||||
import com.mhd.oms.application.service.businessDocumentOrder.BusinessDocumentOrderAdjustService;
|
||||
import com.mhd.oms.application.service.businessDocumentOrder.BusinessDocumentOrderApplicationService;
|
||||
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.oms.interfaces.assembler.businessDocumentOrder.BusinessDocumentOrderAssembler;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import javax.annotation.Resource;
|
||||
@@ -33,6 +38,9 @@ public class BusinessDocumentOrderApi extends BaseController{
|
||||
@Resource
|
||||
private BusinessDocumentOrderAssembler businessDocumentOrderAssembler;
|
||||
|
||||
@Resource
|
||||
private BusinessDocumentOrderAdjustService businessDocumentOrderAdjustService;
|
||||
|
||||
/**
|
||||
* 分页查询【业务单】列表
|
||||
*/
|
||||
@@ -161,7 +169,64 @@ public class BusinessDocumentOrderApi extends BaseController{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单调整 - 提交调整
|
||||
* 若修改了金额字段则进入调整待审核,否则直通更新
|
||||
*/
|
||||
@ApiOperation("订单调整 - 提交调整")
|
||||
@PostMapping("/adjust")
|
||||
public AjaxResult adjust(@RequestBody BusinessDocumentOrderAdjustDTO adjustDTO) {
|
||||
try {
|
||||
return businessDocumentOrderAdjustService.adjust(adjustDTO);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单调整 - 调整记录列表(查全部,可分页/按业务单号或审核状态筛选)
|
||||
*/
|
||||
@ApiOperation("订单调整 - 调整记录列表")
|
||||
@GetMapping("/listAdjustRecord")
|
||||
public TableDataInfo listAdjustRecord(BusinessDocumentOrderAdjustQueryDTO query,
|
||||
@RequestParam(value = "pageNo", required = false, defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", required = false, defaultValue = "20") Integer pageSize) {
|
||||
PageHelper.startPage(pageNo, pageSize);
|
||||
List<BusinessDocumentOrderAdjustRecordDTO> list = businessDocumentOrderAdjustService.listAdjustRecord(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单调整 - 按业务单查询调整记录(供订单详情页展示)
|
||||
*/
|
||||
@ApiOperation("订单调整 - 按业务单查询调整记录")
|
||||
@GetMapping("/listAdjustRecordByOrder/{orderId}")
|
||||
public AjaxResult listAdjustRecordByOrder(@PathVariable("orderId") Long orderId) {
|
||||
return AjaxResult.success(businessDocumentOrderAdjustService.listAdjustRecordByOrder(orderId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单调整 - 调整记录详情
|
||||
*/
|
||||
@ApiOperation("订单调整 - 调整记录详情")
|
||||
@GetMapping("/getAdjustRecord/{adjustId}")
|
||||
public AjaxResult getAdjustRecord(@PathVariable("adjustId") Long adjustId) {
|
||||
return AjaxResult.success(businessDocumentOrderAdjustService.getAdjustRecord(adjustId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单调整 - 审核(通过/驳回)
|
||||
*/
|
||||
@ApiOperation("订单调整 - 审核")
|
||||
@PostMapping("/auditAdjust")
|
||||
public AjaxResult auditAdjust(@RequestBody BusinessDocumentOrderAdjustAuditDTO auditDTO) {
|
||||
try {
|
||||
return businessDocumentOrderAdjustService.auditAdjust(auditDTO);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.30: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.30:6848
|
||||
# server-addr: 10.33.0.129:6010
|
||||
server-addr: 10.102.192.31:6848
|
||||
username: nacos
|
||||
password: manhuoda@2023
|
||||
#线上正式环境
|
||||
|
||||
+9
-1
@@ -116,6 +116,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="businessChargeType" column="BUSINESS_CHARGE_TYPE" />
|
||||
<result property="businessPriceWay" column="BUSINESS_PRICE_WAY" />
|
||||
<result property="discount" column="DISCOUNT" />
|
||||
<result property="totalOutboundQuantity" column="TOTAL_OUTBOUND_QUANTITY" />
|
||||
</resultMap>
|
||||
|
||||
|
||||
@@ -405,7 +406,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<select id="queryList" parameterType="com.mhd.oms.domain.reservationStockOutOrder.repository.todo.ReservationStockOutOrderDO" resultMap="StockOutOrderResult">
|
||||
select
|
||||
<include refid="selectStockOutOrderPo"/>
|
||||
<include refid="selectStockOutOrderPo"/>,
|
||||
<!-- 出库数量:汇总明细表实际出库数量,只统计一级明细(level=1),与详情页汇总口径一致;
|
||||
原逻辑为Java循环逐单调getInfoChildren汇总(N+1)后注释,未再赋值导致列表该字段恒为null -->
|
||||
(select coalesce(sum(omd.outbound_quantity), 0)
|
||||
from reservation_out_material_detail omd
|
||||
where omd.out_order_number = a.out_order_number
|
||||
and omd.del_flag = 1
|
||||
and (omd.level is null or omd.level = 1)) as total_outbound_quantity
|
||||
from reservation_stock_out_order a
|
||||
<where>
|
||||
<include refid="selectStockOutOrderPo1"/>
|
||||
|
||||
+6
-6
@@ -208,9 +208,9 @@ public class HandoverTaskOrderApplicationService {
|
||||
public Boolean completeHandover(HandoverTaskOrderDO handoverTaskOrderDO){
|
||||
Boolean result = handoverTaskOrderDomainService.completeHandover(handoverTaskOrderDO);
|
||||
List<MaterialInventoryParamDO> clearoutParamDOs = handoverTaskOrderDomainService.getLastClearoutParamDOs();
|
||||
for (MaterialInventoryParamDO paramDO : clearoutParamDOs) {
|
||||
materialInventoryApplicationService.pushBillingRecordClearout(paramDO.getMaterialInventoryId(), paramDO.getQuantity());
|
||||
}
|
||||
// for (MaterialInventoryParamDO paramDO : clearoutParamDOs) {
|
||||
// materialInventoryApplicationService.pushBillingRecordClearout(paramDO.getMaterialInventoryId(), paramDO.getQuantity());
|
||||
// }
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -309,9 +309,9 @@ public class HandoverTaskOrderApplicationService {
|
||||
completeDO.setBillingJson(handoverTaskOrderDO.getBillingJson());
|
||||
handoverTaskOrderDomainService.completeHandover(completeDO);
|
||||
List<MaterialInventoryParamDO> clearoutParamDOs = handoverTaskOrderDomainService.getLastClearoutParamDOs();
|
||||
for (MaterialInventoryParamDO paramDO : clearoutParamDOs) {
|
||||
materialInventoryApplicationService.pushBillingRecordClearout(paramDO.getMaterialInventoryId(), paramDO.getQuantity());
|
||||
}
|
||||
// for (MaterialInventoryParamDO paramDO : clearoutParamDOs) {
|
||||
// materialInventoryApplicationService.pushBillingRecordClearout(paramDO.getMaterialInventoryId(), paramDO.getQuantity());
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -226,6 +226,14 @@ public class InvestigationManageApplicationService {
|
||||
materialInventoryPO = materialInventoryMapper.selectByIdWithBatchAttributes(materialInventoryId);
|
||||
}
|
||||
|
||||
// 从库存表回填批次号、入库日期、生产日期、过期日期(入库日期取库存记录入库时间create_time)
|
||||
if (materialInventoryPO != null) {
|
||||
investigetionManageDetailPO.setBatchNumber(materialInventoryPO.getBatchNumber());
|
||||
investigetionManageDetailPO.setInboundDate(materialInventoryPO.getCreateTime());
|
||||
investigetionManageDetailPO.setProductionDate(materialInventoryPO.getProductionDate());
|
||||
investigetionManageDetailPO.setExpiryDate(materialInventoryPO.getExpiryDate());
|
||||
}
|
||||
|
||||
if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) {
|
||||
List<BatchDetailFeignPO> batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId);
|
||||
// 用于跟踪已添加到列表中的batchDetailId
|
||||
|
||||
+18
@@ -1,6 +1,7 @@
|
||||
package com.mhd.wms.domain.investigetionManageDetail.repository.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.mhd.common.core.annotation.Excel;
|
||||
import com.mhd.common.core.web.domain.BaseVOEntity;
|
||||
import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO;
|
||||
@@ -9,6 +10,7 @@ import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -219,4 +221,20 @@ public class InvestigetionManageDetailPO extends BaseVOEntity {
|
||||
@TableField(exist = false)
|
||||
private List<MaterialMoreDetailPO> materialMoreDetailList;
|
||||
|
||||
@ApiModelProperty("批次号")
|
||||
@Excel(name = "批次号")
|
||||
private String batchNumber;
|
||||
|
||||
@ApiModelProperty("入库日期(库存入库时间)")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date inboundDate;
|
||||
|
||||
@ApiModelProperty("生产日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date productionDate;
|
||||
|
||||
@ApiModelProperty("过期日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date expiryDate;
|
||||
|
||||
}
|
||||
|
||||
+14
-1
@@ -810,8 +810,21 @@ public class StockShelfOrderDomainService {
|
||||
stockInOrder.setUpdateBy(loginUser.getUserid());
|
||||
stockInOrder.setUpdateByName(loginUser.getUsername());
|
||||
stockInOrder.setUpdateTime(new Date());
|
||||
return stockInOrderService.update(stockInOrder,
|
||||
boolean updated = stockInOrderService.update(stockInOrder,
|
||||
new QueryWrapper<StockInOrder>().lambda().eq(StockInOrder::getInOrderNumber, stockShelfOrderPO.getInOrderNumber()));
|
||||
if (updated) {
|
||||
// 上架推进入库状态(4-上架中/5-已入库)后回传OMS入库业务单,保证OMS入库状态与WMS一致;
|
||||
// OMS不可用或回传失败只记日志,不影响WMS上架主流程
|
||||
try {
|
||||
AjaxResult notifyResult = omsServiceFeign.returnInResult(stockShelfOrderPO.getInOrderNumber(), Long.valueOf(status), "0");
|
||||
if (notifyResult == null || !"200".equals(String.valueOf(notifyResult.get("code")))) {
|
||||
log.warn("回传OMS入库状态失败: orderNumber={}, status={}, result={}", stockShelfOrderPO.getInOrderNumber(), status, notifyResult);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("回传OMS入库状态异常: orderNumber={}, status={}", stockShelfOrderPO.getInOrderNumber(), status, e);
|
||||
}
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
/**
|
||||
* @description 完成上架
|
||||
|
||||
@@ -9,46 +9,46 @@ import org.springframework.context.annotation.Configuration;
|
||||
/**
|
||||
* XXL-JOB 配置类
|
||||
*/
|
||||
@Configuration
|
||||
//@Configuration
|
||||
public class XxlJobConfig {
|
||||
private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
|
||||
|
||||
@Value("${xxl.job.admin.addresses}")
|
||||
private String adminAddresses;
|
||||
|
||||
@Value("${xxl.job.accessToken}")
|
||||
private String accessToken;
|
||||
|
||||
@Value("${xxl.job.executor.appname}")
|
||||
private String appname;
|
||||
|
||||
@Value("${xxl.job.executor.address}")
|
||||
private String address;
|
||||
|
||||
@Value("${xxl.job.executor.ip}")
|
||||
private String ip;
|
||||
|
||||
@Value("${xxl.job.executor.port}")
|
||||
private int port;
|
||||
|
||||
@Value("${xxl.job.executor.logpath}")
|
||||
private String logPath;
|
||||
|
||||
@Value("${xxl.job.executor.logretentiondays}")
|
||||
private int logRetentionDays;
|
||||
|
||||
@Bean
|
||||
public XxlJobSpringExecutor xxlJobExecutor() {
|
||||
logger.info(">>>>>>>>>>> xxl-job config init.");
|
||||
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
|
||||
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
|
||||
xxlJobSpringExecutor.setAppname(appname);
|
||||
xxlJobSpringExecutor.setAddress(address);
|
||||
xxlJobSpringExecutor.setIp(ip);
|
||||
xxlJobSpringExecutor.setPort(port);
|
||||
xxlJobSpringExecutor.setAccessToken(accessToken);
|
||||
xxlJobSpringExecutor.setLogPath(logPath);
|
||||
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
|
||||
return xxlJobSpringExecutor;
|
||||
}
|
||||
// private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
|
||||
//
|
||||
// @Value("${xxl.job.admin.addresses}")
|
||||
// private String adminAddresses;
|
||||
//
|
||||
// @Value("${xxl.job.accessToken}")
|
||||
// private String accessToken;
|
||||
//
|
||||
// @Value("${xxl.job.executor.appname}")
|
||||
// private String appname;
|
||||
//
|
||||
// @Value("${xxl.job.executor.address}")
|
||||
// private String address;
|
||||
//
|
||||
// @Value("${xxl.job.executor.ip}")
|
||||
// private String ip;
|
||||
//
|
||||
// @Value("${xxl.job.executor.port}")
|
||||
// private int port;
|
||||
//
|
||||
// @Value("${xxl.job.executor.logpath}")
|
||||
// private String logPath;
|
||||
//
|
||||
// @Value("${xxl.job.executor.logretentiondays}")
|
||||
// private int logRetentionDays;
|
||||
//
|
||||
// @Bean
|
||||
// public XxlJobSpringExecutor xxlJobExecutor() {
|
||||
// logger.info(">>>>>>>>>>> xxl-job config init.");
|
||||
// XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
|
||||
// xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
|
||||
// xxlJobSpringExecutor.setAppname(appname);
|
||||
// xxlJobSpringExecutor.setAddress(address);
|
||||
// xxlJobSpringExecutor.setIp(ip);
|
||||
// xxlJobSpringExecutor.setPort(port);
|
||||
// xxlJobSpringExecutor.setAccessToken(accessToken);
|
||||
// xxlJobSpringExecutor.setLogPath(logPath);
|
||||
// xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
|
||||
// return xxlJobSpringExecutor;
|
||||
// }
|
||||
}
|
||||
@@ -14,18 +14,18 @@ spring:
|
||||
nacos:
|
||||
discovery:
|
||||
# server-addr: 127.0.0.1:8848
|
||||
server-addr: 10.33.0.129:6010
|
||||
# server-addr: 10.33.0.129:6010
|
||||
# 线上测试环境配置 容器名+端口号
|
||||
# server-addr: 10.102.192.30:6848
|
||||
server-addr: 10.102.192.31:6848
|
||||
username: nacos
|
||||
password: manhuoda@2023
|
||||
#线上正式环境
|
||||
# server-addr: 10.102.192.105:6848
|
||||
config:
|
||||
# server-addr: 127.0.0.1:8848
|
||||
server-addr: 10.33.0.129:6010
|
||||
# server-addr: 10.33.0.129:6010
|
||||
# 线上测试环境配置 容器名+端口号
|
||||
# server-addr: 10.102.192.30:6848
|
||||
server-addr: 10.102.192.31:6848
|
||||
username: nacos
|
||||
password: manhuoda@2023
|
||||
#线上正式环境
|
||||
|
||||
Reference in New Issue
Block a user