|
@@ -136,10 +136,10 @@ export default {
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
- * 选中的物料ID - 当前在下拉框中选中的物料ID
|
|
|
- * @type {string|null}
|
|
|
+ * 选中的物料ID列表 - 当前在下拉框中选中的物料ID(多选)
|
|
|
+ * @type {string[]}
|
|
|
*/
|
|
|
- selectedMaterialId: null,
|
|
|
+ selectedMaterialIds: [],
|
|
|
|
|
|
/**
|
|
|
* 物料选项列表 - 远程搜索返回的物料选项
|
|
@@ -408,8 +408,8 @@ export default {
|
|
|
if (response?.data?.success && response.data.data) {
|
|
|
// 转换API返回的字段名称为组件所需的格式
|
|
|
// getMaterialFullList返回的是SalesOrderItemListRecord[]数组
|
|
|
- this.materialOptions = response.data.data.map(item => ({
|
|
|
- id: item.id,
|
|
|
+ const mapped = response.data.data.map(item => ({
|
|
|
+ id: String(item.id),
|
|
|
itemId: item.Item_ID,
|
|
|
itemCode: item.Item_Code,
|
|
|
itemName: item.Item_Name,
|
|
@@ -429,6 +429,13 @@ export default {
|
|
|
// 保留原始数据以备后用
|
|
|
_raw: item
|
|
|
}))
|
|
|
+ // 过滤掉已导入到下方表格的数据(使用 itemId 或 id)
|
|
|
+ const existingItemIds = new Set((this.materialDetails || []).map(d => String(d.itemId)))
|
|
|
+ this.materialOptions = mapped.filter(opt => {
|
|
|
+ const itemIdStr = String(opt.itemId)
|
|
|
+ const idStr = String(opt.id)
|
|
|
+ return !(existingItemIds.has(itemIdStr) || existingItemIds.has(idStr))
|
|
|
+ })
|
|
|
} else {
|
|
|
this.materialOptions = []
|
|
|
const errorMsg = response?.data?.msg || '搜索物料失败'
|
|
@@ -470,8 +477,8 @@ export default {
|
|
|
const pageData = response.data.data
|
|
|
const list = pageData.records || []
|
|
|
|
|
|
- this.materialOptions = list.map(item => ({
|
|
|
- id: item.id,
|
|
|
+ const mapped = list.map(item => ({
|
|
|
+ id: String(item.id),
|
|
|
itemId: item.goodsId,
|
|
|
itemCode: item.code,
|
|
|
itemName: item.cname,
|
|
@@ -495,6 +502,13 @@ export default {
|
|
|
// 保留原始数据以备后用
|
|
|
_raw: item
|
|
|
}))
|
|
|
+ // 过滤掉已导入到下方表格的数据(使用 itemId 或 id)
|
|
|
+ const existingItemIds = new Set((this.materialDetails || []).map(d => String(d.itemId)))
|
|
|
+ this.materialOptions = mapped.filter(opt => {
|
|
|
+ const itemIdStr = String(opt.itemId)
|
|
|
+ const idStr = String(opt.id)
|
|
|
+ return !(existingItemIds.has(itemIdStr) || existingItemIds.has(idStr))
|
|
|
+ })
|
|
|
} else {
|
|
|
this.materialOptions = []
|
|
|
const errorMsg = response?.data?.msg || '搜索库存物料失败'
|
|
@@ -515,38 +529,49 @@ export default {
|
|
|
* @this {MaterialDetailTableComponent}
|
|
|
*/
|
|
|
handleImportSelectedMaterial() {
|
|
|
- if (!this.selectedMaterialId) {
|
|
|
+ const ids = Array.isArray(this.selectedMaterialIds) ? this.selectedMaterialIds : []
|
|
|
+ if (!ids.length) {
|
|
|
this.$message.warning('请先选择要导入的物料')
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- // 查找选中的物料数据
|
|
|
- const selectedMaterial = this.materialOptions.find(item => item.id === this.selectedMaterialId)
|
|
|
- if (!selectedMaterial) {
|
|
|
+ // 构建选项映射,便于根据ID快速查找
|
|
|
+ const optionMap = new Map(this.materialOptions.map(opt => [String(opt.id), opt]))
|
|
|
+ const selectedOptions = ids.map(id => optionMap.get(String(id))).filter(Boolean)
|
|
|
+
|
|
|
+ if (!selectedOptions.length) {
|
|
|
this.$message.warning('未找到选中的物料数据')
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- // 检查是否已存在相同物料
|
|
|
- const existingMaterial = this.materialDetails.find(item => item.itemCode === selectedMaterial.itemCode)
|
|
|
- if (existingMaterial) {
|
|
|
- this.$message.warning(`物料 ${selectedMaterial.itemName} 已存在,请勿重复导入`)
|
|
|
+ // 已存在的物料(按 itemId 去重,兼容按 id 判重)
|
|
|
+ const existingSet = new Set((this.materialDetails || []).map(item => String(item.itemId)))
|
|
|
+
|
|
|
+ const toImport = selectedOptions.filter(opt => {
|
|
|
+ const byItemId = existingSet.has(String(opt.itemId))
|
|
|
+ const byId = existingSet.has(String(opt.id))
|
|
|
+ return !(byItemId || byId)
|
|
|
+ })
|
|
|
+
|
|
|
+ if (!toImport.length) {
|
|
|
+ this.$message.warning('选择的物料均已存在,请勿重复导入')
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- // 构造物料明细数据
|
|
|
- let materialDetail = this.prepareMaterialDetailData(selectedMaterial)
|
|
|
-
|
|
|
- // 导入时自动计算金额
|
|
|
- materialDetail = this.calculateAmounts(materialDetail)
|
|
|
+ const materialDetails = toImport.map(material => {
|
|
|
+ let detail = this.prepareMaterialDetailData(material)
|
|
|
+ detail = this.calculateAmounts(detail)
|
|
|
+ return detail
|
|
|
+ })
|
|
|
|
|
|
// 触发导入事件
|
|
|
- this.$emit(MATERIAL_DETAIL_EVENTS.MATERIAL_IMPORT, [materialDetail])
|
|
|
+ this.$emit(MATERIAL_DETAIL_EVENTS.MATERIAL_IMPORT, materialDetails)
|
|
|
this.$emit(MATERIAL_DETAIL_EVENTS.REFRESH)
|
|
|
|
|
|
- // 清空选择
|
|
|
- this.selectedMaterialId = null
|
|
|
- this.materialOptions = []
|
|
|
+ // 清空选择,并从候选项中移除已导入的项
|
|
|
+ this.selectedMaterialIds = []
|
|
|
+ const importedIdSet = new Set(ids.map(id => String(id)))
|
|
|
+ this.materialOptions = this.materialOptions.filter(opt => !importedIdSet.has(String(opt.id)))
|
|
|
},
|
|
|
|
|
|
/**
|