feat(轮胎生命周期): 添加车牌号追溯功能并优化里程记录

- 新增批量查询接口用于获取轮胎安装记录的车牌号
- 在里程记录中增加车牌号字段并实现数据补全逻辑
- 优化轮胎详情页显示历史里程对应的车牌信息
master
zch 1 day ago
parent b9f48a2335
commit cb8d5cd039

@ -452,6 +452,7 @@
<div class="life-time" th:text="${seg.startTime == null ? '-' : #dates.format(seg.startTime, 'yyyy-MM-dd HH:mm:ss')}">-</div> <div class="life-time" th:text="${seg.startTime == null ? '-' : #dates.format(seg.startTime, 'yyyy-MM-dd HH:mm:ss')}">-</div>
</div> </div>
<div class="life-meta"> <div class="life-meta">
<div th:text="${#strings.isEmpty(seg.plateNumber) ? '车牌号:-' : '车牌号:' + seg.plateNumber}">车牌号:-</div>
<div th:text="${seg.endTime == null ? '卸下时间:-' : '卸下时间:' + #dates.format(seg.endTime, 'yyyy-MM-dd HH:mm:ss')}">卸下时间:-</div> <div th:text="${seg.endTime == null ? '卸下时间:-' : '卸下时间:' + #dates.format(seg.endTime, 'yyyy-MM-dd HH:mm:ss')}">卸下时间:-</div>
<div th:text="${seg.mileage == null ? '该程行驶里程:-' : '该程行驶里程:' + seg.mileage + ' km'}">该程行驶里程:-</div> <div th:text="${seg.mileage == null ? '该程行驶里程:-' : '该程行驶里程:' + seg.mileage + ' km'}">该程行驶里程:-</div>
<div th:text="${#strings.isEmpty(seg.patternDepth) ? '本程剩余花纹:-' : '本程剩余花纹:' + seg.patternDepth + ' mm'}">本程剩余花纹:-</div> <div th:text="${#strings.isEmpty(seg.patternDepth) ? '本程剩余花纹:-' : '本程剩余花纹:' + seg.patternDepth + ' mm'}">本程剩余花纹:-</div>

@ -26,10 +26,10 @@ public class CarLifecycleSummaryDTO implements Serializable
/** 所属车队名称由部门ID关联翻译而来前端直接展示。 */ /** 所属车队名称由部门ID关联翻译而来前端直接展示。 */
private String team; private String team;
/** 线路名称,车辆运营的公交/客运线路。 */ /** 线路名称 */
private String line; private String line;
/** 车型,例如:纯电动大巴、混合动力公交等字典值。 */ /** 车型 */
private String type; private String type;
/** /**

@ -42,8 +42,19 @@ public class RecordTyreMileage extends BaseEntity
@Excel(name = "花纹深度") @Excel(name = "花纹深度")
private String patternDepth; private String patternDepth;
/** 车牌号码快照:里程记录按卸胎时车辆归属追溯,避免后续轮胎换车后丢失历史车辆关系。 */
private String plateNumber;
private String recordId; private String recordId;
public String getPlateNumber() {
return plateNumber;
}
public void setPlateNumber(String plateNumber) {
this.plateNumber = plateNumber;
}
public String getRecordId() { public String getRecordId() {
return recordId; return recordId;
} }
@ -137,6 +148,8 @@ public class RecordTyreMileage extends BaseEntity
.append("mileage", getMileage()) .append("mileage", getMileage())
.append("plateNumber", getPlateNumber())
.append("createBy", getCreateBy()) .append("createBy", getCreateBy())
.append("createTime", getCreateTime()) .append("createTime", getCreateTime())

@ -94,4 +94,12 @@ public interface BaseTyreMapper
BaseTyre selectBaseTyreByKeyParam(BaseTyre baseTyre); BaseTyre selectBaseTyreByKeyParam(BaseTyre baseTyre);
int updateBaseTyreByEpc(BaseTyre baseTyre); int updateBaseTyreByEpc(BaseTyre baseTyre);
/**
* RFID
*
* @param tyreEpcs RFID
* @return
*/
List<BaseTyre> selectCarNoByTyreEpcs(List<String> tyreEpcs);
} }

