<template>
|
<div class="inbound-page">
|
<!-- 搜索 -->
|
<el-card class="search-card" shadow="never">
|
<el-form :inline="true" :model="queryForm" label-width="90px">
|
<el-form-item label="单据编号">
|
<el-input v-model="queryForm.inboundOrderNo" placeholder="请输入单据编号" clearable style="width: 170px" />
|
</el-form-item>
|
<el-form-item label="上游单据">
|
<el-input v-model="queryForm.upperOrderNo" placeholder="请输入上游单据编号" clearable style="width: 170px" />
|
</el-form-item>
|
<el-form-item label="单据类型">
|
<el-select v-model="queryForm.orderType" placeholder="请选择" clearable style="width: 150px">
|
<el-option v-for="item in orderTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="单据状态">
|
<el-select v-model="queryForm.orderStatus" placeholder="请选择" clearable style="width: 140px">
|
<el-option v-for="item in orderStatusOptions" :key="item.key" :label="item.value" :value="item.key" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="创建时间">
|
<el-date-picker v-model="queryForm.createDate" type="daterange" range-separator="至" start-placeholder="开始" end-placeholder="结束" value-format="YYYY-MM-DD" />
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" @click="handleSearch">查询</el-button>
|
<el-button @click="handleReset">重置</el-button>
|
</el-form-item>
|
</el-form>
|
</el-card>
|
|
<!-- 表格 -->
|
<el-card class="table-card" shadow="never">
|
<div class="toolbar">
|
<el-button type="primary" @click="handleAdd">新增</el-button>
|
<el-button type="danger" :disabled="!selectedRows.length" @click="handleBatchDelete">批量删除</el-button>
|
</div>
|
|
<el-table v-loading="loading" :data="tableData" border stripe @selection-change="handleSelectionChange">
|
<el-table-column type="selection" width="50" align="center" />
|
<el-table-column prop="inboundOrderNo" label="单据编号" min-width="140" show-overflow-tooltip />
|
<el-table-column prop="upperOrderNo" label="上游单据编号" min-width="150" show-overflow-tooltip />
|
<el-table-column prop="warehouseId" label="仓库" min-width="100" align="center">
|
<template #default="{ row }">
|
{{ getWarehouseText(row.warehouseId) }}
|
</template>
|
</el-table-column>
|
<el-table-column prop="orderType" label="单据类型" min-width="140" align="center">
|
<template #default="{ row }">
|
{{ getOrderTypeText(row.orderType) }}
|
</template>
|
</el-table-column>
|
<el-table-column prop="orderStatus" label="单据状态" min-width="100" align="center">
|
<template #default="{ row }">
|
{{ getOrderStatusText(row.orderStatus) }}
|
</template>
|
</el-table-column>
|
<el-table-column prop="createType" label="创建方式" min-width="110" align="center">
|
<template #default="{ row }">
|
{{ getCreateTypeText(row.createType) }}
|
</template>
|
</el-table-column>
|
<el-table-column prop="creater" label="创建人" min-width="90" align="center" />
|
<el-table-column prop="createDate" label="创建时间" min-width="160" align="center" />
|
<el-table-column label="操作" width="180" align="center" fixed="right">
|
<template #default="{ row }">
|
<el-button link type="primary" size="small" @click="goDetail(row)">明细</el-button>
|
<el-button link type="primary" size="small" @click="handleEdit(row)">编辑</el-button>
|
<el-button link type="danger" size="small" @click="handleDelete(row)">删除</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
|
<el-pagination
|
v-model:current-page="pagination.page"
|
v-model:page-size="pagination.pageSize"
|
:total="pagination.total"
|
:page-sizes="[10, 20, 50, 100]"
|
layout="total, sizes, prev, pager, next, jumper"
|
@size-change="handleSizeChange"
|
@current-change="handlePageChange"
|
style="margin-top: 16px; justify-content: flex-end"
|
/>
|
</el-card>
|
|
<!-- 明细抽屉 -->
|
<el-drawer v-model="detailDrawerVisible" title="入库单明细" size="70%" direction="rtl" destroy-on-close>
|
<el-table :data="detailTableData" border stripe max-height="600">
|
<el-table-column prop="materielCode" label="物料编号" min-width="150" show-overflow-tooltip />
|
<el-table-column prop="materielName" label="物料名称" min-width="150" show-overflow-tooltip />
|
<el-table-column prop="batchNo" label="批次号" min-width="120" align="center" />
|
<el-table-column prop="orderQuantity" label="单据数量" min-width="100" align="center" />
|
<el-table-column prop="receiptQuantity" label="组盘数量" min-width="120" align="center" />
|
<el-table-column prop="overInQuantity" label="上架数量" min-width="120" align="center" />
|
<el-table-column prop="orderDetailStatus" label="明细状态" min-width="110" align="center">
|
<template #default="{ row }">
|
{{ getDetailStatusText(row.orderDetailStatus) }}
|
</template>
|
</el-table-column>
|
<el-table-column prop="creater" label="创建人" min-width="90" align="center" />
|
<el-table-column prop="createDate" label="创建时间" min-width="160" align="center" />
|
</el-table>
|
</el-drawer>
|
|
<!-- 编辑弹窗 -->
|
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="560px" destroy-on-close>
|
<el-form :model="editForm" :rules="editRules" ref="editFormRef" label-width="100px">
|
<el-form-item label="单据类型" prop="orderType">
|
<el-select v-model="editForm.orderType" placeholder="请选择单据类型" style="width: 100%">
|
<el-option v-for="item in orderTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="单据编号" prop="inboundOrderNo">
|
<el-input v-model="editForm.inboundOrderNo" placeholder="请输入单据编号" />
|
</el-form-item>
|
<el-form-item label="上游单据">
|
<el-input v-model="editForm.upperOrderNo" placeholder="请输入上游单据编号" />
|
</el-form-item>
|
<el-form-item label="仓库" prop="warehouseId">
|
<el-select v-model="editForm.warehouseId" placeholder="请选择仓库" style="width: 100%">
|
<el-option v-for="item in warehouseOptions" :key="item.key" :label="item.value" :value="item.key" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="备注">
|
<el-input v-model="editForm.remark" type="textarea" :rows="3" placeholder="请输入备注" />
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, reactive, onMounted } from 'vue';
|
import { useRouter } from 'vue-router';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
import { inboundApi } from '@/api/modules/inbound';
|
import { client } from '@/api/client';
|
|
const router = useRouter();
|
|
// 搜索
|
const queryForm = reactive({ inboundOrderNo: '', upperOrderNo: '', orderType: undefined, orderStatus: undefined, createDate: '' });
|
|
// 表格
|
const loading = ref(false);
|
const tableData = ref([]);
|
const selectedRows = ref([]);
|
|
// 字典
|
const orderTypeOptions = ref([]);
|
const orderStatusOptions = ref([]);
|
const warehouseOptions = ref([]);
|
const createTypeOptions = ref([]);
|
const detailStatusOptions = ref([]);
|
|
// 分页
|
const pagination = reactive({ page: 1, pageSize: 20, total: 0 });
|
|
// 明细抽屉
|
const detailDrawerVisible = ref(false);
|
const detailTableData = ref([]);
|
const currentRow = ref(null);
|
|
// 编辑弹窗
|
const dialogVisible = ref(false);
|
const dialogTitle = ref('新增入库单');
|
const editFormRef = ref(null);
|
const submitLoading = ref(false);
|
const editForm = reactive({ id: undefined, orderType: undefined, inboundOrderNo: '', upperOrderNo: '', warehouseId: undefined, remark: '' });
|
const editRules = {
|
orderType: [{ required: true, message: '请选择单据类型', trigger: 'change' }],
|
inboundOrderNo: [{ required: true, message: '请输入单据编号', trigger: 'blur' }],
|
warehouseId: [{ required: true, message: '请选择仓库', trigger: 'change' }],
|
};
|
|
async function loadData() {
|
loading.value = true;
|
try {
|
const wheres = [
|
queryForm.inboundOrderNo ? { name: 'inboundOrderNo', value: queryForm.inboundOrderNo, displayType: 'like' } : null,
|
queryForm.upperOrderNo ? { name: 'upperOrderNo', value: queryForm.upperOrderNo, displayType: 'like' } : null,
|
queryForm.orderType !== undefined ? { name: 'orderType', value: queryForm.orderType, displayType: 'int' } : null,
|
queryForm.orderStatus !== undefined ? { name: 'orderStatus', value: queryForm.orderStatus, displayType: 'int' } : null,
|
].filter(Boolean);
|
const res = await inboundApi.getPageList({ page: pagination.page, rows: pagination.pageSize, sort: 'id', order: 'desc', wheres: JSON.stringify(wheres) });
|
tableData.value = res?.rows || [];
|
pagination.total = res?.total || 0;
|
} catch { ElMessage.error('加载数据失败'); }
|
finally { loading.value = false; }
|
}
|
|
async function loadDetail(row) {
|
try {
|
const res = await client.post('/api/InboundOrderDetail/getPageList', {
|
page: 1, rows: 200, sort: 'id', order: 'asc',
|
wheres: JSON.stringify([{ name: 'orderId', value: row.id, displayType: 'int' }]),
|
});
|
detailTableData.value = res?.rows || [];
|
} catch { detailTableData.value = []; ElMessage.error('加载明细失败'); }
|
}
|
|
async function loadDictionary() {
|
try {
|
const res = await client.post('/api/Sys_Dictionary/GetVueDictionary', ['inOrderType', 'inboundState', 'warehouses', 'createType', 'orderDetailStatusEnum']);
|
const findData = (dicNo) => res?.find(item => item.dicNo === dicNo)?.data || [];
|
orderTypeOptions.value = findData('inOrderType');
|
orderStatusOptions.value = findData('inboundState');
|
warehouseOptions.value = findData('warehouses');
|
createTypeOptions.value = findData('createType');
|
detailStatusOptions.value = findData('orderDetailStatusEnum');
|
} catch {
|
orderTypeOptions.value = []; orderStatusOptions.value = []; warehouseOptions.value = [];
|
}
|
}
|
|
function goDetail(row) { router.push({ path: '/inbound/inboundOrderDetail', query: { id: row.id, inboundOrderNo: row.inboundOrderNo } }); }
|
|
function handleSearch() { pagination.page = 1; loadData(); }
|
function handleReset() { queryForm.inboundOrderNo = ''; queryForm.upperOrderNo = ''; queryForm.orderType = undefined; queryForm.orderStatus = undefined; queryForm.createDate = ''; handleSearch(); }
|
|
function handleAdd() {
|
editForm.id = undefined; editForm.orderType = undefined; editForm.inboundOrderNo = ''; editForm.upperOrderNo = ''; editForm.warehouseId = undefined; editForm.remark = '';
|
dialogTitle.value = '新增入库单'; dialogVisible.value = true;
|
}
|
|
function handleEdit(row) {
|
Object.assign(editForm, { id: row.id, orderType: row.orderType, inboundOrderNo: row.inboundOrderNo, upperOrderNo: row.upperOrderNo, warehouseId: row.warehouseId, remark: row.remark });
|
dialogTitle.value = '编辑入库单'; dialogVisible.value = true;
|
}
|
|
async function handleSubmit() {
|
await editFormRef.value.validate();
|
submitLoading.value = true;
|
try {
|
if (editForm.id) { await inboundApi.update(editForm); ElMessage.success('更新成功'); }
|
else { await inboundApi.add(editForm); ElMessage.success('新增成功'); }
|
dialogVisible.value = false; loadData();
|
} catch { ElMessage.error('操作失败'); }
|
finally { submitLoading.value = false; }
|
}
|
|
function handleDelete(row) {
|
ElMessageBox.confirm(`确定删除入库单「${row.inboundOrderNo}」吗?`, '提示', { type: 'warning' })
|
.then(async () => { await inboundApi.deleteById(row.id); ElMessage.success('删除成功'); loadData(); }).catch(() => {});
|
}
|
|
function handleBatchDelete() {
|
const ids = selectedRows.value.map(r => r.id);
|
ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条记录吗?`, '提示', { type: 'warning' })
|
.then(async () => { await Promise.all(ids.map(id => inboundApi.deleteById(id))); ElMessage.success('删除成功'); loadData(); }).catch(() => {});
|
}
|
|
function handleSelectionChange(rows) { selectedRows.value = rows; }
|
function handleSizeChange() { loadData(); }
|
function handlePageChange() { loadData(); }
|
|
const getWarehouseText = (val) => warehouseOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
|
const getOrderTypeText = (val) => orderTypeOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
|
const getOrderStatusText = (val) => orderStatusOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
|
const getCreateTypeText = (val) => createTypeOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
|
const getDetailStatusText = (val) => detailStatusOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
|
|
onMounted(() => { loadDictionary(); loadData(); });
|
</script>
|
|
<style scoped>
|
.inbound-page { padding: 16px; }
|
.search-card { margin-bottom: 12px; }
|
.table-card { margin-bottom: 12px; }
|
.toolbar { margin-bottom: 12px; }
|
</style>
|