品号查询

This commit is contained in:
JenniferW 2025-08-20 14:11:59 +08:00
parent 6d2bddcffc
commit bf4d8a7090
1 changed files with 193 additions and 68 deletions

View File

@ -134,7 +134,7 @@
>
<el-icon class="tag-edit-icon" size="14"><Edit /></el-icon>
</el-tag>
<el-button type="text" @click="clearAll" class="clear-button">
<el-button link @click="clearAll" class="clear-button">
<el-icon><RefreshLeft /></el-icon>
清除所有
</el-button>
@ -144,7 +144,7 @@
<!-- 查询结果区域 -->
<div class="results-section" v-if="showResults">
<div
v-if="filteredData.length"
v-if="currentPageData.length"
class="result-card-list-wrap"
style="position: relative"
>
@ -159,21 +159,35 @@
</el-button>
<div class="result-card-list">
<el-card
v-for="item in filteredData"
v-for="item in currentPageData"
:key="item.productNumber"
class="result-card"
:class="{ active: item.selected }"
@click="toggleSelect(item)"
>
<div class="result-card-info">
<div class="result-card-name">{{ item.name }}</div>
<div class="result-card-parameter">
<div
class="result-card-name text-truncate"
:title="item.name"
>
{{ item.name }}
</div>
<div
class="result-card-parameter text-truncate"
:title="`品号:${item.productNumber}`"
>
<span>品号</span>{{ item.productNumber }}
</div>
<div class="result-card-parameter">
<div
class="result-card-parameter text-truncate"
:title="`品号-规格型号:${item.specificationModel}`"
>
<span>品号-规格型号 </span>{{ item.specificationModel }}
</div>
<div class="result-card-parameter">
<div
class="result-card-parameter text-truncate"
:title="`车型:${item.carModel}`"
>
<span>车型</span> {{ item.carModel }}
</div>
</div>
@ -181,9 +195,32 @@
</div>
</div>
<div v-if="filteredData.length === 0" class="no-results">
<div v-if="currentPageData.length === 0" class="no-results">
<el-empty description="没有匹配的结果"></el-empty>
</div>
<!-- 分页控件 -->
<div class="pagination-container" v-if="showResults">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[8, 16, 32]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="totalItems"
></el-pagination>
<!-- 确定按钮 -->
<el-button
type="primary"
class="confirm-button"
@click="handleConfirm"
:disabled="selectedCount !== 1"
>
确定
</el-button>
</div>
</div>
<!-- 参数对比弹窗 -->
@ -233,10 +270,23 @@
</el-table>
</div>
</el-dialog>
</div>
<div class="btn-row" v-if="showResults">
<el-button @click="emit('prev-step')">上一步</el-button>
<el-button type="primary" @click="onNextStep">下一步</el-button>
<!-- 选择确认提示弹窗 -->
<el-dialog
v-model="confirmDialogVisible"
title="选择确认"
width="400px"
:show-close="false"
>
<div class="confirm-message">
您选择的品号为{{ selectedProductNumber }}
</div>
<template #footer>
<el-button type="primary" @click="confirmDialogVisible = false">
确定
</el-button>
</template>
</el-dialog>
</div>
</div>
</div>
@ -252,14 +302,15 @@ import {
mockData,
fieldValueMap,
} from "@/data/step2MockData";
import { ElMessage, ElEmpty } from "element-plus";
import { ElMessage, ElEmpty, ElDialog } from "element-plus";
import { Search, Edit, RefreshLeft } from "@element-plus/icons-vue";
// propsemit
const props = defineProps({
form: Object,
selectedCarType: String,
});
const emit = defineEmits(["update:form", "prev-step", "next-step"]);
const emit = defineEmits(["update:form"]);
//
const selectedCarTypeProxy = computed({
@ -292,12 +343,37 @@ const parsedConditions = ref([]);
const showResults = ref(false);
const filteredData = ref([]);
//
const currentPage = ref(1);
const pageSize = ref(8);
const totalItems = ref(0);
//
const currentPageData = computed(() => {
const startIndex = (currentPage.value - 1) * pageSize.value;
return filteredData.value.slice(startIndex, startIndex + pageSize.value);
});
//
const selectedCount = computed(() => {
return filteredData.value.filter((item) => item.selected).length;
});
//
const selectedProductNumber = computed(() => {
const selected = filteredData.value.find((item) => item.selected);
return selected ? selected.productNumber : "";
});
//
const compareDialogVisible = ref(false);
const selectedCompareList = computed(() =>
filteredData.value.filter((i) => i.selected)
);
//
const confirmDialogVisible = ref(false);
//
const compareTableData = computed(() => {
if (selectedCompareList.value.length === 0) return [];
@ -904,16 +980,23 @@ const parseConditions = (input) => {
//
const handleSearch = () => {
if (!currentInput.value.trim()) return;
//
parsedConditions.value = parseConditions(currentInput.value);
// selected
filteredData.value = filterData(parsedConditions.value).map((item) => ({
...item,
selected: false,
}));
//
if (!currentInput.value.trim()) {
filteredData.value = mockData.map((item) => ({ ...item, selected: false }));
} else {
// selected
filteredData.value = filterData(parsedConditions.value).map((item) => ({
...item,
selected: false,
}));
}
//
totalItems.value = filteredData.value.length;
currentPage.value = 1;
//
showResults.value = true;
@ -966,6 +1049,7 @@ const checkCondition = (fieldValue, conditionValue) => {
const value = processedCondition.substring(op.symbol.length).trim();
if (!isNaN(Number(processedValue)) && !isNaN(Number(value))) {
return op.func(Number(processedValue), Number(value));
return op.func(Number(processedValue), Number(value));
}
return op.func(String(processedValue), value);
}
@ -985,10 +1069,19 @@ const removeCondition = (index) => {
.replace(/[;]+/g, ";")
.trim();
parsedConditions.value = parseConditions(currentInput.value);
filteredData.value = filterData(parsedConditions.value).map((item) => ({
...item,
selected: false,
}));
//
if (!currentInput.value.trim()) {
filteredData.value = mockData.map((item) => ({ ...item, selected: false }));
} else {
filteredData.value = filterData(parsedConditions.value).map((item) => ({
...item,
selected: false,
}));
}
totalItems.value = filteredData.value.length;
currentPage.value = 1;
//
if (selectedConditionIndex.value === index) {
@ -1001,6 +1094,8 @@ const clearAll = () => {
currentInput.value = "";
parsedConditions.value = [];
filteredData.value = [];
totalItems.value = 0;
currentPage.value = 1;
showResults.value = false;
showSuggestions.value = false;
possibleFields.value = [];
@ -1008,11 +1103,25 @@ const clearAll = () => {
if (searchInput.value) {
searchInput.value.focus();
}
handleSearch();
};
//
const handleSizeChange = (val) => {
pageSize.value = val;
currentPage.value = 1; //
};
const handleCurrentChange = (val) => {
currentPage.value = val;
//
window.scrollTo({ top: 0, behavior: "smooth" });
};
//
onMounted(() => {
initializeValues();
handleSearch();
updateInputWidth();
window.addEventListener("resize", updateInputWidth);
@ -1072,26 +1181,11 @@ function onCompare() {
compareDialogVisible.value = true;
}
//
function onNextStep() {
const selected = filteredData.value.filter((i) => i.selected);
if (selected.length !== 1) {
ElMessage.warning("请且只能选择一个卡片进入下一步");
return;
//
function handleConfirm() {
if (selectedCount.value === 1) {
confirmDialogVisible.value = true;
}
// form
if (props.form) {
props.form.selectedCarType = selectedCarTypeProxy.value;
props.form.selectedPartInfo = {
code: selected[0].productNumber,
label: selected[0].name,
image: selected[0].image,
type: selected[0].model,
feature: selected[0].specificationModel,
};
emit("update:form", props.form);
}
emit("next-step");
}
</script>
@ -1741,31 +1835,8 @@ function onNextStep() {
}
.results-section {
max-height: 300px;
overflow-y: auto;
/* 添加内边距避免内容紧贴滚动条 */
/* 移除滚动条相关样式 */
padding: 0 10px 20px;
scrollbar-width: thin;
scrollbar-color: #ccc #f5f5f5;
}
/* 滚动条美化针对WebKit浏览器 */
.results-section::-webkit-scrollbar {
width: 6px;
}
.results-section::-webkit-scrollbar-track {
background: #f5f5f5;
border-radius: 3px;
}
.results-section::-webkit-scrollbar-thumb {
background-color: #ccc;
border-radius: 3px;
}
.results-section::-webkit-scrollbar-thumb:hover {
background-color: #aaa;
}
.no-results {
@ -1783,6 +1854,50 @@ function onNextStep() {
overflow-y: auto;
}
/* 分页和确定按钮容器 */
.pagination-container {
display: flex;
justify-content: end;
align-items: center;
margin-top: 20px;
padding: 10px 0;
border-top: 1px solid #eee;
}
/* 确定按钮样式 */
.confirm-button {
min-width: 100px;
margin-left: 15px;
}
/* 文字溢出处理样式 */
.text-truncate {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
position: relative;
}
.text-truncate:hover {
/* 保持原样式不变但通过title属性显示完整内容 */
overflow: visible;
white-space: normal;
z-index: 10;
background-color: rgba(255, 255, 255, 0.95);
padding: 5px;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
max-width: 300px;
word-break: break-word;
}
/* 确认弹窗样式 */
.confirm-message {
font-size: 16px;
text-align: center;
padding: 20px 0;
}
@media (max-width: 768px) {
.search-box {
flex-direction: column;
@ -1800,5 +1915,15 @@ function onNextStep() {
.result-card {
width: 100%;
}
.pagination-container {
flex-direction: column;
gap: 15px;
align-items: stretch;
}
.confirm-button {
width: 100%;
}
}
</style>