@ -33,7 +33,7 @@ import static com.ruoyi.common.utils.ShiroUtils.getLoginName;
/ * *
* 轮 胎 基 础 信 息 Service 业 务 层 处 理
*
*
* @author highway
* @date 2025 - 12 - 16
* /
@ -60,7 +60,7 @@ public class BaseTyreServiceImpl implements IBaseTyreService
/ * *
* 查 询 轮 胎 基 础 信 息
*
*
* @param tyreId 轮 胎 基 础 信 息 ID
* @return 轮 胎 基 础 信 息
* /
@ -72,7 +72,7 @@ public class BaseTyreServiceImpl implements IBaseTyreService
/ * *
* 查 询 轮 胎 基 础 信 息 列 表
*
*
* @param baseTyre 轮 胎 基 础 信 息
* @return 轮 胎 基 础 信 息
* /
@ -85,7 +85,7 @@ public class BaseTyreServiceImpl implements IBaseTyreService
/ * *
* 新 增 轮 胎 基 础 信 息
*
*
* @param baseTyre 轮 胎 基 础 信 息
* @return 结 果
* /
@ -125,7 +125,7 @@ public class BaseTyreServiceImpl implements IBaseTyreService
/ * *
* 修 改 轮 胎 基 础 信 息
*
*
* @param baseTyre 轮 胎 基 础 信 息
* @return 结 果
* /
@ -260,7 +260,7 @@ public class BaseTyreServiceImpl implements IBaseTyreService
@Override
@DataScope ( deptAlias = "d" , userAlias = "u" )
public List < Map > vTyreStockSummary ( SysDept sysDept ) {
List < Map > mapList = baseTyreMapper . vTyreStockSummary ( sysDept ) ;
List < Map > mapList = baseTyreMapper . vTyreStockSummary ( sysDept ) ;
return mapList ;
}
@ -331,6 +331,8 @@ public class BaseTyreServiceImpl implements IBaseTyreService
// 3. 初始化里程相关字段默认值,确保返回结构完整
map . put ( "recordTyreMileageList" , new ArrayList < > ( ) ) ;
map . put ( "maintenanceMileageList" , new ArrayList < > ( ) ) ;
map . put ( "bizMaintenanceOrderList" , new ArrayList < > ( ) ) ;
map . put ( "totalMileage" , null ) ;
map . put ( "currentPatternDepth" , null ) ;
@ -350,42 +352,59 @@ public class BaseTyreServiceImpl implements IBaseTyreService
// 原 PDA 方法历史上会在 EPC 为空时按空条件查流转表; Web 详情必须置空,避免误把全量历史展示给用户。
map . put ( "recordWarehousingList" , new ArrayList < > ( ) ) ;
map . put ( "recordTyreInstallList" , new ArrayList < > ( ) ) ;
map . put ( "bizMaintenanceOrder" , null ) ;
return map ;
}
// 7. 转换安装记录列表并计算当前花纹深度
List < RecordTyreInstall > installList = castInstallList ( map . get ( "recordTyreInstallList" ) ) ;
map . put ( "currentPatternDepth" , TyreLifecycleCalc . currentPatternDepth ( installList ) ) ;
// 7. Web 详情按“保养”记录作为花纹口径,避免装卸记录和维保记录混用导致当前花纹漂移。
List < String > recentMaintenanceDepthList = baseTyreMapper . selectRecentMaintenancePatternDepthByRFID ( tyreRfid ) ;
if ( ! StringUtils . isEmpty ( recentMaintenanceDepthList ) )
{
map . put ( "currentPatternDepth" , normalizeDepthText ( recentMaintenanceDepthList . get ( 0 ) ) ) ;
}
List < RecordTyreMileage > maintenanceMileageList = baseTyreMapper . selectMaintenanceMileageListByRFID ( tyreRfid ) ;
if ( maintenanceMileageList ! = null & & ! maintenanceMileageList . isEmpty ( ) )
{
fillMissingMileagePlateNumber ( maintenanceMileageList ) ;
}
map . put ( "maintenanceMileageList" , buildMaintenanceMileageVoList ( maintenanceMileageList ) ) ;
putMaintenanceOrderList ( map , resultBase ) ;
// 8. 构造里程查询对象并执行查询
// 8. 轮胎总行驶里程直接由 Mapper 聚合 record_tyre_mileage.mileage, 不按 record_type 过滤。
BigDecimal totalMileage = baseTyreMapper . selectTotalMileageByRFID ( tyreRfid ) ;
map . put ( "totalMileage" , totalMileage = = null ? null : totalMileage . stripTrailingZeros ( ) . toPlainString ( ) ) ;
// 9. 构造里程查询对象并执行查询
RecordTyreMileage query = new RecordTyreMileage ( ) ;
query . setTyreRfid ( tyreRfid ) ;
List < RecordTyreMileage > mileageList = recordTyreMileageMapper . selectRecordTyreMileageList ( query ) ;
// 9. 若无里程记录,直接返回当前已组装的数据
// 10 . 若无里程记录,直接返回当前已组装的数据
if ( mileageList = = null | | mileageList . isEmpty ( ) )
{
return map ;
}
// 1 0 . 老数据可能未写 record_tyre_mileage.plate_number, 按需补查车牌, 避免页面层猜测或全量查询。
// 1 1 . 老数据可能未写 record_tyre_mileage.plate_number, 按需补查车牌, 避免页面层猜测或全量查询。
fillMissingMileagePlateNumber ( mileageList ) ;
// 1 0 . 解析初始花纹深度,并计算各段磨损量
// 1 2 . 解析初始花纹深度,并计算各段磨损量
BigDecimal initialDepth = TyreLifecycleCalc . parseDepth ( resultBase . getPatternDepth ( ) ) ;
Map < Long , String > wearMap = TyreLifecycleCalc . computeSegmentWears ( initialDepth , mileageList ) ;
// 11. 初始化总里程累加器和标志位
BigDecimal totalMileage = BigDecimal . ZERO ;
boolean hasMileage = false ;
// 1 2 . 按开始时间降序、ID 降序对里程记录排序,确保时间线正确
// 13. 按开始时间降序、ID 降序对里程记录排序,确保时间线正确
mileageList . sort ( Comparator
. comparing ( RecordTyreMileage : : getStartTime , Comparator . nullsLast ( Comparator . reverseOrder ( ) ) )
. thenComparing ( RecordTyreMileage : : getId , Comparator . nullsLast ( Comparator . reverseOrder ( ) ) ) ) ;
// 1 3 . 遍历里程记录,构造前端展示用的 VO 列表
// 1 4 . 遍历里程记录,构造前端展示用的 VO 列表
List < Map < String , Object > > mileageVoList = new ArrayList < > ( mileageList . size ( ) ) ;
for ( RecordTyreMileage item : mileageList )
{
if ( "保养" . equals ( item . getRecordType ( ) ) )
{
// 保养记录已在“保养记录”生命周期块按花纹磨损口径单独展示,避免同一条记录在里程块重复出现。
continue ;
}
Map < String , Object > vo = new HashMap < > ( ) ;
vo . put ( "id" , item . getId ( ) ) ; // 记录主键
vo . put ( "tyreRfid" , item . getTyreRfid ( ) ) ; // 轮胎 RFID
@ -401,24 +420,168 @@ public class BaseTyreServiceImpl implements IBaseTyreService
vo . put ( "tyreBrand" , item . getTyreBrand ( ) ) ; // 轮胎品牌
vo . put ( "tyreNo" , item . getTyreNo ( ) ) ; // 轮胎编号
vo . put ( "plateNumber" , item . getPlateNumber ( ) ) ; // 卸胎时的车牌快照,用于详情页按里程段追溯车辆归属
vo . put ( "recordType" , item . getRecordType ( ) ) ; // 记录类型,便于页面区分装胎、卸胎、保养来源
vo . put ( "wearDepth" , item . getId ( ) = = null ? null : wearMap . get ( item . getId ( ) ) ) ; // 磨损深度(从计算结果取)
// 14. 累加有效里程值( mileage 为 Long 类型,表示该段 km 差值)
if ( item . getMileage ( ) ! = null )
{
// mileage 实体类型是 Long, 表示该程 km 差值,直接累加可避免 varchar 花纹解析逻辑误入里程路径。
totalMileage = totalMileage . add ( BigDecimal . valueOf ( item . getMileage ( ) ) ) ;
hasMileage = true ;
}
mileageVoList . add ( vo ) ;
}
// 15. 将组装好的里程列表 和总里程 写入返回 Map
// 15. 将组装好的里程列表写入返回 Map
map . put ( "recordTyreMileageList" , mileageVoList ) ;
map . put ( "totalMileage" , hasMileage ? totalMileage . stripTrailingZeros ( ) . toPlainString ( ) : null ) ;
// 16. 返回完整的轮胎详情数据
return map ;
}
private List < Map < String , Object > > buildMaintenanceMileageVoList ( List < RecordTyreMileage > maintenanceMileageList )
{
List < Map < String , Object > > voList = new ArrayList < > ( ) ;
if ( maintenanceMileageList = = null | | maintenanceMileageList . isEmpty ( ) )
{
return voList ;
}
Map < Long , String > wearMap = computeMaintenanceWearMap ( maintenanceMileageList ) ;
List < RecordTyreMileage > sortedList = new ArrayList < > ( ) ;
for ( RecordTyreMileage item : maintenanceMileageList )
{
if ( item ! = null )
{
sortedList . add ( item ) ;
}
}
sortedList . sort ( Comparator
. comparing ( this : : maintenanceRecordTime , Comparator . nullsLast ( Comparator . reverseOrder ( ) ) )
. thenComparing ( RecordTyreMileage : : getId , Comparator . nullsLast ( Comparator . reverseOrder ( ) ) ) ) ;
for ( RecordTyreMileage item : sortedList )
{
Map < String , Object > vo = new HashMap < > ( ) ;
vo . put ( "id" , item . getId ( ) ) ;
vo . put ( "tyreRfid" , item . getTyreRfid ( ) ) ;
vo . put ( "startTime" , item . getStartTime ( ) ) ;
vo . put ( "endTime" , item . getEndTime ( ) ) ;
vo . put ( "mileage" , item . getMileage ( ) ) ;
vo . put ( "patternDepth" , normalizeDepthText ( item . getPatternDepth ( ) ) ) ;
vo . put ( "plateNumber" , item . getPlateNumber ( ) ) ;
vo . put ( "recordId" , item . getRecordId ( ) ) ;
vo . put ( "recordType" , item . getRecordType ( ) ) ;
vo . put ( "createBy" , item . getCreateBy ( ) ) ;
vo . put ( "createTime" , item . getCreateTime ( ) ) ;
vo . put ( "updateBy" , item . getUpdateBy ( ) ) ;
vo . put ( "updateTime" , item . getUpdateTime ( ) ) ;
vo . put ( "remark" , item . getRemark ( ) ) ;
// 磨损数只比较当前保养和上一条“有效花纹”保养,空值/脏值不参与,避免把异常录入放大到页面。
vo . put ( "wearDepth" , item . getId ( ) = = null ? null : wearMap . get ( item . getId ( ) ) ) ;
voList . add ( vo ) ;
}
return voList ;
}
private Map < Long , String > computeMaintenanceWearMap ( List < RecordTyreMileage > maintenanceMileageList )
{
Map < Long , String > wearMap = new HashMap < > ( ) ;
List < RecordTyreMileage > sortedList = new ArrayList < > ( ) ;
for ( RecordTyreMileage item : maintenanceMileageList )
{
if ( item ! = null )
{
sortedList . add ( item ) ;
}
}
sortedList . sort ( Comparator
. comparing ( this : : maintenanceRecordTime , Comparator . nullsLast ( Comparator . naturalOrder ( ) ) )
. thenComparing ( RecordTyreMileage : : getId , Comparator . nullsLast ( Comparator . naturalOrder ( ) ) ) ) ;
BigDecimal previousDepth = null ;
for ( RecordTyreMileage item : sortedList )
{
BigDecimal currentDepth = TyreLifecycleCalc . parseDepth ( item . getPatternDepth ( ) ) ;
if ( currentDepth = = null )
{
continue ;
}
if ( previousDepth ! = null & & item . getId ( ) ! = null )
{
wearMap . put ( item . getId ( ) , formatDecimal ( previousDepth . subtract ( currentDepth ) ) ) ;
}
previousDepth = currentDepth ;
}
return wearMap ;
}
private void putMaintenanceOrderList ( Map map , BaseTyre resultBase )
{
if ( resultBase . getTyreId ( ) = = null )
{
map . put ( "bizMaintenanceOrder" , null ) ;
return ;
}
BizOrderTireDetail query = new BizOrderTireDetail ( ) ;
query . setTireId ( resultBase . getTyreId ( ) ) ;
List < BizOrderTireDetail > detailList = bizOrderTireDetailMapper . selectBizOrderTireDetailList ( query ) ;
if ( detailList = = null | | detailList . isEmpty ( ) )
{
map . put ( "bizMaintenanceOrder" , null ) ;
return ;
}
Map < Long , List < BizOrderTireDetail > > detailMap = new LinkedHashMap < > ( ) ;
for ( BizOrderTireDetail detail : detailList )
{
if ( detail ! = null & & detail . getOrderId ( ) ! = null )
{
detailMap . computeIfAbsent ( detail . getOrderId ( ) , key - > new ArrayList < > ( ) ) . add ( detail ) ;
}
}
List < BizMaintenanceOrder > orderList = new ArrayList < > ( ) ;
for ( Map . Entry < Long , List < BizOrderTireDetail > > entry : detailMap . entrySet ( ) )
{
BizMaintenanceOrder order = bizMaintenanceOrderMapper . selectBizMaintenanceOrderByOrderId ( entry . getKey ( ) ) ;
if ( order = = null )
{
continue ;
}
order . setBizOrderTireDetailList ( entry . getValue ( ) ) ;
if ( order . getLastMileage ( ) = = null )
{
order . setLastMileage ( BigDecimal . ZERO ) ;
}
orderList . add ( order ) ;
}
orderList . sort ( Comparator
. comparing ( BizMaintenanceOrder : : getMaintainDate , Comparator . nullsLast ( Comparator . reverseOrder ( ) ) )
. thenComparing ( BizMaintenanceOrder : : getOrderId , Comparator . nullsLast ( Comparator . reverseOrder ( ) ) ) ) ;
map . put ( "bizMaintenanceOrderList" , orderList ) ;
// 保留旧 key 便于已有模板或脚本兜底,但 Web 新模板会按列表展示全部维保工单。
map . put ( "bizMaintenanceOrder" , orderList . isEmpty ( ) ? null : orderList . get ( 0 ) ) ;
}
private Date maintenanceRecordTime ( RecordTyreMileage item )
{
if ( item = = null )
{
return null ;
}
// 保养记录的“最新”优先按创建时间判定;历史补录缺 create_time 时再退回业务开始时间。
return item . getCreateTime ( ) ! = null ? item . getCreateTime ( ) : item . getStartTime ( ) ;
}
private String normalizeDepthText ( String value )
{
if ( StringUtils . isBlank ( value ) )
{
return null ;
}
return value . trim ( ) ;
}
private String formatDecimal ( BigDecimal value )
{
return value = = null ? null : value . stripTrailingZeros ( ) . toPlainString ( ) ;
}
private List < RecordTyreInstall > castInstallList ( Object value )