Browse Source

组合按“元素类型+内容”匹配,同名元素互相覆盖,最终使用最后一个元素的公式的问题

master
han\hanst 7 days ago
parent
commit
239e5fe99f
  1. 23
      src/utils/elementCombination.js
  2. 2
      src/utils/zplGenerator.js
  3. 30
      src/views/modules/labelSetting/components/ElementCombinationDialog.vue

23
src/utils/elementCombination.js

@ -6,6 +6,21 @@ const ELEMENT_TYPES = {
'流水号': 'serialNumber'
}
// labelNo 已持久化;新建元素在首次保存前使用画布 ID,由后端统一映射。
export function getElementReferenceKey (element) {
const key = element.labelNo || element.id
return key == null ? null : String(key)
}
export function getElementReference (element) {
if (element.combinationReference) return element.combinationReference
const typeName = Object.keys(ELEMENT_TYPES).find(name => ELEMENT_TYPES[name] === element.type) || element.type
const key = getElementReferenceKey(element)
const identity = key == null ? '' : `@${encodeURIComponent(key)}`
const content = element.data ? `(${element.data})` : ''
return `${typeName}${identity}${content}`
}
// 按配对花括号读取引用,保留 #{字段} 和嵌套组合,不用简单的 /{[^}]+}/ 截断内容。
export function parseElementCombination (data) {
const value = data == null ? '' : String(data)
@ -22,9 +37,13 @@ export function parseElementCombination (data) {
if (start === 0 || value[start - 1] !== '#') {
const reference = value.slice(start + 1, end - 1)
const match = /^(文本|一维码|二维码|图片|流水号)(?:\(([\s\S]*)\))?$/.exec(reference)
const match = /^(文本|一维码|二维码|图片|流水号)(?:@([^(){}]+))?(?:\(([\s\S]*)\))?$/.exec(reference)
if (match) {
references.push({start, end, reference, type: ELEMENT_TYPES[match[1]], data: match[2]})
let elementKey = match[2]
if (elementKey !== undefined) {
try { elementKey = decodeURIComponent(elementKey) } catch (error) { /* 保留损坏标识,不能按同名元素兜底。 */ }
}
references.push({start, end, reference, type: ELEMENT_TYPES[match[1]], data: match[3], elementKey})
}
}
start = end - 1

2
src/utils/zplGenerator.js

@ -237,7 +237,7 @@ export class ZPLGenerator {
}
const weekNo = Math.floor((diffDays - daysToNextWeekStart) / 7) + 2
const normalizedWeekNo = Math.max(1, weekNo)
return `${String(normalizedWeekNo).padStart(2, '0')}${String(date.getFullYear() % 100).padStart(2, '0')}`
return `${String(date.getFullYear() % 100).padStart(2, '0')}${String(normalizedWeekNo).padStart(2, '0')}`
}
calculateWeekday(date, firstDayOfWeekStr) {

30
src/views/modules/labelSetting/components/ElementCombinationDialog.vue

@ -127,7 +127,7 @@
</template>
<script>
import { parseElementCombination } from '@/utils/elementCombination'
import { parseElementCombination, getElementReference, getElementReferenceKey } from '@/utils/elementCombination'
let nextElementId = 0
@ -154,6 +154,7 @@ export default {
selectedElements: [],
separator: '-',
originalReferences: [],
originalSelectedElementIds: [],
originalCombinationData: '',
originalSeparator: '-'
}
@ -205,9 +206,14 @@ export default {
this.selectedElements = references.map((reference, index) => {
const savedId = savedConfig && savedConfig.selectedElements && savedConfig.selectedElements[index]
const candidates = this.allElements.filter(element => element !== this.targetElement && element.type === reference.type)
const source = (savedId != null && candidates.find(element => element.id === savedId)) ||
candidates.find(element => this.getElementFullName(element) === reference.reference) ||
(reference.data === undefined && candidates[0])
// 显式身份未命中表示来源已删除,不能串用同名元素的公式。
const matches = candidates.filter(element => reference.data === undefined || this.getElementFullName(element) === reference.reference)
const source = reference.elementKey !== undefined
? candidates.find(element => getElementReferenceKey(element) === reference.elementKey)
: savedId != null
? candidates.find(element => element.id === savedId)
// 历史同名引用未记录身份时不能猜测来源,保留引用,待用户重新选择。
: matches.length === 1 ? matches[0] : null
// 来源已删除时保留原引用,避免打开后直接确定就悄悄丢失内容。
return source || {
id: `missing_${index}`,
@ -217,6 +223,8 @@ export default {
}
})
this.originalSelectedElementIds = this.selectedElements.map(element => element.id)
if (savedConfig && savedConfig.separator != null) {
this.separator = String(savedConfig.separator)
} else if (references.length > 1) {
@ -229,6 +237,7 @@ export default {
this.selectedElements = []
this.separator = '-'
this.originalReferences = []
this.originalSelectedElementIds = []
this.originalCombinationData = ''
this.originalSeparator = '-'
},
@ -378,13 +387,18 @@ export default {
},
generateSequenceFormat() {
const references = this.selectedElements.map(element => this.getElementFullName(element))
// 未改动时保持原组合字面内容(含手工插入的不同间隔文字),确认不会重写或重复追加。
const references = this.selectedElements.map(element => getElementReference(element))
// 保留原有间隔文字,同时为每个引用写入独立身份;重排同名元素也能生效。
if (this.originalReferences && this.originalReferences.length > 0 &&
this.separator === this.originalSeparator &&
references.length === this.originalReferences.length &&
references.every((reference, index) => reference === this.originalReferences[index])) {
return this.originalCombinationData
this.selectedElements.every((element, index) => element.id === this.originalSelectedElementIds[index])) {
const original = parseElementCombination(this.originalCombinationData)
let result = this.originalCombinationData
for (let index = original.length - 1; index >= 0; index--) {
result = result.slice(0, original[index].start) + `{${references[index]}}` + result.slice(original[index].end)
}
return result
}
return references.map(reference => `{${reference}}`).join(this.separator || '')
}

Loading…
Cancel
Save