Merge remote-tracking branch 'origin/test' into test

This commit is contained in:
rcx
2026-09-15 16:54:43 +08:00
13 changed files with 527 additions and 125 deletions
@@ -0,0 +1,46 @@
-- ----------------------------
-- 入库业务单推送bms计费流水定时任务(XXL-Job: pushBillingRecord)执行日志表 -- 达梦(DM)数据库版
-- 适用:mhd-wms-service 连接的达梦库(生产/测试按环境选择,在WMS服务连接的用户/模式下执行)
-- 用途:记录任务执行过程中的例外情况(执行异常报错、业务continue跳过、生成业务单据失败),
-- 本次执行全程无任何例外时保留一条成功记录(LOG_TYPE=SUCCESS
-- @date 2026-09-15
-- ----------------------------
CREATE TABLE WMS_PUSH_BILLING_RECORD_LOG (
ID BIGINT IDENTITY(1,1) NOT NULL,
JOB_NAME VARCHAR(100) DEFAULT NULL,
SHIPPER_ID VARCHAR(50) DEFAULT NULL,
MATERIAL_INVENTORY_ID BIGINT DEFAULT NULL,
IN_ORDER_NUMBER VARCHAR(100) DEFAULT NULL,
MATERIAL_BASE_INFO_ID BIGINT DEFAULT NULL,
LOT_NUMBER VARCHAR(100) DEFAULT NULL,
WAREHOUSE_CODE VARCHAR(50) DEFAULT NULL,
LOG_TYPE VARCHAR(20) DEFAULT NULL,
LOG_MESSAGE VARCHAR(2000) DEFAULT NULL,
EXECUTION_TIME DATETIME DEFAULT NULL,
DEL_FLAG INT DEFAULT 1,
CONSTRAINT PK_WMS_PUSH_BILLING_RECORD_LOG PRIMARY KEY (ID)
);
COMMENT ON TABLE WMS_PUSH_BILLING_RECORD_LOG IS '入库业务单推送bms计费流水任务执行日志表';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.ID IS '主键ID';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.JOB_NAME IS '任务名称(XXL-Job任务标识,如pushBillingRecord)';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.SHIPPER_ID IS '货主ID(任务参数)';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.MATERIAL_INVENTORY_ID IS '物料库存ID';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.IN_ORDER_NUMBER IS '入库单号';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.MATERIAL_BASE_INFO_ID IS '物料基础信息ID';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOT_NUMBER IS 'LOT编号';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.WAREHOUSE_CODE IS '仓库编码';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOG_TYPE IS '日志类型:SUCCESS-全部执行成功 SKIP-业务跳过(continue) ERROR-执行异常';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOG_MESSAGE IS '日志信息(成功说明/跳过原因/异常信息)';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.EXECUTION_TIME IS '执行时间';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.DEL_FLAG IS '删除标记:0-无状态,1-正常,2-已删除';
CREATE INDEX IDX_WPBR_JOB_NAME ON WMS_PUSH_BILLING_RECORD_LOG (JOB_NAME);
CREATE INDEX IDX_WPBR_SHIPPER_ID ON WMS_PUSH_BILLING_RECORD_LOG (SHIPPER_ID);
CREATE INDEX IDX_WPBR_EXECUTION_TIME ON WMS_PUSH_BILLING_RECORD_LOG (EXECUTION_TIME);
-- ----------------------------
-- 回滚脚本
-- DROP TABLE WMS_PUSH_BILLING_RECORD_LOG;
-- ----------------------------
+2
View File
@@ -0,0 +1,2 @@
-- test write permission
SELECT 1;
@@ -20,7 +20,9 @@ import com.mhd.system.api.model.LoginUser;
import com.mhd.wms.domain.materialBaseInfo.entity.MaterialBaseInfo; import com.mhd.wms.domain.materialBaseInfo.entity.MaterialBaseInfo;
import com.mhd.wms.domain.materialBaseInfo.repository.mapper.MaterialBaseInfoMapper; import com.mhd.wms.domain.materialBaseInfo.repository.mapper.MaterialBaseInfoMapper;
import com.mhd.wms.domain.materialInventory.entity.MaterialInventory; import com.mhd.wms.domain.materialInventory.entity.MaterialInventory;
import com.mhd.wms.domain.materialInventory.entity.PushBillingRecordLog;
import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper; import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper;
import com.mhd.wms.domain.materialInventory.repository.mapper.PushBillingRecordLogMapper;
import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO; import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO;
import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryQueryListPO; import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryQueryListPO;
import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryDO; import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryDO;
@@ -75,6 +77,11 @@ public class MaterialInventoryApplicationService {
private OutMaterialDetailMapper outMaterialDetailMapper; private OutMaterialDetailMapper outMaterialDetailMapper;
@Autowired @Autowired
private MaterialBaseInfoMapper materialBaseInfoMapper; private MaterialBaseInfoMapper materialBaseInfoMapper;
@Autowired
private PushBillingRecordLogMapper pushBillingRecordLogMapper;
/** XXL-Job任务标识:入库业务单推送bms计费流水 */
private static final String JOB_NAME_PUSH_BILLING_RECORD = "pushBillingRecord";
/** /**
@@ -904,7 +911,9 @@ public class MaterialInventoryApplicationService {
String inOrderNumber = materialInventoryPO.getInOrderNumber(); String inOrderNumber = materialInventoryPO.getInOrderNumber();
Long warehouseId = materialInventoryPO.getWarehouseId(); Long warehouseId = materialInventoryPO.getWarehouseId();
Date lastBillingTime = materialInventoryPO.getLastBillingTime(); Date lastBillingTime = materialInventoryPO.getLastBillingTime();
if (warehouseId==19) {//干仓计费 String warehouseCode = materialInventoryMapper.queryWarehouseCode(warehouseId);
if (warehouseCode == null) return;
if ("CMD".equals(warehouseCode)) {//干仓计费
Map<String,Object> shipperParameters = materialInventoryDomainService.queryShipperParameters(shipperId,"干仓计费配置"); Map<String,Object> shipperParameters = materialInventoryDomainService.queryShipperParameters(shipperId,"干仓计费配置");
//客户未配置干仓计费配置 //客户未配置干仓计费配置
if (shipperParameters == null || shipperParameters.size()==0) return; if (shipperParameters == null || shipperParameters.size()==0) return;
@@ -962,7 +971,7 @@ public class MaterialInventoryApplicationService {
buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"冻仓"); buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"冻仓");
buildBusinessDocument(fireInsureFee, materialInventoryPO,"0D08","火险保费",contractManageId,"冻仓"); buildBusinessDocument(fireInsureFee, materialInventoryPO,"0D08","火险保费",contractManageId,"冻仓");
} }
} else if (warehouseId==20) {//冻仓计费 } else if ("CMC".equals(warehouseCode)) {//冻仓计费
Map<String,Object> shipperParameters = materialInventoryDomainService.queryShipperParameters(Long.valueOf(shipperId),"冻仓计费配置"); Map<String,Object> shipperParameters = materialInventoryDomainService.queryShipperParameters(Long.valueOf(shipperId),"冻仓计费配置");
if (shipperParameters == null || shipperParameters.size()==0) return; if (shipperParameters == null || shipperParameters.size()==0) return;
Long contractManageId = (Long) shipperParameters.get("contractManageId"); Long contractManageId = (Long) shipperParameters.get("contractManageId");
@@ -1017,134 +1026,270 @@ public class MaterialInventoryApplicationService {
public void pushBillingRecord(String shipperId) { public void pushBillingRecord(String shipperId) {
List<MaterialInventoryPO> materialInventoryPOS = materialInventoryDomainService.queryPushBms(shipperId); // 例外情况计数(业务跳过continue、执行异常、生成业务单据失败),为0时说明本次执行全程无例外,保留成功记录
//未查询到库存记录 int exceptionCount = 0;
if (materialInventoryPOS==null || materialInventoryPOS.size()==0) return; try {
for (MaterialInventoryPO materialInventoryPO : materialInventoryPOS) { List<MaterialInventoryPO> materialInventoryPOS = materialInventoryDomainService.queryPushBms(shipperId);
Date createTime = materialInventoryPO.getCreateTime(); //未查询到库存记录
Long materialBaseInfoId = materialInventoryPO.getMaterialBaseInfoId(); if (materialInventoryPOS==null || materialInventoryPOS.size()==0) {
String lotNumber = materialInventoryPO.getLotNumber(); savePushBillingRecordLog(shipperId, null, null, PushBillingRecordLog.LOG_TYPE_SUCCESS,
String inOrderNumber = materialInventoryPO.getInOrderNumber(); "未查询到待推送的库存记录,任务正常结束");
Long warehouseId = materialInventoryPO.getWarehouseId(); return;
Date lastBillingTime = materialInventoryPO.getLastBillingTime();
if (warehouseId==19) {//干仓计费
Map<String,Object> shipperParameters = materialInventoryDomainService.queryShipperParameters(Long.valueOf(shipperId),"干仓计费配置");
//客户未配置干仓计费配置
if (shipperParameters == null || shipperParameters.size()==0) continue;
Long contractManageId = (Long) shipperParameters.get("contractManageId");
Long settlementCustomersId = (Long) shipperParameters.get("settlementCustomersId");
String contractNumber = (String) shipperParameters.get("contractNumber");
String content = (String) shipperParameters.get("content");
Map<String, Object> contentMap = content != null ? JSON.parseObject(content, Map.class) : new HashMap<>();
Integer sfzdcz = (Integer) contentMap.get("sfzdcz");
//客户未配置或是否自动推送设置为否
if (sfzdcz==null) continue;
if (sfzdcz!=1) continue;
//计算费用
List<Map<String, Object>> monthFee = materialInventoryDomainService.getMonthFee(inOrderNumber, materialBaseInfoId,lotNumber);
//入库业务单未设置每月仓租
if (monthFee == null || monthFee.size()==0) continue;
Map<String, Object> feeMap = monthFee.get(0);
//半月仓租
BigDecimal halfMonthWhFee = (BigDecimal) feeMap.get("halfMonthWhFee");
//整月仓租
BigDecimal monthlyWarehouseFee = (BigDecimal) feeMap.get("monthlyWarehouseFee");
// 判断是否为昨天
boolean isYesterday = false;
if (createTime != null) {
LocalDate yesterday = LocalDate.now().minusDays(1);
LocalDate createDate = createTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
isYesterday = yesterday.isEqual(createDate);
}
if (isYesterday) {
//首次计费 需要夫力费
//库存数量
BigDecimal inventoryQuantity = materialInventoryPO.getInventoryQuantity();
//仓租
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(monthlyWarehouseFee);
//夫力费
BigDecimal manpowerFee = totalWarehouseRent.multiply(new BigDecimal("0.2"));
MaterialBaseInfo materialBaseInfo = materialBaseInfoMapper.selectById(materialBaseInfoId);
BigDecimal unitPrice = materialBaseInfo.getUnitPrice();
//火险保费
BigDecimal fireInsureFee = unitPrice.multiply(inventoryQuantity).multiply(new BigDecimal("0.0003"));
buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"干仓");
buildBusinessDocument(manpowerFee, materialInventoryPO,"0D082","夫力费",contractManageId,"干仓");
buildBusinessDocument(fireInsureFee, materialInventoryPO,"0D08","火险保费",contractManageId,"干仓");
} else {
//期间付费 不需要夫力费
//库存数量
BigDecimal inventoryQuantity = materialInventoryPO.getInventoryQuantity();
//仓租
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(monthlyWarehouseFee);
MaterialBaseInfo materialBaseInfo = materialBaseInfoMapper.selectById(materialBaseInfoId);
BigDecimal unitPrice = materialBaseInfo.getUnitPrice();
//火险保费
BigDecimal fireInsureFee = unitPrice.multiply(inventoryQuantity).multiply(new BigDecimal("0.0003"));
buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"干仓");
buildBusinessDocument(fireInsureFee, materialInventoryPO,"0D08","火险保费",contractManageId,"干仓");
}
} else if (warehouseId==20) {//冻仓计费
Map<String,Object> shipperParameters = materialInventoryDomainService.queryShipperParameters(Long.valueOf(shipperId),"冻仓计费配置");
if (shipperParameters == null || shipperParameters.size()==0) continue;
Long contractManageId = (Long) shipperParameters.get("contractManageId");
Long settlementCustomersId = (Long) shipperParameters.get("settlementCustomersId");
String contractNumber = (String) shipperParameters.get("contractNumber");
String content = (String) shipperParameters.get("content");
Map<String, Object> contentMap = content != null ? JSON.parseObject(content, Map.class) : new HashMap<>();
Integer sfzdcz = (Integer) contentMap.get("sfzdcz");
//客户未配置或是否自动推送设置为否
if (sfzdcz==null) continue;
if (sfzdcz!=1) continue;
//计算费用
MaterialBaseInfo materialBaseInfo = materialBaseInfoMapper.selectById(materialBaseInfoId);
BigDecimal unitPrice = materialBaseInfo.getUnitPrice();
String materialClassifyId = materialBaseInfo.getMaterialClassifyId();
BigDecimal weightLimit = materialBaseInfo.getWeightLimit();
Map<String,Object> materialClassify = materialInventoryDomainService.queryMaterialClassify(Long.valueOf(materialClassifyId));
//物料分类不存在
if (materialClassify == null || materialClassify.size()==0) continue;
BigDecimal monthlyWarehouseRent = (BigDecimal) materialClassify.get("monthlyWarehouseRent");
BigDecimal halfMonthWarehouseRent = (BigDecimal) materialClassify.get("halfMonthWarehouseRent");
String monthlyWarehouseRentUnit = (String) materialClassify.get("monthlyWarehouseRentUnit");
String halfMonthWarehouseRentUnit = (String) materialClassify.get("halfMonthWarehouseRentUnit");
//半月仓租
BigDecimal halfMonthWhFee = halfMonthWarehouseRent;
//整月仓租
BigDecimal monthlyWarehouseFee = monthlyWarehouseRent;
long daysDiff = 0;
if (lastBillingTime != null) {
LocalDate lastBillingDate = lastBillingTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
daysDiff = ChronoUnit.DAYS.between(lastBillingDate, LocalDate.now());
} else {
daysDiff = -1;
}
BigDecimal inventoryQuantity = materialInventoryPO.getInventoryQuantity();
if (daysDiff < 15) {
// 不足半月: 收半月仓租
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(halfMonthWhFee).multiply(weightLimit);
buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"冻仓");
} else {
// 大于等于半月: 收整月仓租
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(monthlyWarehouseFee).multiply(weightLimit);
buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"冻仓");
}
//更新最后计费时间
Long materialInventoryId = materialInventoryPO.getMaterialInventoryId();
MaterialInventory materialInventory = materialInventoryMapper.selectById(materialInventoryId);
materialInventory.setLastBillingTime(new Date());
materialInventoryMapper.updateById(materialInventory);
} }
for (MaterialInventoryPO materialInventoryPO : materialInventoryPOS) {
try {
String businessChargeType = materialInventoryPO.getBusinessChargeType();
//非散租
if (!"散租".equals(businessChargeType)) {
savePushBillingRecordLog(shipperId, materialInventoryPO, null, PushBillingRecordLog.LOG_TYPE_SKIP,
"业务计价类型[" + businessChargeType + "]非散租,跳过推送");
exceptionCount++;
continue;
}
Date createTime = materialInventoryPO.getCreateTime();
Long materialBaseInfoId = materialInventoryPO.getMaterialBaseInfoId();
String lotNumber = materialInventoryPO.getLotNumber();
String inOrderNumber = materialInventoryPO.getInOrderNumber();
Long warehouseId = materialInventoryPO.getWarehouseId();
Date lastBillingTime = materialInventoryPO.getLastBillingTime();
String warehouseCode = materialInventoryDomainService.queryWarehouseCode(warehouseId);
//仓库代码为空
if (warehouseCode==null) {
savePushBillingRecordLog(shipperId, materialInventoryPO, null, PushBillingRecordLog.LOG_TYPE_SKIP,
"仓库ID[" + warehouseId + "]未查询到仓库编码,跳过推送");
exceptionCount++;
continue;
}
if ("CMD".equals(warehouseCode)) {//干仓计费
Map<String,Object> shipperParameters = materialInventoryDomainService.queryShipperParameters(Long.valueOf(shipperId),"干仓计费配置");
//客户未配置干仓计费配置
if (shipperParameters == null || shipperParameters.size()==0) {
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
"货主未配置[干仓计费配置],跳过推送");
exceptionCount++;
continue;
}
Long contractManageId = (Long) shipperParameters.get("contractManageId");
Long settlementCustomersId = (Long) shipperParameters.get("settlementCustomersId");
String contractNumber = (String) shipperParameters.get("contractNumber");
String content = (String) shipperParameters.get("content");
Map<String, Object> contentMap = content != null ? JSON.parseObject(content, Map.class) : new HashMap<>();
Integer sfzdcz = (Integer) contentMap.get("sfzdcz");
//客户未配置或是否自动推送设置为否
if (sfzdcz==null) {
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
"干仓计费配置未设置[是否自动推送],跳过推送");
exceptionCount++;
continue;
}
if (sfzdcz!=1) {
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
"干仓计费配置[是否自动推送]为否,跳过推送");
exceptionCount++;
continue;
}
//计算费用
List<Map<String, Object>> monthFee = materialInventoryDomainService.getMonthFee(inOrderNumber, materialBaseInfoId,lotNumber);
//入库业务单未设置每月仓租
if (monthFee == null || monthFee.size()==0) {
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
"入库业务单未设置每月仓租,跳过推送");
exceptionCount++;
continue;
}
Map<String, Object> feeMap = monthFee.get(0);
//半月仓租
BigDecimal halfMonthWhFee = (BigDecimal) feeMap.get("halfMonthWhFee");
//整月仓租
BigDecimal monthlyWarehouseFee = (BigDecimal) feeMap.get("monthlyWarehouseFee");
// 判断是否为昨天
boolean isYesterday = false;
if (createTime != null) {
LocalDate yesterday = LocalDate.now().minusDays(1);
LocalDate createDate = createTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
isYesterday = yesterday.isEqual(createDate);
}
if (isYesterday) {
//首次计费 需要夫力费
//库存数量
BigDecimal inventoryQuantity = materialInventoryPO.getInventoryQuantity();
//仓租
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(monthlyWarehouseFee);
//夫力费
BigDecimal manpowerFee = totalWarehouseRent.multiply(new BigDecimal("0.2"));
MaterialBaseInfo materialBaseInfo = materialBaseInfoMapper.selectById(materialBaseInfoId);
BigDecimal unitPrice = materialBaseInfo.getUnitPrice();
//火险保费
BigDecimal fireInsureFee = unitPrice.multiply(inventoryQuantity).multiply(new BigDecimal("0.0003"));
if (!buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"干仓")) {
exceptionCount++;
}
if (!buildBusinessDocument(manpowerFee, materialInventoryPO,"0D082","夫力费",contractManageId,"干仓")) {
exceptionCount++;
}
if (!buildBusinessDocument(fireInsureFee, materialInventoryPO,"0D08","火险保费",contractManageId,"干仓")) {
exceptionCount++;
}
} else {
//期间付费 不需要夫力费
//库存数量
BigDecimal inventoryQuantity = materialInventoryPO.getInventoryQuantity();
//仓租
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(monthlyWarehouseFee);
MaterialBaseInfo materialBaseInfo = materialBaseInfoMapper.selectById(materialBaseInfoId);
BigDecimal unitPrice = materialBaseInfo.getUnitPrice();
//火险保费
BigDecimal fireInsureFee = unitPrice.multiply(inventoryQuantity).multiply(new BigDecimal("0.0003"));
if (!buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"干仓")) {
exceptionCount++;
}
if (!buildBusinessDocument(fireInsureFee, materialInventoryPO,"0D08","火险保费",contractManageId,"干仓")) {
exceptionCount++;
}
}
} else if ("CMC".equals(warehouseCode)) {//冻仓计费
Map<String,Object> shipperParameters = materialInventoryDomainService.queryShipperParameters(Long.valueOf(shipperId),"冻仓计费配置");
if (shipperParameters == null || shipperParameters.size()==0) {
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
"货主未配置[冻仓计费配置],跳过推送");
exceptionCount++;
continue;
}
Long contractManageId = (Long) shipperParameters.get("contractManageId");
Long settlementCustomersId = (Long) shipperParameters.get("settlementCustomersId");
String contractNumber = (String) shipperParameters.get("contractNumber");
String content = (String) shipperParameters.get("content");
Map<String, Object> contentMap = content != null ? JSON.parseObject(content, Map.class) : new HashMap<>();
Integer sfzdcz = (Integer) contentMap.get("sfzdcz");
//客户未配置或是否自动推送设置为否
if (sfzdcz==null) {
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
"冻仓计费配置未设置[是否自动推送],跳过推送");
exceptionCount++;
continue;
}
if (sfzdcz!=1) {
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
"冻仓计费配置[是否自动推送]为否,跳过推送");
exceptionCount++;
continue;
}
//计算费用
MaterialBaseInfo materialBaseInfo = materialBaseInfoMapper.selectById(materialBaseInfoId);
BigDecimal unitPrice = materialBaseInfo.getUnitPrice();
String materialClassifyId = materialBaseInfo.getMaterialClassifyId();
BigDecimal weightLimit = materialBaseInfo.getWeightLimit();
Map<String,Object> materialClassify = materialInventoryDomainService.queryMaterialClassify(Long.valueOf(materialClassifyId));
//物料分类不存在
if (materialClassify == null || materialClassify.size()==0) {
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
"物料分类[" + materialClassifyId + "]不存在,跳过推送");
exceptionCount++;
continue;
}
BigDecimal monthlyWarehouseRent = (BigDecimal) materialClassify.get("monthlyWarehouseRent");
BigDecimal halfMonthWarehouseRent = (BigDecimal) materialClassify.get("halfMonthWarehouseRent");
String monthlyWarehouseRentUnit = (String) materialClassify.get("monthlyWarehouseRentUnit");
String halfMonthWarehouseRentUnit = (String) materialClassify.get("halfMonthWarehouseRentUnit");
//半月仓租
BigDecimal halfMonthWhFee = halfMonthWarehouseRent;
//整月仓租
BigDecimal monthlyWarehouseFee = monthlyWarehouseRent;
long daysDiff = 0;
if (lastBillingTime != null) {
LocalDate lastBillingDate = lastBillingTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
daysDiff = ChronoUnit.DAYS.between(lastBillingDate, LocalDate.now());
} else {
daysDiff = -1;
}
BigDecimal inventoryQuantity = materialInventoryPO.getInventoryQuantity();
if (daysDiff < 15) {
// 不足半月: 收半月仓租
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(halfMonthWhFee).multiply(weightLimit);
if (!buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"冻仓")) {
exceptionCount++;
}
} else {
// 大于等于半月: 收整月仓租
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(monthlyWarehouseFee).multiply(weightLimit);
if (!buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"冻仓")) {
exceptionCount++;
}
}
//更新最后计费时间
Long materialInventoryId = materialInventoryPO.getMaterialInventoryId();
MaterialInventory materialInventory = materialInventoryMapper.selectById(materialInventoryId);
materialInventory.setLastBillingTime(new Date());
materialInventoryMapper.updateById(materialInventory);
}
} catch (Exception e) {
savePushBillingRecordLog(shipperId, materialInventoryPO, null, PushBillingRecordLog.LOG_TYPE_ERROR,
"处理物料库存时发生异常:" + e);
throw e;
}
}
} catch (Exception e) {
savePushBillingRecordLog(shipperId, null, null, PushBillingRecordLog.LOG_TYPE_ERROR,
"任务执行异常中断:" + e);
throw e;
}
// 本次执行无任何例外(无跳过、无异常),保留成功记录
if (exceptionCount == 0) {
savePushBillingRecordLog(shipperId, null, null, PushBillingRecordLog.LOG_TYPE_SUCCESS,
"入库业务单推送bms计费流水全部执行成功");
}
}
/**
* 保存入库业务单推送bms计费流水执行日志(日志写入失败仅打印错误,不影响任务主流程)
*
* @param shipperId 货主ID(任务参数),为空时从物料库存取
* @param materialInventoryPO 物料库存(为空表示任务级日志)
* @param warehouseCode 仓库编码
* @param logType 日志类型:SUCCESS-全部执行成功 SKIP-业务跳过 ERROR-执行异常
* @param logMessage 日志信息(成功说明/跳过原因/异常信息)
*/
private void savePushBillingRecordLog(String shipperId, MaterialInventoryPO materialInventoryPO, String warehouseCode,
String logType, String logMessage) {
try {
PushBillingRecordLog logRecord = new PushBillingRecordLog();
logRecord.setJobName(JOB_NAME_PUSH_BILLING_RECORD);
if (StringUtils.isNotBlank(shipperId)) {
logRecord.setShipperId(shipperId);
} else if (materialInventoryPO != null && materialInventoryPO.getShipperId() != null) {
logRecord.setShipperId(String.valueOf(materialInventoryPO.getShipperId()));
}
if (materialInventoryPO != null) {
logRecord.setMaterialInventoryId(materialInventoryPO.getMaterialInventoryId());
logRecord.setInOrderNumber(materialInventoryPO.getInOrderNumber());
logRecord.setMaterialBaseInfoId(materialInventoryPO.getMaterialBaseInfoId());
logRecord.setLotNumber(materialInventoryPO.getLotNumber());
}
logRecord.setWarehouseCode(warehouseCode);
logRecord.setLogType(logType);
// 日志信息截断,防止超长导致入库失败
if (logMessage != null && logMessage.length() > 2000) {
logMessage = logMessage.substring(0, 2000);
}
logRecord.setLogMessage(logMessage);
logRecord.setExecutionTime(new Date());
logRecord.setDelFlag(1);
pushBillingRecordLogMapper.insert(logRecord);
} catch (Exception e) {
log.error("保存入库业务单推送bms计费流水执行日志失败: {}", e.getMessage(), e);
} }
} }
private void buildBusinessDocument(BigDecimal fee, MaterialInventoryPO materialInventoryPO,String code,String name,Long contractManageId,String warehouseType) { private boolean buildBusinessDocument(BigDecimal fee, MaterialInventoryPO materialInventoryPO,String code,String name,Long contractManageId,String warehouseType) {
Long shipperId = materialInventoryPO.getShipperId(); Long shipperId = materialInventoryPO.getShipperId();
Map<String, Object> shipper = materialInventoryMapper.querySetlleByShipperId(shipperId); Map<String, Object> shipper = materialInventoryMapper.querySetlleByShipperId(shipperId);
if (shipper == null) { if (shipper == null) {
return; savePushBillingRecordLog(null, materialInventoryPO, materialInventoryPO.getWarehouseCode(),
PushBillingRecordLog.LOG_TYPE_SKIP,
"货主[" + shipperId + "]未查询到结算客户信息,未生成业务单据");
return false;
} }
Long settlementCustomersId = (Long) shipper.get("settlementCustomersId"); Long settlementCustomersId = (Long) shipper.get("settlementCustomersId");
Long settlementEntityId = (Long) shipper.get("settlementEntityId"); Long settlementEntityId = (Long) shipper.get("settlementEntityId");
@@ -1174,7 +1319,12 @@ public class MaterialInventoryApplicationService {
businessDocumentFeign.setWarehouseType(warehouseType); businessDocumentFeign.setWarehouseType(warehouseType);
businessDocumentFeign.setOriginalBusinessNum(materialInventoryPO.getInOrderNumber()); businessDocumentFeign.setOriginalBusinessNum(materialInventoryPO.getInOrderNumber());
Map<String, Object> contract = materialInventoryDomainService.queryContract(contractManageId); Map<String, Object> contract = materialInventoryDomainService.queryContract(contractManageId);
if (contract == null) {return;} if (contract == null) {
savePushBillingRecordLog(null, materialInventoryPO, materialInventoryPO.getWarehouseCode(),
PushBillingRecordLog.LOG_TYPE_SKIP,
"合同[" + contractManageId + "]未查询到合同信息,未生成业务单据");
return false;
}
String contractName = (String) contract.get("contractName"); String contractName = (String) contract.get("contractName");
String contractNumber = (String) contract.get("contractNumber"); String contractNumber = (String) contract.get("contractNumber");
businessDocumentFeign.setContractName(contractName); businessDocumentFeign.setContractName(contractName);
@@ -1185,6 +1335,11 @@ public class MaterialInventoryApplicationService {
AjaxResult ajaxResult = bmsServiceFeign.feignSaveBusinessDocument(businessDocumentFeign); AjaxResult ajaxResult = bmsServiceFeign.feignSaveBusinessDocument(businessDocumentFeign);
if (ajaxResult == null || !"200".equals(String.valueOf(ajaxResult.get("code")))) { if (ajaxResult == null || !"200".equals(String.valueOf(ajaxResult.get("code")))) {
log.error("保存业务单据失败: {}", ajaxResult != null ? ajaxResult.get("msg") : "feign调用异常"); log.error("保存业务单据失败: {}", ajaxResult != null ? ajaxResult.get("msg") : "feign调用异常");
savePushBillingRecordLog(null, materialInventoryPO, materialInventoryPO.getWarehouseCode(),
PushBillingRecordLog.LOG_TYPE_ERROR,
"保存业务单据失败:" + (ajaxResult != null ? ajaxResult.get("msg") : "feign调用异常"));
return false;
} }
return true;
} }
} }
@@ -0,0 +1,66 @@
package com.mhd.wms.domain.materialInventory.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;
/**
* 入库业务单推送bms计费流水任务(XXL-JobpushBillingRecord)执行日志对象 wms_push_billing_record_log
*
* @author mhd
* @date 2026-09-15
*/
@Data
@TableName("WMS_PUSH_BILLING_RECORD_LOG")
public class PushBillingRecordLog implements Serializable {
private static final long serialVersionUID = 1L;
/** 日志类型:全部执行成功 */
public static final String LOG_TYPE_SUCCESS = "SUCCESS";
/** 日志类型:业务跳过(continue跳出) */
public static final String LOG_TYPE_SKIP = "SKIP";
/** 日志类型:执行异常(报错) */
public static final String LOG_TYPE_ERROR = "ERROR";
@ApiModelProperty("主键ID")
@TableId(type = IdType.AUTO)
private Long id;
@ApiModelProperty("任务名称(XXL-Job任务标识)")
private String jobName;
@ApiModelProperty("货主ID(任务参数)")
private String shipperId;
@ApiModelProperty("物料库存ID")
private Long materialInventoryId;
@ApiModelProperty("入库单号")
private String inOrderNumber;
@ApiModelProperty("物料基础信息ID")
private Long materialBaseInfoId;
@ApiModelProperty("LOT编号")
private String lotNumber;
@ApiModelProperty("仓库编码")
private String warehouseCode;
@ApiModelProperty("日志类型:SUCCESS-全部执行成功 SKIP-业务跳过 ERROR-执行异常")
private String logType;
@ApiModelProperty("日志信息(成功说明/跳过原因/异常信息)")
private String logMessage;
@ApiModelProperty("执行时间")
private Date executionTime;
@ApiModelProperty("删除标记:0-无状态,1-正常,2-已删除")
private Integer delFlag;
}
@@ -136,4 +136,6 @@ public interface IMaterialInventoryService extends IService<MaterialInventory>
public Map<String,Object> queryShipperParameters(Long shipperId,String parametersName); public Map<String,Object> queryShipperParameters(Long shipperId,String parametersName);
Map<String, Object> queryMaterialClassify(Long id); Map<String, Object> queryMaterialClassify(Long id);
String queryWarehouseCode(Long id);
} }
@@ -177,4 +177,6 @@ public interface MaterialInventoryMapper extends BaseMapper<MaterialInventory>
public int omsRestoreInventoryToFrozen(@Param("materialInventoryId") Long materialInventoryId, @Param("quantity") BigDecimal quantity, public int omsRestoreInventoryToFrozen(@Param("materialInventoryId") Long materialInventoryId, @Param("quantity") BigDecimal quantity,
@Param("netWeight") BigDecimal netWeight, @Param("grossWeight") BigDecimal grossWeight, @Param("netWeight") BigDecimal netWeight, @Param("grossWeight") BigDecimal grossWeight,
@Param("volume") BigDecimal volume, @Param("area") BigDecimal area); @Param("volume") BigDecimal volume, @Param("area") BigDecimal area);
public String queryWarehouseCode(@Param("id") Long id);
} }
@@ -0,0 +1,13 @@
package com.mhd.wms.domain.materialInventory.repository.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mhd.wms.domain.materialInventory.entity.PushBillingRecordLog;
/**
* 入库业务单推送bms计费流水任务执行日志Mapper接口
*
* @author mhd
* @date 2026-09-15
*/
public interface PushBillingRecordLogMapper extends BaseMapper<PushBillingRecordLog> {
}
@@ -1324,4 +1324,9 @@ public class MaterialInventoryImpl extends ServiceImpl<MaterialInventoryMapper,
public Map<String, Object> queryMaterialClassify(Long id) { public Map<String, Object> queryMaterialClassify(Long id) {
return materialInventoryMapper.queryMaterialClassify(id); return materialInventoryMapper.queryMaterialClassify(id);
} }
@Override
public String queryWarehouseCode(Long id) {
return materialInventoryMapper.queryWarehouseCode(id);
}
} }
@@ -277,4 +277,7 @@ public class MaterialInventoryPO extends MaterialBasePO {
@ApiModelProperty("半月仓租单位") @ApiModelProperty("半月仓租单位")
@Excel(name = "半月仓租单位") @Excel(name = "半月仓租单位")
private String halfMonthWarehouseRentUnit; private String halfMonthWarehouseRentUnit;
@ApiModelProperty("业务计价类型")
private String businessChargeType;
} }
@@ -149,4 +149,8 @@ public class MaterialInventoryDomainService {
public Map<String,Object> queryMaterialClassify(Long id) { public Map<String,Object> queryMaterialClassify(Long id) {
return materialInventoryService.queryMaterialClassify(id); return materialInventoryService.queryMaterialClassify(id);
} }
public String queryWarehouseCode(Long id) {
return materialInventoryService.queryWarehouseCode(id);
}
} }
@@ -75,6 +75,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="halfMonthWarehouseRentUnit" column="half_month_warehouse_rent_unit" /> <result property="halfMonthWarehouseRentUnit" column="half_month_warehouse_rent_unit" />
<result property="halfMonthWarehouseRent" column="half_month_warehouse_rent" /> <result property="halfMonthWarehouseRent" column="half_month_warehouse_rent" />
<result property="monthlyWarehouseRent" column="monthly_warehouse_rent" /> <result property="monthlyWarehouseRent" column="monthly_warehouse_rent" />
<result property="businessChargeType" column="BUSINESS_CHARGE_TYPE" />
</resultMap> </resultMap>
@@ -1822,8 +1823,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select> </select>
<select id="queryPushBms" resultMap="MaterialInventoryResult"> <select id="queryPushBms" resultMap="MaterialInventoryResult">
SELECT * SELECT *,
FROM MATERIAL_INVENTORY (SELECT BUSINESS_CHARGE_TYPE FROM NGWL_TEST_OMS.RESERVATION_STOCK_IN_ORDER WHERE EXECUTION_IN_ORDER_NUMBER = a.in_order_number) as BUSINESS_CHARGE_TYPE
FROM MATERIAL_INVENTORY a
WHERE EXTRACT(DAY FROM CREATE_TIME) = EXTRACT(DAY FROM SYSDATE - 1) AND INVENTORY_QUANTITY > 0 WHERE EXTRACT(DAY FROM CREATE_TIME) = EXTRACT(DAY FROM SYSDATE - 1) AND INVENTORY_QUANTITY > 0
AND DEL_FLAG = 1 AND SHIPPER_ID = #{shipperId} AND DEL_FLAG = 1 AND SHIPPER_ID = #{shipperId}
</select> </select>
@@ -1933,4 +1935,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
WHERE material_inventory_id = #{materialInventoryId} WHERE material_inventory_id = #{materialInventoryId}
AND del_flag = 1 AND del_flag = 1
</update> </update>
<select id="queryWarehouseCode" resultType="java.lang.String">
SELECT
WAREHOUSE_CODE AS "warehouseCode"
FROM
NGWL_TEST_SYSTEM.WAREHOUSE
WHERE
1 = 1
AND WAREHOUSE_ID = #{id} AND DEL_FLAG = 1
</select>
</mapper> </mapper>
@@ -0,0 +1,46 @@
-- ----------------------------
-- 入库业务单推送bms计费流水定时任务(XXL-Job: pushBillingRecord)执行日志表 -- 达梦(DM)数据库版
-- 适用:mhd-wms-service 连接的达梦库(生产/测试按环境选择,在WMS服务连接的用户/模式下执行)
-- 用途:记录任务执行过程中的例外情况(执行异常报错、业务continue跳过、生成业务单据失败),
-- 本次执行全程无任何例外时保留一条成功记录(LOG_TYPE=SUCCESS
-- @date 2026-09-15
-- ----------------------------
CREATE TABLE WMS_PUSH_BILLING_RECORD_LOG (
ID BIGINT IDENTITY(1,1) NOT NULL,
JOB_NAME VARCHAR(100) DEFAULT NULL,
SHIPPER_ID VARCHAR(50) DEFAULT NULL,
MATERIAL_INVENTORY_ID BIGINT DEFAULT NULL,
IN_ORDER_NUMBER VARCHAR(100) DEFAULT NULL,
MATERIAL_BASE_INFO_ID BIGINT DEFAULT NULL,
LOT_NUMBER VARCHAR(100) DEFAULT NULL,
WAREHOUSE_CODE VARCHAR(50) DEFAULT NULL,
LOG_TYPE VARCHAR(20) DEFAULT NULL,
LOG_MESSAGE VARCHAR(2000) DEFAULT NULL,
EXECUTION_TIME DATETIME DEFAULT NULL,
DEL_FLAG INT DEFAULT 1,
CONSTRAINT PK_WMS_PUSH_BILLING_RECORD_LOG PRIMARY KEY (ID)
);
COMMENT ON TABLE WMS_PUSH_BILLING_RECORD_LOG IS '入库业务单推送bms计费流水任务执行日志表';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.ID IS '主键ID';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.JOB_NAME IS '任务名称(XXL-Job任务标识,如pushBillingRecord)';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.SHIPPER_ID IS '货主ID(任务参数)';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.MATERIAL_INVENTORY_ID IS '物料库存ID';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.IN_ORDER_NUMBER IS '入库单号';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.MATERIAL_BASE_INFO_ID IS '物料基础信息ID';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOT_NUMBER IS 'LOT编号';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.WAREHOUSE_CODE IS '仓库编码';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOG_TYPE IS '日志类型:SUCCESS-全部执行成功 SKIP-业务跳过(continue) ERROR-执行异常';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOG_MESSAGE IS '日志信息(成功说明/跳过原因/异常信息)';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.EXECUTION_TIME IS '执行时间';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.DEL_FLAG IS '删除标记:0-无状态,1-正常,2-已删除';
CREATE INDEX IDX_WPBR_JOB_NAME ON WMS_PUSH_BILLING_RECORD_LOG (JOB_NAME);
CREATE INDEX IDX_WPBR_SHIPPER_ID ON WMS_PUSH_BILLING_RECORD_LOG (SHIPPER_ID);
CREATE INDEX IDX_WPBR_EXECUTION_TIME ON WMS_PUSH_BILLING_RECORD_LOG (EXECUTION_TIME);
-- ----------------------------
-- 回滚脚本
-- DROP TABLE WMS_PUSH_BILLING_RECORD_LOG;
-- ----------------------------
+46
View File
@@ -0,0 +1,46 @@
-- ----------------------------
-- 入库业务单推送bms计费流水定时任务(XXL-Job: pushBillingRecord)执行日志表 -- 达梦(DM)数据库版
-- 适用:mhd-wms-service 连接的达梦库(生产/测试按环境选择,在WMS服务连接的用户/模式下执行)
-- 用途:记录任务执行过程中的例外情况(执行异常报错、业务continue跳过、生成业务单据失败),
-- 本次执行全程无任何例外时保留一条成功记录(LOG_TYPE=SUCCESS
-- @date 2026-09-15
-- ----------------------------
CREATE TABLE WMS_PUSH_BILLING_RECORD_LOG (
ID BIGINT IDENTITY(1,1) NOT NULL,
JOB_NAME VARCHAR(100) DEFAULT NULL,
SHIPPER_ID VARCHAR(50) DEFAULT NULL,
MATERIAL_INVENTORY_ID BIGINT DEFAULT NULL,
IN_ORDER_NUMBER VARCHAR(100) DEFAULT NULL,
MATERIAL_BASE_INFO_ID BIGINT DEFAULT NULL,
LOT_NUMBER VARCHAR(100) DEFAULT NULL,
WAREHOUSE_CODE VARCHAR(50) DEFAULT NULL,
LOG_TYPE VARCHAR(20) DEFAULT NULL,
LOG_MESSAGE VARCHAR(2000) DEFAULT NULL,
EXECUTION_TIME DATETIME DEFAULT NULL,
DEL_FLAG INT DEFAULT 1,
CONSTRAINT PK_WMS_PUSH_BILLING_RECORD_LOG PRIMARY KEY (ID)
);
COMMENT ON TABLE WMS_PUSH_BILLING_RECORD_LOG IS '入库业务单推送bms计费流水任务执行日志表';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.ID IS '主键ID';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.JOB_NAME IS '任务名称(XXL-Job任务标识,如pushBillingRecord)';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.SHIPPER_ID IS '货主ID(任务参数)';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.MATERIAL_INVENTORY_ID IS '物料库存ID';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.IN_ORDER_NUMBER IS '入库单号';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.MATERIAL_BASE_INFO_ID IS '物料基础信息ID';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOT_NUMBER IS 'LOT编号';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.WAREHOUSE_CODE IS '仓库编码';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOG_TYPE IS '日志类型:SUCCESS-全部执行成功 SKIP-业务跳过(continue) ERROR-执行异常';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOG_MESSAGE IS '日志信息(成功说明/跳过原因/异常信息)';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.EXECUTION_TIME IS '执行时间';
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.DEL_FLAG IS '删除标记:0-无状态,1-正常,2-已删除';
CREATE INDEX IDX_WPBR_JOB_NAME ON WMS_PUSH_BILLING_RECORD_LOG (JOB_NAME);
CREATE INDEX IDX_WPBR_SHIPPER_ID ON WMS_PUSH_BILLING_RECORD_LOG (SHIPPER_ID);
CREATE INDEX IDX_WPBR_EXECUTION_TIME ON WMS_PUSH_BILLING_RECORD_LOG (EXECUTION_TIME);
-- ----------------------------
-- 回滚脚本
-- DROP TABLE WMS_PUSH_BILLING_RECORD_LOG;
-- ----------------------------