步骤二查询变更

This commit is contained in:
JenniferW 2025-08-14 15:25:14 +08:00
parent a8e35a7eee
commit 5ad4767667
2 changed files with 1772 additions and 269 deletions

File diff suppressed because it is too large Load Diff

View File

@ -117,33 +117,144 @@
<!-- 查询结果区域 -->
<div class="results-section" v-if="showResults">
<div class="results-header">
<h2>查询结果</h2>
<h2>查询结果 ({{ filteredData.length }})</h2>
<el-button type="text" @click="clearAll" class="clear-button">
<el-icon><RefreshLeft /></el-icon>
清除所有
</el-button>
</div>
<el-table :data="filteredData" border class="results-table">
<el-table-column
v-for="field in allFields"
:key="field.key"
:prop="field.key"
:label="field.label"
sortable
/>
</el-table>
<!-- 结果卡片区 -->
<div
v-if="filteredData.length"
class="result-card-list-wrap"
style="position: relative"
>
<el-button
v-if="selectedCompareList.length > 0"
type="warning"
class="compare-btn-float"
@click="onCompare"
circle
>
参数<br />对比
</el-button>
<div class="result-card-list">
<el-card
v-for="item in filteredData"
:key="item.productNumber"
class="result-card"
:class="{ active: item.selected }"
@click="toggleSelect(item)"
>
<div class="result-card-checkbox-wrap" @click.stop>
<el-checkbox
v-model="item.selected"
class="result-card-checkbox"
/>
</div>
<img
:src="item.image"
class="result-card-img"
:alt="item.name"
@click.stop="toggleSelect(item)"
/>
<div class="result-card-info">
<div class="result-card-name">{{ item.name }}</div>
<div class="result-card-code">{{ item.productNumber }}</div>
<div class="result-card-spec">{{ item.specificationModel }}</div>
<div class="result-card-car-model">
适用车型: {{ item.carModel }}
</div>
</div>
</el-card>
</div>
</div>
<div v-if="filteredData.length === 0" class="no-results">
<el-empty description="没有匹配的结果"></el-empty>
</div>
</div>
<!-- 参数对比弹窗 -->
<el-dialog
v-model="compareDialogVisible"
title="参数对比"
width="80%"
top="40px"
:close-on-click-modal="false"
>
<!-- 表格对比区图片放在表头下方 -->
<div class="compare-table-wrap">
<el-table :data="compareTableData" border style="width: 100%">
<el-table-column
prop="param"
label="参数"
width="180"
class-name="param-col"
align="center"
header-align="center"
/>
<el-table-column
v-for="item in selectedCompareList"
:key="item.productNumber"
:label="item.productNumber"
:prop="item.productNumber"
align="center"
header-align="center"
>
<template #header="{ column }">
<div
style="
display: flex;
flex-direction: column;
align-items: center;
"
>
<img
v-if="
selectedCompareList.find(
(i) => i.productNumber === column.label
)?.image
"
:src="
selectedCompareList.find(
(i) => i.productNumber === column.label
).image
"
style="
width: 60px;
height: 40px;
object-fit: contain;
margin-top: 4px;
border-radius: 4px;
border: 1px solid #eee;
"
:alt="
selectedCompareList.find(
(i) => i.productNumber === column.label
).name
"
/>
<span>{{ column.label }}</span>
<span style="font-size: 12px; color: #666">{{
selectedCompareList.find(
(i) => i.productNumber === column.label
).name
}}</span>
</div>
</template>
</el-table-column>
</el-table>
</div>
</el-dialog>
</div>
</template>
<script setup>
import { ref, onMounted, watch, nextTick } from "vue";
import { Search, RefreshLeft, Edit } from "@element-plus/icons-vue";
//
const allFields = [
@ -174,6 +285,7 @@ const mockData = [
wheelTread: null,
paintManufacturer: "Weckerle",
image: "/images/cars/1_1_1.jpg",
selected: false,
},
{
productNumber: "D311299000044-00005",
@ -187,6 +299,7 @@ const mockData = [
wheelTread: null,
paintManufacturer: "Weckerle",
image: "/images/cars/1_1_2.jpg",
selected: false,
},
{
productNumber: "D311102000025-00022",
@ -200,6 +313,7 @@ const mockData = [
wheelTread: "LMB10",
paintManufacturer: "Weckerle",
image: "/images/cars/1_2_1.jpg",
selected: false,
},
{
productNumber: "D311102000025-00021",
@ -213,6 +327,7 @@ const mockData = [
wheelTread: "LMB10",
paintManufacturer: "Weckerle",
image: "/images/cars/1_2.jpg",
selected: false,
},
{
productNumber: "D311199000035-00037",
@ -226,6 +341,7 @@ const mockData = [
wheelTread: "LMB10",
paintManufacturer: "Weckerle",
image: "/images/cars/1_2_1_1.jpg",
selected: false,
},
{
productNumber: "D311199020097-00006",
@ -239,6 +355,7 @@ const mockData = [
wheelTread: "LMB10",
paintManufacturer: "Weckerle",
image: "/images/cars/2.jpg",
selected: false,
},
{
productNumber: "D311102010007-00037",
@ -252,6 +369,7 @@ const mockData = [
wheelTread: "LMB10",
paintManufacturer: null,
image: "/images/cars/3.jpg",
selected: false,
},
{
productNumber: "D325000000014-10001",
@ -265,6 +383,7 @@ const mockData = [
wheelTread: null,
paintManufacturer: null,
image: "/images/cars/4.jpg",
selected: false,
},
];
@ -364,6 +483,54 @@ const parsedConditions = ref([]);
const showResults = ref(false);
const filteredData = ref([]);
//
const compareDialogVisible = ref(false);
const selectedCompareList = computed(() =>
filteredData.value.filter((i) => i.selected)
);
//
const compareTableData = computed(() => {
if (selectedCompareList.value.length <= 1) return [];
//
const paramsToCompare = [
"品名/物料名称",
"品号",
"图号",
"品号-规格型号",
"车型",
"型号",
"材质",
"采购属性",
"车轮踏面形式",
"油漆制造商",
];
//
const fieldMap = {
"品名/物料名称": "name",
品号: "productNumber",
图号: "drawingNumber",
"品号-规格型号": "specificationModel",
车型: "carModel",
型号: "model",
材质: "material",
采购属性: "procurementAttributes",
车轮踏面形式: "wheelTread",
油漆制造商: "paintManufacturer",
};
//
return paramsToCompare.map((param) => {
const row = { param };
selectedCompareList.value.forEach((item) => {
row[item.productNumber] = item[fieldMap[param]] || "-";
});
return row;
});
});
//
const getCurrentInputPart = () => {
const parts = currentInput.value.split(";");
@ -922,8 +1089,11 @@ const handleSearch = () => {
//
parsedConditions.value = parseConditions(currentInput.value);
//
filteredData.value = filterData(parsedConditions.value);
// selected
filteredData.value = filterData(parsedConditions.value).map((item) => ({
...item,
selected: false,
}));
//
showResults.value = true;
@ -992,7 +1162,10 @@ const removeCondition = (index) => {
parts.splice(index, 1);
currentInput.value = parts.join(";").replace(/;;+/g, ";").trim();
parsedConditions.value = parseConditions(currentInput.value);
filteredData.value = filterData(parsedConditions.value);
filteredData.value = filterData(parsedConditions.value).map((item) => ({
...item,
selected: false,
}));
//
if (selectedConditionIndex.value === index) {
@ -1012,6 +1185,27 @@ const clearAll = () => {
searchInput.value.focus();
};
//
const toggleSelect = (item) => {
//
const selectedCount = filteredData.value.filter((i) => i.selected).length;
if (!item.selected && selectedCount >= 3) {
// 3
alert("最多只能选择3个卡片进行对比");
return;
}
item.selected = !item.selected;
};
//
const onCompare = () => {
if (selectedCompareList.value.length === 0) {
alert("请先选择要对比的卡片");
return;
}
compareDialogVisible.value = true;
};
//
const updateInputWidth = () => {
if (searchInput.value) {
@ -1256,6 +1450,150 @@ watch(
color: #666;
}
/* 卡片样式 - 与step2保持一致 */
.result-card-list {
display: flex;
flex-wrap: wrap;
gap: 24px;
margin: 24px;
}
.result-card {
width: 220px;
position: relative;
padding-top: 16px;
box-sizing: border-box;
transition: box-shadow 0.2s, transform 0.15s, border-color 0.2s;
cursor: pointer;
border: 1px solid #eee;
}
.result-card:hover {
box-shadow: 0 4px 16px rgba(33, 86, 243, 0.12);
transform: translateY(-4px) scale(1.03);
border-color: #2156f3;
}
.result-card.active {
box-shadow: 0 6px 20px rgba(33, 86, 243, 0.18);
border-color: #2156f3;
background: #f5f8ff;
transform: scale(1.04);
}
.result-card-checkbox-wrap {
position: absolute;
left: 20px;
top: 22px;
z-index: 2;
}
.result-card-checkbox {
position: static;
}
.result-card-img {
width: 100%;
height: 120px;
object-fit: contain;
border-radius: 4px;
border: 1px solid #eee;
margin-bottom: 12px;
transition: transform 0.2s;
}
.result-card:hover .result-card-img,
.result-card.active .result-card-img {
transform: scale(1.08);
}
.result-card-info {
text-align: left;
padding: 0 16px 16px;
}
.result-card-name {
font-size: 15px;
color: #333;
font-weight: 500;
margin-bottom: 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.result-card-code {
font-size: 13px;
color: #888;
margin-bottom: 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.result-card-spec {
font-size: 12px;
color: #666;
margin-bottom: 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.result-card-car-model {
font-size: 12px;
color: #666;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.result-card-list-wrap {
position: relative;
}
.compare-btn-float {
position: sticky;
float: right;
right: 20px;
top: 20px;
z-index: 10;
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
padding: 0;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(33, 86, 243, 0.12);
transition: box-shadow 0.2s, background 0.2s;
font-size: 14px;
margin: 10px 20px 0 0;
}
.compare-btn-float:hover {
background: #ffe9c6;
color: #999;
box-shadow: 0 4px 16px rgba(255, 153, 0, 0.18);
}
.compare-table-wrap {
margin-top: 16px;
max-height: 500px;
overflow-y: auto;
}
/* 参数对比表格第一列背景色与表头一致 */
:deep(.el-table .param-col),
:deep(.el-table th.param-col) {
background: #f5f7fa !important;
}
.result-card-checkbox .el-checkbox__input.is-checked .el-checkbox__inner {
border-color: #2156f3 !important;
background-color: #2156f3 !important;
}
@media (max-width: 768px) {
.search-box {
flex-direction: column;
@ -1269,5 +1607,9 @@ watch(
.search-button {
width: 100%;
}
.result-card {
width: 100%;
}
}
</style>