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的参数
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row[col.prop] || '-' }}
+
+
+
+
+
+ 关闭
+
+
+
@@ -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">