diff --git a/src/api/part/partProductGroupInformation.js b/src/api/part/partProductGroupInformation.js index 628bdcc..e7b19dd 100644 --- a/src/api/part/partProductGroupInformation.js +++ b/src/api/part/partProductGroupInformation.js @@ -24,3 +24,17 @@ export const productGroupInformationEdit = data => createAPI(`/plm/partProductGr * @returns {*} */ export const productGroupInformationDelete = data => createAPI(`/plm/partProductGroupInformation/productGroupInformationDelete`,'post',data) + +/** + * 查询商品组的PTM条件 + * @param data + * @returns {*} + */ +export const searchProductGroupPtmCondition = data => createAPI(`/plm/partProductGroupInformation/searchProductGroupPtmCondition`,'post',data) + +/** + * 批量查询商品组下所有PTM条件及其参数(一次查询) + * @param data + * @returns {*} + */ +export const batchSearchProductGroupPtmConditionsWithItems = data => createAPI(`/plm/partProductGroupInformation/batchSearchProductGroupPtmConditionsWithItems`,'post',data) diff --git a/src/views/modules/inquiry/inquiryTechnicalMaterialsNoBuilt.vue b/src/views/modules/inquiry/inquiryTechnicalMaterialsNoBuilt.vue index 44be8df..0bf48d4 100644 --- a/src/views/modules/inquiry/inquiryTechnicalMaterialsNoBuilt.vue +++ b/src/views/modules/inquiry/inquiryTechnicalMaterialsNoBuilt.vue @@ -2773,7 +2773,64 @@ export default { this.$router.push({ path: 'inquiry-inquiryDetail', query: { id : id} }); }, navigateToBomQuickCreation(data){ - this.$router.push({ path: 'part-quicklyCreateBom',query:{ data: data} }); + // 为每个页签生成唯一的名称,使用物料的testPartNo或id作为标识 + const uniqueName = `part-quicklyCreateBom-${data.testPartNo || data.id || Date.now()}`; + + // 动态添加新路由 + const route = { + path: uniqueName, + component: () => import('@/views/modules/part/quicklyCreateBom.vue'), + name: uniqueName, + meta: { + menuId: this.$router.resolve({ name: 'part-quicklyCreateBom' }).route.meta.menuId, + title: `BOM快速创建 - ${data.testPartNo || data.testPartDesc || ''}`, + isDynamic: true, + isTab: true, + iframeUrl: '' + } + }; + + // 检查路由是否已存在 + const existingRoute = this.$router.options.routes.find(r => r.name === uniqueName); + if (!existingRoute) { + // 动态添加路由到 main 路由下 + this.$router.addRoutes([{ + path: '/', + component: () => import('@/views/main.vue'), + name: 'main-dynamic-' + uniqueName, + children: [route] + }]); + } + + // 手动添加页签 + const newTab = { + menuId: route.meta.menuId || uniqueName, + name: uniqueName, + title: route.meta.title, + type: 'module', + iframeUrl: '', + params: {}, + query: { data: data } + }; + + // 检查是否已存在相同的页签 + const existingTab = this.$store.state.common.mainTabs.find(item => item.name === uniqueName); + if (!existingTab) { + // 添加新页签 + this.$store.commit('common/updateMainTabs', [...this.$store.state.common.mainTabs, newTab]); + } + + // 切换到该页签 + this.$store.commit('common/updateMainTabsActiveName', uniqueName); + this.$store.commit('common/updateMenuActiveName', newTab.menuId + ''); + + // 跳转路由 + this.$router.push({ + name: uniqueName, + query: { data: data } + }).catch(err => { + console.error('路由跳转失败:', err); + }); }, // 动态列开始 获取 用户保存的 格式列 async getTableUserColumn(tableId, columnId) { diff --git a/src/views/modules/part/quicklyCreateBom.vue b/src/views/modules/part/quicklyCreateBom.vue index 978c090..3431153 100644 --- a/src/views/modules/part/quicklyCreateBom.vue +++ b/src/views/modules/part/quicklyCreateBom.vue @@ -502,6 +502,7 @@ 新增 {{ attributeFlag1?'编辑':'保存' }} 选择ProcessTimeMatrix + 韩ProcessTimeMatrix
+ + +
+ + + + + + 筛选 + 重置 + + + + 💡 提示:双击某一行直接添加该ProcessTimeMatrix的参数 + + + + + + + + + + + + +
+ + 关闭 + +
+ @@ -1467,6 +1537,7 @@ import RoutingCreate from "./routing_create.vue"; import PartCreate from "./part_create.vue"; import {updateInquiryDetailStatusAndPart} from "../../../api/inquiry/inquiryDetail"; import {EventBus} from "../../../main"; +import {searchProductGroupPtmCondition, batchSearchProductGroupPtmConditionsWithItems} from "../../../api/part/partProductGroupInformation"; import { addPartItem, batchUpdateItem, @@ -3581,7 +3652,16 @@ export default { copyPartModelFlag: false, itemUpdateFlag: false, processTimeMatrixFlag: false, - productGroupFlag: false + productGroupFlag: false, + + ptmDialogVisible: false, // PTM参数选择对话框显示控制 + ptmDataList: [], // PTM完整数据列表(53行,每行包含Code和12个参数列) + filteredPtmDataList: [], // PTM筛选后的数据列表 + ptmColumnList: [], // PTM参数动态列配置(12个参数列) + ptmSearchCode: '', // PTM Code筛选条件 + ptmItemList: [], // PTM参数列表(去重后的item列表) + selectedPtmItems: [], // 用户勾选的PTM参数 + copyPartModelFlag: false } }, created () { @@ -6006,7 +6086,332 @@ export default { }) } }) - } + }, + + /** + * 打开PTM参数选择对话框 + * 展示商品组1下所有ProcessTimeMatrix及其参数(横向展示:53行 × 12列) + * 使用批量查询API,只请求一次后台 + */ + openPtmDialog() { + if (!this.attributeFlag1) { + this.$message.warning('请先保存当前编辑的内容!') + return + } + + // 检查是否有选中的物料 + if (!this.partList1 || this.partList1.length === 0) { + this.$message.warning('请先选择物料!') + return + } + + // 获取第一个物料的信息 + const firstPart = this.partList1[0] + if (!firstPart.productGroupId1) { + this.$message.warning('当前物料未设置商品组1,无法查询PTM参数!') + return + } + + // 查询该商品组下所有PTM条件及其参数(一次查询) + const queryData = { + site: this.$store.state.user.site, + buNo: firstPart.buNo, + productGroupId: firstPart.productGroupId1 + } + + // 显示加载提示 + const loadingInstance = this.$loading({ + lock: true, + text: '正在加载ProcessTimeMatrix数据...', + spinner: 'el-icon-loading', + background: 'rgba(0, 0, 0, 0.7)' + }) + + batchSearchProductGroupPtmConditionsWithItems(queryData).then(({data}) => { + loadingInstance.close() + + if (data && data.code === 0) { + const ptmConditions = data.conditions || [] + const allItems = data.items || [] + + if (ptmConditions.length === 0) { + this.$message.info('该商品组下未配置PTM参数') + return + } + + if (allItems.length === 0) { + this.$message.info('该商品组的PTM配置中没有参数') + return + } + + // 处理数据:将items按conditionId分组 + this.processPtmData(ptmConditions, allItems) + + } else { + this.$alert(data.msg || '查询PTM条件失败', '错误', { + confirmButtonText: '确定' + }) + } + }).catch(error => { + loadingInstance.close() + this.$message.error('查询PTM条件异常') + console.error(error) + }) + }, + + /** + * 处理PTM数据(横向展示) + * 将后端返回的数据处理成表格展示格式 + * @param ptmConditions PTM条件列表 + * @param allItems 所有参数列表 + */ + processPtmData(ptmConditions, allItems) { + const flatDataList = [] + const columnSet = new Set() + const columnMap = new Map() + + // 将items按conditionId分组 + const itemsByCondition = {} + allItems.forEach(item => { + if (!itemsByCondition[item.conditionId]) { + itemsByCondition[item.conditionId] = [] + } + itemsByCondition[item.conditionId].push(item) + + // 收集唯一的列信息 + if (!columnSet.has(item.itemNo)) { + columnSet.add(item.itemNo) + columnMap.set(item.itemNo, { + itemNo: item.itemNo, + itemDesc: item.itemDesc, + valueType: item.valueTypeDb, + valueChooseFlag: item.valueChooseFlag + }) + } + }) + + // 构建表格数据 + ptmConditions.forEach(condition => { + const items = itemsByCondition[condition.conditionId] || [] + + if (items.length === 0) { + return + } + + // 构建一行数据:包含conditionDesc和所有参数的值 + const rowData = { + conditionId: condition.conditionId, + conditionDesc: condition.conditionDesc, + seqNo: condition.seqNo, + site: condition.site, + buNo: condition.buNo, + productGroupId: condition.productGroupId, + items: items // 保存原始items数据,用于后续添加操作 + } + + // 将每个参数转换为列数据 + items.forEach(item => { + const propName = `param_${item.itemNo}` + const displayValue = item.valueTypeDb === 'T' ? item.textValue : item.numValue + rowData[propName] = displayValue || '-' + }) + + flatDataList.push(rowData) + }) + + // 构建动态列配置 + const columns = [] + columnMap.forEach((colInfo, itemNo) => { + columns.push({ + prop: `param_${itemNo}`, + label: colInfo.itemDesc || itemNo, + itemNo: itemNo, + valueType: colInfo.valueType, + width: 110, + align: colInfo.valueType === 'N' ? 'right' : 'left' + }) + }) + + // 按itemNo排序列 + columns.sort((a, b) => a.itemNo.localeCompare(b.itemNo)) + + // 设置数据并打开对话框 + this.ptmDataList = flatDataList + this.filteredPtmDataList = flatDataList + this.ptmColumnList = columns + this.ptmSearchCode = '' + this.ptmDialogVisible = true + + this.$message.success(`已加载 ${flatDataList.length} 个 ProcessTimeMatrix(共 ${columns.length} 个参数列)`) + }, + + /** + * 处理双击PTM行事件 + * @param row 双击的行数据 + */ + handlePtmRowDoubleClick(row) { + if (!row || !row.items || row.items.length === 0) { + this.$message.warning('该ProcessTimeMatrix没有参数!') + return + } + + // 显示loading + const loadingInstance = this.$loading({ + lock: true, + text: '正在添加参数...', + spinner: 'el-icon-loading', + background: 'rgba(0, 0, 0, 0.7)' + }) + + // 直接添加该行的参数 + this.addPtmItemsFromRow(row, loadingInstance) + }, + + /** + * 筛选PTM列表(按Code条件描述) + */ + filterPtmList() { + if (!this.ptmSearchCode || this.ptmSearchCode.trim() === '') { + this.filteredPtmDataList = this.ptmDataList + return + } + + const searchText = this.ptmSearchCode.trim().toLowerCase() + this.filteredPtmDataList = this.ptmDataList.filter(row => { + return row.conditionDesc && row.conditionDesc.toLowerCase().includes(searchText) + }) + + if (this.filteredPtmDataList.length === 0) { + this.$message.info('没有找到匹配的ProcessTimeMatrix') + } else { + this.$message.success(`找到 ${this.filteredPtmDataList.length} 条匹配的ProcessTimeMatrix`) + } + }, + + /** + * 重置PTM筛选 + */ + resetPtmFilter() { + this.ptmSearchCode = '' + this.filteredPtmDataList = this.ptmDataList + this.$message.info('已重置筛选条件') + }, + + /** + * 添加选中的PTM行的参数到物料属性列表 + * @param row 双击的行数据 + * @param loadingInstance loading实例 + */ + addPtmItemsFromRow(row, loadingInstance) { + // 从行中提取参数,并转换为后端期望的格式 + const allItems = [] + + if (row.items && row.items.length > 0) { + row.items.forEach(item => { + // 转换为后端期望的格式 + const itemData = { + itNo: item.itemNo, // 属性编码(后端接口字段名为itNo) + valueTypeDb: item.valueTypeDb, + itemDesc: item.itemDesc + } + + // 根据类型设置值 + if (item.valueTypeDb === 'T') { + itemData.textValue = item.textValue || null + itemData.numValue = null + } else if (item.valueTypeDb === 'N') { + itemData.textValue = null + // 确保numValue是数值类型 + itemData.numValue = item.numValue !== null && item.numValue !== undefined && item.numValue !== '' + ? (typeof item.numValue === 'number' ? item.numValue : parseFloat(item.numValue)) + : null + } + + allItems.push(itemData) + }) + } + + if (allItems.length === 0) { + loadingInstance.close() + this.$message.warning('选中的ProcessTimeMatrix中没有参数!') + return + } + + // 使用与addItem1相同的逻辑 + const partList = this.partList1.filter(item => + item.partNo && item.partNo !== '' && item.buNo && item.buNo === this.searchData.buNo + ) + + if (partList.length === 0) { + loadingInstance.close() + this.$message.warning('没有符合条件的物料!') + return + } + const inDataList = [] + + for (let i = 0; i < partList.length; i++) { + if (!partList[i].codeNo || partList[i].codeNo === '') { + continue + } + + inDataList.push({ + site: partList[i].site, + buNo: partList[i].buNo, + partNo: partList[i].partNo, + codeNo: partList[i].codeNo, + codeDesc: partList[i].codeDesc, + recordType: 'IP', + itemList: allItems + }) + } + + if (inDataList.length === 0) { + loadingInstance.close() + this.$message.warning('请确保物料已配置属性模板(codeNo)!') + return + } + + // 调用批量添加接口(与addItem1相同的逻辑) + addPartsItem(inDataList).then(({data}) => { + if (data && data.code === 0) { + // 更新可选属性列表和已有属性列表 + getItemLists(inDataList[0]).then(({data}) => { + this.itemList1 = data.row1 + this.itemList2 = data.row2 + loadingInstance.close() + // 刷新物料属性列表 + this.getPartItem2() + + this.$message.success(`成功添加 ${allItems.length} 个参数(ProcessTimeMatrix: ${row.conditionDesc})`) + + // 关闭对话框 + this.ptmDialogVisible = false + + // 清空数据 + this.ptmDataList = [] + this.filteredPtmDataList = [] + this.ptmColumnList = [] + }).catch(error => { + loadingInstance.close() + this.getPartItem2() + this.$message.success(`成功添加 ${allItems.length} 个参数(ProcessTimeMatrix: ${row.conditionDesc})`) + this.ptmDialogVisible = false + this.ptmDataList = [] + this.filteredPtmDataList = [] + this.ptmColumnList = [] + }) + } else { + loadingInstance.close() + this.$alert(data.msg || '添加属性失败', '错误', { + confirmButtonText: '确定' + }) + } + }).catch(error => { + loadingInstance.close() + this.$message.error('添加属性异常: ' + error.message) + console.error(error) + }) + }, }, } diff --git a/src/views/modules/part/routing_create.vue b/src/views/modules/part/routing_create.vue index 74e6115..a295778 100644 --- a/src/views/modules/part/routing_create.vue +++ b/src/views/modules/part/routing_create.vue @@ -2181,6 +2181,12 @@ export default { cancelButtonText: "取消", type: "warning" }).then(() => { + // 根据选中行的标识(operationNo)从 standardOperationList 中获取最新的编辑数据 + const selectedOperationNos = this.standardOperationSelections.map(item => item.operationNo) + const latestSelectedData = this.standardOperationList.filter(item => + selectedOperationNos.includes(item.operationNo) + ) + let tempData = { site: this.detailData.site, buNo: this.detailData.buNo, @@ -2188,10 +2194,11 @@ export default { routingRevision: this.detailData.routingRevision, routingType: this.detailData.routingType, alternativeNo: this.detailData.alternativeNo, - informationList: this.standardOperationSelections + informationList: latestSelectedData // 使用最新的编辑后数据 } saveStandardOperation(tempData).then(({data}) => { if (data && data.code === 0) { + // 后端已经保存了ref_speed、ref_time、ref_efficiency字段,直接使用返回的数据 this.subDetailList = data.rows this.standardOperationModal = false this.$message({ diff --git a/src/views/modules/part/standardRoutingOperation.vue b/src/views/modules/part/standardRoutingOperation.vue index fcf8b36..a918ce3 100644 --- a/src/views/modules/part/standardRoutingOperation.vue +++ b/src/views/modules/part/standardRoutingOperation.vue @@ -7,7 +7,7 @@ v-for = "i in userBuList" :key = "i.buNo" :label = "i.buDesc" - :value = "i.buNo"> + :value = "i.buDesc">