步骤二查询变更
This commit is contained in:
parent
a8e35a7eee
commit
5ad4767667
File diff suppressed because it is too large
Load Diff
|
|
@ -117,33 +117,144 @@
|
||||||
<!-- 查询结果区域 -->
|
<!-- 查询结果区域 -->
|
||||||
<div class="results-section" v-if="showResults">
|
<div class="results-section" v-if="showResults">
|
||||||
<div class="results-header">
|
<div class="results-header">
|
||||||
<h2>查询结果</h2>
|
<h2>查询结果 ({{ filteredData.length }})</h2>
|
||||||
<el-button type="text" @click="clearAll" class="clear-button">
|
<el-button type="text" @click="clearAll" class="clear-button">
|
||||||
<el-icon><RefreshLeft /></el-icon>
|
<el-icon><RefreshLeft /></el-icon>
|
||||||
清除所有
|
清除所有
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table :data="filteredData" border class="results-table">
|
<!-- 结果卡片区 -->
|
||||||
<el-table-column
|
<div
|
||||||
v-for="field in allFields"
|
v-if="filteredData.length"
|
||||||
:key="field.key"
|
class="result-card-list-wrap"
|
||||||
:prop="field.key"
|
style="position: relative"
|
||||||
:label="field.label"
|
>
|
||||||
sortable
|
<el-button
|
||||||
/>
|
v-if="selectedCompareList.length > 0"
|
||||||
</el-table>
|
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">
|
<div v-if="filteredData.length === 0" class="no-results">
|
||||||
<el-empty description="没有匹配的结果"></el-empty>
|
<el-empty description="没有匹配的结果"></el-empty>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, watch, nextTick } from "vue";
|
import { ref, onMounted, watch, nextTick } from "vue";
|
||||||
|
import { Search, RefreshLeft, Edit } from "@element-plus/icons-vue";
|
||||||
|
|
||||||
// 定义可查询的字段
|
// 定义可查询的字段
|
||||||
const allFields = [
|
const allFields = [
|
||||||
|
|
@ -174,6 +285,7 @@ const mockData = [
|
||||||
wheelTread: null,
|
wheelTread: null,
|
||||||
paintManufacturer: "Weckerle",
|
paintManufacturer: "Weckerle",
|
||||||
image: "/images/cars/1_1_1.jpg",
|
image: "/images/cars/1_1_1.jpg",
|
||||||
|
selected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
productNumber: "D311299000044-00005",
|
productNumber: "D311299000044-00005",
|
||||||
|
|
@ -187,6 +299,7 @@ const mockData = [
|
||||||
wheelTread: null,
|
wheelTread: null,
|
||||||
paintManufacturer: "Weckerle",
|
paintManufacturer: "Weckerle",
|
||||||
image: "/images/cars/1_1_2.jpg",
|
image: "/images/cars/1_1_2.jpg",
|
||||||
|
selected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
productNumber: "D311102000025-00022",
|
productNumber: "D311102000025-00022",
|
||||||
|
|
@ -200,6 +313,7 @@ const mockData = [
|
||||||
wheelTread: "LMB10",
|
wheelTread: "LMB10",
|
||||||
paintManufacturer: "Weckerle",
|
paintManufacturer: "Weckerle",
|
||||||
image: "/images/cars/1_2_1.jpg",
|
image: "/images/cars/1_2_1.jpg",
|
||||||
|
selected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
productNumber: "D311102000025-00021",
|
productNumber: "D311102000025-00021",
|
||||||
|
|
@ -213,6 +327,7 @@ const mockData = [
|
||||||
wheelTread: "LMB10",
|
wheelTread: "LMB10",
|
||||||
paintManufacturer: "Weckerle",
|
paintManufacturer: "Weckerle",
|
||||||
image: "/images/cars/1_2.jpg",
|
image: "/images/cars/1_2.jpg",
|
||||||
|
selected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
productNumber: "D311199000035-00037",
|
productNumber: "D311199000035-00037",
|
||||||
|
|
@ -226,6 +341,7 @@ const mockData = [
|
||||||
wheelTread: "LMB10",
|
wheelTread: "LMB10",
|
||||||
paintManufacturer: "Weckerle",
|
paintManufacturer: "Weckerle",
|
||||||
image: "/images/cars/1_2_1_1.jpg",
|
image: "/images/cars/1_2_1_1.jpg",
|
||||||
|
selected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
productNumber: "D311199020097-00006",
|
productNumber: "D311199020097-00006",
|
||||||
|
|
@ -239,6 +355,7 @@ const mockData = [
|
||||||
wheelTread: "LMB10",
|
wheelTread: "LMB10",
|
||||||
paintManufacturer: "Weckerle",
|
paintManufacturer: "Weckerle",
|
||||||
image: "/images/cars/2.jpg",
|
image: "/images/cars/2.jpg",
|
||||||
|
selected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
productNumber: "D311102010007-00037",
|
productNumber: "D311102010007-00037",
|
||||||
|
|
@ -252,6 +369,7 @@ const mockData = [
|
||||||
wheelTread: "LMB10",
|
wheelTread: "LMB10",
|
||||||
paintManufacturer: null,
|
paintManufacturer: null,
|
||||||
image: "/images/cars/3.jpg",
|
image: "/images/cars/3.jpg",
|
||||||
|
selected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
productNumber: "D325000000014-10001",
|
productNumber: "D325000000014-10001",
|
||||||
|
|
@ -265,6 +383,7 @@ const mockData = [
|
||||||
wheelTread: null,
|
wheelTread: null,
|
||||||
paintManufacturer: null,
|
paintManufacturer: null,
|
||||||
image: "/images/cars/4.jpg",
|
image: "/images/cars/4.jpg",
|
||||||
|
selected: false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -364,6 +483,54 @@ const parsedConditions = ref([]);
|
||||||
const showResults = ref(false);
|
const showResults = ref(false);
|
||||||
const filteredData = ref([]);
|
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 getCurrentInputPart = () => {
|
||||||
const parts = currentInput.value.split(";");
|
const parts = currentInput.value.split(";");
|
||||||
|
|
@ -922,8 +1089,11 @@ const handleSearch = () => {
|
||||||
// 解析条件
|
// 解析条件
|
||||||
parsedConditions.value = parseConditions(currentInput.value);
|
parsedConditions.value = parseConditions(currentInput.value);
|
||||||
|
|
||||||
// 执行过滤
|
// 执行过滤,创建副本并添加selected属性
|
||||||
filteredData.value = filterData(parsedConditions.value);
|
filteredData.value = filterData(parsedConditions.value).map((item) => ({
|
||||||
|
...item,
|
||||||
|
selected: false,
|
||||||
|
}));
|
||||||
|
|
||||||
// 显示结果
|
// 显示结果
|
||||||
showResults.value = true;
|
showResults.value = true;
|
||||||
|
|
@ -992,7 +1162,10 @@ const removeCondition = (index) => {
|
||||||
parts.splice(index, 1);
|
parts.splice(index, 1);
|
||||||
currentInput.value = parts.join(";").replace(/;;+/g, ";").trim();
|
currentInput.value = parts.join(";").replace(/;;+/g, ";").trim();
|
||||||
parsedConditions.value = parseConditions(currentInput.value);
|
parsedConditions.value = parseConditions(currentInput.value);
|
||||||
filteredData.value = filterData(parsedConditions.value);
|
filteredData.value = filterData(parsedConditions.value).map((item) => ({
|
||||||
|
...item,
|
||||||
|
selected: false,
|
||||||
|
}));
|
||||||
|
|
||||||
// 重置选中的条件索引
|
// 重置选中的条件索引
|
||||||
if (selectedConditionIndex.value === index) {
|
if (selectedConditionIndex.value === index) {
|
||||||
|
|
@ -1012,6 +1185,27 @@ const clearAll = () => {
|
||||||
searchInput.value.focus();
|
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 = () => {
|
const updateInputWidth = () => {
|
||||||
if (searchInput.value) {
|
if (searchInput.value) {
|
||||||
|
|
@ -1256,6 +1450,150 @@ watch(
|
||||||
color: #666;
|
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) {
|
@media (max-width: 768px) {
|
||||||
.search-box {
|
.search-box {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
@ -1269,5 +1607,9 @@ watch(
|
||||||
.search-button {
|
.search-button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.result-card {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue