feat(tyre): 新增轮胎报废管理功能,优化维保工单与生命周期展示
1. 新增轮胎报废查询页面与控制器,仅读取PDA落库的报废事实 2. 扩展维保类型枚举,新增抢碎修、小修、轮胎修补/报废类型 3. 重构车辆生命周期里程计算逻辑,修复历史里程显示异常 4. 优化工单详情页渲染,支持空工单空态提示,修复轮位展示逻辑 5. 新增维保前后轮胎快照查询接口,优化工单校验逻辑 6. 完善轮胎生命周期页面,展示报废记录与关联照片 7. 修复订单查询条件与映射逻辑,修正部分页面API路径master
parent
16a9178708
commit
8314e1b94f
@ -0,0 +1,283 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
|
||||
<head>
|
||||
<th:block th:include="include :: header('轮胎报废查询')" />
|
||||
<style>
|
||||
.scrap-photo-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.scrap-photo-item {
|
||||
width: 150px;
|
||||
border: 1px solid #e7eaec;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scrap-photo-item img {
|
||||
width: 150px;
|
||||
height: 110px;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.scrap-photo-name {
|
||||
padding: 6px 8px;
|
||||
color: #676a6c;
|
||||
font-size: 12px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.scrap-photo-empty {
|
||||
padding: 48px 16px;
|
||||
color: #999;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="gray-bg">
|
||||
<div class="container-div">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 search-collapse">
|
||||
<form id="formId">
|
||||
<div class="select-list">
|
||||
<ul>
|
||||
<li>
|
||||
<label>工单编号:</label>
|
||||
<input type="text" name="orderNo"/>
|
||||
</li>
|
||||
<li>
|
||||
<label>车牌号码:</label>
|
||||
<input type="text" name="plateNumber"/>
|
||||
</li>
|
||||
<li>
|
||||
<label>胎号:</label>
|
||||
<input type="text" name="tyreNo"/>
|
||||
</li>
|
||||
<li>
|
||||
<label>轮胎编号:</label>
|
||||
<input type="text" name="tireCode"/>
|
||||
</li>
|
||||
<li>
|
||||
<label>工单类型:</label>
|
||||
<select name="typeCode" th:with="type=${@dict.getType('main_type')}">
|
||||
<option value="">所有</option>
|
||||
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
|
||||
</select>
|
||||
</li>
|
||||
<li>
|
||||
<label>工单状态:</label>
|
||||
<select name="orderStatus" th:with="type=${@dict.getType('order_status')}">
|
||||
<option value="">所有</option>
|
||||
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
|
||||
</select>
|
||||
</li>
|
||||
<li>
|
||||
<label>维修站点:</label>
|
||||
<input type="text" name="factoryName"/>
|
||||
</li>
|
||||
<li class="select-time">
|
||||
<label>报废时间: </label>
|
||||
<input type="text" class="time-input" id="startTime" placeholder="开始时间" name="params[beginTime]"/>
|
||||
<span>-</span>
|
||||
<input type="text" class="time-input" id="endTime" placeholder="结束时间" name="params[endTime]"/>
|
||||
</li>
|
||||
<li>
|
||||
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i> 搜索</a>
|
||||
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i> 重置</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="btn-group-sm" id="toolbar" role="group">
|
||||
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="tyre:scrap:export">
|
||||
<i class="fa fa-download"></i> 导出
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-sm-12 select-table table-striped">
|
||||
<table id="bootstrap-table"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
<script th:inline="javascript">
|
||||
var typeCodeDatas = [[${@dict.getType('main_type')}]];
|
||||
var statusDatas = [[${@dict.getType('order_status')}]];
|
||||
var prefix = ctx + "tyre/scrap";
|
||||
|
||||
$(function() {
|
||||
var options = {
|
||||
url: prefix + "/list",
|
||||
exportUrl: prefix + "/export",
|
||||
modalName: "轮胎报废查询",
|
||||
columns: [{
|
||||
checkbox: true
|
||||
},
|
||||
{
|
||||
field: 'detailId',
|
||||
title: '明细ID',
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
field: 'scrapTime',
|
||||
title: '报废时间',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
field: 'orderNo',
|
||||
title: '工单编号'
|
||||
},
|
||||
{
|
||||
field: 'typeCode',
|
||||
title: '工单类型',
|
||||
formatter: function(value) {
|
||||
return $.table.selectDictLabel(typeCodeDatas, value);
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'orderStatus',
|
||||
title: '工单状态',
|
||||
formatter: function(value) {
|
||||
return $.table.selectDictLabel(statusDatas, value);
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'plateNumber',
|
||||
title: '车牌号码'
|
||||
},
|
||||
{
|
||||
field: 'tyreNo',
|
||||
title: '胎号',
|
||||
formatter: function(value, row) {
|
||||
var text = $.common.isEmpty(value) ? row.tireCode : value;
|
||||
if ($.common.isEmpty(row.tireId)) {
|
||||
return $.common.nullToStr(text);
|
||||
}
|
||||
return '<a href="javascript:void(0)" onclick="openTyreDetail(\'' + row.tireId + '\')">' + escapeHtml(text) + '</a>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'selfNo',
|
||||
title: '自编号'
|
||||
},
|
||||
{
|
||||
field: 'tyreBrand',
|
||||
title: '品牌'
|
||||
},
|
||||
{
|
||||
field: 'tyreModel',
|
||||
title: '规格'
|
||||
},
|
||||
{
|
||||
field: 'positionName',
|
||||
title: '轮位'
|
||||
},
|
||||
{
|
||||
field: 'treadDepth',
|
||||
title: '报废前花纹',
|
||||
formatter: function(value) {
|
||||
return $.common.isEmpty(value) ? '-' : value + ' mm';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'inputMileage',
|
||||
title: '报废时里程',
|
||||
formatter: function(value) {
|
||||
return $.common.isEmpty(value) ? '-' : value + ' km';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'factoryName',
|
||||
title: '维修站点'
|
||||
},
|
||||
{
|
||||
field: 'photoCount',
|
||||
title: '照片',
|
||||
formatter: function(value, row) {
|
||||
var count = value == null ? 0 : value;
|
||||
if (count === 0 || $.common.isEmpty(row.orderId)) {
|
||||
return '<span class="text-muted">0 张</span>';
|
||||
}
|
||||
return '<a href="javascript:void(0)" onclick="openScrapPhotos(\'' + row.orderId + '\')">' + count + ' 张</a>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'createBy',
|
||||
title: '操作人'
|
||||
},
|
||||
{
|
||||
field: 'remark',
|
||||
title: '备注'
|
||||
}]
|
||||
};
|
||||
$.table.init(options);
|
||||
});
|
||||
|
||||
function openTyreDetail(tireId) {
|
||||
// 复用现有生命周期详情页,列表页不再重复实现轮胎全生命周期展示逻辑。
|
||||
$.modal.openTab("轮胎详情", ctx + "tyre/tyre/detail2?tyreId=" + encodeURIComponent(tireId));
|
||||
}
|
||||
|
||||
function openScrapPhotos(orderId) {
|
||||
$.get(prefix + "/photos/" + encodeURIComponent(orderId), function(result) {
|
||||
if (result.code !== web_status.SUCCESS) {
|
||||
$.modal.alertWarning(result.msg);
|
||||
return;
|
||||
}
|
||||
showPhotoLayer(result.data || []);
|
||||
});
|
||||
}
|
||||
|
||||
function showPhotoLayer(photos) {
|
||||
var html;
|
||||
if (!photos || photos.length === 0) {
|
||||
html = '<div class="scrap-photo-empty">该报废工单暂无照片</div>';
|
||||
} else {
|
||||
html = '<div class="scrap-photo-list">';
|
||||
for (var i = 0; i < photos.length; i++) {
|
||||
var photo = photos[i] || {};
|
||||
var url = buildFileUrl(photo.filePath);
|
||||
html += '<a class="scrap-photo-item" href="' + url + '" target="_blank" title="' + escapeHtml(photo.fileName) + '">'
|
||||
+ '<img src="' + url + '" alt="报废照片"/>'
|
||||
+ '<div class="scrap-photo-name">' + escapeHtml(photo.fileName || "报废照片") + '</div>'
|
||||
+ '</a>';
|
||||
}
|
||||
html += '</div>';
|
||||
}
|
||||
top.layer.open({
|
||||
type: 1,
|
||||
title: '该报废工单照片',
|
||||
area: ['840px', '560px'],
|
||||
shade: 0.3,
|
||||
content: html
|
||||
});
|
||||
}
|
||||
|
||||
function buildFileUrl(filePath) {
|
||||
if ($.common.isEmpty(filePath)) {
|
||||
return '#';
|
||||
}
|
||||
if (filePath.indexOf('http://') === 0 || filePath.indexOf('https://') === 0) {
|
||||
return filePath;
|
||||
}
|
||||
// FileUploadUtils 返回 /profile/... 形式;拼 ctx 时去掉开头斜杠以兼容非根上下文部署。
|
||||
return filePath.charAt(0) === '/' ? ctx + filePath.substring(1) : ctx + filePath;
|
||||
}
|
||||
|
||||
function escapeHtml(value) {
|
||||
return String(value == null ? "" : value)
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue