north-glass-erp/northglass-erp/src/components/pp/PrintCustomLabel.vue
@@ -74,53 +74,105 @@ const isComposing = ref(false) const getCaretOffset = (el) => { const sel = window.getSelection() if (!sel || sel.rangeCount === 0) return 0 const range = sel.getRangeAt(0) if (!el.contains(range.startContainer)) return 0 const preRange = range.cloneRange() preRange.selectNodeContents(el) preRange.setEnd(range.startContainer, range.startOffset) return preRange.toString().length } const setCaretOffset = (el, offset) => { const sel = window.getSelection() if (!sel) return const range = document.createRange() range.selectNodeContents(el) let current = 0 const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null) let node = walker.nextNode() while (node) { const next = current + (node.nodeValue?.length || 0) if (offset <= next) { range.setStart(node, Math.max(0, offset - current)) range.collapse(true) sel.removeAllRanges() sel.addRange(range) return } current = next node = walker.nextNode() } // 超出长度则放到末尾 range.collapse(false) sel.removeAllRanges() sel.addRange(range) } // ============================================= //修改相同产品名称标签 const updateProductName = (event, index,id) => { // 创建映射对象 const propertyMapping = {}; const updateProductName = async (event, fieldIndex, rowIndex) => { // 输入法组词阶段不要同步,否则会抖动/错乱 if (isComposing.value) return const el = event.target // 保存光标 const caret = getCaretOffset(el) // 取“纯值”此时 contenteditable 只包含值,不包含标题: const result = (el.innerText ?? '').trim() // 映射:fieldIndex -> 字段名 const propertyMapping = {} labelList.forEach(item => { propertyMapping[item.name] = item.title; }); // 输入的值 const newValue = event.target.innerText; const parts = newValue.split(':'); const result = parts[1]; // 获取冒号后的部分 propertyMapping[item.name] = item.title }) const keys = Object.keys(propertyMapping) const propertyName = keys[fieldIndex] if (!propertyName) return // 获取映射中所有的键 const keys = Object.keys(propertyMapping); //更新 const baseRow = props.lastList?.[rowIndex] if (!baseRow) return // 根据 index 获取对应的属性名 const propertyName = keys[index]; const basePrefix = (baseRow.processId ?? '').substring(0, 11) const baseGlassNumber = baseRow.glassNumber const baseOrderId = baseRow.orderId // 如果映射中没有该 index,直接返回 if (!propertyName) { console.warn('Unsupported index:', index); return; } props.lastList.forEach(obj => { const objPrefix = (obj.processId ?? '').substring(0, 11) // 遍历 lastList 并更新对应的属性 lastList.value.forEach(obj => { // 获取前缀和 orderId const prefix = lastList.value[id].processId.substring(0, 11); const orderId = obj.orderId; const glassNumber=lastList.value[id].glassNumber const customerName = obj.customerName // 根据 propertyName 更新属性 if (propertyName === 'productAbbreviation' && prefix === obj.processId.substring(0, 11)) { obj.productAbbreviation = result; } if (propertyName === 'productAbbreviation' && basePrefix === objPrefix) obj.productAbbreviation = result if (propertyName === 'project' && baseOrderId === obj.orderId) obj.project = result if (propertyName === 'productName' && basePrefix === objPrefix) obj.productName = result if (propertyName === 'customerName' && baseOrderId === obj.orderId) obj.customerName = result if (propertyName === 'orderId' && baseOrderId === obj.orderId) obj.orderId = result if (propertyName === 'project' && orderId === obj.orderId) { obj.project = result; } if (propertyName === 'productName' && prefix === obj.processId.substring(0, 11)){ obj.productName = result; } if (propertyName === 'customerName' && orderId === obj.orderId){ obj.customerName = result; } }); if (propertyName === 'glassNumber' && baseGlassNumber === obj.glassNumber) obj.glassNumber = result if (propertyName === 'width' && baseGlassNumber === obj.glassNumber) obj.width = result if (propertyName === 'height' && baseGlassNumber === obj.glassNumber) obj.height = result if (propertyName === 'custom1' && baseOrderId === obj.orderId) obj.custom1 = result if (propertyName === 'custom2' && baseOrderId === obj.orderId) obj.custom2 = result if (propertyName === 'custom3' && baseOrderId === obj.orderId) obj.custom3 = result if (propertyName === 'custom4' && baseOrderId === obj.orderId) obj.custom4 = result if (propertyName === 'custom5' && baseOrderId === obj.orderId) obj.custom5 = result }) // 5) 等 Vue patch 完成后,把光标放回去 await nextTick() setCaretOffset(el, caret) } @@ -132,9 +184,16 @@ <div v-for="(item1,index) in lastList" :class="company.printLabel.className.custom.entiretyName()"> <div class="row4">{{ faceOrientation }}</div> <div v-for="(item,id) in labelList" :class="company.printLabel.className.custom.contentRowName()"> <div v-if="item1[item.name] != null && item1[item.name] !== ''" class="row1" contenteditable="true" @input="updateProductName($event, id,index)" v-text="item.title+':'+item1[item.name]"></div> <!-- <div class="row2" style="width: 100%;"><input class="contentRow2" v-model="item1[item.name]" @keyup="updataProductName()" style="border: none;"/></div>--> <!-- <div v-if="item1[item.name] != null && item1[item.name] !== ''" class="row2" style="width: 100%;" contenteditable="true" @input="updateProductName($event, id)" v-text="item1[item.name]"></div>--> <div class="row1" v-show="item1[item.name] != null && item1[item.name] !== ''"> <span class="label">{{ item.title }}:</span> <span class="value" contenteditable="true" @compositionstart="isComposing.value = true" @compositionend="(e) => { isComposing.value = false; updateProductName(e, id, index) }" @input="(e) => updateProductName(e, id, index)" >{{ item1[item.name] }}</span> </div> </div> <div v-html="company.printLabel.custom(item1)"></div> </div> north-glass-erp/northglass-erp/src/components/pp/PrintCustomLabelDetails.vue
@@ -83,76 +83,105 @@ const isComposing = ref(false) const getCaretOffset = (el) => { const sel = window.getSelection() if (!sel || sel.rangeCount === 0) return 0 const range = sel.getRangeAt(0) if (!el.contains(range.startContainer)) return 0 const preRange = range.cloneRange() preRange.selectNodeContents(el) preRange.setEnd(range.startContainer, range.startOffset) return preRange.toString().length } const setCaretOffset = (el, offset) => { const sel = window.getSelection() if (!sel) return const range = document.createRange() range.selectNodeContents(el) let current = 0 const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null) let node = walker.nextNode() while (node) { const next = current + (node.nodeValue?.length || 0) if (offset <= next) { range.setStart(node, Math.max(0, offset - current)) range.collapse(true) sel.removeAllRanges() sel.addRange(range) return } current = next node = walker.nextNode() } // 超出长度则放到末尾 range.collapse(false) sel.removeAllRanges() sel.addRange(range) } // ============================================= //修改相同产品名称标签 const updateProductName = (event, index,id) => { // 创建映射对象 const propertyMapping = {}; const updateProductName = async (event, fieldIndex, rowIndex) => { // 输入法组词阶段不要同步,否则会抖动/错乱 if (isComposing.value) return const el = event.target // 保存光标 const caret = getCaretOffset(el) // 取“纯值”此时 contenteditable 只包含值,不包含标题: const result = (el.innerText ?? '').trim() // 映射:fieldIndex -> 字段名 const propertyMapping = {} labelList.forEach(item => { propertyMapping[item.name] = item.title; }); // 输入的值 const newValue = event.target.innerText; const parts = newValue.split(':'); const result = parts[1]; // 获取冒号后的部分 // 获取映射中所有的键 const keys = Object.keys(propertyMapping); // 根据 index 获取对应的属性名 propertyMapping[item.name] = item.title }) const keys = Object.keys(propertyMapping) const propertyName = keys[fieldIndex] if (!propertyName) return const propertyName = keys[index]; // 如果映射中没有该 index,直接返回 if (!propertyName) { console.warn('Unsupported index:', index); return; } //更新 const baseRow = props.lastList?.[rowIndex] if (!baseRow) return // 遍历 lastList 并更新对应的属性 const basePrefix = (baseRow.processId ?? '').substring(0, 11) const baseGlassNumber = baseRow.glassNumber const baseOrderId = baseRow.orderId props.lastList.forEach(obj => { // 获取前缀和 orderId const prefix = props.lastList[id].processId.substring(0, 11); const orderId = obj.orderId; const glassNumber=props.lastList[id].glassNumber // 根据 propertyName 更新属性 if (propertyName === 'productAbbreviation' && prefix === obj.processId.substring(0, 11)) { obj.productAbbreviation = result; } const objPrefix = (obj.processId ?? '').substring(0, 11) if (propertyName === 'project' && orderId === obj.orderId) { obj.project = result; } if (propertyName === 'productName' && prefix === obj.processId.substring(0, 11)){ obj.productName = result; } if (propertyName === 'customerName' && orderId === obj.orderId){ obj.customerName = result; } if (propertyName === 'orderId' && orderId === obj.orderId){ obj.orderId = result; } if (propertyName === 'glassNumber' && glassNumber === obj.glassNumber){ obj.glassNumber = result; } if (propertyName === 'width' && glassNumber === obj.glassNumber){ obj.width = result; } if (propertyName === 'height' && glassNumber === obj.glassNumber){ obj.height = result; } if (propertyName === 'custom1' && orderId === obj.orderId){ obj.custom1 = result; } if (propertyName === 'custom2' && orderId === obj.orderId){ obj.custom2 = result; } if (propertyName === 'custom3' && orderId === obj.orderId){ obj.custom3 = result; } if (propertyName === 'custom4' && orderId === obj.orderId){ obj.custom4 = result; } if (propertyName === 'custom5' && orderId === obj.orderId){ obj.custom5 = result; } }); if (propertyName === 'productAbbreviation' && basePrefix === objPrefix) obj.productAbbreviation = result if (propertyName === 'project' && baseOrderId === obj.orderId) obj.project = result if (propertyName === 'productName' && basePrefix === objPrefix) obj.productName = result if (propertyName === 'customerName' && baseOrderId === obj.orderId) obj.customerName = result if (propertyName === 'orderId' && baseOrderId === obj.orderId) obj.orderId = result if (propertyName === 'glassNumber' && baseGlassNumber === obj.glassNumber) obj.glassNumber = result if (propertyName === 'width' && baseGlassNumber === obj.glassNumber) obj.width = result if (propertyName === 'height' && baseGlassNumber === obj.glassNumber) obj.height = result if (propertyName === 'custom1' && baseOrderId === obj.orderId) obj.custom1 = result if (propertyName === 'custom2' && baseOrderId === obj.orderId) obj.custom2 = result if (propertyName === 'custom3' && baseOrderId === obj.orderId) obj.custom3 = result if (propertyName === 'custom4' && baseOrderId === obj.orderId) obj.custom4 = result if (propertyName === 'custom5' && baseOrderId === obj.orderId) obj.custom5 = result }) // 5) 等 Vue patch 完成后,把光标放回去 await nextTick() setCaretOffset(el, caret) } @@ -164,10 +193,16 @@ <div v-for="(item1,index) in props.lastList" :class="company.printLabel.className.custom.entiretyName()"> <div class="row4">{{ faceOrientation }}</div> <div v-for="(item,id) in labelList" :class="company.printLabel.className.custom.contentRowName()"> <div v-if="item1[item.name] != null && item1[item.name] !== ''" class="row1" contenteditable="true" @input="updateProductName($event, id,index)" v-text="item.title+':'+item1[item.name]"></div> <div v-else class="row1" contenteditable="true" @input="updateProductName($event, id,index)" v-text="item.title+':'"></div> <!-- <div class="row2" style="width: 100%;"><input class="contentRow2" v-model="item1[item.name]" @keyup="updataProductName()" style="border: none;"/></div>--> <!-- <div v-if="item1[item.name] != null && item1[item.name] !== ''" class="row2" style="width: 100%;" contenteditable="true" @input="updateProductName($event, id)" v-text="item1[item.name]"></div>--> <div class="row1" v-show="item1[item.name] != null && item1[item.name] !== ''"> <span class="label">{{ item.title }}:</span> <span class="value" contenteditable="true" @compositionstart="isComposing.value = true" @compositionend="(e) => { isComposing.value = false; updateProductName(e, id, index) }" @input="(e) => updateProductName(e, id, index)" >{{ item1[item.name] }}</span> </div> </div> <div v-html="company.printLabel.custom(item1)"></div> </div> north-glass-erp/northglass-erp/src/components/pp/PrintCustomLabelTwo.vue
@@ -82,10 +82,8 @@ for (const group of list.value) { // 遍历每组中的数据(替换 j) for (const item of group.data) { console.log(item) const { quantity, newList } = item; // 跳过 quantity 为 0 或无效的情况 console.log(quantity) if (!quantity || quantity <= 0) continue; // 处理 newList:确保是数组,不足时用空对象兜底 @@ -119,80 +117,180 @@ } ) const isComposing = ref(false) const getCaretOffset = (el) => { const sel = window.getSelection() if (!sel || sel.rangeCount === 0) return 0 const range = sel.getRangeAt(0) if (!el.contains(range.startContainer)) return 0 const preRange = range.cloneRange() preRange.selectNodeContents(el) preRange.setEnd(range.startContainer, range.startOffset) return preRange.toString().length } const setCaretOffset = (el, offset) => { const sel = window.getSelection() if (!sel) return const range = document.createRange() range.selectNodeContents(el) let current = 0 const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null) let node = walker.nextNode() while (node) { const next = current + (node.nodeValue?.length || 0) if (offset <= next) { range.setStart(node, Math.max(0, offset - current)) range.collapse(true) sel.removeAllRanges() sel.addRange(range) return } current = next node = walker.nextNode() } // 超出长度则放到末尾 range.collapse(false) sel.removeAllRanges() sel.addRange(range) } // ============================================= //修改相同产品名称标签 const updateProductName = (event, index,id) => { // 创建映射对象 const propertyMapping = {}; const updateProductName = async (event, fieldIndex, rowIndex) => { // 输入法组词阶段不要同步,否则会抖动/错乱 if (isComposing.value) return const el = event.target // 保存光标 const caret = getCaretOffset(el) // 取“纯值”此时 contenteditable 只包含值,不包含标题: const result = (el.innerText ?? '').trim() // 映射:fieldIndex -> 字段名 const propertyMapping = {} labelList.forEach(item => { propertyMapping[item.name] = item.title; }); // 输入的值 const newValue = event.target.innerText; const parts = newValue.split(':'); const result = parts[1]; // 获取冒号后的部分 propertyMapping[item.name] = item.title }) const keys = Object.keys(propertyMapping) const propertyName = keys[fieldIndex] if (!propertyName) return // 获取映射中所有的键 const keys = Object.keys(propertyMapping); //更新 const baseRow = props.lastList?.[rowIndex] if (!baseRow) return // 根据 index 获取对应的属性名 const propertyName = keys[index]; const basePrefix = (baseRow.processId ?? '').substring(0, 11) const baseGlassNumber = baseRow.glassNumber const baseOrderId = baseRow.orderId // 如果映射中没有该 index,直接返回 if (!propertyName) { console.warn('Unsupported index:', index); return; } // 遍历 lastList 并更新对应的属性 props.lastList.forEach(obj => { // 获取前缀和 orderId console.log(index) const prefix = props.lastList[id].processId.substring(0, 11); const orderId = obj.orderId; const glassNumber=props.lastList[id].glassNumber // 根据 propertyName 更新属性 if (propertyName === 'productAbbreviation' && prefix === obj.processId.substring(0, 11)) { obj.productAbbreviation = result; const objPrefix = (obj.processId ?? '').substring(0, 11) if (propertyName === 'productAbbreviation' && basePrefix === objPrefix) obj.productAbbreviation = result if (propertyName === 'project' && baseOrderId === obj.orderId) obj.project = result if (propertyName === 'productName' && basePrefix === objPrefix) obj.productName = result if (propertyName === 'customerName' && baseOrderId === obj.orderId) obj.customerName = result if (propertyName === 'orderId' && baseOrderId === obj.orderId) obj.orderId = result if (propertyName === 'glassNumber' && baseGlassNumber === obj.glassNumber) obj.glassNumber = result if (propertyName === 'width' && baseGlassNumber === obj.glassNumber) obj.width = result if (propertyName === 'height' && baseGlassNumber === obj.glassNumber) obj.height = result if (propertyName === 'custom1' && baseOrderId === obj.orderId) obj.custom1 = result if (propertyName === 'custom2' && baseOrderId === obj.orderId) obj.custom2 = result if (propertyName === 'custom3' && baseOrderId === obj.orderId) obj.custom3 = result if (propertyName === 'custom4' && baseOrderId === obj.orderId) obj.custom4 = result if (propertyName === 'custom5' && baseOrderId === obj.orderId) obj.custom5 = result }) // 5) 等 Vue patch 完成后,把光标放回去 await nextTick() setCaretOffset(el, caret) } if (propertyName === 'project' && orderId === obj.orderId) { obj.project = result; } if (propertyName === 'productName' && prefix === obj.processId.substring(0, 11)){ obj.productName = result; } if (propertyName === 'customerName' && orderId === obj.orderId){ obj.customerName = result; } if (propertyName === 'orderId' && orderId === obj.orderId){ obj.orderId = result; } if (propertyName === 'glassNumber' && glassNumber === obj.glassNumber){ obj.glassNumber = result; } if (propertyName === 'width' && glassNumber === obj.glassNumber){ obj.width = result; } if (propertyName === 'height' && glassNumber === obj.glassNumber){ obj.height = result; } if (propertyName === 'custom1' && orderId === obj.orderId){ obj.custom1 = result; } if (propertyName === 'custom2' && orderId === obj.orderId){ obj.custom2 = result; } if (propertyName === 'custom3' && orderId === obj.orderId){ obj.custom3 = result; } if (propertyName === 'custom4' && orderId === obj.orderId){ obj.custom4 = result; } if (propertyName === 'custom5' && orderId === obj.orderId){ obj.custom5 = result; } }); } //修改相同产品名称标签 // const updateProductName = (event, index,id) => { // // 创建映射对象 // const propertyMapping = {}; // labelList.forEach(item => { // propertyMapping[item.name] = item.title; // }); // // 输入的值 // const newValue = event.target.innerText; // const parts = newValue.split(':'); // const result = parts[1]; // 获取冒号后的部分 // // // 获取映射中所有的键 // const keys = Object.keys(propertyMapping); // // // 根据 index 获取对应的属性名 // const propertyName = keys[index]; // // 如果映射中没有该 index,直接返回 // if (!propertyName) { // console.warn('Unsupported index:', index); // return; // } // // // 遍历 lastList 并更新对应的属性 // props.lastList.forEach(obj => { // // 获取前缀和 orderId // const prefix = props.lastList[id].processId.substring(0, 11); // const orderId = obj.orderId; // const glassNumber=props.lastList[id].glassNumber // // 根据 propertyName 更新属性 // if (propertyName === 'productAbbreviation' && prefix === obj.processId.substring(0, 11)) { // obj.productAbbreviation = result; // } // // if (propertyName === 'project' && orderId === obj.orderId) { // obj.project = result; // } // if (propertyName === 'productName' && prefix === obj.processId.substring(0, 11)){ // obj.productName = result; // } // if (propertyName === 'customerName' && orderId === obj.orderId){ // obj.customerName = result; // } // if (propertyName === 'orderId' && orderId === obj.orderId){ // obj.orderId = result; // } // if (propertyName === 'glassNumber' && glassNumber === obj.glassNumber){ // obj.glassNumber = result; // } // if (propertyName === 'width' && glassNumber === obj.glassNumber){ // obj.width = result; // } // if (propertyName === 'height' && glassNumber === obj.glassNumber){ // obj.height = result; // } // if (propertyName === 'custom1' && orderId === obj.orderId){ // obj.custom1 = result; // } // if (propertyName === 'custom2' && orderId === obj.orderId){ // obj.custom2 = result; // } // if (propertyName === 'custom3' && orderId === obj.orderId){ // obj.custom3 = result; // } // if (propertyName === 'custom4' && orderId === obj.orderId){ // obj.custom4 = result; // } // if (propertyName === 'custom5' && orderId === obj.orderId){ // obj.custom5 = result; // } // }); // } </script> @@ -203,8 +301,16 @@ <div class="entirety_semi"> <div class="row4">{{ faceOrientation }}</div> <div v-for="(item,id) in labelList" class="contentRow"> <div contenteditable="true" v-if="item1[item.name] != null && item1[item.name] !== ''" class="row1" @input="updateProductName($event, id,index)">{{ item.title }}:{{ item1[item.name] }}</div> <!-- <div v-if="item1[item.name] != null && item1[item.name] !== ''" class="row2">{{ item1[item.name] }}</div>--> <div class="row1" v-show="item1[item.name] != null && item1[item.name] !== ''"> <span class="label">{{ item.title }}:</span> <span class="value" contenteditable="true" @compositionstart="isComposing.value = true" @compositionend="(e) => { isComposing.value = false; updateProductName(e, id, index) }" @input="(e) => updateProductName(e, id, index)" >{{ item1[item.name] }}</span> </div> </div> <div v-html="company.printLabel.customSemi(item1)"></div> </div> north-glass-erp/northglass-erp/src/components/pp/PrintProcessReplenish.vue
@@ -289,7 +289,7 @@ <td v-else-if="itemTr.qrcodeList.length*1>1" colspan="3" >多层合并,详情见产品名称</td> <td v-else colspan="3" style="font-size: 18px;">{{ itemTr.glass_child }}</td> <td class="tdNowrap">产品名称:</td> <td v-if="!company.processFontSize" :colspan="2+item.processList.length*2">{{ itemTr.product_name }}</td> <td v-if="!company.processFontSize" :colspan="5+item.processList.length*2">{{ itemTr.product_name }}</td> <td v-else :colspan="5+item.processList.length*2" style="font-size: 18px;">{{ itemTr.product_name }}</td> </tr> <tr> north-glass-erp/northglass-erp/src/views/pp/processCard/PrintProgressProcessCard.vue
@@ -330,9 +330,12 @@ {field: 'order_number', width: 100,title: t('order.OrderNum'),showOverflow:"ellipsis",filters: [{data: ''}], slots: {filter: 'num1_filter'}, filterMethod: filterChanged}, // {field: 'glassNumber', width: 110,title: t('reportingWorks.glassNumber'),showOverflow:"ellipsis",filters: [{data: ''}], // slots: {filter: 'num1_filter'}, // filterMethod: filterChanged}, {field: 'child_width', title: t('order.width'),width: 80,filters: [{data: ''}], slots: {filter: 'num1_filter'}, filterMethod: filterChanged }, {field: 'child_height', title: t('order.height'),width: 80 ,filters: [{data: ''}], slots: {filter: 'num1_filter'}, filterMethod: filterChanged}, {field: 'quantity', width: 90,title: t('order.quantity')}, {field: 'grossArea', width: 90,title: t('order.area')}, {field: 'broken_num',width: 90, title: t('reportingWorks.quantityBroken')},