Commit e1b0bfb8 by zhangtw

入库结合物料组件

parent 203b5590
......@@ -33,8 +33,7 @@
:key="item.orderTypeId"
:label="item.orderTypeName"
:value="item.orderTypeId"
>
</el-option>
/>
</el-select>
</el-form-item>
......@@ -45,8 +44,7 @@
:key="item.orderStatus"
:label="item.orderStatusName"
:value="item.orderStatus"
>
</el-option>
/>
</el-select>
</el-form-item>
<el-form-item label="订单类型" prop="orderType">
......@@ -56,8 +54,7 @@
:key="item.orderType"
:label="item.orderTypeName"
:value="item.orderType"
>
</el-option>
/>
</el-select>
</el-form-item>
<el-form-item>
......@@ -118,18 +115,36 @@
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="入库单号" align="center" prop="orderId" />
<el-table-column label="系统编号" align="center" prop="systemNo" />
<el-table-column label="入库类型" align="center" prop="orderTypeId" />
<el-table-column label="入库类型" align="center" prop="orderTypeId">
<template slot-scope="scope">
<el-tag type="success" size="small">
{{ getInBoundTypeName(scope.row.orderTypeId) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="订单类型" align="center" prop="orderType">
<template slot-scope="scope">
<el-tag type="success" size="small">
{{ getOrderTypeName(scope.row.orderType) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="批次ID" align="center" prop="batchCode" />
<el-table-column label="入库单状态" align="center" prop="orderStatus"/>
<el-table-column label="排序" align="center" prop="sortNo" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<el-table-column label="入库单状态" align="center" prop="orderStatus">
<!-- 状态显示 -->
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
<el-tag
:type="getStatusType(scope.row.orderStatus)"
size="small"
>
{{ getStatusName(scope.row.orderStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="更新时间" align="center" prop="updateTime" width="180">
<el-table-column label="创建时间" align="center" prop="createTime" width="120">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span>
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="300">
......@@ -175,8 +190,7 @@
/>
<!-- 添加或修改入库对话框 -->
<el-dialog :title="title" :visible.sync="open" width="1200px" append-to-body>
<el-dialog :title="title" :visible.sync="open" width="1200px" append-to-body class="scrollable-dialog">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<!-- 表单内容保持不变 -->
<el-divider content-position="center">入库单基础信息</el-divider>
......@@ -185,21 +199,20 @@
<el-form-item label="入库单号" prop="orderId">
<el-input v-model="form.orderId" placeholder="请输入入库单号" />
</el-form-item>
<el-form-item label="入库类型" prop="orderTypeId">
<el-input v-model="form.orderTypeId" placeholder="请输入入库类型" />
</el-form-item>
<el-form-item label="货主ID" prop="ownerId">
<el-input v-model="form.ownerId" placeholder="请输入货主ID" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="系统编号" prop="systemNo">
<el-input v-model="form.systemNo" placeholder="请输入系统编号" />
</el-form-item>
<el-form-item label="批次ID" prop="batchCode">
<el-input v-model="form.batchCode" placeholder="请输入批次ID" />
</el-form-item>
<el-form-item label="入库日期" prop="inboundDate" lebel-width="100">
<el-form-item label="入库类型" prop="orderTypeId">
<el-select v-model="form.orderTypeId" placeholder="请选择入库类型" clearable>
<el-option
v-for="item in inBoundTypeOptions"
:key="item.orderTypeId"
:label="item.orderTypeName"
:value="item.orderTypeId"
/>
</el-select>
</el-form-item>
<el-form-item label="入库日期" prop="inboundDate">
<el-date-picker clearable
v-model="form.inboundDate"
type="date"
......@@ -208,11 +221,30 @@
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="系统编号" prop="systemNo">
<el-input v-model="form.systemNo" placeholder="请输入系统编号" />
</el-form-item>
<el-form-item label="货主ID" prop="ownerId">
<el-input v-model="form.ownerId" placeholder="请输入货主ID" />
</el-form-item>
<el-form-item label="订单类型" prop="orderType">
<el-select v-model="form.orderType" placeholder="请选择订单类型" clearable>
<el-option
v-for="item in orderTypeOptions"
:key="item.orderType"
:label="item.orderTypeName"
:value="item.orderType"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-divider content-position="center">入库其他信息</el-divider>
<el-row :gutter="24">
<el-col :span="12">
<div class="form-col">
<el-form-item label="计划量" prop="totalPlannedQuantity">
<el-input v-model="form.totalPlannedQuantity" placeholder="请输入计划量" />
</el-form-item>
......@@ -222,7 +254,9 @@
<el-form-item label="仓库ID" prop="warehouseId">
<el-input v-model="form.warehouseId" placeholder="请输入仓库ID" />
</el-form-item>
</div>
</el-col>
<el-col :span="12">
<el-form-item label="实际量" prop="totalActualQuantity">
<el-input v-model="form.totalActualQuantity" placeholder="请输入实际量" />
......@@ -230,40 +264,22 @@
<el-form-item label="负责人" prop="opUserName">
<el-input v-model="form.opUserName" placeholder="请输入负责人" />
</el-form-item>
<el-form-item label="排序" prop="sortNo">
<!-- <el-form-item label="排序" prop="sortNo">
<el-input v-model="form.sortNo" placeholder="请输入排序" />
</el-form-item>
</el-form-item> -->
</el-col>
</el-row>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"/>
</el-form-item>
</el-row>
<el-divider content-position="center">入库单明细信息</el-divider>
<!-- <el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAddInboundItem"
>添加明细</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
@click="handleDeleteSelectedItems"
>删除选中</el-button>
</el-col>
</el-row> -->
<!-- 入库明细组件 -->
<el-divider content-position="center">入库单明细信息</el-divider>
<InboundItems
ref="inboundItemsRef"
v-model="form.inboundOrderItemsList"
:embedded="true"
:order-id="form.orderId"
:order-id="orderId"
:show-search-form="false"
:show-pagination="false"
:show-toolbar="true"
......@@ -280,6 +296,7 @@
@row-deleted="handleRowDeleted"
@batch-delete="handleBatchDelete"
@cell-change="handleCellChange"
@show-materials="showMaterials"
/>
</el-form>
<div slot="footer" class="dialog-footer">
......@@ -287,17 +304,94 @@
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 入库单详情弹窗 -->
<el-dialog
title="入库单详细信息"
:visible.sync="detailOpen"
width="1200px"
append-to-body
class="scrollable-dialog"
>
<div class="detail-container">
<!-- 基础信息展示 -->
<el-descriptions :column="2" border class="mb20">
<el-descriptions-item label="入库单号">{{ detailForm.orderId || '-' }}</el-descriptions-item>
<el-descriptions-item label="系统编号">{{ detailForm.systemNo || '-' }}</el-descriptions-item>
<el-descriptions-item label="批次ID">{{ detailForm.batchCode || '-' }}</el-descriptions-item>
<el-descriptions-item label="货主ID">{{ detailForm.ownerId || '-' }}</el-descriptions-item>
<el-descriptions-item label="入库类型">
{{ getInBoundTypeName(detailForm.orderTypeId) }}
</el-descriptions-item>
<el-descriptions-item label="订单类型">
{{ getOrderTypeName(detailForm.orderType) }}
</el-descriptions-item>
<el-descriptions-item label="入库日期">{{ detailForm.inboundDate || '-' }}</el-descriptions-item>
<el-descriptions-item label="负责人">{{ detailForm.opUserName || '-' }}</el-descriptions-item>
<el-descriptions-item label="计划量">{{ detailForm.totalPlannedQuantity || '-' }}</el-descriptions-item>
<el-descriptions-item label="实际量">{{ detailForm.totalActualQuantity || '-' }}</el-descriptions-item>
<el-descriptions-item label="总件数">{{ detailForm.totalPackages || '-' }}</el-descriptions-item>
<el-descriptions-item label="仓库ID">{{ detailForm.warehouseId || '-' }}</el-descriptions-item>
<!-- <el-descriptions-item label="排序">{{ detailForm.sortNo || '-' }}</el-descriptions-item> -->
<el-descriptions-item label="备注" :span="2">
<div class="remark-text">{{ detailForm.remark || '-' }}</div>
</el-descriptions-item>
</el-descriptions>
<!-- 明细信息展示 -->
<el-divider content-position="center">入库单明细信息</el-divider>
<InboundItems
ref="detailItemsRef"
v-model="detailForm.inboundOrderItemsList"
:embedded="true"
:order-id="detailForm.orderId"
:show-search-form="false"
:show-pagination="false"
:show-toolbar="false"
:show-action-column="false"
:show-selection="false"
:show-add-button="false"
:show-edit-button="false"
:show-delete-button="false"
/>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="detailOpen = false">关闭</el-button>
</div>
</el-dialog>
<!-- 物料选择弹窗 -->
<el-dialog
title="选择物料"
:visible.sync="materialSelectOpen"
width="1200px"
append-to-body
>
<MaterialSelector
v-model="selectedMaterialIds"
:multiple="true"
@change="handleMaterialChange"
ref="materialSelector"
/>
<div slot="footer">
<el-button @click="materialSelectOpen = false">取消</el-button>
<el-button type="primary" @click="confirmMaterialSelect">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listInbound, getInbound, delInbound, addInbound, updateInbound } from "@/api/inventory/inbound"
import InboundItems from "@/views/inventory/inbound_items/index.vue"
import RightToolbar from "@/components/RightToolbar" // 确保导入这个组件
import MaterialSelector from "@/views/inventory/materials/materialsSeletor.vue";
export default {
name: "Inbound",
components: {
InboundItems
InboundItems,
RightToolbar,
MaterialSelector
},
data() {
return {
......@@ -306,14 +400,23 @@ export default {
{ orderTypeId: '2', orderTypeName: '入库类型2' }
],
inBoundStatusOptions: [
{ orderStatus: '1', orderStatusName: '草稿' },
{ orderStatus: '2', orderStatusName: '已完成' },
{ orderStatus: '3', orderStatusName: '已取消' }
{ orderStatus: 1, orderStatusName: '草稿', type: 'info'},
{ orderStatus: 2, orderStatusName: '已完成', type: 'success'},
{ orderStatus: 3, orderStatusName: '已取消', type: 'danger'}
],
orderTypeOptions:[
{ orderType: '1', orderTypeName: '订单类型1' },
{ orderType: '2', orderTypeName: '订单类型2' }
],
// 物料组件显示
materialSelectOpen: false,
selectedMaterialIds: [],
// 组件带来的选中的物料详情(code、name)
selectedMaterials: [],
detailOpen: false,
detailForm: {}, // 新增详情表单数据
// 组件监听修改时的orderId变化
orderId: null,
// 选中的明细项
selectedItems: [],
// 遮罩层
......@@ -355,7 +458,7 @@ export default {
batchCode: null,
warehouseId: null,
ownerId: null,
orderStatus: null,
orderStatus: 1,
referenceNo: null,
plannedArrivalDate: undefined,
actualArrivalDate: undefined,
......@@ -401,9 +504,30 @@ export default {
this.inboundList = response.rows
this.total = response.total
this.loading = false
}).catch(() => {
this.loading = false
})
},
/** 获取状态样式类型 */
getStatusType(status) {
const item = this.inBoundStatusOptions.find(item => item.orderStatus === status)
return item ? item.type : 'info'
},
/** 获取状态类型名称 */
getStatusName(status) {
const item = this.inBoundStatusOptions.find(item => item.orderStatus === status)
return item ? item.orderStatusName : status
},
getInBoundTypeName(typeId) {
if (!typeId) return '未知类型'
const item = this.inBoundTypeOptions.find(item => item.orderTypeId === typeId)
return item ? item.orderTypeName : '未知类型'
},
getOrderTypeName(type) {
if (!type) return '未知类型'
const item = this.orderTypeOptions.find(item => item.orderType === type)
return item ? item.orderTypeName : '未知类型'
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
......@@ -412,14 +536,14 @@ export default {
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.$refs.queryForm.resetFields()
this.handleQuery()
},
/** 多选框选中数据 */
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.single = selection.length !== 1
this.multiple = !selection.length
},
......@@ -436,16 +560,54 @@ export default {
const id = row.id || this.ids
getInbound(id).then(response => {
this.form = response.data
console.log(this.form)
this.orderId = response.data.orderId
// 加载明细数据
if (response.data.inboundOrderItemsList) {
this.form.inboundOrderItemsList = response.data.inboundOrderItemsList
if (this.$refs.inboundItemsRef) {
this.$refs.inboundItemsRef.loadRelatedData(this.orderId)
}
this.open = true
this.title = "修改入库"
this.title = "修改入库"
})
},
// 打开物料选择弹窗
showMaterials(status) {
this.materialSelectOpen = status;
// 清空之前的选择
this.selectedMaterialIds = [];
this.selectedMaterials = [];
},
// 物料选择变化回调
handleMaterialChange(selectedRows) {
this.selectedMaterials = selectedRows;
},
// 确认选择物料并添加到明细
confirmMaterialSelect() {
if (this.selectedMaterials.length === 0) {
this.$message.warning("请选择物料");
return;
}
// 将选中的物料添加到入库明细
this.selectedMaterials.forEach(material => {
// 检查是否已存在该物料,避免重复添加
const exists = this.form.inboundOrderItemsList.some(
item => item.materialCode === material.materialCode
);
if (!exists) {
this.form.inboundOrderItemsList.push({
materialCode: material.materialCode, // 存储物料编码
materialName: material.materialName, // 仅用于展示
// 其他需要的字段...
});
}
});
this.materialSelectOpen = false;
this.$message.success(`成功添加 ${this.selectedMaterials.length} 个物料`);
},
/** 确认入库操作 */
handleConfirm(row) {
this.$confirm('确认要入库吗?', '提示', {
......@@ -458,23 +620,34 @@ export default {
// this.$modal.msgSuccess("确认成功")
// this.getList()
// })
this.$message.success('确认入库成功')
this.getList()
})
},
/** 查看详情 */
handleDetail(row) {
// 可以打开一个新的详情页面或者弹窗
console.log('查看详情:', row)
const id = row.id || this.ids
getInbound(id).then(response => {
this.detailForm = response.data
// 加载明细数据到详情
if (this.$refs.detailItemsRef) {
this.$refs.detailItemsRef.loadRelatedData(this.detailForm.orderId)
}
this.detailOpen = true
})
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids
this.$modal.confirm('是否确认删除入库编号为"' + ids + '"的数据项?').then(function() {
this.$confirm('是否确认删除入库编号为"' + ids + '"的数据项?', '提示', {
type: 'warning'
}).then(() => {
return delInbound(ids)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
this.$message.success("删除成功")
}).catch(() => {})
},
......@@ -510,13 +683,13 @@ export default {
if (this.form.id != null) {
updateInbound(submitData).then(response => {
this.$modal.msgSuccess("修改成功")
this.$message.success("修改成功")
this.open = false
this.getList()
})
} else {
addInbound(submitData).then(response => {
this.$modal.msgSuccess("新增成功")
this.$message.success("新增成功")
this.open = false
this.getList()
})
......@@ -539,7 +712,7 @@ export default {
batchCode: null,
warehouseId: null,
ownerId: null,
orderStatus: null,
orderStatus: 1,
referenceNo: null,
plannedArrivalDate: null,
actualArrivalDate: null,
......@@ -559,7 +732,9 @@ export default {
if (this.$refs.inboundItemsRef) {
this.$refs.inboundItemsRef.resetEmbeddedData()
}
this.resetForm("form")
if (this.$refs.form) {
this.$refs.form.resetFields()
}
},
......@@ -634,8 +809,6 @@ export default {
this.form.totalPackages = totals.packages
},
/** 导出按钮操作 */
handleExport() {
this.download('inventory/inbound/export', {
......@@ -645,18 +818,28 @@ export default {
}
}
</script>
<style scoped>
/* 强制允许点击输入框 */
.el-form-item .el-input__inner {
pointer-events: all !important;
cursor: auto !important;
.scrollable-dialog .el-dialog__body {
max-height: 80vh; /* 最大高度80%视口高度 */
overflow-y: auto; /* 超出滚动 */
padding: 20px;
}
.detail-container {
padding: 10px;
}
/* 确保没有遮罩层 */
.el-dialog__wrapper {
overflow: visible !important;
.remark-text {
line-height: 1.5;
min-height: 40px;
white-space: pre-wrap;
}
.mb20 {
margin-bottom: 20px;
}
.el-dialog__body {
overflow: visible !important;
.mb8 {
margin-bottom: 8px;
}
</style>
<template>
<div class="inbound-items-container">
<!-- 保留查询表单,但可以通过props控制显示 -->
<el-form
v-if="showSearchForm"
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
label-width="100px"
class="mb8"
>
<el-form-item label="货物ID" prop="materialId">
<el-input
v-model="queryParams.materialId"
placeholder="请输入货物ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="批次ID" prop="batchId">
<el-input
v-model="queryParams.batchId"
placeholder="请输入批次ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="仓库ID" prop="warehouseId">
<el-input
v-model="queryParams.warehouseId"
placeholder="请输入仓库ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="库位ID" prop="locationId">
<el-input
v-model="queryParams.locationId"
placeholder="请输入库位ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
<!-- 添加关联查询按钮 -->
<el-button v-if="embedded" type="info" icon="el-icon-connection" size="mini" @click="handleLoadRelated">加载关联</el-button>
</el-form-item>
</el-form>
<!-- 操作按钮区域 -->
<div v-if="showToolbar" class="toolbar-container mb8">
<div class="toolbar-container mb8">
<el-row :gutter="10">
<el-col :span="1.5">
<el-button
v-if="showAddButton"
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAddItem"
>新增明细</el-button>
>新增物料</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button
v-if="showEditButton"
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleEditItem"
>修改</el-button>
</el-col> -->
<el-col :span="1.5">
<el-button
v-if="showDeleteButton"
type="danger"
plain
icon="el-icon-delete"
......@@ -85,7 +22,7 @@
@click="handleBatchDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5" v-if="showExportButton">
<el-col :span="1.5">
<el-button
type="warning"
plain
......@@ -95,7 +32,7 @@
v-hasPermi="['inventory:inbound_items:import']"
>导入</el-button>
</el-col>
<el-col :span="1.5" v-if="showExportButton">
<el-col :span="1.5">
<el-button
type="warning"
plain
......@@ -111,7 +48,7 @@
<div class="table-container">
<el-table
v-loading="loading"
:data="displayData"
:data="pagedDisplayData"
@selection-change="handleSelectionChange"
:row-key="getRowKey"
ref="dataTable"
......@@ -123,7 +60,6 @@
>
<!-- 选择列 -->
<el-table-column
v-if="showSelection"
type="selection"
width="55"
align="center"
......@@ -131,7 +67,15 @@
/>
<!-- 序号列 -->
<el-table-column label="序号" align="center" width="60" type="index" />
<el-table-column
label="序号"
align="center"
width="60"
>
<template slot-scope="scope">
{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
</template>
</el-table-column>
<!-- 数据列 -->
<el-table-column
......@@ -166,7 +110,6 @@
<el-input-number
v-model="scope.row[column.prop]"
:min="column.min || 0"
:max="column.max"
:step="column.step || 1"
size="small"
style="width: 100%"
......@@ -187,7 +130,6 @@
<!-- 只读模式 -->
<template v-else>
<!-- 状态显示 -->
<template v-if="column.prop === 'itemStatus'">
<el-tag
:type="getStatusType(scope.row[column.prop])"
......@@ -196,13 +138,9 @@
{{ getStatusText(scope.row[column.prop]) }}
</el-tag>
</template>
<!-- 数字格式化 -->
<template v-else-if="column.type === 'number'">
{{ formatNumber(scope.row[column.prop]) }}
</template>
<!-- 默认显示 -->
<template v-else>
{{ scope.row[column.prop] }}
</template>
......@@ -212,14 +150,12 @@
<!-- 操作列 -->
<el-table-column
v-if="showActionColumn"
label="操作"
align="center"
width="150"
fixed="right"
>
<template slot-scope="scope">
<template v-if="embedded">
<el-button
size="mini"
type="text"
......@@ -241,32 +177,17 @@
@click="handleRowDelete(scope.row, scope.$index)"
>删除</el-button>
</template>
<template v-else>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="() => { this.$refs.dataTable.toggleRowSelection(scope.row); handleEditItem(); }"
>编辑</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleRowDelete(scope.row)"
>删除</el-button>
</template>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<pagination
v-if="showPagination && !embedded"
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
@pagination="handlePagination"
@size-change="handleSizeChange"
/>
<import-excel
ref="import"
......@@ -274,173 +195,38 @@
import-url="/inventory/inbound_items/import"
template-url="/inventory/inbound_items/exportTemplate"
template-name="入库明细模板"
@success="getList"
/>
</div>
<!-- 非嵌入式模式下的添加/编辑对话框 -->
<el-dialog
v-if="!embedded"
:title="dialogTitle"
:visible.sync="dialogVisible"
width="800px"
append-to-body
@closed="handleDialogClosed"
>
<el-form
ref="dialogForm"
:model="form"
:rules="rules"
label-width="120px"
size="small"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="货物ID" prop="materialId">
<el-input v-model="form.materialId" placeholder="请输入货物ID" />
</el-form-item>
<el-form-item label="批次ID" prop="batchId">
<el-input v-model="form.batchId" placeholder="请输入批次ID" />
</el-form-item>
<el-form-item label="仓库ID" prop="warehouseId">
<el-input v-model="form.warehouseId" placeholder="请输入仓库ID" />
</el-form-item>
<el-form-item label="库位ID" prop="locationId">
<el-input v-model="form.locationId" placeholder="请输入库位ID" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划数量" prop="plannedQuantity">
<el-input-number
v-model="form.plannedQuantity"
:min="0"
:step="1"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="实际数量" prop="actualQuantity">
<el-input-number
v-model="form.actualQuantity"
:min="0"
:step="1"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="单价" prop="unitPrice">
<el-input-number
v-model="form.unitPrice"
:min="0"
:precision="2"
style="width: 100%"
@success="handleImportSuccess"
/>
</el-form-item>
<el-form-item label="状态" prop="itemStatus">
<el-select v-model="form.itemStatus" placeholder="请选择状态" style="width: 100%">
<el-option label="待入库" value="1" />
<el-option label="已入库" value="2" />
<el-option label="已取消" value="3" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="submitDialogForm">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listInbound_items, getInbound_items, delInbound_items, addInbound_items, updateInbound_items } from "@/api/inventory/inbound_items"
import { listInbound_items, delInbound_items } from "@/api/inventory/inbound_items"
import ImportExcel from "@/components/ImportExcel/index"
export default {
name: "InboundItems",
inheritAttrs: false,
components: {
ImportExcel
},
components: { ImportExcel },
props: {
// 数据源(用于嵌入式模式)
// 数据源
value: {
type: Array,
default: () => []
},
// 是否为嵌入式模式(在表单中)
embedded: {
type: Boolean,
default: false
},
// 主表ID(入库单号)
// 主表ID
orderId: {
type: [String, Number],
default: null
},
// 是否显示查询表单
showSearchForm: {
type: Boolean,
default: true
},
// 是否显示工具栏
showToolbar: {
type: Boolean,
default: true
},
// 是否显示操作列
showActionColumn: {
type: Boolean,
default: true
},
// 是否显示选择框
showSelection: {
type: Boolean,
default: false
},
// 是否显示分页
showPagination: {
type: Boolean,
default: true
},
// 是否显示新增按钮
showAddButton: {
type: Boolean,
default: true
},
// 是否显示编辑按钮
showEditButton: {
type: Boolean,
default: true
},
// 是否显示删除按钮
showDeleteButton: {
type: Boolean,
default: true
},
// 是否显示导出按钮
showExportButton: {
type: Boolean,
default: true
},
// 权限控制
permissions: {
type: Array,
default: () => []
},
// 初始查询参数
initQuery: {
type: Object,
default: () => ({})
},
// 表格列配置
columns: {
type: Array,
default: () => [
{ prop: 'materialId', label: '货物ID', width: '120', editable: true },
{ prop: 'batchId', label: '批次ID', width: '120', editable: true },
{ prop: 'materialsName', label: '货物名称', width: '120', editable: true},
// { prop: 'batchId', label: '批次ID', width: '120', editable: true },
{ prop: 'warehouseId', label: '仓库ID', width: '120', editable: true },
{ prop: 'locationId', label: '库位ID', width: '120', editable: true },
{ prop: 'plannedQuantity', label: '计划数量', width: '100', type: 'number', editable: true },
......@@ -448,68 +234,48 @@ export default {
{ prop: 'plannedPackages', label: '计划件数', width: '100', type: 'number', editable: true },
{ prop: 'actualPackages', label: '实际件数', width: '100', type: 'number', editable: true },
{ prop: 'unitPrice', label: '单价', width: '100', type: 'number', editable: true },
{ prop: 'itemStatus', label: '状态', width: '100', editable: true, type: 'select' },
{ prop: 'remark', label: '备注', minWidth: '150', editable: true },
]
},
// 每页条数
pageSize: {
type: Number,
default: 10
}
},
data() {
return {
// 遮罩层
loading: false,
// 选中数组
selectedRows: [],
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 总条数
total: 0,
// 显示数据
displayData: [],
// 对话框相关
dialogVisible: false,
dialogTitle: "",
dialogMode: 'add', // 'add' or 'edit'
// 查询参数
pagedDisplayData: [],
queryParams: {
pageNum: 1,
pageSize: 10,
orderId: this.orderId,
materialId: null,
batchId: null,
warehouseId: null,
locationId: null,
labelColor: null,
...this.initQuery
},
// 表单参数
form: this.getDefaultForm(),
// 表单校验
rules: {
materialId: [
{ required: true, message: "货物ID不能为空", trigger: "blur" }
],
plannedQuantity: [
{ required: true, message: "计划数量不能为空", trigger: "blur" },
{ type: 'number', min: 0, message: "计划数量不能小于0", trigger: "blur" }
],
actualQuantity: [
{ type: 'number', min: 0, message: "实际数量不能小于0", trigger: "blur" }
]
pageSize: this.pageSize,
orderId: this.orderId
},
// 缓存原始数据(用于嵌入式模式)
cachedData: []
}
},
computed: {
multiple() {
return this.selectedRows.length === 0
},
// 计算总数
totals() {
return this.displayData.reduce((acc, item) => {
acc.plannedQuantity += parseFloat(item.plannedQuantity) || 0
acc.actualQuantity += parseFloat(item.actualQuantity) || 0
acc.totalAmount += (parseFloat(item.plannedQuantity) || 0) * (parseFloat(item.unitPrice) || 0)
return acc
}, { plannedQuantity: 0, actualQuantity: 0, totalAmount: 0 })
}
},
watch: {
// 监听value变化(嵌入式模式)
value: {
immediate: true,
handler(newVal) {
if (this.embedded) {
// 只有当数据真正变化时才更新
const stringifiedNewVal = JSON.stringify(newVal || [])
const stringifiedDisplayData = JSON.stringify(this.displayData.map(item => {
const { editable, tempId, ...rest } = item
......@@ -523,204 +289,159 @@ export default {
editable: false,
tempId: item.id || Date.now() + Math.random()
}))
this.total = this.displayData.length
this.handlePagination()
this.calculateTotals()
}
}
}
},
// 监听嵌入式数据变化,通知父组件
displayData: {
deep: true,
handler(newVal) {
if (this.embedded) {
const dataToEmit = newVal.map(item => {
const { editable, tempId, ...rest } = item
// 确保新添加的行有orderId
if (this.orderId && !rest.orderId) {
rest.orderId = this.orderId
}
return rest
})
// 避免不必要的更新循环
const shouldEmit = JSON.stringify(dataToEmit) !== JSON.stringify(this.value || [])
if (shouldEmit) {
this.$emit('input', dataToEmit)
this.$emit('data-change', dataToEmit)
}
handler() {
this.total = this.displayData.length
this.handlePagination()
this.calculateTotals()
}
this.syncDataToParent()
}
},
// 监听orderId变化
orderId: {
immediate: true,
handler(newVal) {
if (newVal) {
if (!this.embedded) {
this.queryParams.orderId = newVal
this.getList()
} else {
// 在嵌入式模式下,更新所有没有orderId的项
this.displayData = this.displayData.map(item => ({
...item,
orderId: item.orderId || newVal
}))
}
}
}
this.loadRelatedData(newVal)
this.displayData.forEach(item => {
if (!item.orderId) item.orderId = newVal
})
}
},
computed: {
// 计算总数量和金额
totals() {
if (!this.displayData.length) return { plannedQuantity: 0, actualQuantity: 0, totalAmount: 0 }
return this.displayData.reduce((acc, item) => {
acc.plannedQuantity += parseFloat(item.plannedQuantity) || 0
acc.actualQuantity += parseFloat(item.actualQuantity) || 0
acc.totalAmount += (parseFloat(item.plannedQuantity) || 0) * (parseFloat(item.unitPrice) || 0)
return acc
}, { plannedQuantity: 0, actualQuantity: 0, totalAmount: 0 })
pageSize: {
handler(val) {
this.queryParams.pageSize = val
this.handlePagination()
}
}
},
created() {
if (!this.embedded) {
this.getList()
}
this.handlePagination()
},
methods: {
/** 获取默认表单数据 */
getDefaultForm() {
return {
id: null,
orderId: this.orderId,
materialId: null,
batchId: null,
warehouseId: null,
locationId: null,
plannedQuantity: 0,
actualQuantity: 0,
plannedPackages: 0,
actualPackages: 0,
unitPrice: 0,
itemStatus: '1',
remark: null
}
},
// 加载关联数据
loadRelatedData(orderId) {
if (!orderId) return
/** 查询数据列表 */
getList() {
this.loading = true
this.queryParams.orderId = orderId
listInbound_items(this.queryParams).then(response => {
this.displayData = response.rows
this.displayData = response.rows.map(item => ({
...item,
editable: false,
tempId: item.id || Date.now() + Math.random()
}))
this.total = response.total
this.handlePagination()
this.loading = false
this.$emit('load-success', response)
}).catch(() => {
this.loading = false
})
},
// 分页处理
handlePagination() {
const totalItems = this.displayData.length
const totalPages = Math.ceil(totalItems / this.queryParams.pageSize)
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.queryParams = {
pageNum: 1,
pageSize: 10,
orderId: this.orderId,
...this.initQuery
// 页码越界处理
if (this.queryParams.pageNum > totalPages && totalPages > 0) {
this.queryParams.pageNum = totalPages
}
this.handleQuery()
},
/** 加载关联数据 */
handleLoadRelated() {
if (!this.orderId) {
this.$message.warning('请先保存主表信息')
return
}
this.queryParams.orderId = this.orderId
this.getList()
// 计算分页数据
const start = (this.queryParams.pageNum - 1) * this.queryParams.pageSize
const end = start + this.queryParams.pageSize
this.pagedDisplayData = this.displayData.slice(start, end)
},
/** 处理选择变化 */
handleSelectionChange(selection) {
this.selectedRows = selection
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
this.$emit('selection-change', selection)
// 切换每页条数
handleSizeChange(val) {
this.queryParams.pageSize = val
this.queryParams.pageNum = 1
this.handlePagination()
},
/** 获取行key */
// 同步数据到父组件
syncDataToParent() {
const dataToEmit = this.displayData.map(item => {
const { editable, tempId, ...rest } = item
return rest
})
this.$emit('input', dataToEmit)
this.$emit('data-change', dataToEmit)
},
// 获取行key
getRowKey(row) {
return row.id || row.tempId
},
/** 新增明细项 */
// 新增物料
handleAddItem() {
if (this.embedded) {
// 嵌入式模式:直接添加行
this.$emit('show-materials',true)
const newItem = {
...this.getDefaultForm(),
id: null,
orderId: this.orderId,
materialId: null,
batchId: null,
warehouseId: null,
locationId: null,
plannedQuantity: 0,
actualQuantity: 0,
plannedPackages: 0,
actualPackages: 0,
unitPrice: 0,
remark: null,
editable: true,
tempId: Date.now() + Math.random()
}
this.displayData.push(newItem)
this.$emit('item-added', newItem)
} else {
// 独立模式:打开对话框
this.dialogMode = 'add'
this.dialogTitle = "添加入库明细"
this.form = this.getDefaultForm()
this.dialogVisible = true
}
},
/** 编辑明细项 */
handleEditItem() {
if (this.single) return
const row = this.selectedRows[0]
if (this.embedded) {
// 嵌入式模式:直接设置为可编辑
const index = this.displayData.findIndex(item => (item.id || item.tempId) === (row.id || row.tempId))
if (index > -1) {
this.$set(this.displayData[index], 'editable', true)
// 自动跳转到最后一页
const totalPages = Math.ceil(this.displayData.length / this.queryParams.pageSize)
if (totalPages > this.queryParams.pageNum) {
this.queryParams.pageNum = totalPages
}
} else {
// 独立模式:打开对话框
this.dialogMode = 'edit'
this.dialogTitle = "修改入库明细"
this.form = JSON.parse(JSON.stringify(row))
this.dialogVisible = true
}
},
/** 行编辑 */
this.$emit('item-added', newItem)
},
// 行编辑
handleRowEdit(row) {
const index = this.displayData.findIndex(item => (item.id || item.tempId) === (row.id || row.tempId))
const index = this.displayData.findIndex(item => item.tempId === row.tempId)
if (index > -1) {
this.$set(this.displayData[index], 'editable', true)
}
},
/** 行保存 */
// 行保存
handleRowSave(row) {
const index = this.displayData.findIndex(item => (item.id || item.tempId) === (row.id || row.tempId))
const index = this.displayData.findIndex(item => item.tempId === row.tempId)
if (index > -1) {
this.$set(this.displayData[index], 'editable', false)
this.$emit('row-saved', row)
}
},
// 行删除
handleRowDelete(row, index) {
this.$confirm('确定要删除该明细项吗?', '提示', {
type: 'warning'
}).then(() => {
this.displayData.splice(index, 1)
// 删除后页码处理
const currentPageDataCount = this.pagedDisplayData.length
if (currentPageDataCount === 0 && this.queryParams.pageNum > 1) {
this.queryParams.pageNum -= 1
}
/** 批量删除 */
this.$emit('row-deleted', row)
})
},
// 批量删除
handleBatchDelete() {
if (this.selectedRows.length === 0) {
this.$message.warning('请先选择要删除的项')
......@@ -728,131 +449,88 @@ export default {
}
this.$confirm('确定要删除选中的明细项吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if (this.embedded) {
// 嵌入式模式:从displayData中删除
const idsToDelete = this.selectedRows.map(row => row.id || row.tempId)
this.displayData = this.displayData.filter(item =>
!idsToDelete.includes(item.id || item.tempId)
)
// 删除后页码处理
const totalPages = Math.ceil(this.displayData.length / this.queryParams.pageSize)
if (this.queryParams.pageNum > totalPages && totalPages > 0) {
this.queryParams.pageNum = totalPages
}
this.selectedRows = []
this.$emit('batch-delete', idsToDelete)
} else {
// 独立模式:调用API删除
const ids = this.selectedRows.map(row => row.id).join(',')
delInbound_items(ids).then(() => {
this.$modal.msgSuccess("删除成功")
this.getList()
this.selectedRows = []
})
}
})
},
/** 行删除 */
handleRowDelete(row, index) {
this.$confirm('确定要删除该明细项吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if (this.embedded) {
this.displayData.splice(index, 1)
this.$emit('row-deleted', row)
} else {
delInbound_items(row.id).then(() => {
this.$modal.msgSuccess("删除成功")
this.getList()
})
}
/** 导入按钮操作 */
handleImport() {
this.$refs.import.show()
},
// 导入成功处理
handleImportSuccess() {
this.$message.success('导入成功')
this.loading = true
listInbound_items(this.queryParams).then(response => {
this.displayData = response.rows.map(item => ({
...item,
editable: false,
tempId: item.id || Date.now() + Math.random()
}))
this.loading = false
})
},
/** 导出 */
// 导出
handleExport() {
this.download('inventory/inbound_items/export', {
...this.queryParams
}, `inbound_items_${new Date().getTime()}.xlsx`)
},
/** 处理输入框变化 */
// 输入框变化
handleInputChange(row, prop) {
this.$emit('cell-change', { row, prop, value: row[prop] })
},
/** 处理数字变化 */
// 数字变化
handleNumberChange(row, prop) {
row[prop] = parseFloat(row[prop]) || 0
this.$emit('cell-change', { row, prop, value: row[prop] })
},
/** 处理列变化 */
// 选择框变化
handleColumnChange(row, prop) {
this.$emit('cell-change', { row, prop, value: row[prop] })
},
/** 处理输入框失去焦点 */
// 输入框失去焦点
handleInputBlur(row, prop) {
// 可以在这里添加验证逻辑
this.$emit('cell-blur', { row, prop, value: row[prop] })
},
/** 提交对话框表单 */
submitDialogForm() {
this.$refs["dialogForm"].validate(valid => {
if (valid) {
if (this.dialogMode === 'add') {
addInbound_items(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.dialogVisible = false
this.getList()
})
} else {
updateInbound_items(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.dialogVisible = false
this.getList()
})
}
}
})
},
/** 对话框关闭 */
handleDialogClosed() {
this.$refs["dialogForm"].resetFields()
// 选择变化
handleSelectionChange(selection) {
this.selectedRows = selection
this.$emit('selection-change', selection)
},
/** 获取状态类型 */
// 获取状态类型
getStatusType(status) {
const map = { '1': 'info', '2': 'success', '3': 'danger' }
return map[status] || 'info'
},
/** 获取状态文本 */
// 获取状态文本
getStatusText(status) {
const map = { '1': '待入库', '2': '已入库', '3': '已取消' }
return map[status] || status
},
/** 格式化数字 */
// 格式化数字
formatNumber(num) {
if (num == null) return ''
return parseFloat(num).toLocaleString()
},
/** 计算总数并通知父组件 */
// 计算总数并通知父组件
calculateTotals() {
if (this.embedded) {
const totals = this.totals
this.$emit('totals-change', totals)
}
this.$emit('totals-change', this.totals)
},
/** 验证数据 */
// 验证数据
validate() {
const errors = []
this.displayData.forEach((item, index) => {
......@@ -865,57 +543,20 @@ export default {
})
return errors
},
/** 获取所有数据 */
// 获取所有数据
getItems() {
return this.displayData.map(item => {
const { editable, tempId, ...rest } = item
return rest
})
},
/** 重置数据(嵌入式模式) */
// 重置数据
resetEmbeddedData() {
this.displayData = JSON.parse(JSON.stringify(this.cachedData)).map(item => ({
...item,
editable: false,
tempId: item.id || Date.now() + Math.random()
}))
},
/** 导入按钮操作 */
handleImport() {
this.$refs.import.show()
},
/** 新增明细项(供父组件调用) */
addItem(options = {}) {
const newItem = {
...this.getDefaultForm(),
...options,
orderId: this.orderId || options.orderId,
editable: true,
tempId: Date.now() + Math.random()
}
this.displayData.push(newItem)
return newItem
},
/** 新增空行(嵌入式模式) */
addEmptyRow() {
return this.addItem()
},
/** 删除选中项(供父组件调用) */
deleteSelected() {
if (this.selectedRows.length > 0) {
const idsToDelete = this.selectedRows.map(row => row.id || row.tempId)
this.displayData = this.displayData.filter(item =>
!idsToDelete.includes(item.id || item.tempId)
)
this.selectedRows = []
this.$emit('batch-delete', idsToDelete)
return true
}
return false
}
}
}
......
......@@ -143,8 +143,8 @@
<!-- 表格列保持不变 -->
<el-table-column type="selection" width="55" align="center" />
<el-table-column type="index" label="序号" align="center"/>
<el-table-column label="物料编码" align="center" prop="materialCode" />
<el-table-column label="物料名称" align="center" prop="materialName" />
<el-table-column label="物料编码" align="center" prop="materialCode" width="120"/>
<el-table-column label="物料名称" align="center" prop="materialName" width="150"/>
<el-table-column label="SAP物料号" align="center" prop="sapNo" />
<el-table-column label="TS Code" align="center" prop="tsCode" />
<el-table-column label="物料分类" align="center" prop="categoryCode" >
......
<template>
<div class="material-selector-container" style="overflow: hidden;">
<splitpanes class="default-theme">
<!-- 左侧分类树 -->
<pane size="16" style="overflow: auto;">
<TreeComponent
ref="treeComponent"
:tree-data="categoryTreeData"
:tree-props="treeProps"
:node-key="nodeKey"
:show-search="true"
search-placeholder="请输入分类名称"
:default-expand-all="true"
:highlight-current="true"
:loading="loadingTree"
@node-click="handleTreeClick"
>
<template #node-content="{ node, data }">
<span class="custom-tree-node">{{ node.label }}</span>
</template>
</TreeComponent>
</pane>
<!-- 右侧物料列表(仅展示和查询) -->
<pane size="84" style="overflow: auto;">
<div style="padding: 10px; display: flex; flex-direction: column;">
<!-- 查询表单 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="88px">
<el-form-item label="物料编码" prop="materialCode">
<el-input
v-model="queryParams.materialCode"
placeholder="请输入物料编码"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="物料名称" prop="materialName">
<el-input
v-model="queryParams.materialName"
placeholder="请输入物料名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="SAP物料号" prop="sapNo">
<el-input
v-model="queryParams.sapNo"
placeholder="请输入SAP物料号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="物料分类" prop="categoryNameInput">
<el-input
v-model="queryParams.categoryNameInput"
placeholder="请输入物料分类"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 物料表格(隐藏操作列,保留选择功能) -->
<el-table
v-loading="loading"
:data="materialsList"
@selection-change="handleSelectionChange"
:scroll-x="true"
:row-key="row => row.id"
@row-click="handleRowClick"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column type="index" label="序号" align="center"/>
<el-table-column label="物料编码" align="center" prop="materialCode" width="120"/>
<el-table-column label="物料名称" align="center" prop="materialName" width="150"/>
<el-table-column label="SAP物料号" align="center" prop="sapNo" />
<el-table-column label="TS Code" align="center" prop="tsCode" />
<el-table-column label="物料分类" align="center" prop="categoryCode" >
<template slot-scope="scope">
{{ scope.row.displayCategory || categoryMap[scope.row.categoryCode] || scope.row.categoryCode }}
</template>
</el-table-column>
<el-table-column label="规格型号" align="center" prop="specification" />
<el-table-column label="计量单位" align="center" prop="materialUnit" />
<el-table-column label="是否批次管理" align="center" prop="isBatchManaged">
<template slot-scope="scope">
<el-tag :type="scope.row.isBatchManaged === 1 ? 'success' : 'info'" size="mini">
{{ scope.row.isBatchManaged === 1 ? '是' : '否' }}
</el-tag>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</pane>
</splitpanes>
</div>
</template>
<script>
import { listMaterials } from "@/api/inventory/materials"
import { listMaterials_category } from "@/api/inventory/materials_category"
import TreeComponent from '@/views/inventory/materials_category/treeComponent.vue'
import { Splitpanes, Pane } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'
export default {
name: "MaterialSelector",
components: { TreeComponent, Splitpanes, Pane },
props: {
// 支持传入默认选中的物料ID(可选)
value: {
type: [Array, Number, String],
default: () => []
},
// 是否允许多选
multiple: {
type: Boolean,
default: true
}
},
data() {
return {
categoryTreeData: [],
treeProps: { children: 'children', label: 'label', value: 'sid' },
nodeKey: 'sid',
loadingTree: false,
categoryMap: {},
categoryNameToCodeMap: {},
currentNodeId: null,
queryParams: {
pageNum: 1,
pageSize: 10,
materialCode: null,
materialName: null,
sapNo: null,
tsCode: null,
categoryCode: null,
categoryNameInput: null,
specification: null,
},
materialsList: [],
total: 0,
loading: true,
selectedRows: [] // 选中的物料数据
}
},
watch: {
value: {
immediate: true,
handler(val) {
// 初始化选中状态(如果需要)
if (val && val.length) {
this.$nextTick(() => {
if (this.$refs.table) {
this.materialsList.forEach(row => {
if (val.includes(row.id)) {
this.$refs.table.toggleRowSelection(row, true)
}
})
}
})
}
}
}
},
async created() {
await Promise.all([
this.getCategoryTreeData(),
this.getCategoryList()
]);
this.getList()
},
methods: {
async getCategoryList() {
try {
const response = await listMaterials_category({ pageNum: 1, pageSize: 1000 });
if (response.rows && response.rows.length > 0) {
this.categoryMap = {};
this.categoryNameToCodeMap = {};
response.rows.forEach(item => {
if (item.isUsed !== 0 && item.isUsed !== '0') {
this.categoryMap[item.categoryCode] = item.categoryName;
if (!this.categoryNameToCodeMap[item.categoryName]) {
this.categoryNameToCodeMap[item.categoryName] = item.categoryCode;
} else if (!Array.isArray(this.categoryNameToCodeMap[item.categoryName])) {
this.categoryNameToCodeMap[item.categoryName] = [this.categoryNameToCodeMap[item.categoryName], item.categoryCode];
} else {
this.categoryNameToCodeMap[item.categoryName].push(item.categoryCode);
}
}
});
}
} catch (error) {
console.error('获取分类列表失败:', error);
}
},
async getCategoryTreeData() {
this.loadingTree = true;
try {
const response = await listMaterials_category({ pageNum: 1, pageSize: 1000 });
if (response.rows && response.rows.length > 0) {
const activeCategories = response.rows.filter(item => item.isUsed !== 0 && item.isUsed !== '0');
this.categoryTreeData = this.buildTreeData(activeCategories);
}
} catch (error) {
console.error('获取分类树数据失败:', error);
} finally {
this.loadingTree = false;
}
},
buildTreeData(list, parentId = null) {
return list
.filter(item => parentId === null
? (!item.parentId || item.parentId === 0 || item.parentId === '0')
: item.parentId == parentId
)
.map(item => ({
...item,
sid: String(item.id),
label: item.categoryName,
children: this.buildTreeData(list, item.id).length
? this.buildTreeData(list, item.id)
: undefined
}));
},
handleTreeClick(data) {
this.currentNodeId = data.sid;
this.queryParams.categoryCode = data.categoryCode;
this.queryParams.categoryNameInput = null;
this.queryParams.pageNum = 1;
this.getList();
},
getList() {
this.loading = true;
listMaterials(this.queryParams).then(response => {
this.materialsList = response.rows
.filter(item => item.isUsed !== 0 && item.isUsed !== '0')
.map(item => ({
...item,
displayCategory: this.categoryMap[item.categoryCode] || `${item.categoryCode}(未匹配分类)`
}));
this.total = response.total;
}).finally(() => {
this.loading = false;
});
},
handleQuery() {
const inputName = this.queryParams.categoryNameInput;
if (inputName) {
const matchedCode = this.categoryNameToCodeMap[inputName];
if (matchedCode) {
this.queryParams.categoryCode = Array.isArray(matchedCode) ? matchedCode[0] : matchedCode;
} else {
const matchedCodes = Object.entries(this.categoryMap)
.filter(([code, name]) => name.includes(inputName))
.map(([code]) => code);
if (matchedCodes.length > 0) {
this.queryParams.categoryCode = matchedCodes[0];
}
}
}
this.queryParams.pageNum = 1;
this.getList();
},
resetQuery() {
this.queryParams = {
pageNum: 1,
pageSize: 10,
materialCode: null,
materialName: null,
sapNo: null,
tsCode: null,
categoryCode: null,
categoryNameInput: null,
specification: null,
};
this.currentNodeId = null;
if (this.$refs.treeComponent && this.$refs.treeComponent.$refs.tree) {
this.$refs.treeComponent.$refs.tree.setCurrentKey(null);
}
this.getList();
},
handleSelectionChange(selection) {
this.selectedRows = selection;
const selectedData = selection.map(item => ({
id: item.id,
materialCode: item.materialCode,
materialName: item.materialName,
// specification: item.specification, // 可选:规格型号
// materialUnit: item.materialUnit // 可选:计量单位
}));
this.$emit('change', selectedData); // 返回包含所需字段的对象
this.$emit('input', selection.map(item => item.id));
},
handleRowClick(row) {
if (!this.multiple) {
// 单选模式下点击行直接选中并触发事件
this.$refs.table.clearSelection();
this.$refs.table.toggleRowSelection(row, true);
this.$emit('input', row.id);
this.$emit('select', row);
}
},
// 提供外部调用的方法:获取选中的物料详情
getSelectedMaterials() {
return this.selectedRows;
}
}
}
</script>
<style scoped>
.material-selector-container {
height: 100%;
min-height: 500px;
}
.custom-tree-node {
font-size: 14px;
}
</style>
\ No newline at end of file
......@@ -83,10 +83,10 @@ public class InboundOrdersController extends BaseController
}
/**
* 修改入库单
* 修改入库单
*/
@PreAuthorize("@ss.hasPermi('inventory:inbound:edit')")
@Log(title = "入库单", businessType = BusinessType.UPDATE)
@Log(title = "入库单", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody InboundOrders inboundOrders)
{
......@@ -94,10 +94,10 @@ public class InboundOrdersController extends BaseController
}
/**
* 删除入库单
* 删除入库单
*/
@PreAuthorize("@ss.hasPermi('inventory:inbound:remove')")
@Log(title = "入库单", businessType = BusinessType.DELETE)
@Log(title = "入库单", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
......
......@@ -77,7 +77,7 @@ public class InboundOrdersServiceImpl implements IInboundOrdersService
public int updateInboundOrders(InboundOrders inboundOrders)
{
inboundOrders.setUpdateTime(DateUtils.getNowDate());
inboundOrdersMapper.deleteInboundOrderItemsByOrderId(inboundOrders.getId());
inboundOrdersMapper.deleteInboundOrderItemsByOrderId(inboundOrders.getOrderId());
insertInboundOrderItems(inboundOrders);
return inboundOrdersMapper.updateInboundOrders(inboundOrders);
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论