优化库位和库区管理的仓库选择交互,将下拉选择改为弹窗选择模式,新增库位必填字段验证,调整盘点管理导入功能从列表操作移至详情操作,优化查询条件从ID改为名称模糊查询

This commit is contained in:
WUSIJIAN
2026-02-28 16:03:33 +08:00
parent 95b97314a2
commit 7e2595467b
9 changed files with 607 additions and 115 deletions

View File

@@ -101,8 +101,9 @@ export function exportInventoryCountTemplate() {
}
// 上传盘点Excel
export function importInventoryCount(file: File) {
export function importInventoryCount(id: string, file: File) {
const formData = new FormData();
formData.append('id', id);
formData.append('file', file);
return newService({
url: 'assets/inventory/count/importInventoryCount',

View File

@@ -0,0 +1,141 @@
<template>
<el-dialog title="选择仓库" v-model="isShowDialog" width="700px" :close-on-click-modal="false" @close="onCancel">
<div class="search-box mb15">
<el-input v-model="searchKeyword" placeholder="请输入关键词搜索" clearable style="width: 300px" @keyup.enter="onSearch">
<template #append>
<el-button :icon="Search" @click="onSearch" />
</template>
</el-input>
</div>
<el-table :data="tableData.data" style="width: 100%" v-loading="tableData.loading" border highlight-current-row @current-change="onCurrentChange">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="warehouseName" label="仓库名称" min-width="200" show-overflow-tooltip />
<el-table-column prop="warehouseCode" label="编码" width="150" show-overflow-tooltip />
</el-table>
<div class="mt15" style="text-align: right">
<el-pagination
v-model:current-page="tableData.param.pageNum"
v-model:page-size="tableData.param.pageSize"
:page-sizes="[10, 20, 50, 100]"
:total="tableData.total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="onSizeChange"
@current-change="onPageChange"
/>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="onCancel"> </el-button>
<el-button type="primary" @click="onConfirm"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts">
export default {
name: 'selectWarehouseDialog',
};
</script>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import { Search } from '@element-plus/icons-vue';
import { listWarehouses } from '/@/api/assets/warehouse';
// 定义事件
const emit = defineEmits(['confirm']);
// 弹窗状态
const isShowDialog = ref(false);
// 搜索关键词
const searchKeyword = ref('');
// 当前选中的行
const currentRow = ref<any>(null);
// 表格数据
const tableData = reactive({
data: [] as any[],
total: 0,
loading: false,
param: {
keyword: '',
pageNum: 1,
pageSize: 10,
},
});
// 获取仓库列表
const getWarehouseList = async () => {
tableData.loading = true;
try {
tableData.param.keyword = searchKeyword.value;
const res: any = await listWarehouses(tableData.param);
tableData.data = res.data?.list || [];
tableData.total = res.data?.total || 0;
} catch (error) {
console.error('获取仓库列表失败:', error);
} finally {
tableData.loading = false;
}
};
// 搜索
const onSearch = () => {
tableData.param.pageNum = 1;
getWarehouseList();
};
// 表格行选中
const onCurrentChange = (row: any) => {
currentRow.value = row;
};
// 分页大小改变
const onSizeChange = (size: number) => {
tableData.param.pageSize = size;
getWarehouseList();
};
// 当前页改变
const onPageChange = (page: number) => {
tableData.param.pageNum = page;
getWarehouseList();
};
// 打开弹窗
const openDialog = () => {
searchKeyword.value = '';
currentRow.value = null;
tableData.param.pageNum = 1;
isShowDialog.value = true;
getWarehouseList();
};
// 取消
const onCancel = () => {
isShowDialog.value = false;
};
// 确定
const onConfirm = () => {
if (currentRow.value) {
emit('confirm', currentRow.value);
}
isShowDialog.value = false;
};
// 暴露方法
defineExpose({
openDialog,
});
</script>
<style scoped lang="scss">
.search-box {
display: flex;
align-items: center;
}
</style>

View File

@@ -0,0 +1,147 @@
<template>
<el-dialog title="选择库区" v-model="isShowDialog" width="700px" :close-on-click-modal="false" @close="onCancel">
<div class="search-box mb15">
<el-input v-model="searchKeyword" placeholder="请输入关键词搜索" clearable style="width: 300px" @keyup.enter="onSearch">
<template #append>
<el-button :icon="Search" @click="onSearch" />
</template>
</el-input>
</div>
<el-table :data="tableData.data" style="width: 100%" v-loading="tableData.loading" border highlight-current-row @current-change="onCurrentChange">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="zoneName" label="库区名称" min-width="200" show-overflow-tooltip />
<el-table-column prop="zoneCode" label="编码" width="150" show-overflow-tooltip />
</el-table>
<div class="mt15" style="text-align: right">
<el-pagination
v-model:current-page="tableData.param.pageNum"
v-model:page-size="tableData.param.pageSize"
:page-sizes="[10, 20, 50, 100]"
:total="tableData.total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="onSizeChange"
@current-change="onPageChange"
/>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="onCancel"> </el-button>
<el-button type="primary" @click="onConfirm"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts">
export default {
name: 'selectZoneDialog',
};
</script>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import { Search } from '@element-plus/icons-vue';
import { listZones } from '/@/api/assets/zone';
// 定义事件
const emit = defineEmits(['confirm']);
// 弹窗状态
const isShowDialog = ref(false);
// 搜索关键词
const searchKeyword = ref('');
// 当前选中的行
const currentRow = ref<any>(null);
// 仓库ID
const warehouseId = ref('');
// 表格数据
const tableData = reactive({
data: [] as any[],
total: 0,
loading: false,
param: {
keyword: '',
warehouseId: '',
pageNum: 1,
pageSize: 10,
},
});
// 获取库区列表
const getZoneList = async () => {
tableData.loading = true;
try {
tableData.param.keyword = searchKeyword.value;
tableData.param.warehouseId = warehouseId.value;
const res: any = await listZones(tableData.param);
tableData.data = res.data?.list || [];
tableData.total = res.data?.total || 0;
} catch (error) {
console.error('获取库区列表失败:', error);
} finally {
tableData.loading = false;
}
};
// 搜索
const onSearch = () => {
tableData.param.pageNum = 1;
getZoneList();
};
// 表格行选中
const onCurrentChange = (row: any) => {
currentRow.value = row;
};
// 分页大小改变
const onSizeChange = (size: number) => {
tableData.param.pageSize = size;
getZoneList();
};
// 当前页改变
const onPageChange = (page: number) => {
tableData.param.pageNum = page;
getZoneList();
};
// 打开弹窗
const openDialog = (filterWarehouseId?: string) => {
searchKeyword.value = '';
currentRow.value = null;
tableData.param.pageNum = 1;
warehouseId.value = filterWarehouseId || '';
isShowDialog.value = true;
getZoneList();
};
// 取消
const onCancel = () => {
isShowDialog.value = false;
};
// 确定
const onConfirm = () => {
if (currentRow.value) {
emit('confirm', currentRow.value);
}
isShowDialog.value = false;
};
// 暴露方法
defineExpose({
openDialog,
});
</script>
<style scoped lang="scss">
.search-box {
display: flex;
align-items: center;
}
</style>

View File

@@ -22,16 +22,20 @@
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="所属仓库" prop="warehouseId">
<el-select v-model="ruleForm.warehouseId" placeholder="请选择仓库" clearable style="width: 100%" @change="onWarehouseChange">
<el-option v-for="item in warehouseOptions" :key="item.id" :label="item.warehouseName" :value="item.id" />
</el-select>
<el-input v-model="warehouseDisplayName" placeholder="请选择仓库" readonly style="width: 100%" @click="onSelectWarehouse">
<template #append>
<el-button :icon="Search" @click="onSelectWarehouse" />
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属库区" prop="zoneId">
<el-select v-model="ruleForm.zoneId" placeholder="请选择库区" clearable style="width: 100%">
<el-option v-for="item in filteredZoneOptions" :key="item.id" :label="item.zoneName" :value="item.id" />
</el-select>
<el-input v-model="zoneDisplayName" placeholder="请选择仓库" readonly :disabled="!ruleForm.warehouseId" style="width: 100%" @click="onSelectZone">
<template #append>
<el-button :icon="Search" @click="onSelectZone" />
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
@@ -93,6 +97,8 @@
</span>
</template>
</el-dialog>
<SelectWarehouseDialog ref="selectWarehouseRef" @confirm="onWarehouseSelected" />
<SelectZoneDialog ref="selectZoneRef" @confirm="onZoneSelected" />
</template>
<script lang="ts">
@@ -102,10 +108,13 @@ export default {
</script>
<script setup lang="ts">
import { ref, reactive, computed } from 'vue';
import { ref, reactive } from 'vue';
import { ElMessage } from 'element-plus';
import { Search } from '@element-plus/icons-vue';
import type { FormInstance, FormRules } from 'element-plus';
import { createLocation, updateLocation, getLocation, getCapacityUnitType } from '/@/api/assets/location';
import SelectWarehouseDialog from '/@/views/assets/component/selectWarehouseDialog.vue';
import SelectZoneDialog from '/@/views/assets/component/selectZoneDialog.vue';
// 定义props
const props = defineProps<{
@@ -127,6 +136,44 @@ const submitLoading = ref(false);
// 容量单位类型选项
const capacityUnitTypeOptions = ref<{ label: string; value: string }[]>([]);
// 仓库选择弹窗ref
const selectWarehouseRef = ref();
// 库区选择弹窗ref
const selectZoneRef = ref();
// 仓库显示名称
const warehouseDisplayName = ref('');
// 库区显示名称
const zoneDisplayName = ref('');
// 打开仓库选择弹窗
const onSelectWarehouse = () => {
selectWarehouseRef.value?.openDialog();
};
// 打开库区选择弹窗
const onSelectZone = () => {
if (!ruleForm.warehouseId) {
ElMessage.warning('请先选择仓库');
return;
}
selectZoneRef.value?.openDialog(ruleForm.warehouseId);
};
// 仓库选择确认
const onWarehouseSelected = (row: any) => {
ruleForm.warehouseId = row.id;
warehouseDisplayName.value = row.warehouseName;
// 清空库区选择
ruleForm.zoneId = '';
zoneDisplayName.value = '';
};
// 库区选择确认
const onZoneSelected = (row: any) => {
ruleForm.zoneId = row.id;
zoneDisplayName.value = row.zoneName;
};
// 表单数据
const ruleForm = reactive({
id: '',
@@ -142,24 +189,16 @@ const ruleForm = reactive({
remark: '',
});
// 根据选中的仓库过滤库区选项
const filteredZoneOptions = computed(() => {
if (!ruleForm.warehouseId) {
return props.zoneOptions;
}
return props.zoneOptions.filter((z: any) => z.warehouseId === ruleForm.warehouseId);
});
// 仓库选择变化时清空库区选择
const onWarehouseChange = () => {
ruleForm.zoneId = '';
};
// 表单验证规则
const rules = reactive<FormRules>({
locationName: [{ required: true, message: '请输入库位名称', trigger: 'blur' }],
locationCode: [{ required: true, message: '请输入库位编码', trigger: 'blur' }],
locationType: [{ required: true, message: '请选择库位类型', trigger: 'change' }],
warehouseId: [{ required: true, message: '请选择所属仓库', trigger: 'change' }],
zoneId: [{ required: true, message: '请选择所属库区', trigger: 'change' }],
capacityUnitType: [{ required: true, message: '请选择容量单位类型', trigger: 'change' }],
capacityUnit: [{ required: true, message: '请输入容量单位', trigger: 'blur' }],
maxCapacity: [{ required: true, message: '请输入最大容量', trigger: 'blur' }],
});
// 重置表单
@@ -175,6 +214,8 @@ const resetForm = () => {
ruleForm.capacityUnit = '';
ruleForm.maxCapacity = 0;
ruleForm.remark = '';
warehouseDisplayName.value = '';
zoneDisplayName.value = '';
};
// 加载容量单位类型选项
@@ -210,6 +251,8 @@ const openDialog = async (row?: any) => {
ruleForm.locationType = data.locationType || '';
ruleForm.warehouseId = data.warehouseId || '';
ruleForm.zoneId = data.zoneId || '';
warehouseDisplayName.value = data.warehouseName || '';
zoneDisplayName.value = data.zoneName || '';
ruleForm.status = data.status || 'idle';
ruleForm.capacityUnitType = data.capacityUnitType || '';
ruleForm.capacityUnit = data.capacityUnit || '';

View File

@@ -8,14 +8,10 @@
<el-input size="default" v-model="tableData.param.keyword" placeholder="请输入库位名称" clearable style="width: 200px" />
</el-form-item>
<el-form-item label="所属仓库">
<el-select size="default" v-model="tableData.param.warehouseId" placeholder="请选择仓库" clearable style="width: 180px" @change="onWarehouseChange">
<el-option v-for="item in warehouseOptions" :key="item.id" :label="item.warehouseName" :value="item.id" />
</el-select>
<el-input size="default" v-model="tableData.param.warehouseName" placeholder="请输入仓库名称" clearable style="width: 180px" />
</el-form-item>
<el-form-item label="所属库区">
<el-select size="default" v-model="tableData.param.zoneId" placeholder="请选择库区" clearable style="width: 180px">
<el-option v-for="item in filteredZoneOptions" :key="item.id" :label="item.zoneName" :value="item.id" />
</el-select>
<el-input size="default" v-model="tableData.param.zoneName" placeholder="请输入库区名称" clearable style="width: 180px" />
</el-form-item>
<el-form-item label="状态">
<el-select size="default" v-model="tableData.param.status" placeholder="请选择状态" clearable style="width: 120px">
@@ -90,7 +86,7 @@ export default {
</script>
<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue';
import { ref, reactive, onMounted } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { listLocations, deleteLocation } from '/@/api/assets/location';
import { listWarehouses } from '/@/api/assets/warehouse';
@@ -105,8 +101,8 @@ const tableData = reactive({
loading: false,
param: {
keyword: '',
warehouseId: '',
zoneId: '',
warehouseName: '',
zoneName: '',
status: undefined as string | undefined,
pageNum: 1,
pageSize: 10,
@@ -118,14 +114,6 @@ const warehouseOptions = ref<any[]>([]);
// 库区选项
const zoneOptions = ref<any[]>([]);
// 根据选中的仓库过滤库区选项
const filteredZoneOptions = computed(() => {
if (!tableData.param.warehouseId) {
return zoneOptions.value;
}
return zoneOptions.value.filter((z: any) => z.warehouseId === tableData.param.warehouseId);
});
// 编辑弹窗ref
const editLocationRef = ref();
// 日志弹窗ref
@@ -151,11 +139,6 @@ const getZoneOptions = async () => {
}
};
// 仓库选择变化时清空库区选择
const onWarehouseChange = () => {
tableData.param.zoneId = '';
};
// 获取库位列表
const getLocationList = async () => {
tableData.loading = true;
@@ -181,8 +164,8 @@ const getLocationList = async () => {
// 重置查询
const onResetQuery = () => {
tableData.param.keyword = '';
tableData.param.warehouseId = '';
tableData.param.zoneId = '';
tableData.param.warehouseName = '';
tableData.param.zoneName = '';
tableData.param.status = undefined;
tableData.param.pageNum = 1;
getLocationList();

View File

@@ -0,0 +1,209 @@
<template>
<el-dialog title="导入盘点" v-model="isShowDialog" width="550px" :close-on-click-modal="false" @close="onCancel">
<el-alert title="请先选择要上传的Excel文件" type="warning" :closable="false" show-icon class="mb15" />
<el-upload
ref="uploadRef"
class="upload-area"
drag
action="#"
:auto-upload="false"
:show-file-list="true"
:limit="1"
accept=".xlsx,.xls"
:on-change="handleFileChange"
:on-exceed="handleExceed"
>
<el-icon class="el-icon--upload"><ele-Upload /></el-icon>
<div class="el-upload__text">
将Excel文件拖到此处<em>点击上传</em>
</div>
</el-upload>
<div class="upload-tip">支持 .xlsx, .xls 格式文件大小不超过 10MB</div>
<div class="import-tips">
<div class="tips-title">导入说明</div>
<ul class="tips-list">
<li>1. 请先<el-link type="primary" @click="onDownloadTemplate">下载导入模板</el-link>查看数据格式</li>
<li>2. 按照模板格式准备您的盘点数据</li>
<li>3. 选择准备好的Excel文件上传</li>
<li>4. 文件编码请使用UTF-8</li>
<li>5. 文件大小不能超过 10MB</li>
</ul>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="onCancel"> </el-button>
<el-button type="primary" @click="onSubmit" :loading="submitLoading" :disabled="!selectedFile"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts">
export default {
name: 'importDialog',
};
</script>
<script setup lang="ts">
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
import type { UploadFile, UploadInstance, UploadRawFile } from 'element-plus';
import { exportInventoryCountTemplate, importInventoryCount } from '/@/api/assets/operation/count';
// 定义事件
const emit = defineEmits(['refresh']);
// 弹窗状态
const isShowDialog = ref(false);
const submitLoading = ref(false);
// 盘点任务ID
const countId = ref('');
// 上传组件ref
const uploadRef = ref<UploadInstance>();
// 选中的文件
const selectedFile = ref<UploadRawFile | null>(null);
// 文件变化
const handleFileChange = (file: UploadFile) => {
if (file.raw) {
// 校验文件大小
const isLt10M = file.raw.size / 1024 / 1024 < 10;
if (!isLt10M) {
ElMessage.error('文件大小不能超过 10MB');
uploadRef.value?.clearFiles();
selectedFile.value = null;
return;
}
selectedFile.value = file.raw;
}
};
// 文件超出限制
const handleExceed = () => {
ElMessage.warning('只能上传一个文件,请先删除已选文件');
};
// 下载模板
const onDownloadTemplate = async () => {
try {
const res = await exportInventoryCountTemplate();
const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = '盘点模板.xlsx';
link.click();
window.URL.revokeObjectURL(url);
ElMessage.success('模板下载成功');
} catch (error) {
console.error('下载模板失败:', error);
ElMessage.error('下载模板失败');
}
};
// 打开弹窗
const openDialog = (id: string) => {
if (!id) {
ElMessage.warning('请先选择要导入的盘点任务');
return;
}
countId.value = id;
selectedFile.value = null;
uploadRef.value?.clearFiles();
isShowDialog.value = true;
};
// 取消
const onCancel = () => {
isShowDialog.value = false;
selectedFile.value = null;
uploadRef.value?.clearFiles();
};
// 提交
const onSubmit = async () => {
if (!selectedFile.value) {
ElMessage.warning('请先选择要上传的文件');
return;
}
submitLoading.value = true;
try {
const res = await importInventoryCount(countId.value, selectedFile.value);
if (res.data.code === 200) {
ElMessage.success('导入成功');
isShowDialog.value = false;
emit('refresh');
} else {
ElMessage.error(res.data.msg || '导入失败');
}
} catch (error) {
console.error('导入失败:', error);
ElMessage.error('导入失败');
} finally {
submitLoading.value = false;
uploadRef.value?.clearFiles();
selectedFile.value = null;
}
};
// 暴露方法
defineExpose({
openDialog,
});
</script>
<style scoped lang="scss">
.upload-area {
width: 100%;
:deep(.el-upload) {
width: 100%;
}
:deep(.el-upload-dragger) {
width: 100%;
height: 150px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
}
.upload-tip {
font-size: 12px;
color: #909399;
margin-top: 8px;
}
.import-tips {
margin-top: 20px;
padding: 15px;
background-color: #f5f7fa;
border-radius: 4px;
.tips-title {
font-size: 14px;
font-weight: bold;
color: #303133;
margin-bottom: 10px;
}
.tips-list {
margin: 0;
padding: 0;
list-style: none;
li {
font-size: 13px;
color: #606266;
line-height: 24px;
}
}
}
</style>

View File

@@ -36,24 +36,6 @@
<el-icon><ele-Plus /></el-icon>
新增
</el-button>
<el-button size="default" type="warning" @click="onExportTemplate">
<el-icon><ele-Download /></el-icon>
导出模板
</el-button>
<el-upload
ref="uploadRef"
action="#"
:auto-upload="false"
:show-file-list="false"
accept=".xlsx,.xls"
:on-change="handleImportChange"
style="display: inline-block; margin-left: 10px;"
>
<el-button size="default" type="info" :loading="importLoading">
<el-icon><ele-Upload /></el-icon>
导入
</el-button>
</el-upload>
</el-form-item>
</el-form>
</div>
@@ -88,9 +70,9 @@
</el-table-column>
<el-table-column prop="assigneeName" label="负责人" width="100" align="center" />
<el-table-column prop="createdAt" label="创建时间" width="170" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right" align="center">
<el-table-column label="操作" width="150" fixed="right" align="center">
<template #default="scope">
<el-button link type="primary" @click="onOpenImport(scope.row)">导入</el-button>
<el-button link type="danger" @click="onDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
@@ -110,6 +92,7 @@
</el-card>
</div>
<EditInventoryCount ref="editRef" @refresh="getList" />
<ImportDialog ref="importRef" @refresh="getList" />
</div>
</template>
@@ -122,13 +105,12 @@ export default {
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { listInventoryCounts, deleteInventoryCount, completeInventoryCount, cancelInventoryCount, exportInventoryCountTemplate, importInventoryCount } from '/@/api/assets/operation/count';
import type { UploadFile } from 'element-plus';
import { listInventoryCounts, deleteInventoryCount, completeInventoryCount, cancelInventoryCount } from '/@/api/assets/operation/count';
import EditInventoryCount from './component/editInventoryCount.vue';
import ImportDialog from './component/importDialog.vue';
const editRef = ref();
const uploadRef = ref();
const importLoading = ref(false);
const importRef = ref();
const tableData = reactive({
data: [] as any[],
@@ -312,44 +294,9 @@ const onDelete = (row: any) => {
}).catch(() => {});
};
// 导出模板
const onExportTemplate = async () => {
try {
const res = await exportInventoryCountTemplate();
const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = '盘点模板.xlsx';
link.click();
window.URL.revokeObjectURL(url);
ElMessage.success('导出成功');
} catch (error) {
console.error('导出模板失败:', error);
ElMessage.error('导出模板失败');
}
};
// 导入文件变化
const handleImportChange = async (file: UploadFile) => {
if (!file.raw) return;
importLoading.value = true;
try {
const res = await importInventoryCount(file.raw);
if (res.data.code === 200) {
ElMessage.success('导入成功');
getList();
} else {
ElMessage.error(res.data.msg || '导入失败');
}
} catch (error) {
console.error('导入失败:', error);
ElMessage.error('导入失败');
} finally {
importLoading.value = false;
uploadRef.value?.clearFiles();
}
// 打开导入弹窗
const onOpenImport = (row: any) => {
importRef.value?.openDialog(row.id);
};
// 分页大小变化

View File

@@ -22,9 +22,11 @@
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="所属仓库" prop="warehouseId">
<el-select v-model="ruleForm.warehouseId" placeholder="请选择仓库" clearable style="width: 100%">
<el-option v-for="item in warehouseOptions" :key="item.id" :label="item.warehouseName" :value="item.id" />
</el-select>
<el-input v-model="warehouseDisplayName" placeholder="请选择仓库" readonly style="width: 100%" @click="onSelectWarehouse">
<template #append>
<el-button :icon="Search" @click="onSelectWarehouse" />
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -54,6 +56,7 @@
</span>
</template>
</el-dialog>
<SelectWarehouseDialog ref="selectWarehouseRef" @confirm="onWarehouseSelected" />
</template>
<script lang="ts">
@@ -65,8 +68,10 @@ export default {
<script setup lang="ts">
import { ref, reactive } from 'vue';
import { ElMessage } from 'element-plus';
import { Search } from '@element-plus/icons-vue';
import type { FormInstance, FormRules } from 'element-plus';
import { createZone, updateZone, getZone } from '/@/api/assets/zone';
import SelectWarehouseDialog from '/@/views/assets/component/selectWarehouseDialog.vue';
// 定义props
defineProps<{
@@ -84,6 +89,22 @@ const isShowDialog = ref(false);
const isEdit = ref(false);
const submitLoading = ref(false);
// 仓库选择弹窗ref
const selectWarehouseRef = ref();
// 仓库显示名称
const warehouseDisplayName = ref('');
// 打开仓库选择弹窗
const onSelectWarehouse = () => {
selectWarehouseRef.value?.openDialog();
};
// 仓库选择确认
const onWarehouseSelected = (row: any) => {
ruleForm.warehouseId = row.id;
warehouseDisplayName.value = row.warehouseName;
};
// 表单数据
const ruleForm = reactive({
id: '',
@@ -110,6 +131,7 @@ const resetForm = () => {
ruleForm.zoneType = '';
ruleForm.warehouseId = '';
ruleForm.remark = '';
warehouseDisplayName.value = '';
};
// 打开弹窗
@@ -126,6 +148,7 @@ const openDialog = async (row?: any) => {
ruleForm.zoneCode = data.zoneCode || '';
ruleForm.zoneType = data.zoneType || '';
ruleForm.warehouseId = data.warehouseId || '';
warehouseDisplayName.value = data.warehouseName || '';
ruleForm.remark = data.remark || '';
} catch (error) {
console.error('获取库区详情失败:', error);

View File

@@ -8,9 +8,7 @@
<el-input size="default" v-model="tableData.param.keyword" placeholder="请输入库区名称" clearable style="width: 200px" />
</el-form-item>
<el-form-item label="所属仓库">
<el-select size="default" v-model="tableData.param.warehouseId" placeholder="请选择仓库" clearable style="width: 180px">
<el-option v-for="item in warehouseOptions" :key="item.id" :label="item.warehouseName" :value="item.id" />
</el-select>
<el-input size="default" v-model="tableData.param.warehouseName" placeholder="请输入仓库名称" clearable style="width: 180px" />
</el-form-item>
<el-form-item label="状态">
<el-select size="default" v-model="tableData.param.status" placeholder="请选择状态" clearable style="width: 120px">
@@ -101,7 +99,7 @@ const tableData = reactive({
loading: false,
param: {
keyword: '',
warehouseId: '',
warehouseName: '',
status: undefined as string | undefined,
pageNum: 1,
pageSize: 10,
@@ -150,7 +148,7 @@ const getZoneList = async () => {
// 重置查询
const onResetQuery = () => {
tableData.param.keyword = '';
tableData.param.warehouseId = '';
tableData.param.warehouseName = '';
tableData.param.status = undefined;
tableData.param.pageNum = 1;
getZoneList();