<template>
|
<el-dialog
|
v-model="visibleProxy"
|
title="选择产品"
|
width="900px"
|
@close="handleClose"
|
>
|
<div class="search-row">
|
<el-input
|
v-model="keyword"
|
placeholder="请输入产品名称/规格搜索"
|
clearable
|
style="width: 320px"
|
@keyup.enter="handleQuery"
|
/>
|
<el-button type="primary" @click="handleQuery">查询</el-button>
|
<el-button @click="handleReset">重置</el-button>
|
</div>
|
|
<el-table
|
v-loading="loading"
|
:data="tableData"
|
border
|
height="420"
|
style="width: 100%"
|
@selection-change="handleSelectionChange"
|
@row-click="handleRowClick"
|
>
|
<el-table-column
|
v-if="!single"
|
type="selection"
|
width="55"
|
align="center"
|
/>
|
<el-table-column label="产品名称" prop="productName" min-width="180" />
|
<el-table-column label="规格型号" prop="model" min-width="180" />
|
<el-table-column label="单位" prop="unit" width="100" />
|
<el-table-column label="产品类型" prop="parentName" width="120" />
|
</el-table>
|
|
<Pagination
|
:total="total"
|
:page="page.current"
|
:limit="page.size"
|
@pagination="handlePagination"
|
/>
|
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button type="primary" :disabled="selectedRows.length === 0" @click="handleConfirm">
|
确定
|
</el-button>
|
<el-button @click="visibleProxy = false">取消</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
</template>
|
|
<script setup>
|
import { computed, onMounted, reactive, ref, watch } from "vue";
|
import Pagination from "@/components/PIMTable/Pagination.vue";
|
import { modelListPage } from "@/api/basicData/product.js";
|
|
const props = defineProps({
|
modelValue: { type: Boolean, default: false },
|
single: { type: Boolean, default: false },
|
});
|
|
const emit = defineEmits(["update:modelValue", "confirm"]);
|
|
const visibleProxy = computed({
|
get: () => props.modelValue,
|
set: val => emit("update:modelValue", val),
|
});
|
|
const keyword = ref("");
|
const loading = ref(false);
|
const tableData = ref([]);
|
const selectedRows = ref([]);
|
const total = ref(0);
|
|
const page = reactive({
|
current: 1,
|
size: 10,
|
});
|
|
const normalizeRow = row => {
|
if (!row) return row;
|
return {
|
...row,
|
productId: row.productId ?? row.product_id ?? row.product?.id,
|
productName: row.productName ?? row.product_name ?? row.name,
|
model: row.model ?? row.productModelName ?? row.modelName ?? row.specificationModel,
|
id: row.id ?? row.productModelId ?? row.modelId,
|
unit: row.unit ?? row.productUnit,
|
productType: row.productType ?? row.type,
|
};
|
};
|
|
const fetchList = () => {
|
loading.value = true;
|
const params = {
|
current: page.current,
|
size: page.size,
|
};
|
if (keyword.value) {
|
params.keyword = keyword.value;
|
params.productName = keyword.value;
|
params.model = keyword.value;
|
}
|
modelListPage(params)
|
.then(res => {
|
const records = res?.data?.records || [];
|
tableData.value = records.map(normalizeRow);
|
total.value = res?.data?.total || 0;
|
})
|
.finally(() => {
|
loading.value = false;
|
});
|
};
|
|
const handleQuery = () => {
|
page.current = 1;
|
fetchList();
|
};
|
|
const handleReset = () => {
|
keyword.value = "";
|
page.current = 1;
|
fetchList();
|
};
|
|
const handlePagination = ({ page: p, limit }) => {
|
page.current = p;
|
page.size = limit;
|
fetchList();
|
};
|
|
const handleSelectionChange = selection => {
|
selectedRows.value = Array.isArray(selection) ? selection : [];
|
};
|
|
const handleRowClick = row => {
|
if (!props.single) return;
|
selectedRows.value = row ? [row] : [];
|
};
|
|
const handleConfirm = () => {
|
if (selectedRows.value.length === 0) return;
|
emit("confirm", selectedRows.value);
|
visibleProxy.value = false;
|
};
|
|
const handleClose = () => {
|
selectedRows.value = [];
|
};
|
|
watch(
|
() => props.modelValue,
|
val => {
|
if (!val) return;
|
page.current = 1;
|
selectedRows.value = [];
|
fetchList();
|
}
|
);
|
|
onMounted(() => {
|
if (props.modelValue) fetchList();
|
});
|
</script>
|
|
<style scoped>
|
.search-row {
|
display: flex;
|
align-items: center;
|
gap: 12px;
|
padding-bottom: 12px;
|
}
|
</style>
|