🐛 修复车务非必填-1占位落库,并完善总单分段调度与运单导入

上一段运单完成到达后才可调度且不超过到达量;车务多模块保存/列表/导出将-1归一为null;同步网关大报文限制与导入校验能力。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-27 21:26:54 +08:00
parent 0c52797c31
commit 1185c9792c
42 changed files with 536 additions and 4447 deletions
@@ -2,6 +2,9 @@ server:
port: 80
spring:
codec:
# 运单批量导入等大 JSON / 失败明细导出场景,默认 256KB 会触发网关 500
max-in-memory-size: 20MB
cloud:
gateway:
server:
@@ -33,4 +33,6 @@ public class WaybillImportBatchRequest {
private String planName;
private String remark;
private List<Map<String, Object>> rows;
/** 分批确认导入时,是否追加到已有批次(首批为 false,后续批为 true)。 */
private Boolean append;
}
@@ -41,6 +41,11 @@ public class MasterOrderVO extends MasterOrder {
private List<Waybill> boundWaybills;
@TableField(exist = false)
private BigDecimal totalQuantity;
/**
* 各品类已调度量(按货物名称+类型聚合,取各分段已调度量的最大值)
*/
@TableField(exist = false)
private Map<String, BigDecimal> dispatchedGoods;
@TableField(exist = false)
private String createUserName;
@TableField(exist = false)
@@ -0,0 +1,26 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
*/
package org.springblade.transport.pojo.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/** 运单批量导入单行校验错误。 */
@Data
@Schema(description = "运单批量导入单行校验错误")
public class WaybillImportRowErrorVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "行号(从0开始,相对当前批次)")
private Integer rowIndex;
@Schema(description = "错误信息")
private String errorMessage;
}
@@ -0,0 +1,28 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
*/
package org.springblade.transport.pojo.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/** 运单批量导入校验结果。 */
@Data
@Schema(description = "运单批量导入校验结果")
public class WaybillImportValidateResultVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "是否全部通过")
private Boolean success;
@Schema(description = "校验错误列表")
private List<WaybillImportRowErrorVO> errors = new ArrayList<>();
}
@@ -54,6 +54,7 @@ import org.springblade.transport.pojo.dto.WaybillImportBatchRequest;
import org.springblade.transport.pojo.vo.BusinessRemoveResultVO;
import org.springblade.transport.pojo.vo.LoadingManageVO;
import org.springblade.transport.pojo.vo.WaybillImportBatchVO;
import org.springblade.transport.pojo.vo.WaybillImportValidateResultVO;
import org.springblade.transport.pojo.vo.WaybillLocateVO;
import org.springblade.transport.pojo.vo.WaybillTrackVO;
import org.springblade.transport.pojo.vo.WaybillPunchRecordsVO;
@@ -192,15 +193,22 @@ public class WaybillController extends BladeController {
@PostMapping("/import-batch/validate")
@ApiOperationSupport(order = 6)
@Operation(summary = "校验运单批量导入数据")
public void validateImportBatch(@RequestBody WaybillImportBatchRequest request, HttpServletResponse response) {
waybillImportBatchService.validate(request, response);
public R<WaybillImportValidateResultVO> validateImportBatch(@RequestBody WaybillImportBatchRequest request) {
return R.data(waybillImportBatchService.validate(request));
}
@PostMapping("/import-batch/export-failures")
@ApiOperationSupport(order = 6)
@Operation(summary = "导出运单批量导入失败明细")
public void exportImportFailures(@RequestBody WaybillImportBatchRequest request, HttpServletResponse response) {
waybillImportBatchService.exportFailures(request, response);
}
@PostMapping("/import-batch/confirm")
@ApiOperationSupport(order = 7)
@Operation(summary = "确认运单批量导入")
public void confirmImportBatch(@RequestBody WaybillImportBatchRequest request, HttpServletResponse response) {
waybillImportBatchService.confirm(request, response);
public R<WaybillImportBatchVO> confirmImportBatch(@RequestBody WaybillImportBatchRequest request) {
return R.data(waybillImportBatchService.confirm(request));
}
@PostMapping("/import-batch/remove")
@@ -69,6 +69,8 @@ public class MasterOrderWaybillExcel {
private String businessStatus;
@ExcelProperty("备注")
private String remark;
@ExcelProperty("更新时间")
private Date updateTime;
@ExcelProperty("创建时间")
private Date createTime;
}
@@ -42,8 +42,8 @@
accident_location,
accident_nature,
accident_responsibility,
CASE WHEN direct_economic_loss &lt; 0 THEN 0 ELSE direct_economic_loss END AS direct_economic_loss,
CASE WHEN insurance_claim_amount &lt; 0 THEN 0 ELSE insurance_claim_amount END AS insurance_claim_amount,
CASE WHEN direct_economic_loss = -1 THEN NULL WHEN direct_economic_loss &lt; 0 THEN 0 ELSE direct_economic_loss END AS direct_economic_loss,
CASE WHEN insurance_claim_amount = -1 THEN NULL WHEN insurance_claim_amount &lt; 0 THEN 0 ELSE insurance_claim_amount END AS insurance_claim_amount,
accident_reason_damage,
attachments,
remark
@@ -88,7 +88,7 @@
valid_until_date,
passenger_type_level,
inspection_unit,
CASE WHEN fee &lt; 0 THEN 0 ELSE fee END AS fee,
CASE WHEN fee = -1 THEN NULL WHEN fee &lt; 0 THEN 0 ELSE fee END AS fee,
assessment_unit,
attachments,
remark
@@ -44,8 +44,8 @@
policy_no,
start_date,
end_date,
CASE WHEN insured_amount &lt; 0 THEN 0 ELSE insured_amount END AS insured_amount,
CASE WHEN premium &lt; 0 THEN 0 ELSE premium END AS premium,
CASE WHEN insured_amount = -1 THEN NULL ELSE insured_amount END AS insured_amount,
CASE WHEN premium = -1 THEN NULL ELSE premium END AS premium,
invoice_no,
invoice_date,
ocr_template,
@@ -44,7 +44,7 @@
vehicle_no,
maintainer,
maintenance_time,
CASE WHEN mileage &lt; 0 THEN 0 ELSE mileage END AS mileage,
CASE WHEN mileage = -1 THEN NULL WHEN mileage &lt; 0 THEN 0 ELSE mileage END AS mileage,
mileage_unit,
maintenance_item,
cost,
@@ -52,7 +52,7 @@
contact_phone,
address,
next_maintenance_time,
CASE WHEN next_maintenance_mileage &lt; 0 THEN 0 ELSE next_maintenance_mileage END AS next_maintenance_mileage,
CASE WHEN next_maintenance_mileage = -1 THEN NULL WHEN next_maintenance_mileage &lt; 0 THEN 0 ELSE next_maintenance_mileage END AS next_maintenance_mileage,
attachments,
remark
FROM
@@ -36,10 +36,10 @@
is_deleted,
vehicle_type,
vehicle_no,
CASE WHEN previous_month_mileage &lt; 0 THEN 0 ELSE previous_month_mileage END AS previous_month_mileage,
CASE WHEN current_month_mileage &lt; 0 THEN 0 ELSE current_month_mileage END AS current_month_mileage,
CASE WHEN monthly_mileage &lt; 0 THEN 0 ELSE monthly_mileage END AS monthly_mileage,
CASE WHEN total_mileage &lt; 0 THEN 0 ELSE total_mileage END AS total_mileage,
CASE WHEN previous_month_mileage = -1 THEN NULL WHEN previous_month_mileage &lt; 0 THEN 0 ELSE previous_month_mileage END AS previous_month_mileage,
CASE WHEN current_month_mileage = -1 THEN NULL WHEN current_month_mileage &lt; 0 THEN 0 ELSE current_month_mileage END AS current_month_mileage,
CASE WHEN monthly_mileage = -1 THEN NULL WHEN monthly_mileage &lt; 0 THEN 0 ELSE monthly_mileage END AS monthly_mileage,
CASE WHEN total_mileage = -1 THEN NULL WHEN total_mileage &lt; 0 THEN 0 ELSE total_mileage END AS total_mileage,
mileage_unit,
attachments,
remark
@@ -48,10 +48,10 @@
vehicle_no,
card_holder,
data_source,
CASE WHEN quantity &lt; 0 THEN 0 ELSE quantity END AS quantity,
CASE WHEN unit_price &lt; 0 THEN 0 ELSE unit_price END AS unit_price,
CASE WHEN transaction_amount &lt; 0 THEN 0 ELSE transaction_amount END AS transaction_amount,
CASE WHEN balance &lt; 0 THEN 0 ELSE balance END AS balance,
CASE WHEN quantity = -1 THEN NULL WHEN quantity &lt; 0 THEN 0 ELSE quantity END AS quantity,
CASE WHEN unit_price = -1 THEN NULL WHEN unit_price &lt; 0 THEN 0 ELSE unit_price END AS unit_price,
CASE WHEN transaction_amount = -1 THEN NULL WHEN transaction_amount &lt; 0 THEN 0 ELSE transaction_amount END AS transaction_amount,
CASE WHEN balance = -1 THEN NULL WHEN balance &lt; 0 THEN 0 ELSE balance END AS balance,
station,
attachments,
remark
@@ -38,8 +38,8 @@
handler,
replacement_time,
tire_brand,
CASE WHEN tire_quantity &lt; 0 THEN 0 ELSE tire_quantity END AS tire_quantity,
CASE WHEN replacement_cost &lt; 0 THEN 0 ELSE replacement_cost END AS replacement_cost,
CASE WHEN tire_quantity = -1 THEN NULL WHEN tire_quantity &lt; 0 THEN 0 ELSE tire_quantity END AS tire_quantity,
CASE WHEN replacement_cost = -1 THEN NULL WHEN replacement_cost &lt; 0 THEN 0 ELSE replacement_cost END AS replacement_cost,
replacement_description,
attachments,
remark
@@ -46,8 +46,8 @@
violation_item,
violation_time,
location,
CASE WHEN fine_amount &lt; 0 THEN 0 ELSE fine_amount END AS fine_amount,
CASE WHEN deduct_points &lt; 0 THEN 0 ELSE deduct_points END AS deduct_points,
CASE WHEN fine_amount = -1 THEN NULL WHEN fine_amount &lt; 0 THEN 0 ELSE fine_amount END AS fine_amount,
CASE WHEN deduct_points = -1 THEN NULL WHEN deduct_points &lt; 0 THEN 0 ELSE deduct_points END AS deduct_points,
penalty_unit,
process_status,
process_description,
@@ -7,12 +7,14 @@ import org.springblade.transport.pojo.dto.WaybillImportBatchRequest;
import org.springblade.transport.pojo.entity.WaybillImportBatch;
import org.springblade.transport.pojo.vo.BusinessRemoveResultVO;
import org.springblade.transport.pojo.vo.WaybillImportBatchVO;
import org.springblade.transport.pojo.vo.WaybillImportValidateResultVO;
/** 运单批次服务。 */
public interface IWaybillImportBatchService extends BaseService<WaybillImportBatch> {
WaybillImportBatch saveDraft(WaybillImportBatchRequest request);
void validate(WaybillImportBatchRequest request, HttpServletResponse response);
void confirm(WaybillImportBatchRequest request, HttpServletResponse response);
WaybillImportValidateResultVO validate(WaybillImportBatchRequest request);
void exportFailures(WaybillImportBatchRequest request, HttpServletResponse response);
WaybillImportBatchVO confirm(WaybillImportBatchRequest request);
IPage<WaybillImportBatchVO> page(IPage<WaybillImportBatch> page, WaybillImportBatchRequest request);
BusinessRemoveResultVO removeBatches(String ids);
String nextBatchNo();
@@ -61,6 +61,8 @@ public class AccidentRecordServiceImpl extends BaseServiceImpl<AccidentRecordMap
private static final int REMARK_MAX_LENGTH = 200;
private static final int ATTACHMENTS_MAX_LENGTH = 1000;
private static final int MONEY_SCALE = 2;
/** 非必填金额未填写时的历史占位值,统一转为 null */
private static final BigDecimal EMPTY_AMOUNT_SENTINEL = BigDecimal.valueOf(-1);
private static final String VEHICLE = "车辆";
private static final String SHIP = "船舶";
private static final Set<String> ACCIDENT_NATURES = Set.of("重大事故", "一般事故", "轻微事故", "其他");
@@ -69,7 +71,11 @@ public class AccidentRecordServiceImpl extends BaseServiceImpl<AccidentRecordMap
@Override
public IPage<AccidentRecordVO> selectAccidentRecordPage(IPage<AccidentRecordVO> page, AccidentRecordVO accidentRecord) {
List<AccidentRecordVO> records = baseMapper.selectAccidentRecordPage(page, accidentRecord);
records.forEach(record -> record.setUpdateUserName(UserCache.getUserRealName(record.getUpdateUser())));
records.forEach(record -> {
record.setDirectEconomicLoss(normalizeEmptyAmount(record.getDirectEconomicLoss()));
record.setInsuranceClaimAmount(normalizeEmptyAmount(record.getInsuranceClaimAmount()));
record.setUpdateUserName(UserCache.getUserRealName(record.getUpdateUser()));
});
return page.setRecords(records);
}
@@ -153,8 +159,8 @@ public class AccidentRecordServiceImpl extends BaseServiceImpl<AccidentRecordMap
public List<AccidentRecordExportExcel> exportAccidentRecord(Wrapper<AccidentRecord> queryWrapper) {
return list(queryWrapper).stream().map(accidentRecord -> {
AccidentRecordExportExcel excel = Objects.requireNonNull(BeanUtil.copyProperties(accidentRecord, AccidentRecordExportExcel.class));
excel.setDirectEconomicLoss(nonNegative(accidentRecord.getDirectEconomicLoss()));
excel.setInsuranceClaimAmount(nonNegative(accidentRecord.getInsuranceClaimAmount()));
excel.setDirectEconomicLoss(normalizeEmptyAmount(accidentRecord.getDirectEconomicLoss()));
excel.setInsuranceClaimAmount(normalizeEmptyAmount(accidentRecord.getInsuranceClaimAmount()));
excel.setUpdateUserName(UserCache.getUserRealName(accidentRecord.getUpdateUser()));
return excel;
}).toList();
@@ -169,6 +175,9 @@ public class AccidentRecordServiceImpl extends BaseServiceImpl<AccidentRecordMap
accidentRecord.setAccidentReasonDamage(trimToNull(accidentRecord.getAccidentReasonDamage()));
accidentRecord.setAttachments(trimToNull(accidentRecord.getAttachments()));
accidentRecord.setRemark(trimToNull(accidentRecord.getRemark()));
// 非必填金额未填写禁止落库 -1 占位值
accidentRecord.setDirectEconomicLoss(normalizeEmptyAmount(accidentRecord.getDirectEconomicLoss()));
accidentRecord.setInsuranceClaimAmount(normalizeEmptyAmount(accidentRecord.getInsuranceClaimAmount()));
}
private void validate(AccidentRecord accidentRecord) {
@@ -238,11 +247,8 @@ public class AccidentRecordServiceImpl extends BaseServiceImpl<AccidentRecordMap
}
}
private BigDecimal nonNegative(BigDecimal value) {
if (Func.isEmpty(value) || value.compareTo(BigDecimal.ZERO) >= 0) {
return value;
}
return BigDecimal.ZERO;
private BigDecimal normalizeEmptyAmount(BigDecimal value) {
return Func.isNotEmpty(value) && value.compareTo(EMPTY_AMOUNT_SENTINEL) == 0 ? null : value;
}
private String normalizeVehicleType(String vehicleType) {
@@ -256,7 +262,7 @@ public class AccidentRecordServiceImpl extends BaseServiceImpl<AccidentRecordMap
private String trimToNull(String value) {
String trimValue = trimToEmpty(value);
return trimValue.isEmpty() ? null : trimValue;
return trimValue.isEmpty() || "-1".equals(trimValue) ? null : trimValue;
}
}
@@ -63,6 +63,8 @@ public class AnnualInspectionRecordServiceImpl extends BaseServiceImpl<AnnualIns
private static final int REMARK_MAX_LENGTH = 200;
private static final int ATTACHMENTS_MAX_LENGTH = 1000;
private static final int MONEY_SCALE = 2;
/** 费用等数值未填写时的历史占位值,统一转为 null */
private static final BigDecimal EMPTY_AMOUNT_SENTINEL = BigDecimal.valueOf(-1);
private static final String VEHICLE = "车辆";
private static final String SHIP = "船舶";
private static final Set<String> PASSENGER_TYPE_LEVELS = Set.of("一级", "二级", "其他");
@@ -70,7 +72,10 @@ public class AnnualInspectionRecordServiceImpl extends BaseServiceImpl<AnnualIns
@Override
public IPage<AnnualInspectionRecordVO> selectAnnualInspectionRecordPage(IPage<AnnualInspectionRecordVO> page, AnnualInspectionRecordVO annualInspectionRecord) {
List<AnnualInspectionRecordVO> records = baseMapper.selectAnnualInspectionRecordPage(page, annualInspectionRecord);
records.forEach(record -> record.setUpdateUserName(UserCache.getUserRealName(record.getUpdateUser())));
records.forEach(record -> {
record.setFee(normalizeEmptyAmount(record.getFee()));
record.setUpdateUserName(UserCache.getUserRealName(record.getUpdateUser()));
});
return page.setRecords(records);
}
@@ -176,7 +181,7 @@ public class AnnualInspectionRecordServiceImpl extends BaseServiceImpl<AnnualIns
AnnualInspectionRecordExportExcel excel = Objects.requireNonNull(BeanUtil.copyProperties(annualInspectionRecord, AnnualInspectionRecordExportExcel.class));
excel.setVehicleTechnicalLevel(VEHICLE.equals(annualInspectionRecord.getVehicleType()) ? annualInspectionRecord.getVehicleTechnicalLevel() : null);
excel.setShipInspectionType(SHIP.equals(annualInspectionRecord.getVehicleType()) ? annualInspectionRecord.getShipInspectionType() : null);
excel.setFee(nonNegative(annualInspectionRecord.getFee()));
excel.setFee(normalizeEmptyAmount(annualInspectionRecord.getFee()));
excel.setUpdateUserName(UserCache.getUserRealName(annualInspectionRecord.getUpdateUser()));
return excel;
}).toList();
@@ -192,6 +197,8 @@ public class AnnualInspectionRecordServiceImpl extends BaseServiceImpl<AnnualIns
annualInspectionRecord.setAssessmentUnit(trimToNull(annualInspectionRecord.getAssessmentUnit()));
annualInspectionRecord.setAttachments(trimToNull(annualInspectionRecord.getAttachments()));
annualInspectionRecord.setRemark(trimToNull(annualInspectionRecord.getRemark()));
// 费用必填,-1 占位转 null 后由校验拦截;展示侧同步为空
annualInspectionRecord.setFee(normalizeEmptyAmount(annualInspectionRecord.getFee()));
if (VEHICLE.equals(annualInspectionRecord.getVehicleType())) {
annualInspectionRecord.setShipInspectionType(null);
} else {
@@ -268,11 +275,8 @@ public class AnnualInspectionRecordServiceImpl extends BaseServiceImpl<AnnualIns
}
}
private BigDecimal nonNegative(BigDecimal value) {
if (Func.isEmpty(value) || value.compareTo(BigDecimal.ZERO) >= 0) {
return value;
}
return BigDecimal.ZERO;
private BigDecimal normalizeEmptyAmount(BigDecimal value) {
return Func.isNotEmpty(value) && value.compareTo(EMPTY_AMOUNT_SENTINEL) == 0 ? null : value;
}
private String normalizeVehicleType(String vehicleType) {
@@ -286,7 +290,7 @@ public class AnnualInspectionRecordServiceImpl extends BaseServiceImpl<AnnualIns
private String trimToNull(String value) {
String trimValue = trimToEmpty(value);
return trimValue.isEmpty() ? null : trimValue;
return trimValue.isEmpty() || "-1".equals(trimValue) ? null : trimValue;
}
}
@@ -82,6 +82,7 @@ public class InsuranceRecordServiceImpl extends BaseServiceImpl<InsuranceRecordM
private static final int OCR_TEMPLATE_MAX_LENGTH = 100;
private static final int POLICY_FILE_MAX_LENGTH = 1000;
private static final int REMARK_MAX_LENGTH = 200;
private static final BigDecimal EMPTY_AMOUNT_SENTINEL = BigDecimal.valueOf(-1);
private static final Set<String> INSURANCE_TYPES = Set.of("交强险", "商业险", "承运人责任险", "货运险", "船舶险");
private static final Set<String> SUPPORT_FILE_TYPES = Set.of("jpg", "jpeg", "png", "bmp");
private static final Pattern DATE_PATTERN = Pattern.compile("(\\d{4})[-/.年](\\d{1,2})[-/.月](\\d{1,2})日?");
@@ -93,7 +94,11 @@ public class InsuranceRecordServiceImpl extends BaseServiceImpl<InsuranceRecordM
@Override
public IPage<InsuranceRecordVO> selectInsuranceRecordPage(IPage<InsuranceRecordVO> page, InsuranceRecordVO insuranceRecord) {
List<InsuranceRecordVO> records = baseMapper.selectInsuranceRecordPage(page, insuranceRecord);
records.forEach(record -> record.setUpdateUserName(UserCache.getUserRealName(record.getUpdateUser())));
records.forEach(record -> {
record.setInsuredAmount(normalizeEmptyAmount(record.getInsuredAmount()));
record.setPremium(normalizeEmptyAmount(record.getPremium()));
record.setUpdateUserName(UserCache.getUserRealName(record.getUpdateUser()));
});
return page.setRecords(records);
}
@@ -191,8 +196,8 @@ public class InsuranceRecordServiceImpl extends BaseServiceImpl<InsuranceRecordM
public List<InsuranceRecordExportExcel> exportInsuranceRecord(Wrapper<InsuranceRecord> queryWrapper) {
return list(queryWrapper).stream().map(insuranceRecord -> {
InsuranceRecordExportExcel excel = Objects.requireNonNull(BeanUtil.copyProperties(insuranceRecord, InsuranceRecordExportExcel.class));
excel.setInsuredAmount(nonNegative(insuranceRecord.getInsuredAmount()));
excel.setPremium(nonNegative(insuranceRecord.getPremium()));
excel.setInsuredAmount(normalizeEmptyAmount(insuranceRecord.getInsuredAmount()));
excel.setPremium(normalizeEmptyAmount(insuranceRecord.getPremium()));
excel.setUpdateUserName(UserCache.getUserRealName(insuranceRecord.getUpdateUser()));
return excel;
}).toList();
@@ -337,6 +342,9 @@ public class InsuranceRecordServiceImpl extends BaseServiceImpl<InsuranceRecordM
insuranceRecord.setOcrTemplate(trimToNull(insuranceRecord.getOcrTemplate()));
insuranceRecord.setPolicyFile(trimToNull(insuranceRecord.getPolicyFile()));
insuranceRecord.setRemark(trimToNull(insuranceRecord.getRemark()));
// 未填写金额禁止落库 -1 占位值,统一存 null
insuranceRecord.setInsuredAmount(normalizeEmptyAmount(insuranceRecord.getInsuredAmount()));
insuranceRecord.setPremium(normalizeEmptyAmount(insuranceRecord.getPremium()));
}
private void validate(InsuranceRecord insuranceRecord) {
@@ -422,11 +430,8 @@ public class InsuranceRecordServiceImpl extends BaseServiceImpl<InsuranceRecordM
}
}
private BigDecimal nonNegative(BigDecimal value) {
if (Func.isEmpty(value) || value.compareTo(BigDecimal.ZERO) >= 0) {
return value;
}
return BigDecimal.ZERO;
private BigDecimal normalizeEmptyAmount(BigDecimal value) {
return Func.isNotEmpty(value) && value.compareTo(EMPTY_AMOUNT_SENTINEL) == 0 ? null : value;
}
private String normalizeVehicleType(String vehicleType) {
@@ -60,11 +60,17 @@ public class MaintenancePlanServiceImpl extends BaseServiceImpl<MaintenancePlanM
private static final int MAINTENANCE_ITEM_MAX_LENGTH = 100;
private static final int ADDRESS_MAX_LENGTH = 100;
private static final int REMARK_MAX_LENGTH = 500;
/** 非必填里程未填写时的历史占位值,统一转为 null */
private static final BigDecimal EMPTY_MILEAGE_SENTINEL = BigDecimal.valueOf(-1);
@Override
public IPage<MaintenancePlanVO> selectMaintenancePlanPage(IPage<MaintenancePlanVO> page, MaintenancePlanVO maintenancePlan) {
List<MaintenancePlanVO> records = baseMapper.selectMaintenancePlanPage(page, maintenancePlan);
records.forEach(record -> record.setUpdateUserName(UserCache.getUserRealName(record.getUpdateUser())));
records.forEach(record -> {
record.setMileage(normalizeEmptyMileage(record.getMileage()));
record.setNextMaintenanceMileage(normalizeEmptyMileage(record.getNextMaintenanceMileage()));
record.setUpdateUserName(UserCache.getUserRealName(record.getUpdateUser()));
});
return page.setRecords(records);
}
@@ -147,8 +153,8 @@ public class MaintenancePlanServiceImpl extends BaseServiceImpl<MaintenancePlanM
return list(queryWrapper).stream().map(maintenancePlan -> {
MaintenancePlanExportExcel excel = Objects.requireNonNull(BeanUtil.copyProperties(maintenancePlan, MaintenancePlanExportExcel.class));
excel.setUpdateUserName(UserCache.getUserRealName(maintenancePlan.getUpdateUser()));
excel.setMileage(nonNegative(maintenancePlan.getMileage()));
excel.setNextMaintenanceMileage(nonNegative(maintenancePlan.getNextMaintenanceMileage()));
excel.setMileage(normalizeEmptyMileage(maintenancePlan.getMileage()));
excel.setNextMaintenanceMileage(normalizeEmptyMileage(maintenancePlan.getNextMaintenanceMileage()));
if (Func.isEmpty(excel.getMileageUnit())) {
excel.setMileageUnit(defaultMileageUnit(maintenancePlan.getVehicleType()));
}
@@ -165,6 +171,9 @@ public class MaintenancePlanServiceImpl extends BaseServiceImpl<MaintenancePlanM
maintenancePlan.setContactPhone(trimToNull(maintenancePlan.getContactPhone()));
maintenancePlan.setAddress(trimToNull(maintenancePlan.getAddress()));
maintenancePlan.setRemark(trimToNull(maintenancePlan.getRemark()));
// 非必填里程未填写禁止落库 -1 占位值
maintenancePlan.setMileage(normalizeEmptyMileage(maintenancePlan.getMileage()));
maintenancePlan.setNextMaintenanceMileage(normalizeEmptyMileage(maintenancePlan.getNextMaintenanceMileage()));
if (Func.isEmpty(maintenancePlan.getMileageUnit())) {
maintenancePlan.setMileageUnit(defaultMileageUnit(maintenancePlan.getVehicleType()));
}
@@ -219,11 +228,8 @@ public class MaintenancePlanServiceImpl extends BaseServiceImpl<MaintenancePlanM
}
}
private BigDecimal nonNegative(BigDecimal value) {
if (Func.isEmpty(value) || value.compareTo(BigDecimal.ZERO) >= 0) {
return value;
}
return BigDecimal.ZERO;
private BigDecimal normalizeEmptyMileage(BigDecimal value) {
return Func.isNotEmpty(value) && value.compareTo(EMPTY_MILEAGE_SENTINEL) == 0 ? null : value;
}
private String defaultMileageUnit(String vehicleType) {
@@ -236,7 +242,7 @@ public class MaintenancePlanServiceImpl extends BaseServiceImpl<MaintenancePlanM
private String trimToNull(String value) {
String trimValue = trimToEmpty(value);
return trimValue.isEmpty() ? null : trimValue;
return trimValue.isEmpty() || "-1".equals(trimValue) ? null : trimValue;
}
}
@@ -28,6 +28,8 @@ import org.springblade.transport.service.IProjectApplyService;
import org.springblade.transport.service.ITransportPlanService;
import org.springblade.transport.service.IWaybillService;
import org.springblade.transport.support.TransportBusinessSupport;
import org.springblade.transport.support.WaybillProcessSupport;
import org.springblade.transport.wrapper.WaybillWrapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -92,16 +94,42 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
@Transactional(rollbackFor = Exception.class)
public MasterOrderVO submit(MasterOrderVO request, boolean draft) {
boolean created = Func.isEmpty(request.getId());
MasterOrder target = created ? new MasterOrder() : getRequired(request.getId());
if (!created && "completed".equals(target.getBusinessStatus())) {
assertRestrictedEdit(target, request);
MasterOrder oldRecord = created ? null : getRequired(request.getId());
MasterOrder target = created ? new MasterOrder()
: Objects.requireNonNull(BeanUtil.copyProperties(oldRecord, MasterOrder.class));
String previousStatus = oldRecord == null ? null : oldRecord.getBusinessStatus();
if (!created && "closed".equals(previousStatus)) {
throw new ServiceException("调度关闭的总单不能编辑");
}
// 非草稿编辑:基本信息与路线不可改
if (!created && !"draft".equals(previousStatus)) {
assertRestrictedEdit(oldRecord, request);
}
if (!created && "closed".equals(target.getBusinessStatus())) throw new ServiceException("调度关闭的总单不能编辑");
copyWritable(request, target);
if (created) target.setMasterNo(nextCode());
if (!created && !"draft".equals(previousStatus)) {
restoreBasicAndRoute(target, oldRecord);
}
if (created) {
target.setMasterNo(nextCode());
}
target.setTransportOrganizationType("多式联运");
target.setBusinessStatus(draft ? "draft" : ("dispatching".equals(target.getBusinessStatus()) ? "dispatching" : "waiting_dispatch"));
if (draft) {
// 仅新建或原草稿可暂存为 draft;已进入待调度及之后状态的编辑保持原状态
if (created || Func.isEmpty(previousStatus) || "draft".equals(previousStatus)) {
target.setBusinessStatus("draft");
} else {
target.setBusinessStatus(previousStatus);
}
} else if ("dispatching".equals(previousStatus) || "completed".equals(previousStatus)) {
// 调度中 / 调度完成编辑后保持原状态,避免误回退为待调度
target.setBusinessStatus(previousStatus);
} else {
target.setBusinessStatus("waiting_dispatch");
}
validate(target, draft);
if (!created) {
validateGoodsAgainstDispatched(oldRecord, target);
}
saveOrUpdate(target);
return detail(target.getId());
}
@@ -210,8 +238,14 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
row.setVehicleNo(waybill.getVehicleNo());
row.setStartDate(waybill.getStartDate());
row.setEndDate(waybill.getEndDate());
row.setBusinessStatus(waybill.getBusinessStatus());
// 与前端运单状态展示一致:先按接单配置校正,再转中文
row.setBusinessStatus(WaybillWrapper.businessStatusName(
WaybillProcessSupport.normalizeBusinessStatus(
waybill.getBusinessStatus(),
waybill.getProcessJson(),
waybill.getDriverAcceptStatus())));
row.setRemark(waybill.getRemark());
row.setUpdateTime(waybill.getUpdateTime());
row.setCreateTime(waybill.getCreateTime());
result.add(row);
}
@@ -302,6 +336,7 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
List<Waybill> boundWaybills = waybillsByMasterNo(entity.getMasterNo());
vo.setBoundWaybills(boundWaybills);
vo.setRouteProgress(buildProgress(entity, vo.getRoutes(), boundWaybills));
vo.setDispatchedGoods(maxDispatchedGoodsByCategory(entity));
vo.setCreateUserName(UserCache.getUserRealName(entity.getCreateUser())); vo.setUpdateUserName(UserCache.getUserRealName(entity.getUpdateUser()));
return vo;
}
@@ -343,7 +378,89 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
}
private void assertRestrictedEdit(MasterOrder oldRecord, MasterOrderVO request) {
if (!Objects.equals(oldRecord.getProjectId(), request.getProjectId()) || !Objects.equals(oldRecord.getRouteJson(), JsonUtil.toJson(request.getRoutes()))) throw new ServiceException("调度完成的总单不能修改基本信息和路线");
boolean basicChanged = !Objects.equals(oldRecord.getProjectId(), request.getProjectId())
|| !Objects.equals(oldRecord.getContractId(), request.getContractId())
|| !Objects.equals(normalizeText(oldRecord.getRemark()), normalizeText(request.getRemark()));
boolean routeChanged = !Objects.equals(normalizeText(oldRecord.getDepartureName()), normalizeText(request.getDepartureName()))
|| !Objects.equals(normalizeText(oldRecord.getDepartureAddress()), normalizeText(request.getDepartureAddress()))
|| !Objects.equals(normalizeText(oldRecord.getDepartureContact()), normalizeText(request.getDepartureContact()))
|| !Objects.equals(normalizeText(oldRecord.getDeparturePhone()), normalizeText(request.getDeparturePhone()))
|| !Objects.equals(normalizeText(oldRecord.getArrivalName()), normalizeText(request.getArrivalName()))
|| !Objects.equals(normalizeText(oldRecord.getArrivalAddress()), normalizeText(request.getArrivalAddress()))
|| !Objects.equals(normalizeText(oldRecord.getArrivalContact()), normalizeText(request.getArrivalContact()))
|| !Objects.equals(normalizeText(oldRecord.getArrivalPhone()), normalizeText(request.getArrivalPhone()))
|| !Objects.equals(oldRecord.getPlanStartTime(), request.getPlanStartTime())
|| !Objects.equals(oldRecord.getPlanEndTime(), request.getPlanEndTime())
|| !Objects.equals(normalizeText(oldRecord.getRouteJson()), normalizeText(JsonUtil.toJson(request.getRoutes())));
if (basicChanged || routeChanged) {
throw new ServiceException("当前总单不能修改基本信息和路线");
}
}
/** 非草稿编辑时强制保留库中基本信息与路线,避免前端绕过禁用项提交 */
private void restoreBasicAndRoute(MasterOrder target, MasterOrder oldRecord) {
target.setProjectId(oldRecord.getProjectId());
target.setProjectName(oldRecord.getProjectName());
target.setContractId(oldRecord.getContractId());
target.setContractName(oldRecord.getContractName());
target.setCustomerName(oldRecord.getCustomerName());
target.setRemark(oldRecord.getRemark());
target.setDepartureName(oldRecord.getDepartureName());
target.setDepartureAddress(oldRecord.getDepartureAddress());
target.setDepartureContact(oldRecord.getDepartureContact());
target.setDeparturePhone(oldRecord.getDeparturePhone());
target.setArrivalName(oldRecord.getArrivalName());
target.setArrivalAddress(oldRecord.getArrivalAddress());
target.setArrivalContact(oldRecord.getArrivalContact());
target.setArrivalPhone(oldRecord.getArrivalPhone());
target.setPlanStartTime(oldRecord.getPlanStartTime());
target.setPlanEndTime(oldRecord.getPlanEndTime());
target.setRouteJson(oldRecord.getRouteJson());
}
/**
* 编辑时货物数量不得低于该品类已调度量(各分段已调度量取最大值)。
*/
private void validateGoodsAgainstDispatched(MasterOrder oldRecord, MasterOrder target) {
Map<String, BigDecimal> maxDispatched = maxDispatchedGoodsByCategory(oldRecord);
if (maxDispatched.isEmpty()) {
return;
}
Map<String, BigDecimal> newAvailable = availableGoods(target);
for (Map.Entry<String, BigDecimal> entry : maxDispatched.entrySet()) {
BigDecimal dispatched = entry.getValue();
if (dispatched == null || dispatched.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
BigDecimal newQuantity = newAvailable.getOrDefault(entry.getKey(), BigDecimal.ZERO);
if (newQuantity.compareTo(dispatched) < 0) {
String cargoName = entry.getKey().contains("\u0000")
? entry.getKey().substring(0, entry.getKey().indexOf('\u0000'))
: entry.getKey();
throw new ServiceException("货物【" + cargoName + "】数量不能低于已调度量("
+ dispatched.stripTrailingZeros().toPlainString() + ")");
}
}
}
/** 各品类已调度量:同一品类取各分段已调度量的最大值 */
private Map<String, BigDecimal> maxDispatchedGoodsByCategory(MasterOrder masterOrder) {
Map<String, BigDecimal> result = new LinkedHashMap<>();
List<Map<String, Object>> routes = parseArray(masterOrder.getRouteJson());
if (routes.isEmpty()) {
return dispatchedGoods(masterOrder.getMasterNo(), null);
}
for (Map<String, Object> route : routes) {
Map<String, BigDecimal> dispatched = dispatchedGoods(masterOrder.getMasterNo(), string(route, "segmentNo"));
for (Map.Entry<String, BigDecimal> entry : dispatched.entrySet()) {
result.merge(entry.getKey(), entry.getValue(), BigDecimal::max);
}
}
return result;
}
private String normalizeText(String value) {
return value == null ? "" : value.trim();
}
private void validate(MasterOrder masterOrder, boolean draft) {
@@ -403,10 +520,13 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
String segmentNo = string(route, "segmentNo");
BigDecimal requestQuantity = requestQuantityBySegment.get(segmentNo);
if (requestQuantity == null) continue;
BigDecimal dispatchTotal = routeDispatchedQuantity(masterOrder, route).add(requestQuantity);
BigDecimal previousCompletedQuantity = completedQuantity(masterOrder.getMasterNo(), routes.get(index - 1));
if (previousCompletedQuantity.compareTo(BigDecimal.ZERO) <= 0) {
throw new ServiceException(segmentNo + "需等上一段运单完成到达后才能调度");
}
BigDecimal dispatchTotal = routeDispatchedQuantity(masterOrder, route).add(requestQuantity);
if (dispatchTotal.compareTo(previousCompletedQuantity) > 0) {
throw new ServiceException(segmentNo + "调度总量不能大于上一段已完成数量(" + previousCompletedQuantity.stripTrailingZeros().toPlainString() + ")");
throw new ServiceException(segmentNo + "调度总量不能大于上一段已到达数量(" + previousCompletedQuantity.stripTrailingZeros().toPlainString() + ")");
}
}
}
@@ -58,13 +58,21 @@ public class MileageRecordServiceImpl extends BaseServiceImpl<MileageRecordMappe
private static final int REMARK_MAX_LENGTH = 200;
private static final int ATTACHMENTS_MAX_LENGTH = 1000;
private static final int MILEAGE_SCALE = 2;
/** 非必填里程未填写时的历史占位值,统一转为 null */
private static final BigDecimal EMPTY_MILEAGE_SENTINEL = BigDecimal.valueOf(-1);
private static final String VEHICLE_TYPE_VEHICLE = "车辆";
private static final String MILEAGE_UNIT = "公里";
@Override
public IPage<MileageRecordVO> selectMileageRecordPage(IPage<MileageRecordVO> page, MileageRecordVO mileageRecord) {
List<MileageRecordVO> records = baseMapper.selectMileageRecordPage(page, mileageRecord);
records.forEach(record -> record.setUpdateUserName(UserCache.getUserRealName(record.getUpdateUser())));
records.forEach(record -> {
record.setPreviousMonthMileage(normalizeEmptyMileage(record.getPreviousMonthMileage()));
record.setCurrentMonthMileage(normalizeEmptyMileage(record.getCurrentMonthMileage()));
record.setMonthlyMileage(normalizeEmptyMileage(record.getMonthlyMileage()));
record.setTotalMileage(normalizeEmptyMileage(record.getTotalMileage()));
record.setUpdateUserName(UserCache.getUserRealName(record.getUpdateUser()));
});
return page.setRecords(records);
}
@@ -145,10 +153,10 @@ public class MileageRecordServiceImpl extends BaseServiceImpl<MileageRecordMappe
MileageRecordExportExcel excel = Objects.requireNonNull(
BeanUtil.copyProperties(mileageRecord, MileageRecordExportExcel.class)
);
excel.setPreviousMonthMileage(nonNegative(mileageRecord.getPreviousMonthMileage()));
excel.setCurrentMonthMileage(nonNegative(mileageRecord.getCurrentMonthMileage()));
excel.setMonthlyMileage(nonNegative(mileageRecord.getMonthlyMileage()));
excel.setTotalMileage(nonNegative(mileageRecord.getTotalMileage()));
excel.setPreviousMonthMileage(normalizeEmptyMileage(mileageRecord.getPreviousMonthMileage()));
excel.setCurrentMonthMileage(normalizeEmptyMileage(mileageRecord.getCurrentMonthMileage()));
excel.setMonthlyMileage(normalizeEmptyMileage(mileageRecord.getMonthlyMileage()));
excel.setTotalMileage(normalizeEmptyMileage(mileageRecord.getTotalMileage()));
excel.setUpdateUserName(UserCache.getUserRealName(mileageRecord.getUpdateUser()));
return excel;
}).toList();
@@ -160,6 +168,11 @@ public class MileageRecordServiceImpl extends BaseServiceImpl<MileageRecordMappe
mileageRecord.setMileageUnit(MILEAGE_UNIT);
mileageRecord.setRemark(trimToNull(mileageRecord.getRemark()));
mileageRecord.setAttachments(trimToNull(mileageRecord.getAttachments()));
// 非必填里程未填写禁止落库 -1 占位值
mileageRecord.setPreviousMonthMileage(normalizeEmptyMileage(mileageRecord.getPreviousMonthMileage()));
mileageRecord.setCurrentMonthMileage(normalizeEmptyMileage(mileageRecord.getCurrentMonthMileage()));
mileageRecord.setMonthlyMileage(normalizeEmptyMileage(mileageRecord.getMonthlyMileage()));
mileageRecord.setTotalMileage(normalizeEmptyMileage(mileageRecord.getTotalMileage()));
if (mileageRecord.getMonthlyMileage() == null
&& mileageRecord.getPreviousMonthMileage() != null
&& mileageRecord.getCurrentMonthMileage() != null) {
@@ -235,11 +248,8 @@ public class MileageRecordServiceImpl extends BaseServiceImpl<MileageRecordMappe
}
}
private BigDecimal nonNegative(BigDecimal value) {
if (Func.isEmpty(value) || value.compareTo(BigDecimal.ZERO) >= 0) {
return value;
}
return BigDecimal.ZERO;
private BigDecimal normalizeEmptyMileage(BigDecimal value) {
return Func.isNotEmpty(value) && value.compareTo(EMPTY_MILEAGE_SENTINEL) == 0 ? null : value;
}
private String normalizeVehicleNo(String vehicleNo) {
@@ -252,7 +262,7 @@ public class MileageRecordServiceImpl extends BaseServiceImpl<MileageRecordMappe
private String trimToNull(String value) {
String trimValue = trimToEmpty(value);
return trimValue.isEmpty() ? null : trimValue;
return trimValue.isEmpty() || "-1".equals(trimValue) ? null : trimValue;
}
}
@@ -45,6 +45,8 @@ public class OilElectricRecordServiceImpl extends BaseServiceImpl<OilElectricRec
private static final int ATTACHMENTS_MAX_LENGTH = 1000;
private static final int MONEY_SCALE = 2;
private static final int QUANTITY_SCALE = 2;
/** 非必填数值未填写时的历史占位值,统一转为 null */
private static final BigDecimal EMPTY_AMOUNT_SENTINEL = BigDecimal.valueOf(-1);
private static final String VEHICLE = "车辆";
private static final String SHIP = "船舶";
private static final String FUEL = "加油";
@@ -54,7 +56,13 @@ public class OilElectricRecordServiceImpl extends BaseServiceImpl<OilElectricRec
@Override
public IPage<OilElectricRecordVO> selectOilElectricRecordPage(IPage<OilElectricRecordVO> page, OilElectricRecordVO oilElectricRecord) {
List<OilElectricRecordVO> records = baseMapper.selectOilElectricRecordPage(page, oilElectricRecord);
records.forEach(record -> record.setUpdateUserName(UserCache.getUserRealName(record.getUpdateUser())));
records.forEach(record -> {
record.setQuantity(normalizeEmptyAmount(record.getQuantity()));
record.setUnitPrice(normalizeEmptyAmount(record.getUnitPrice()));
record.setTransactionAmount(normalizeEmptyAmount(record.getTransactionAmount()));
record.setBalance(normalizeEmptyAmount(record.getBalance()));
record.setUpdateUserName(UserCache.getUserRealName(record.getUpdateUser()));
});
return page.setRecords(records);
}
@@ -138,10 +146,10 @@ public class OilElectricRecordServiceImpl extends BaseServiceImpl<OilElectricRec
public List<OilElectricRecordExportExcel> exportOilElectricRecord(Wrapper<OilElectricRecord> queryWrapper) {
return list(queryWrapper).stream().map(oilElectricRecord -> {
OilElectricRecordExportExcel excel = Objects.requireNonNull(BeanUtil.copyProperties(oilElectricRecord, OilElectricRecordExportExcel.class));
excel.setQuantity(nonNegative(oilElectricRecord.getQuantity()));
excel.setUnitPrice(nonNegative(oilElectricRecord.getUnitPrice()));
excel.setTransactionAmount(nonNegative(oilElectricRecord.getTransactionAmount()));
excel.setBalance(nonNegative(oilElectricRecord.getBalance()));
excel.setQuantity(normalizeEmptyAmount(oilElectricRecord.getQuantity()));
excel.setUnitPrice(normalizeEmptyAmount(oilElectricRecord.getUnitPrice()));
excel.setTransactionAmount(normalizeEmptyAmount(oilElectricRecord.getTransactionAmount()));
excel.setBalance(normalizeEmptyAmount(oilElectricRecord.getBalance()));
excel.setUpdateUserName(UserCache.getUserRealName(oilElectricRecord.getUpdateUser()));
return excel;
}).toList();
@@ -161,6 +169,11 @@ public class OilElectricRecordServiceImpl extends BaseServiceImpl<OilElectricRec
oilElectricRecord.setDataSource(defaultDataSource(oilElectricRecord.getDataSource()));
oilElectricRecord.setAttachments(trimToNull(oilElectricRecord.getAttachments()));
oilElectricRecord.setRemark(trimToNull(oilElectricRecord.getRemark()));
// 非必填数值未填写禁止落库 -1;交易金额必填,-1 转 null 后由校验拦截
oilElectricRecord.setQuantity(normalizeEmptyAmount(oilElectricRecord.getQuantity()));
oilElectricRecord.setUnitPrice(normalizeEmptyAmount(oilElectricRecord.getUnitPrice()));
oilElectricRecord.setTransactionAmount(normalizeEmptyAmount(oilElectricRecord.getTransactionAmount()));
oilElectricRecord.setBalance(normalizeEmptyAmount(oilElectricRecord.getBalance()));
if (ELECTRIC.equals(oilElectricRecord.getFeeType())) {
oilElectricRecord.setOilProduct(null);
}
@@ -223,11 +236,8 @@ public class OilElectricRecordServiceImpl extends BaseServiceImpl<OilElectricRec
}
}
private BigDecimal nonNegative(BigDecimal value) {
if (Func.isEmpty(value) || value.compareTo(BigDecimal.ZERO) >= 0) {
return value;
}
return BigDecimal.ZERO;
private BigDecimal normalizeEmptyAmount(BigDecimal value) {
return Func.isNotEmpty(value) && value.compareTo(EMPTY_AMOUNT_SENTINEL) == 0 ? null : value;
}
private String defaultDataSource(String dataSource) {
@@ -246,7 +256,7 @@ public class OilElectricRecordServiceImpl extends BaseServiceImpl<OilElectricRec
private String trimToNull(String value) {
String trimValue = trimToEmpty(value);
return trimValue.isEmpty() ? null : trimValue;
return trimValue.isEmpty() || "-1".equals(trimValue) ? null : trimValue;
}
}
@@ -62,11 +62,18 @@ public class TireReplacementRecordServiceImpl extends BaseServiceImpl<TireReplac
private static final int REMARK_MAX_LENGTH = 500;
private static final int ATTACHMENTS_MAX_LENGTH = 1000;
private static final int MONEY_SCALE = 2;
/** 非必填数量/金额未填写时的历史占位值,统一转为 null */
private static final BigDecimal EMPTY_AMOUNT_SENTINEL = BigDecimal.valueOf(-1);
private static final Integer EMPTY_INTEGER_SENTINEL = -1;
@Override
public IPage<TireReplacementRecordVO> selectTireReplacementRecordPage(IPage<TireReplacementRecordVO> page, TireReplacementRecordVO tireReplacementRecord) {
List<TireReplacementRecordVO> records = baseMapper.selectTireReplacementRecordPage(page, tireReplacementRecord);
records.forEach(record -> record.setUpdateUserName(UserCache.getUserRealName(record.getUpdateUser())));
records.forEach(record -> {
record.setTireQuantity(normalizeEmptyInteger(record.getTireQuantity()));
record.setReplacementCost(normalizeEmptyAmount(record.getReplacementCost()));
record.setUpdateUserName(UserCache.getUserRealName(record.getUpdateUser()));
});
return page.setRecords(records);
}
@@ -153,8 +160,8 @@ public class TireReplacementRecordServiceImpl extends BaseServiceImpl<TireReplac
public List<TireReplacementRecordExportExcel> exportTireReplacementRecord(Wrapper<TireReplacementRecord> queryWrapper) {
return list(queryWrapper).stream().map(tireReplacementRecord -> {
TireReplacementRecordExportExcel excel = Objects.requireNonNull(BeanUtil.copyProperties(tireReplacementRecord, TireReplacementRecordExportExcel.class));
excel.setTireQuantity(validQuantity(tireReplacementRecord.getTireQuantity()));
excel.setReplacementCost(nonNegative(tireReplacementRecord.getReplacementCost()));
excel.setTireQuantity(normalizeEmptyInteger(tireReplacementRecord.getTireQuantity()));
excel.setReplacementCost(normalizeEmptyAmount(tireReplacementRecord.getReplacementCost()));
excel.setUpdateUserName(UserCache.getUserRealName(tireReplacementRecord.getUpdateUser()));
return excel;
}).toList();
@@ -167,6 +174,9 @@ public class TireReplacementRecordServiceImpl extends BaseServiceImpl<TireReplac
tireReplacementRecord.setReplacementDescription(trimToNull(tireReplacementRecord.getReplacementDescription()));
tireReplacementRecord.setAttachments(trimToNull(tireReplacementRecord.getAttachments()));
tireReplacementRecord.setRemark(trimToNull(tireReplacementRecord.getRemark()));
// 非必填数量及金额占位值 -1 统一存 null(费用必填,-1 转 null 后由校验拦截)
tireReplacementRecord.setTireQuantity(normalizeEmptyInteger(tireReplacementRecord.getTireQuantity()));
tireReplacementRecord.setReplacementCost(normalizeEmptyAmount(tireReplacementRecord.getReplacementCost()));
}
private void validate(TireReplacementRecord tireReplacementRecord) {
@@ -214,18 +224,12 @@ public class TireReplacementRecordServiceImpl extends BaseServiceImpl<TireReplac
}
}
private BigDecimal nonNegative(BigDecimal value) {
if (Func.isEmpty(value) || value.compareTo(BigDecimal.ZERO) >= 0) {
return value;
}
return BigDecimal.ZERO;
private BigDecimal normalizeEmptyAmount(BigDecimal value) {
return Func.isNotEmpty(value) && value.compareTo(EMPTY_AMOUNT_SENTINEL) == 0 ? null : value;
}
private Integer validQuantity(Integer value) {
if (Func.isEmpty(value) || value > 0) {
return value;
}
return null;
private Integer normalizeEmptyInteger(Integer value) {
return Func.isNotEmpty(value) && value.equals(EMPTY_INTEGER_SENTINEL) ? null : value;
}
private String trimToEmpty(String value) {
@@ -234,7 +238,7 @@ public class TireReplacementRecordServiceImpl extends BaseServiceImpl<TireReplac
private String trimToNull(String value) {
String trimValue = trimToEmpty(value);
return trimValue.isEmpty() ? null : trimValue;
return trimValue.isEmpty() || "-1".equals(trimValue) ? null : trimValue;
}
}
@@ -192,7 +192,7 @@ public class TransportChangeRecordServiceImpl extends BaseServiceImpl<TransportC
private String trimToNull(String value) {
String trimValue = trimToEmpty(value);
return trimValue.isEmpty() ? null : trimValue;
return trimValue.isEmpty() || "-1".equals(trimValue) ? null : trimValue;
}
}
@@ -69,6 +69,9 @@ public class ViolationRecordServiceImpl extends BaseServiceImpl<ViolationRecordM
private static final String UNPROCESSED = "未处理";
private static final String CAR = "车辆";
private static final String SHIP = "船舶";
/** 非必填数值未填写时的历史占位值,统一转为 null 落库/展示 */
private static final BigDecimal EMPTY_AMOUNT_SENTINEL = BigDecimal.valueOf(-1);
private static final Integer EMPTY_INTEGER_SENTINEL = -1;
@Override
public IPage<ViolationRecordVO> selectViolationRecordPage(IPage<ViolationRecordVO> page, ViolationRecordVO violationRecord) {
@@ -168,8 +171,8 @@ public class ViolationRecordServiceImpl extends BaseServiceImpl<ViolationRecordM
public List<ViolationRecordExcel> exportViolationRecord(Wrapper<ViolationRecord> queryWrapper) {
return list(queryWrapper).stream().map(violationRecord -> {
ViolationRecordExcel excel = Objects.requireNonNull(BeanUtil.copyProperties(violationRecord, ViolationRecordExcel.class));
excel.setFineAmount(nonNegative(violationRecord.getFineAmount()));
excel.setDeductPoints(validDeductPoints(violationRecord.getDeductPoints()));
excel.setFineAmount(normalizeEmptyAmount(violationRecord.getFineAmount()));
excel.setDeductPoints(validDeductPoints(normalizeEmptyInteger(violationRecord.getDeductPoints())));
excel.setUpdateUserName(UserCache.getUserRealName(violationRecord.getUpdateUser()));
return excel;
}).toList();
@@ -187,6 +190,9 @@ public class ViolationRecordServiceImpl extends BaseServiceImpl<ViolationRecordM
violationRecord.setProcessDescription(trimToEmpty(violationRecord.getProcessDescription()));
violationRecord.setProcessResult(trimToNull(violationRecord.getProcessResult()));
violationRecord.setAttachments(trimToNull(violationRecord.getAttachments()));
// 非必填数值未填写禁止落库 -1 占位值
violationRecord.setFineAmount(normalizeEmptyAmount(violationRecord.getFineAmount()));
violationRecord.setDeductPoints(normalizeEmptyInteger(violationRecord.getDeductPoints()));
if (UNPROCESSED.equals(violationRecord.getProcessStatus())) {
violationRecord.setProcessResult(null);
}
@@ -290,11 +296,12 @@ public class ViolationRecordServiceImpl extends BaseServiceImpl<ViolationRecordM
}
}
private BigDecimal nonNegative(BigDecimal value) {
if (Func.isEmpty(value) || value.compareTo(BigDecimal.ZERO) >= 0) {
return value;
}
return BigDecimal.ZERO;
private BigDecimal normalizeEmptyAmount(BigDecimal value) {
return Func.isNotEmpty(value) && value.compareTo(EMPTY_AMOUNT_SENTINEL) == 0 ? null : value;
}
private Integer normalizeEmptyInteger(Integer value) {
return Func.isNotEmpty(value) && value.equals(EMPTY_INTEGER_SENTINEL) ? null : value;
}
private Integer validDeductPoints(Integer value) {
@@ -323,7 +330,7 @@ public class ViolationRecordServiceImpl extends BaseServiceImpl<ViolationRecordM
private String trimToNull(String value) {
String trimValue = trimToEmpty(value);
return trimValue.isEmpty() ? null : trimValue;
return trimValue.isEmpty() || "-1".equals(trimValue) ? null : trimValue;
}
}
@@ -18,7 +18,6 @@ import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.WebUtil;
import org.springblade.core.tool.jackson.JsonUtil;
import org.springblade.system.cache.DictCache;
import org.springblade.system.cache.DictBizCache;
@@ -36,6 +35,8 @@ import org.springblade.transport.pojo.entity.Waybill;
import org.springblade.transport.pojo.entity.WaybillImportBatch;
import org.springblade.transport.pojo.vo.BusinessRemoveResultVO;
import org.springblade.transport.pojo.vo.WaybillImportBatchVO;
import org.springblade.transport.pojo.vo.WaybillImportRowErrorVO;
import org.springblade.transport.pojo.vo.WaybillImportValidateResultVO;
import org.springblade.transport.service.ICustomerArchiveService;
import org.springblade.transport.service.IProjectApplyService;
import org.springblade.transport.service.IReceivablePayableDetailService;
@@ -46,9 +47,7 @@ import org.springblade.transport.service.IWaybillService;
import org.springblade.transport.support.TransportBusinessSupport;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
@@ -98,89 +97,97 @@ public class WaybillImportBatchServiceImpl extends BaseServiceImpl<WaybillImport
}
@Override
public void validate(WaybillImportBatchRequest request, HttpServletResponse response) {
public WaybillImportValidateResultVO validate(WaybillImportBatchRequest request) {
if (Func.isEmpty(request.getRows())) throw new ServiceException("请上传至少一条运单明细");
// 确定导入状态
WaybillImportValidateResultVO result = new WaybillImportValidateResultVO();
String importStatus = STATUS_DRAFT.equals(request.getStatus()) ? STATUS_DRAFT : STATUS_COMPLETED;
boolean draft = STATUS_DRAFT.equals(importStatus);
// 草稿状态不校验,直接返回成功
if (draft) {
WebUtil.renderJson(response, R.success("校验通过"));
return;
result.setSuccess(Boolean.TRUE);
return result;
}
// 执行校验
List<Map<String, Object>> rows = request.getRows();
Map<Integer, String> validationErrors = validateImportRows(rows, importStatus);
// 如果有校验错误,导出错误明细Excel
if (!validationErrors.isEmpty()) {
List<WaybillImportBatchExcel> failureList = new ArrayList<>();
for (int i = 0; i < rows.size(); i++) {
WaybillImportBatchExcel excel = mapToExcel(rows.get(i));
String errorMessage = validationErrors.get(i);
excel.setErrorMessage(Func.isNotEmpty(errorMessage) ? errorMessage : "");
failureList.add(excel);
}
ImportFailureExcelUtil.export(response, "运单导入失败明细" + DateUtil.time(), "导入失败明细", failureList, WaybillImportBatchExcel.class);
return;
List<WaybillImportRowErrorVO> errors = new ArrayList<>();
for (Map.Entry<Integer, String> entry : validationErrors.entrySet()) {
WaybillImportRowErrorVO error = new WaybillImportRowErrorVO();
error.setRowIndex(entry.getKey());
error.setErrorMessage(entry.getValue());
errors.add(error);
}
result.setErrors(errors);
result.setSuccess(errors.isEmpty());
return result;
}
// 校验通过,返回成功响应
WebUtil.renderJson(response, R.success("校验通过"));
@Override
public void exportFailures(WaybillImportBatchRequest request, HttpServletResponse response) {
if (Func.isEmpty(request.getRows())) throw new ServiceException("请至少提供一条失败明细");
List<WaybillImportBatchExcel> failureList = new ArrayList<>();
for (Map<String, Object> row : request.getRows()) {
WaybillImportBatchExcel excel = mapToExcel(row);
excel.setErrorMessage(stringValue(row, "errorMessage", "导入失败原因", "失败原因"));
failureList.add(excel);
}
ImportFailureExcelUtil.export(response, "运单导入失败明细" + DateUtil.time(), "导入失败明细", failureList, WaybillImportBatchExcel.class);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void confirm(WaybillImportBatchRequest request, HttpServletResponse response) {
public WaybillImportBatchVO confirm(WaybillImportBatchRequest request) {
if (Func.isEmpty(request.getRows())) throw new ServiceException("请上传至少一条运单明细");
// 执行校验
String importStatus = STATUS_DRAFT.equals(request.getStatus()) ? STATUS_DRAFT : STATUS_COMPLETED;
boolean draft = STATUS_DRAFT.equals(importStatus);
if (!draft) {
List<Map<String, Object>> rows = request.getRows();
Map<Integer, String> validationErrors = validateImportRows(rows, importStatus);
// 如果有校验错误,导出错误明细Excel
Map<Integer, String> validationErrors = validateImportRows(request.getRows(), importStatus);
if (!validationErrors.isEmpty()) {
List<WaybillImportBatchExcel> failureList = new ArrayList<>();
for (int i = 0; i < rows.size(); i++) {
WaybillImportBatchExcel excel = mapToExcel(rows.get(i));
String errorMessage = validationErrors.get(i);
excel.setErrorMessage(Func.isNotEmpty(errorMessage) ? errorMessage : "");
failureList.add(excel);
}
ImportFailureExcelUtil.export(response, "运单导入失败明细" + DateUtil.time(), "导入失败明细", failureList, WaybillImportBatchExcel.class);
return;
String firstError = validationErrors.values().iterator().next();
Integer firstIndex = validationErrors.keySet().iterator().next();
throw new ServiceException("第" + (firstIndex + 1) + "行校验失败:" + firstError);
}
}
// 校验通过,执行导入
WaybillImportBatch batch = persist(request, importStatus);
// 返回成功响应
WebUtil.renderJson(response, R.success("操作成功"));
return toVO(batch);
}
/** 草稿与确认导入共用落库流程,差异仅在于运单是否走校验以及是否生成应收应付明细。 */
private WaybillImportBatch persist(WaybillImportBatchRequest request, String importStatus) {
boolean draft = STATUS_DRAFT.equals(importStatus);
WaybillImportBatch batch = buildBatch(request, importStatus);
if (Func.isNotEmpty(request.getId())) {
boolean append = Boolean.TRUE.equals(request.getAppend());
WaybillImportBatch batch;
int existingWaybillCount = 0;
if (append) {
if (Func.isEmpty(request.getId())) {
throw new ServiceException("分批追加导入必须指定批次ID");
}
WaybillImportBatch oldBatch = getById(request.getId());
if (oldBatch == null || Objects.equals(oldBatch.getIsDeleted(), 1)) throw new ServiceException("运单批次不存在");
if (!STATUS_DRAFT.equals(oldBatch.getImportStatus())) throw new ServiceException("仅草稿状态的批次允许编辑");
batch.setId(oldBatch.getId());
batch.setBatchNo(oldBatch.getBatchNo());
if (oldBatch == null || Objects.equals(oldBatch.getIsDeleted(), 1)) {
throw new ServiceException("运单批次不存在");
}
batch = oldBatch;
existingWaybillCount = Func.toInt(oldBatch.getWaybillCount(), 0);
} else {
batch = buildBatch(request, importStatus);
if (Func.isNotEmpty(request.getId())) {
WaybillImportBatch oldBatch = getById(request.getId());
if (oldBatch == null || Objects.equals(oldBatch.getIsDeleted(), 1)) throw new ServiceException("运单批次不存在");
if (!STATUS_DRAFT.equals(oldBatch.getImportStatus())) throw new ServiceException("仅草稿状态的批次允许编辑");
batch.setId(oldBatch.getId());
batch.setBatchNo(oldBatch.getBatchNo());
}
batch.setWaybillCount(0);
saveOrUpdate(batch);
// 重新落库前清理批次已生成的运单,避免草稿反复保存产生重复运单。
clearBatchWaybills(batch.getId());
}
batch.setWaybillCount(0);
saveOrUpdate(batch);
// 重新落库前清理批次已生成的运单,避免草稿反复保存产生重复运单。
clearBatchWaybills(batch.getId());
List<Map<String, Object>> rows = Func.isEmpty(request.getRows()) ? List.of() : request.getRows();
@@ -216,7 +223,10 @@ public class WaybillImportBatchServiceImpl extends BaseServiceImpl<WaybillImport
}
}
loadingWaybills.forEach(loadingManageService::createFromImportedWaybills);
batch.setWaybillCount(waybills.size());
batch.setWaybillCount(existingWaybillCount + waybills.size());
if (append && !draft) {
batch.setImportStatus(STATUS_COMPLETED);
}
updateById(batch);
// 导入完成且导入类型为运单时,按合同费用生成模式(系统生成)同步生成应收应付明细。
if (!draft && IMPORT_TYPE_WAYBILL.equals(batch.getImportType())) {
@@ -685,6 +685,10 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
@Transactional(rollbackFor = Exception.class)
public boolean submit(Waybill waybill) {
boolean created = Func.isEmpty(waybill.getId());
// 正式提交须脱离草稿:draft 在过程校正中被视为终态不会提升,需先清空再按接单配置校正为 pending/running
if (STATUS_DRAFT.equals(waybill.getBusinessStatus())) {
waybill.setBusinessStatus(null);
}
prepareForSave(waybill);
validate(waybill);
boolean result = saveOrUpdate(waybill);
@@ -1309,7 +1313,16 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
queryWrapper.like(Waybill::getOriginalNo, waybill.getOriginalNo());
}
if (Func.isNotEmpty(waybill.getBusinessStatus())) {
queryWrapper.eq(Waybill::getBusinessStatus, waybill.getBusinessStatus());
List<String> businessStatuses = Arrays.stream(waybill.getBusinessStatus().split("[,,]"))
.map(String::trim)
.filter(Func::isNotEmpty)
.distinct()
.toList();
if (businessStatuses.size() == 1) {
queryWrapper.eq(Waybill::getBusinessStatus, businessStatuses.get(0));
} else if (!businessStatuses.isEmpty()) {
queryWrapper.in(Waybill::getBusinessStatus, businessStatuses);
}
}
if (Func.isNotEmpty(waybill.getDataSource())) {
queryWrapper.eq(Waybill::getDataSource, waybill.getDataSource());
@@ -31,6 +31,7 @@ import org.springblade.system.cache.UserCache;
import org.springblade.transport.pojo.entity.AccidentRecord;
import org.springblade.transport.pojo.vo.AccidentRecordVO;
import java.math.BigDecimal;
import java.util.Objects;
/**
@@ -40,6 +41,8 @@ import java.util.Objects;
*/
public class AccidentRecordWrapper extends BaseEntityWrapper<AccidentRecord, AccidentRecordVO> {
private static final BigDecimal EMPTY_AMOUNT_SENTINEL = BigDecimal.valueOf(-1);
public static AccidentRecordWrapper build() {
return new AccidentRecordWrapper();
}
@@ -47,8 +50,15 @@ public class AccidentRecordWrapper extends BaseEntityWrapper<AccidentRecord, Acc
@Override
public AccidentRecordVO entityVO(AccidentRecord accidentRecord) {
AccidentRecordVO accidentRecordVO = Objects.requireNonNull(BeanUtil.copyProperties(accidentRecord, AccidentRecordVO.class));
// 未填写金额的占位值 -1 对外展示为空
accidentRecordVO.setDirectEconomicLoss(normalizeEmptyAmount(accidentRecordVO.getDirectEconomicLoss()));
accidentRecordVO.setInsuranceClaimAmount(normalizeEmptyAmount(accidentRecordVO.getInsuranceClaimAmount()));
accidentRecordVO.setUpdateUserName(UserCache.getUserRealName(accidentRecord.getUpdateUser()));
return accidentRecordVO;
}
private BigDecimal normalizeEmptyAmount(BigDecimal value) {
return value != null && value.compareTo(EMPTY_AMOUNT_SENTINEL) == 0 ? null : value;
}
}
@@ -31,6 +31,7 @@ import org.springblade.system.cache.UserCache;
import org.springblade.transport.pojo.entity.AnnualInspectionRecord;
import org.springblade.transport.pojo.vo.AnnualInspectionRecordVO;
import java.math.BigDecimal;
import java.util.Objects;
/**
@@ -40,6 +41,8 @@ import java.util.Objects;
*/
public class AnnualInspectionRecordWrapper extends BaseEntityWrapper<AnnualInspectionRecord, AnnualInspectionRecordVO> {
private static final BigDecimal EMPTY_AMOUNT_SENTINEL = BigDecimal.valueOf(-1);
public static AnnualInspectionRecordWrapper build() {
return new AnnualInspectionRecordWrapper();
}
@@ -47,8 +50,14 @@ public class AnnualInspectionRecordWrapper extends BaseEntityWrapper<AnnualInspe
@Override
public AnnualInspectionRecordVO entityVO(AnnualInspectionRecord annualInspectionRecord) {
AnnualInspectionRecordVO annualInspectionRecordVO = Objects.requireNonNull(BeanUtil.copyProperties(annualInspectionRecord, AnnualInspectionRecordVO.class));
// 费用占位值 -1 对外展示为空
annualInspectionRecordVO.setFee(normalizeEmptyAmount(annualInspectionRecordVO.getFee()));
annualInspectionRecordVO.setUpdateUserName(UserCache.getUserRealName(annualInspectionRecord.getUpdateUser()));
return annualInspectionRecordVO;
}
private BigDecimal normalizeEmptyAmount(BigDecimal value) {
return value != null && value.compareTo(EMPTY_AMOUNT_SENTINEL) == 0 ? null : value;
}
}
@@ -31,6 +31,7 @@ import org.springblade.system.cache.UserCache;
import org.springblade.transport.pojo.entity.InsuranceRecord;
import org.springblade.transport.pojo.vo.InsuranceRecordVO;
import java.math.BigDecimal;
import java.util.Objects;
/**
@@ -40,6 +41,8 @@ import java.util.Objects;
*/
public class InsuranceRecordWrapper extends BaseEntityWrapper<InsuranceRecord, InsuranceRecordVO> {
private static final BigDecimal EMPTY_AMOUNT_SENTINEL = BigDecimal.valueOf(-1);
public static InsuranceRecordWrapper build() {
return new InsuranceRecordWrapper();
}
@@ -47,8 +50,15 @@ public class InsuranceRecordWrapper extends BaseEntityWrapper<InsuranceRecord, I
@Override
public InsuranceRecordVO entityVO(InsuranceRecord insuranceRecord) {
InsuranceRecordVO insuranceRecordVO = Objects.requireNonNull(BeanUtil.copyProperties(insuranceRecord, InsuranceRecordVO.class));
// 未填写保额等金额的占位值 -1 对外展示为空
insuranceRecordVO.setInsuredAmount(normalizeEmptyAmount(insuranceRecordVO.getInsuredAmount()));
insuranceRecordVO.setPremium(normalizeEmptyAmount(insuranceRecordVO.getPremium()));
insuranceRecordVO.setUpdateUserName(UserCache.getUserRealName(insuranceRecord.getUpdateUser()));
return insuranceRecordVO;
}
private BigDecimal normalizeEmptyAmount(BigDecimal value) {
return value != null && value.compareTo(EMPTY_AMOUNT_SENTINEL) == 0 ? null : value;
}
}
@@ -31,6 +31,7 @@ import org.springblade.system.cache.UserCache;
import org.springblade.transport.pojo.entity.MaintenancePlan;
import org.springblade.transport.pojo.vo.MaintenancePlanVO;
import java.math.BigDecimal;
import java.util.Objects;
/**
@@ -40,6 +41,8 @@ import java.util.Objects;
*/
public class MaintenancePlanWrapper extends BaseEntityWrapper<MaintenancePlan, MaintenancePlanVO> {
private static final BigDecimal EMPTY_MILEAGE_SENTINEL = BigDecimal.valueOf(-1);
public static MaintenancePlanWrapper build() {
return new MaintenancePlanWrapper();
}
@@ -47,8 +50,15 @@ public class MaintenancePlanWrapper extends BaseEntityWrapper<MaintenancePlan, M
@Override
public MaintenancePlanVO entityVO(MaintenancePlan maintenancePlan) {
MaintenancePlanVO maintenancePlanVO = Objects.requireNonNull(BeanUtil.copyProperties(maintenancePlan, MaintenancePlanVO.class));
// 未填写里程的占位值 -1 对外展示为空
maintenancePlanVO.setMileage(normalizeEmptyMileage(maintenancePlanVO.getMileage()));
maintenancePlanVO.setNextMaintenanceMileage(normalizeEmptyMileage(maintenancePlanVO.getNextMaintenanceMileage()));
maintenancePlanVO.setUpdateUserName(UserCache.getUserRealName(maintenancePlan.getUpdateUser()));
return maintenancePlanVO;
}
private BigDecimal normalizeEmptyMileage(BigDecimal value) {
return value != null && value.compareTo(EMPTY_MILEAGE_SENTINEL) == 0 ? null : value;
}
}
@@ -31,6 +31,7 @@ import org.springblade.system.cache.UserCache;
import org.springblade.transport.pojo.entity.MileageRecord;
import org.springblade.transport.pojo.vo.MileageRecordVO;
import java.math.BigDecimal;
import java.util.Objects;
/**
@@ -40,6 +41,8 @@ import java.util.Objects;
*/
public class MileageRecordWrapper extends BaseEntityWrapper<MileageRecord, MileageRecordVO> {
private static final BigDecimal EMPTY_MILEAGE_SENTINEL = BigDecimal.valueOf(-1);
public static MileageRecordWrapper build() {
return new MileageRecordWrapper();
}
@@ -47,8 +50,17 @@ public class MileageRecordWrapper extends BaseEntityWrapper<MileageRecord, Milea
@Override
public MileageRecordVO entityVO(MileageRecord mileageRecord) {
MileageRecordVO mileageRecordVO = Objects.requireNonNull(BeanUtil.copyProperties(mileageRecord, MileageRecordVO.class));
// 未填写里程的占位值 -1 对外展示为空
mileageRecordVO.setPreviousMonthMileage(normalizeEmptyMileage(mileageRecordVO.getPreviousMonthMileage()));
mileageRecordVO.setCurrentMonthMileage(normalizeEmptyMileage(mileageRecordVO.getCurrentMonthMileage()));
mileageRecordVO.setMonthlyMileage(normalizeEmptyMileage(mileageRecordVO.getMonthlyMileage()));
mileageRecordVO.setTotalMileage(normalizeEmptyMileage(mileageRecordVO.getTotalMileage()));
mileageRecordVO.setUpdateUserName(UserCache.getUserRealName(mileageRecord.getUpdateUser()));
return mileageRecordVO;
}
private BigDecimal normalizeEmptyMileage(BigDecimal value) {
return value != null && value.compareTo(EMPTY_MILEAGE_SENTINEL) == 0 ? null : value;
}
}
@@ -12,6 +12,7 @@ import org.springblade.system.cache.UserCache;
import org.springblade.transport.pojo.entity.OilElectricRecord;
import org.springblade.transport.pojo.vo.OilElectricRecordVO;
import java.math.BigDecimal;
import java.util.Objects;
/**
@@ -21,6 +22,8 @@ import java.util.Objects;
*/
public class OilElectricRecordWrapper extends BaseEntityWrapper<OilElectricRecord, OilElectricRecordVO> {
private static final BigDecimal EMPTY_AMOUNT_SENTINEL = BigDecimal.valueOf(-1);
public static OilElectricRecordWrapper build() {
return new OilElectricRecordWrapper();
}
@@ -28,8 +31,17 @@ public class OilElectricRecordWrapper extends BaseEntityWrapper<OilElectricRecor
@Override
public OilElectricRecordVO entityVO(OilElectricRecord oilElectricRecord) {
OilElectricRecordVO oilElectricRecordVO = Objects.requireNonNull(BeanUtil.copyProperties(oilElectricRecord, OilElectricRecordVO.class));
// 未填写数量/金额的占位值 -1 对外展示为空
oilElectricRecordVO.setQuantity(normalizeEmptyAmount(oilElectricRecordVO.getQuantity()));
oilElectricRecordVO.setUnitPrice(normalizeEmptyAmount(oilElectricRecordVO.getUnitPrice()));
oilElectricRecordVO.setTransactionAmount(normalizeEmptyAmount(oilElectricRecordVO.getTransactionAmount()));
oilElectricRecordVO.setBalance(normalizeEmptyAmount(oilElectricRecordVO.getBalance()));
oilElectricRecordVO.setUpdateUserName(UserCache.getUserRealName(oilElectricRecord.getUpdateUser()));
return oilElectricRecordVO;
}
private BigDecimal normalizeEmptyAmount(BigDecimal value) {
return value != null && value.compareTo(EMPTY_AMOUNT_SENTINEL) == 0 ? null : value;
}
}
@@ -31,6 +31,7 @@ import org.springblade.system.cache.UserCache;
import org.springblade.transport.pojo.entity.TireReplacementRecord;
import org.springblade.transport.pojo.vo.TireReplacementRecordVO;
import java.math.BigDecimal;
import java.util.Objects;
/**
@@ -40,6 +41,9 @@ import java.util.Objects;
*/
public class TireReplacementRecordWrapper extends BaseEntityWrapper<TireReplacementRecord, TireReplacementRecordVO> {
private static final BigDecimal EMPTY_AMOUNT_SENTINEL = BigDecimal.valueOf(-1);
private static final Integer EMPTY_INTEGER_SENTINEL = -1;
public static TireReplacementRecordWrapper build() {
return new TireReplacementRecordWrapper();
}
@@ -47,8 +51,19 @@ public class TireReplacementRecordWrapper extends BaseEntityWrapper<TireReplacem
@Override
public TireReplacementRecordVO entityVO(TireReplacementRecord tireReplacementRecord) {
TireReplacementRecordVO tireReplacementRecordVO = Objects.requireNonNull(BeanUtil.copyProperties(tireReplacementRecord, TireReplacementRecordVO.class));
// 未填写数量/费用的占位值 -1 对外展示为空
tireReplacementRecordVO.setTireQuantity(normalizeEmptyInteger(tireReplacementRecordVO.getTireQuantity()));
tireReplacementRecordVO.setReplacementCost(normalizeEmptyAmount(tireReplacementRecordVO.getReplacementCost()));
tireReplacementRecordVO.setUpdateUserName(UserCache.getUserRealName(tireReplacementRecord.getUpdateUser()));
return tireReplacementRecordVO;
}
private BigDecimal normalizeEmptyAmount(BigDecimal value) {
return value != null && value.compareTo(EMPTY_AMOUNT_SENTINEL) == 0 ? null : value;
}
private Integer normalizeEmptyInteger(Integer value) {
return value != null && value.equals(EMPTY_INTEGER_SENTINEL) ? null : value;
}
}
@@ -31,6 +31,7 @@ import org.springblade.system.cache.UserCache;
import org.springblade.transport.pojo.entity.ViolationRecord;
import org.springblade.transport.pojo.vo.ViolationRecordVO;
import java.math.BigDecimal;
import java.util.Objects;
/**
@@ -40,6 +41,9 @@ import java.util.Objects;
*/
public class ViolationRecordWrapper extends BaseEntityWrapper<ViolationRecord, ViolationRecordVO> {
private static final BigDecimal EMPTY_AMOUNT_SENTINEL = BigDecimal.valueOf(-1);
private static final Integer EMPTY_INTEGER_SENTINEL = -1;
public static ViolationRecordWrapper build() {
return new ViolationRecordWrapper();
}
@@ -47,8 +51,19 @@ public class ViolationRecordWrapper extends BaseEntityWrapper<ViolationRecord, V
@Override
public ViolationRecordVO entityVO(ViolationRecord violationRecord) {
ViolationRecordVO violationRecordVO = Objects.requireNonNull(BeanUtil.copyProperties(violationRecord, ViolationRecordVO.class));
// 未填写罚款/扣分的占位值 -1 对外展示为空
violationRecordVO.setFineAmount(normalizeEmptyAmount(violationRecordVO.getFineAmount()));
violationRecordVO.setDeductPoints(normalizeEmptyInteger(violationRecordVO.getDeductPoints()));
violationRecordVO.setUpdateUserName(UserCache.getUserRealName(violationRecord.getUpdateUser()));
return violationRecordVO;
}
private BigDecimal normalizeEmptyAmount(BigDecimal value) {
return value != null && value.compareTo(EMPTY_AMOUNT_SENTINEL) == 0 ? null : value;
}
private Integer normalizeEmptyInteger(Integer value) {
return value != null && value.equals(EMPTY_INTEGER_SENTINEL) ? null : value;
}
}
@@ -85,9 +85,10 @@ public class WaybillWrapper extends BaseEntityWrapper<Waybill, WaybillVO> {
case "pending" -> "待执行";
case "waiting_dispatch" -> "待调度";
case "dispatching" -> "调度中";
case "running" -> "进行中";
case "running", "processing", "in_progress", "inProgress" -> "进行中";
case "completed" -> "已完成";
case "cancelled" -> "已取消";
case "closed" -> "已关闭";
default -> "未知";
};
}
+3
View File
@@ -13,6 +13,9 @@ server:
#spring配置
spring:
codec:
# 运单批量导入等大 JSON / 失败明细导出场景,默认 256KB 会触发网关 500
max-in-memory-size: 20MB
servlet:
multipart:
max-file-size: 500MB
-1379
View File
File diff suppressed because it is too large Load Diff
-157
View File
@@ -1,157 +0,0 @@
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGBUS (0xa) at pc=0x0000000104d364c0, pid=22822, tid=5379
#
# JRE version: OpenJDK Runtime Environment Zulu17.44+15-CA (17.0.8+7) (build 17.0.8+7-LTS)
# Java VM: OpenJDK 64-Bit Server VM Zulu17.44+15-CA (17.0.8+7-LTS, mixed mode, emulated-client, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, bsd-aarch64)
# Problematic frame:
# C [libzip.dylib+0x64c0] newEntry+0x68
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
# http://www.azul.com/support/
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
--------------- S U M M A R Y ------------
Command Line: -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:54448,suspend=y,server=n -javaagent:/Users/liangxin/Library/Caches/JetBrains/IntelliJIdea2026.1/captureAgent/debugger-agent.jar=file:///var/folders/pk/drq93rk10q733kk02fgp89xh0000gn/T/capture14073385024433055703.props -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dmanagement.endpoints.jmx.exposure.include=* -Dkotlinx.coroutines.debug.enable.creation.stack.trace=false -Ddebugger.agent.enable.coroutines=true -Dkotlinx.coroutines.debug.enable.flows.stack.trace=true -Dkotlinx.coroutines.debug.enable.mutable.state.flows.stack.trace=true -Ddebugger.async.stack.trace.for.all.threads=true -Dfile.encoding=UTF-8 org.springblade.admin.AdminApplication
Host: "Mac15,6" arm64, 12 cores, 36G, Darwin 25.6.0, macOS 26.6.2 (25G83)
Time: Mon Sep 14 22:15:03 2026 CST elapsed time: 5.909458 seconds (0d 0h 0m 5s)
--------------- T H R E A D ---------------
Current thread (0x000000013601ac00): JavaThread "main" [_thread_in_native, id=5379, stack(0x000000016b250000,0x000000016b453000)]
Stack: [0x000000016b250000,0x000000016b453000], sp=0x000000016b450260, free space=2048k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libzip.dylib+0x64c0] newEntry+0x68
C [libzip.dylib+0x6390] ZIP_GetEntry2+0x14c
C [libzip.dylib+0x6d78] ZIP_FindEntry+0x3c
V [libjvm.dylib+0x25a408] ClassPathZipEntry::open_entry(JavaThread*, char const*, int*, bool)+0xb4
V [libjvm.dylib+0x25a53c] ClassPathZipEntry::open_stream(JavaThread*, char const*)+0x20
V [libjvm.dylib+0x25d918] ClassLoader::load_class(Symbol*, bool, JavaThread*)+0x150
V [libjvm.dylib+0x981d60] SystemDictionary::load_instance_class_impl(Symbol*, Handle, JavaThread*)+0x2d0
V [libjvm.dylib+0x98063c] SystemDictionary::load_instance_class(unsigned int, Symbol*, Handle, JavaThread*)+0x30
V [libjvm.dylib+0x97fd48] SystemDictionary::resolve_instance_class_or_null(Symbol*, Handle, Handle, JavaThread*)+0x4dc
V [libjvm.dylib+0x97f334] SystemDictionary::resolve_or_fail(Symbol*, Handle, Handle, bool, JavaThread*)+0x80
V [libjvm.dylib+0x2beb54] ConstantPool::klass_at_impl(constantPoolHandle const&, int, JavaThread*)+0x1e0
V [libjvm.dylib+0x46d6f0] InterpreterRuntime::_new(JavaThread*, ConstantPool*, int)+0x94
j com.intellij.rt.debugger.agent.CaptureStorage.createCapturedStack(Ljava/lang/Throwable;Lcom/intellij/rt/debugger/agent/CaptureStorage$CapturedStack;)Lcom/intellij/rt/debugger/agent/CaptureStorage$CapturedStack;+14
j com.intellij.rt.debugger.agent.CaptureStorage.access$500(Ljava/lang/Throwable;Lcom/intellij/rt/debugger/agent/CaptureStorage$CapturedStack;)Lcom/intellij/rt/debugger/agent/CaptureStorage$CapturedStack;+2
j com.intellij.rt.debugger.agent.CaptureStorage$3.run()V+75
j com.intellij.rt.debugger.agent.OverheadDetector$PerThread.runIfNoOverhead(Ljava/lang/Runnable;)Z+62
j com.intellij.rt.debugger.agent.CaptureStorage.runWithOverheadTrackingAndWithoutThrowableCapture(Lcom/intellij/rt/debugger/agent/CaptureStorage$ThreadLocalContext;Ljava/lang/Runnable;)Z+15
j com.intellij.rt.debugger.agent.CaptureStorage.capture(Ljava/lang/Object;)V+26
j java.util.concurrent.FutureTask.<init>(Ljava/util/concurrent/Callable;)V+5 java.base@17.0.8
j org.springframework.cglib.core.internal.LoadingCache.createEntry(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+27
j org.springframework.cglib.core.internal.LoadingCache.get(Ljava/lang/Object;)Ljava/lang/Object;+39
j org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(Lorg/springframework/cglib/core/AbstractClassGenerator;Z)Ljava/lang/Object;+11
j org.springframework.cglib.core.AbstractClassGenerator.create(Ljava/lang/Object;)Ljava/lang/Object;+115
j org.springframework.cglib.reflect.FastClass$Generator.create()Lorg/springframework/cglib/reflect/FastClass;+19
j org.springframework.cglib.proxy.MethodProxy.helper(Lorg/springframework/cglib/proxy/MethodProxy$CreateInfo;Ljava/lang/Class;)Lorg/springframework/cglib/reflect/FastClass;+54
j org.springframework.cglib.proxy.MethodProxy.init()V+40
j org.springframework.cglib.proxy.MethodProxy.create(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/springframework/cglib/proxy/MethodProxy;+80
j org.springframework.cloud.loadbalancer.config.BlockingLoadBalancerClientAutoConfiguration$BlockingLoadBalancerRetryConfig$$SpringCGLIB$$0.CGLIB$STATICHOOK1()V+112
j org.springframework.cloud.loadbalancer.config.BlockingLoadBalancerClientAutoConfiguration$BlockingLoadBalancerRetryConfig$$SpringCGLIB$$0.<clinit>()V+3
v ~StubRoutines::call_stub
V [libjvm.dylib+0x4781f8] JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x394
V [libjvm.dylib+0x457c84] InstanceKlass::call_class_initializer(JavaThread*)+0x1e8
V [libjvm.dylib+0x456f48] InstanceKlass::initialize_impl(JavaThread*)+0x65c
V [libjvm.dylib+0x51e020] JVM_FindClassFromCaller+0x340
C [libjava.dylib+0x3a6c] Java_java_lang_Class_forName0+0x138
J 1317 java.lang.Class.forName0(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class; java.base@17.0.8 (0 bytes) @ 0x000000010ed5306c [0x000000010ed52fc0+0x00000000000000ac]
V [libjvm.dylib+0x4715a0] InterpreterRuntime::resolve_from_cache(JavaThread*, Bytecodes::Code)+0x98
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j com.intellij.rt.debugger.agent.CaptureStorage.createCapturedStack(Ljava/lang/Throwable;Lcom/intellij/rt/debugger/agent/CaptureStorage$CapturedStack;)Lcom/intellij/rt/debugger/agent/CaptureStorage$CapturedStack;+14
j com.intellij.rt.debugger.agent.CaptureStorage.access$500(Ljava/lang/Throwable;Lcom/intellij/rt/debugger/agent/CaptureStorage$CapturedStack;)Lcom/intellij/rt/debugger/agent/CaptureStorage$CapturedStack;+2
j com.intellij.rt.debugger.agent.CaptureStorage$3.run()V+75
j com.intellij.rt.debugger.agent.OverheadDetector$PerThread.runIfNoOverhead(Ljava/lang/Runnable;)Z+62
j com.intellij.rt.debugger.agent.CaptureStorage.runWithOverheadTrackingAndWithoutThrowableCapture(Lcom/intellij/rt/debugger/agent/CaptureStorage$ThreadLocalContext;Ljava/lang/Runnable;)Z+15
j com.intellij.rt.debugger.agent.CaptureStorage.capture(Ljava/lang/Object;)V+26
j java.util.concurrent.FutureTask.<init>(Ljava/util/concurrent/Callable;)V+5 java.base@17.0.8
j org.springframework.cglib.core.internal.LoadingCache.createEntry(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+27
j org.springframework.cglib.core.internal.LoadingCache.get(Ljava/lang/Object;)Ljava/lang/Object;+39
j org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(Lorg/springframework/cglib/core/AbstractClassGenerator;Z)Ljava/lang/Object;+11
j org.springframework.cglib.core.AbstractClassGenerator.create(Ljava/lang/Object;)Ljava/lang/Object;+115
j org.springframework.cglib.reflect.FastClass$Generator.create()Lorg/springframework/cglib/reflect/FastClass;+19
j org.springframework.cglib.proxy.MethodProxy.helper(Lorg/springframework/cglib/proxy/MethodProxy$CreateInfo;Ljava/lang/Class;)Lorg/springframework/cglib/reflect/FastClass;+54
j org.springframework.cglib.proxy.MethodProxy.init()V+40
j org.springframework.cglib.proxy.MethodProxy.create(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/springframework/cglib/proxy/MethodProxy;+80
j org.springframework.cloud.loadbalancer.config.BlockingLoadBalancerClientAutoConfiguration$BlockingLoadBalancerRetryConfig$$SpringCGLIB$$0.CGLIB$STATICHOOK1()V+112
j org.springframework.cloud.loadbalancer.config.BlockingLoadBalancerClientAutoConfiguration$BlockingLoadBalancerRetryConfig$$SpringCGLIB$$0.<clinit>()V+3
v ~StubRoutines::call_stub
J 1317 java.lang.Class.forName0(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class; java.base@17.0.8 (0 bytes) @ 0x000000010ed5306c [0x000000010ed52fc0+0x00000000000000ac]
J 1432 c1 java.lang.Class.forName(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class; java.base@17.0.8 (47 bytes) @ 0x000000010ed807c8 [0x000000010ed806c0+0x0000000000000108]
j org.springframework.cglib.core.ReflectUtils.defineClass(Ljava/lang/String;[BLjava/lang/ClassLoader;Ljava/security/ProtectionDomain;Ljava/lang/Class;)Ljava/lang/Class;+460
j org.springframework.cglib.core.AbstractClassGenerator.generate(Lorg/springframework/cglib/core/AbstractClassGenerator$ClassLoaderData;)Ljava/lang/Class;+209
j org.springframework.cglib.proxy.Enhancer.generate(Lorg/springframework/cglib/core/AbstractClassGenerator$ClassLoaderData;)Ljava/lang/Class;+53
j org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.lambda$new$1(Lorg/springframework/cglib/core/AbstractClassGenerator;)Ljava/lang/Object;+2
j org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$$Lambda$857+0x00000070016c9418.apply(Ljava/lang/Object;)Ljava/lang/Object;+8
j org.springframework.cglib.core.internal.LoadingCache.lambda$createEntry$1(Ljava/lang/Object;)Ljava/lang/Object;+5
j org.springframework.cglib.core.internal.LoadingCache$$Lambda$859+0x00000070016c9a98.call()Ljava/lang/Object;+8
j java.util.concurrent.FutureTask.run$$$capture()V+39 java.base@17.0.8
j java.util.concurrent.FutureTask.run()V+5 java.base@17.0.8
j org.springframework.cglib.core.internal.LoadingCache.createEntry(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+56
j org.springframework.cglib.core.internal.LoadingCache.get(Ljava/lang/Object;)Ljava/lang/Object;+39
j org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(Lorg/springframework/cglib/core/AbstractClassGenerator;Z)Ljava/lang/Object;+11
j org.springframework.cglib.core.AbstractClassGenerator.create(Ljava/lang/Object;)Ljava/lang/Object;+115
j org.springframework.cglib.proxy.Enhancer.createHelper()Ljava/lang/Object;+102
j org.springframework.cglib.proxy.Enhancer.createClass()Ljava/lang/Class;+6
j org.springframework.context.annotation.ConfigurationClassEnhancer.createClass(Lorg/springframework/cglib/proxy/Enhancer;Z)Ljava/lang/Class;+1
j org.springframework.context.annotation.ConfigurationClassEnhancer.enhance(Ljava/lang/Class;Ljava/lang/ClassLoader;)Ljava/lang/Class;+134
j org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(Lorg/springframework/beans/factory/config/ConfigurableListableBeanFactory;)V+418
j org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(Lorg/springframework/beans/factory/config/ConfigurableListableBeanFactory;)V+78
j org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(Ljava/util/Collection;Lorg/springframework/beans/factory/config/ConfigurableListableBeanFactory;)V+61
j org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(Lorg/springframework/beans/factory/config/ConfigurableListableBeanFactory;Ljava/util/List;)V+521
j org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(Lorg/springframework/beans/factory/config/ConfigurableListableBeanFactory;)V+5
j org.springframework.context.support.AbstractApplicationContext.refresh()V+62
j org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh()V+1
j org.springframework.boot.SpringApplication.refresh(Lorg/springframework/context/ConfigurableApplicationContext;)V+1
j org.springframework.boot.SpringApplication.refreshContext(Lorg/springframework/context/ConfigurableApplicationContext;)V+19
j org.springframework.boot.SpringApplication.run([Ljava/lang/String;)Lorg/springframework/context/ConfigurableApplicationContext;+113
j org.springframework.boot.builder.SpringApplicationBuilder.run([Ljava/lang/String;)Lorg/springframework/context/ConfigurableApplicationContext;+38
j org.springblade.core.launch.BladeApplication.run(Ljava/lang/String;Ljava/lang/Class;[Ljava/lang/String;)Lorg/springframework/context/ConfigurableApplicationContext;+9
j org.springblade.admin.AdminApplication.main([Ljava/lang/String;)V+5
v ~StubRoutines::call_stub
siginfo: si_signo: 10 (SIGBUS), si_code: 1 (BUS_ADRALN), si_addr: 0x0000000104cfe958
Register to memory mapping:
x0=0x0000600001ebc820 points into unknown readable memory: 0x0000000000000000 | 00 00 00 00 00 00 00 00
x1=0x0 is NULL
x2=0xfffffffffffffff0 is an unknown value
x3=0x0000600001ebc830 points into unknown readable memory: 0x0000000000000000 | 00 00 00 00 00 00 00 00
x4=0x0000600001ebc880 points into unknown readable memory: 0x0000000000000000 | 00 00 00 00 00 00 00 00
x5=0x000000009b858ffb is an unknown value
x6=0x000000001ba00000 is an unknown value
x7=0x00000005c0183f80 is an oop: com.intellij.rt.debugger.agent.CaptureStorage$ConcurrentIdentityWeakHashMap$WeakKey
{0x00000005c0183f80} - klass: 'com/intellij/rt/debugger/agent/CaptureStorage$ConcurrentIdentityWeakHashMap$WeakKey'
- ---- fields (total size 4 words):
- private 'referent' 'Ljava/lang/Object;' @12 a 'java/lang/Thread'{0x00000005c0203dc0} (b80407b8)
- volatile 'queue' 'Ljava/lang/ref/ReferenceQueue;' @16 a 'java/lang/ref/ReferenceQueue'{0x00000005c0183ea0} (b80307d4)
- volatile 'next' 'Ljava/lang/ref/Reference;' @20 NULL (0)
- private transient 'discovered' 'Ljava/lang/ref/Reference;' @24 NULL (0)
- private final 'myHash' 'I' @28 897913732 (35851384)
x8=0x0000000104e2693c: getProcessHandle.procHandle+0x971c in /Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/lib/libjava.dylib at 0x0000000104e00000
x9=0x0000000000128000 is an unknown value
x10=0x0000600001ebc000 points into unknown readable memory: 0x4c2800498af20001 | 01 00 f2 8a 49 00 28 4c
x11=0x0000000000000820 is an unknown value
x12=0x0000000000000050 is an unknown value
x13=0x0000000000000001 is an unknown value
x14=0x00000000ffffff4e is an unknown value
x15=0x00000000000007fb is an unknown value
x16=0x00000001829fd030: __bzero+0 in /usr/lib/system/libsystem_platform.dylib at 0x00000001829fa000
x17=0x00000001f0a754a8 points into unknown readable memory: 0x00000001829fd030 | 30 d0 9f 82 01 00 00 00
x18=0x0 is NULL
x19=0x0000600001ebc820 points into unknown readable memory: 0x0000000000000000 | 00 00 00 00 00 00 00 00
x20=0x0 is NULL
x21=0x0000600000bf4240 points into unknown readable memory: 0x0000600001af00c0 | c0 00 af 01 00 60 00 00
x22=0x0000000104cfe93c points into unknown readable memory: 50 4b 01 02
x23=
-1375
View File
File diff suppressed because it is too large Load Diff
-1368
View File
File diff suppressed because it is too large Load Diff