|
|
|
@ -4,6 +4,62 @@ |
|
|
|
:showTitle="false" |
|
|
|
> |
|
|
|
<div class="page-container"> |
|
|
|
<!-- 查询栏:总缺陷数 + 缺陷类型/点位名称/采集时间条件 --> |
|
|
|
<div class="query-bar"> |
|
|
|
<div class="total-chip"> |
|
|
|
<span class="total-label">总缺陷数</span> |
|
|
|
<span class="total-value">{{ total }}</span> |
|
|
|
</div> |
|
|
|
<el-select |
|
|
|
v-model="defectTypeList" |
|
|
|
class="query-item query-type" |
|
|
|
multiple |
|
|
|
collapse-tags |
|
|
|
filterable |
|
|
|
clearable |
|
|
|
placeholder="缺陷类型" |
|
|
|
@change="handleQuery" |
|
|
|
> |
|
|
|
<el-option |
|
|
|
v-for="item in defectTypeOptions" |
|
|
|
:key="item" |
|
|
|
:label="item" |
|
|
|
:value="item" |
|
|
|
/> |
|
|
|
</el-select> |
|
|
|
<el-input |
|
|
|
v-model="queryParams.pointName" |
|
|
|
class="query-item query-input" |
|
|
|
placeholder="点位名称" |
|
|
|
clearable |
|
|
|
@keyup.enter.native="handleQuery" |
|
|
|
/> |
|
|
|
<el-date-picker |
|
|
|
v-model="dateRange" |
|
|
|
class="query-item query-date" |
|
|
|
type="daterange" |
|
|
|
value-format="yyyy-MM-dd" |
|
|
|
range-separator="-" |
|
|
|
start-placeholder="采集开始日期" |
|
|
|
end-placeholder="采集结束日期" |
|
|
|
:picker-options="dateRangePickerOptions" |
|
|
|
:clearable="true" |
|
|
|
@change="handleQuery" |
|
|
|
/> |
|
|
|
<el-button |
|
|
|
type="primary" |
|
|
|
icon="el-icon-search" |
|
|
|
class="query-btn" |
|
|
|
@click="handleQuery" |
|
|
|
>搜索</el-button |
|
|
|
> |
|
|
|
<el-button |
|
|
|
icon="el-icon-refresh" |
|
|
|
class="query-btn query-reset-btn" |
|
|
|
@click="resetQuery" |
|
|
|
>重置</el-button |
|
|
|
> |
|
|
|
</div> |
|
|
|
<div class="table-card" ref="tableCardRef"> |
|
|
|
<el-table |
|
|
|
v-loading="loading" |
|
|
|
@ -80,7 +136,10 @@ export default { |
|
|
|
components: { CardBox, CardPagination, ImagePreview, AsyncImage }, |
|
|
|
data() { |
|
|
|
return { |
|
|
|
queryParams: { pageNum: 1, pageSize: 20 }, |
|
|
|
queryParams: { pageNum: 1, pageSize: 20, pointName: "" }, |
|
|
|
defectTypeList: [], |
|
|
|
allDataList: [], // 后端一次性返回的全量数据,筛选在前端完成 |
|
|
|
filteredList: [], // 前端筛选后的结果 |
|
|
|
dataList: [], |
|
|
|
loading: false, |
|
|
|
total: 0, |
|
|
|
@ -106,8 +165,19 @@ export default { |
|
|
|
previewImagePos: 0, |
|
|
|
}; |
|
|
|
}, |
|
|
|
computed: { |
|
|
|
// 缺陷类型下拉选项:直接取全量数据里的缺陷结果去重 |
|
|
|
defectTypeOptions() { |
|
|
|
const set = new Set(); |
|
|
|
this.allDataList.forEach((item) => { |
|
|
|
const desc = (item.desc || "").trim(); |
|
|
|
if (desc) set.add(desc); |
|
|
|
}); |
|
|
|
return Array.from(set).sort((a, b) => a.localeCompare(b, "zh")); |
|
|
|
}, |
|
|
|
}, |
|
|
|
created() { |
|
|
|
this.getList(); |
|
|
|
this.loadData(); |
|
|
|
window.addEventListener("resize", this.setTableHeight); |
|
|
|
}, |
|
|
|
mounted() { |
|
|
|
@ -139,7 +209,91 @@ export default { |
|
|
|
|
|
|
|
handleQuery() { |
|
|
|
this.queryParams.pageNum = 1; |
|
|
|
this.getList(); |
|
|
|
this.applyFilters(); |
|
|
|
}, |
|
|
|
|
|
|
|
// 重置查询条件(筛选在前端完成,无需重新请求后端) |
|
|
|
resetQuery() { |
|
|
|
this.defectTypeList = []; |
|
|
|
this.queryParams.pointName = ""; |
|
|
|
this.dateRange = []; |
|
|
|
this.handleQuery(); |
|
|
|
}, |
|
|
|
|
|
|
|
// 一次性拉取全量数据,之后的筛选、分页都在前端完成 |
|
|
|
loadData() { |
|
|
|
this.loading = true; |
|
|
|
// 重置图片计数器 |
|
|
|
this.imageLoadCount = 0; |
|
|
|
this.expectedImageCount = 0; |
|
|
|
|
|
|
|
defectRecordList({ pageNum: 1, pageSize: 9999 }) |
|
|
|
.then((res) => { |
|
|
|
this.allDataList = res.rows || []; |
|
|
|
this.applyFilters(); |
|
|
|
}) |
|
|
|
.catch((error) => { |
|
|
|
console.error("获取缺陷记录失败:", error); |
|
|
|
this.allDataList = []; |
|
|
|
this.applyFilters(); |
|
|
|
}) |
|
|
|
.finally(() => { |
|
|
|
this.loading = false; |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
// 前端筛选:缺陷结果、点位名称、采集时间,随后本地分页 |
|
|
|
applyFilters() { |
|
|
|
const keyword = (this.queryParams.pointName || "").trim().toLowerCase(); |
|
|
|
const types = this.defectTypeList || []; |
|
|
|
const range = |
|
|
|
this.dateRange && this.dateRange.length === 2 ? this.dateRange : null; |
|
|
|
|
|
|
|
this.filteredList = this.allDataList.filter((row) => { |
|
|
|
if (types.length && !types.includes((row.desc || "").trim())) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
if ( |
|
|
|
keyword && |
|
|
|
(row.pointName || "").toLowerCase().indexOf(keyword) === -1 |
|
|
|
) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
if (range) { |
|
|
|
const day = (row.patrolTime || "").slice(0, 10); |
|
|
|
if (!day || day < range[0] || day > range[1]) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
}); |
|
|
|
|
|
|
|
this.total = this.filteredList.length; |
|
|
|
// 当前页超出范围时回到第一页 |
|
|
|
const maxPage = Math.max( |
|
|
|
1, |
|
|
|
Math.ceil(this.total / (this.queryParams.pageSize || 20)) |
|
|
|
); |
|
|
|
if (this.queryParams.pageNum > maxPage) { |
|
|
|
this.queryParams.pageNum = 1; |
|
|
|
} |
|
|
|
const start = (this.queryParams.pageNum - 1) * this.queryParams.pageSize; |
|
|
|
this.dataList = this.filteredList.slice( |
|
|
|
start, |
|
|
|
start + this.queryParams.pageSize |
|
|
|
); |
|
|
|
|
|
|
|
// 计算需要加载的图片数量 |
|
|
|
this.expectedImageCount = this.dataList.filter( |
|
|
|
(item) => item.imgAnalyse |
|
|
|
).length; |
|
|
|
|
|
|
|
// 如果没有图片需要加载,直接刷新表格 |
|
|
|
if (this.expectedImageCount === 0) { |
|
|
|
this.forceRefreshTable(); |
|
|
|
} else { |
|
|
|
this.$nextTick(this.setTableHeight); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
linkUrl() { |
|
|
|
@ -201,42 +355,13 @@ export default { |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
// 翻页:数据已在前端,直接本地切片(首次进入时才请求后端) |
|
|
|
getList() { |
|
|
|
this.loading = true; |
|
|
|
// 重置图片计数器 |
|
|
|
this.imageLoadCount = 0; |
|
|
|
this.expectedImageCount = 0; |
|
|
|
|
|
|
|
const params = { ...this.queryParams }; |
|
|
|
if (this.dateRange && this.dateRange.length === 2) { |
|
|
|
params.beginTime = this.dateRange[0]; |
|
|
|
params.endTime = this.dateRange[1]; |
|
|
|
if (!this.allDataList.length) { |
|
|
|
this.loadData(); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
defectRecordList(params) |
|
|
|
.then((res) => { |
|
|
|
this.dataList = res.rows || []; |
|
|
|
this.total = res.total || 0; |
|
|
|
this.$nextTick(this.setTableHeight); |
|
|
|
|
|
|
|
// 计算需要加载的图片数量 |
|
|
|
this.expectedImageCount = this.dataList.filter( |
|
|
|
(item) => item.imgAnalyse |
|
|
|
).length; |
|
|
|
|
|
|
|
// 如果没有图片需要加载,直接刷新表格 |
|
|
|
if (this.expectedImageCount === 0) { |
|
|
|
this.forceRefreshTable(); |
|
|
|
} |
|
|
|
}) |
|
|
|
.catch((error) => { |
|
|
|
console.error("获取缺陷记录失败:", error); |
|
|
|
this.dataList = []; |
|
|
|
this.total = 0; |
|
|
|
}) |
|
|
|
.finally(() => { |
|
|
|
this.loading = false; |
|
|
|
}); |
|
|
|
this.applyFilters(); |
|
|
|
}, |
|
|
|
|
|
|
|
onSubmit() { |
|
|
|
@ -252,6 +377,67 @@ export default { |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
} |
|
|
|
// 查询栏:总缺陷数 + 条件筛选 |
|
|
|
.query-bar { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
flex-wrap: wrap; |
|
|
|
gap: 12px; |
|
|
|
padding: 12px 14px; |
|
|
|
margin-bottom: 12px; |
|
|
|
border: 1px solid #0b2567; |
|
|
|
border-radius: 2px; |
|
|
|
background: rgba(11, 37, 103, 0.35); |
|
|
|
|
|
|
|
.total-chip { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
gap: 10px; |
|
|
|
padding: 5px 14px; |
|
|
|
border: 1px solid rgba(63, 127, 216, 0.72); |
|
|
|
border-radius: 2px; |
|
|
|
background: rgba(11, 37, 103, 0.55); |
|
|
|
|
|
|
|
.total-label { |
|
|
|
font-size: 14px; |
|
|
|
color: #dcecff; |
|
|
|
} |
|
|
|
|
|
|
|
.total-value { |
|
|
|
font-size: 20px; |
|
|
|
font-weight: 700; |
|
|
|
color: #54ffff; |
|
|
|
line-height: 1.2; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.query-type { |
|
|
|
width: 220px; |
|
|
|
} |
|
|
|
|
|
|
|
.query-input { |
|
|
|
width: 180px; |
|
|
|
} |
|
|
|
|
|
|
|
.query-date { |
|
|
|
width: 260px; |
|
|
|
} |
|
|
|
|
|
|
|
// 重置按钮:与巡视方案页“添加”按钮同款配色 |
|
|
|
.query-reset-btn { |
|
|
|
background: linear-gradient(#01016b, #01016b) padding-box, |
|
|
|
linear-gradient(135deg, #3988ff, #0351c6) border-box !important; |
|
|
|
border: 1px solid transparent !important; |
|
|
|
color: #43c0ff !important; |
|
|
|
|
|
|
|
&:hover, |
|
|
|
&:focus { |
|
|
|
background: linear-gradient(#01016b, #01016b) padding-box, |
|
|
|
linear-gradient(135deg, #3988ff, #0351c6) border-box !important; |
|
|
|
color: #43c0ff !important; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
.card-page { |
|
|
|
height: 100%; |
|
|
|
min-height: 0; |
|
|
|
|