@ -31,6 +31,7 @@ public interface RecordTyreInstallMapper
*/ */
public List<RecordTyreInstall> selectRecordTyreInstallList(RecordTyreInstall recordTyreInstall); public List<RecordTyreInstall> selectRecordTyreInstallList(RecordTyreInstall recordTyreInstall);
/** /**
* *
* *
@ -64,4 +65,13 @@ public interface RecordTyreInstallMapper
public int deleteRecordTyreInstallByIds(String[] ids); public int deleteRecordTyreInstallByIds(String[] ids);
RecordTyreInstall selectRecordTyreInstallStart(RecordTyreInstall start); RecordTyreInstall selectRecordTyreInstallStart(RecordTyreInstall start);
/**
*
*
* @param recordIds
* @return
*/
public List<RecordTyreInstall> selectCarNoByRecordIds(List<String> recordIds);
} }

@ -355,6 +355,9 @@ public class BaseTyreServiceImpl implements IBaseTyreService
return map; return map;
} }
// 10. 老数据可能未写 record_tyre_mileage.plate_number按需补查车牌避免页面层猜测或全量查询。
fillMissingMileagePlateNumber(mileageList);
// 10. 解析初始花纹深度,并计算各段磨损量 // 10. 解析初始花纹深度,并计算各段磨损量
BigDecimal initialDepth = TyreLifecycleCalc.parseDepth(resultBase.getPatternDepth()); BigDecimal initialDepth = TyreLifecycleCalc.parseDepth(resultBase.getPatternDepth());
Map<Long, String> wearMap = TyreLifecycleCalc.computeSegmentWears(initialDepth, mileageList); Map<Long, String> wearMap = TyreLifecycleCalc.computeSegmentWears(initialDepth, mileageList);
@ -385,6 +388,7 @@ public class BaseTyreServiceImpl implements IBaseTyreService
vo.put("remark", item.getRemark()); // 备注信息 vo.put("remark", item.getRemark()); // 备注信息
vo.put("tyreBrand", item.getTyreBrand()); // 轮胎品牌 vo.put("tyreBrand", item.getTyreBrand()); // 轮胎品牌
vo.put("tyreNo", item.getTyreNo()); // 轮胎编号 vo.put("tyreNo", item.getTyreNo()); // 轮胎编号
vo.put("plateNumber", item.getPlateNumber()); // 卸胎时的车牌快照,用于详情页按里程段追溯车辆归属
vo.put("wearDepth", item.getId() == null ? null : wearMap.get(item.getId())); // 磨损深度(从计算结果取) vo.put("wearDepth", item.getId() == null ? null : wearMap.get(item.getId())); // 磨损深度(从计算结果取)
// 14. 累加有效里程值mileage 为 Long 类型,表示该段 km 差值) // 14. 累加有效里程值mileage 为 Long 类型,表示该段 km 差值)
if (item.getMileage() != null) if (item.getMileage() != null)
@ -403,6 +407,8 @@ public class BaseTyreServiceImpl implements IBaseTyreService
return map; return map;
} }
private List<RecordTyreInstall> castInstallList(Object value) private List<RecordTyreInstall> castInstallList(Object value)
{ {
// 1. 初始化空结果列表,用于存放转换后的安装记录 // 1. 初始化空结果列表,用于存放转换后的安装记录
@ -423,4 +429,79 @@ public class BaseTyreServiceImpl implements IBaseTyreService
// 4. 返回类型安全的安装记录列表 // 4. 返回类型安全的安装记录列表
return result; return result;
} }
// 轮胎生命周期里程记录填充车牌号
private void fillMissingMileagePlateNumber(List<RecordTyreMileage> mileageList)
{
Set<String> recordIdSet = new LinkedHashSet<>();
for (RecordTyreMileage item : mileageList)
{
if (item != null && StringUtils.isBlank(item.getPlateNumber()) && !StringUtils.isBlank(item.getRecordId()))
{
recordIdSet.add(item.getRecordId());
}
}
if (!recordIdSet.isEmpty())
{
List<RecordTyreInstall> installList = recordTyreInstallMapper.selectCarNoByRecordIds(new ArrayList<>(recordIdSet));
Map<String, String> recordIdCarNoMap = new HashMap<>();
if (installList != null && !installList.isEmpty())
{
for (RecordTyreInstall install : installList)
{
if (install != null && !StringUtils.isBlank(install.getRecordId()) && !StringUtils.isBlank(install.getCarNo()))
{
recordIdCarNoMap.put(install.getRecordId(), install.getCarNo());
}
}
}
for (RecordTyreMileage item : mileageList)
{
if (item != null && StringUtils.isBlank(item.getPlateNumber()) && !StringUtils.isBlank(item.getRecordId()))
{
// record_id 对应卸胎当次装卸记录,优先使用它保留历史车辆归属,不被轮胎后续换车影响。
item.setPlateNumber(recordIdCarNoMap.get(item.getRecordId()));
}
}
}
Set<String> tyreRfidSet = new LinkedHashSet<>();
for (RecordTyreMileage item : mileageList)
{
if (item != null && StringUtils.isBlank(item.getPlateNumber()) && !StringUtils.isBlank(item.getTyreRfid()))
{
tyreRfidSet.add(item.getTyreRfid());
}
}
if (tyreRfidSet.isEmpty())
{
return;
}
List<BaseTyre> tyreList = baseTyreMapper.selectCarNoByTyreEpcs(new ArrayList<>(tyreRfidSet));
if (tyreList == null || tyreList.isEmpty())
{
return;
}
Map<String, String> tyreRfidCarNoMap = new HashMap<>();
for (BaseTyre tyre : tyreList)
{
if (tyre != null && !StringUtils.isBlank(tyre.getTyreEpc()) && !StringUtils.isBlank(tyre.getCarNo()))
{
tyreRfidCarNoMap.put(tyre.getTyreEpc(), tyre.getCarNo());
}
}
for (RecordTyreMileage item : mileageList)
{
if (item != null && StringUtils.isBlank(item.getPlateNumber()) && !StringUtils.isBlank(item.getTyreRfid()))
{
// tyre_rfid 只作为历史记录缺 record_id 时的兜底,按当前轮胎基础信息补齐展示字段。
item.setPlateNumber(tyreRfidCarNoMap.get(item.getTyreRfid()));
}
}
}
} }

@ -173,6 +173,8 @@ public class RecordTyreInstallServiceImpl implements IRecordTyreInstallService
recordTyreMileage.setCreateTime(DateUtils.getNowDate()); recordTyreMileage.setCreateTime(DateUtils.getNowDate());
recordTyreMileage.setCreateBy(recordTyreInstall.getCreateBy()); recordTyreMileage.setCreateBy(recordTyreInstall.getCreateBy());
recordTyreMileage.setRecordId(recordId); recordTyreMileage.setRecordId(recordId);
// 车牌号按卸胎当下车辆归属写入里程快照,避免轮胎后续换车后历史里程记录无法追溯车辆。
// recordTyreMileage.setPlateNumber(recordTyreInstall.getCarNo());
recordTyreMileageMapper.insertRecordTyreMileage(recordTyreMileage); recordTyreMileageMapper.insertRecordTyreMileage(recordTyreMileage);
if (n>0&&m>0){ if (n>0&&m>0){
return AjaxResult.success("卸胎成功!"); return AjaxResult.success("卸胎成功!");

@ -118,6 +118,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where> </where>
</select> </select>
<select id="getTeamByUser" resultType="java.lang.String"> <select id="getTeamByUser" resultType="java.lang.String">
SELECT SELECT
dept_name dept_name
@ -294,4 +296,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where inbound_code = #{inboundCode} where inbound_code = #{inboundCode}
</select> </select>
<select id="selectCarNoByTyreEpcs" parameterType="java.util.List" resultMap="BaseTyreResult">
select tyre_epc, car_no
from base_tyre
where car_no is not null
and car_no != ''
and tyre_epc in
<foreach item="tyreEpc" collection="list" open="(" separator="," close=")">
#{tyreEpc}
</foreach>
</select>
</mapper> </mapper>

@ -25,6 +25,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="company" column="company" /> <result property="company" column="company" />
<result property="carTeam" column="carTeam" /> <result property="carTeam" column="carTeam" />
<result property="stageMileage" column="stage_mileage" /> <result property="stageMileage" column="stage_mileage" />
<result property="recordId" column="record_id" />
</resultMap> </resultMap>
<sql id="selectRecordTyreInstallVo"> <sql id="selectRecordTyreInstallVo">
@ -57,6 +58,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
${params.dataScope} ${params.dataScope}
</select> </select>
<select id="selectRecordTyreInstallById" parameterType="Long" resultMap="RecordTyreInstallResult"> <select id="selectRecordTyreInstallById" parameterType="Long" resultMap="RecordTyreInstallResult">
select rti.id, rti.tyre_rfid, rti.type, rti.mileage, rti.create_by, rti.create_time, rti.update_by, rti.update_time, select rti.id, rti.tyre_rfid, rti.type, rti.mileage, rti.create_by, rti.create_time, rti.update_by, rti.update_time,
rti.remark,rti.car_no,rti.wheel_postion,bt.tyre_no,bt.self_no from record_tyre_install rti rti.remark,rti.car_no,rti.wheel_postion,bt.tyre_no,bt.self_no from record_tyre_install rti
@ -138,4 +140,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</foreach> </foreach>
</delete> </delete>
<select id="selectCarNoByRecordIds" parameterType="java.util.List" resultMap="RecordTyreInstallResult">
select record_id, car_no
from record_tyre_install
where car_no is not null
and car_no != ''
and record_id in
<foreach item="recordId" collection="list" open="(" separator="," close=")">
#{recordId}
</foreach>
</select>
</mapper> </mapper>

@ -18,15 +18,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="tyreBrand" column="tyre_brand" /> <result property="tyreBrand" column="tyre_brand" />
<result property="tyreNo" column="tyre_no" /> <result property="tyreNo" column="tyre_no" />
<result property="patternDepth" column="pattern_depth" /> <result property="patternDepth" column="pattern_depth" />
<result property="plateNumber" column="plate_number" />
<result property="recordId" column="record_id" />
</resultMap> </resultMap>
<sql id="selectRecordTyreMileageVo"> <sql id="selectRecordTyreMileageVo">
select id, tyre_rfid, start_time, end_time, mileage, pattern_depth, create_by, create_time, update_by, update_time, remark from record_tyre_mileage select id, tyre_rfid, start_time, end_time, mileage, pattern_depth, plate_number, record_id, create_by, create_time, update_by, update_time, remark from record_tyre_mileage
</sql> </sql>
<select id="selectRecordTyreMileageList" parameterType="RecordTyreMileage" resultMap="RecordTyreMileageResult"> <select id="selectRecordTyreMileageList" parameterType="RecordTyreMileage" resultMap="RecordTyreMileageResult">
select rtm.id, rtm.tyre_rfid, rtm.start_time, rtm.end_time, rtm.mileage, rtm.pattern_depth, select rtm.id, rtm.tyre_rfid, rtm.start_time, rtm.end_time, rtm.mileage, rtm.pattern_depth,
rtm.create_by, rtm.create_time, rtm.update_by, rtm.update_time, rtm.remark,bt.tyre_brand,bt.tyre_no rtm.create_by, rtm.create_time, rtm.update_by, rtm.update_time, rtm.remark, rtm.plate_number, rtm.record_id, bt.tyre_brand, bt.tyre_no
from record_tyre_mileage rtm from record_tyre_mileage rtm
LEFT JOIN base_tyre bt ON rtm.tyre_rfid = bt.tyre_epc LEFT JOIN base_tyre bt ON rtm.tyre_rfid = bt.tyre_epc
where rtm.id is not null where rtm.id is not null
@ -58,6 +60,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="updateTime != null ">update_time,</if> <if test="updateTime != null ">update_time,</if>
<if test="remark != null and remark != ''">remark,</if> <if test="remark != null and remark != ''">remark,</if>
<if test="patternDepth != null ">pattern_depth,</if> <if test="patternDepth != null ">pattern_depth,</if>
<if test="plateNumber != null and plateNumber != ''">plate_number,</if>
<if test="recordId != null ">record_id,</if> <if test="recordId != null ">record_id,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
@ -72,6 +75,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="updateTime != null ">#{updateTime},</if> <if test="updateTime != null ">#{updateTime},</if>
<if test="remark != null and remark != ''">#{remark},</if> <if test="remark != null and remark != ''">#{remark},</if>
<if test="patternDepth != null and patternDepth != ''">#{patternDepth},</if> <if test="patternDepth != null and patternDepth != ''">#{patternDepth},</if>
<if test="plateNumber != null and plateNumber != ''">#{plateNumber},</if>
<if test="recordId != null and recordId != ''">#{recordId},</if> <if test="recordId != null and recordId != ''">#{recordId},</if>
</trim> </trim>
</insert> </insert>
@ -88,6 +92,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
<if test="updateTime != null ">update_time = #{updateTime},</if> <if test="updateTime != null ">update_time = #{updateTime},</if>
<if test="patternDepth != null ">pattern_depth = #{patternDepth},</if> <if test="patternDepth != null ">pattern_depth = #{patternDepth},</if>
<if test="plateNumber != null and plateNumber != ''">plate_number = #{plateNumber},</if>
<if test="remark != null and remark != ''">remark = #{remark},</if> <if test="remark != null and remark != ''">remark = #{remark},</if>
</trim> </trim>
where id = #{id} where id = #{id}

Loading…
Cancel
Save