feat(wms):重构条码配置功能以支持灵活规则

- 将简单的组件选择重构为可自定义的片段式条码规则配置
- 支持多种片段类型:文本、日期、时间、字段片段和分隔符
- 提供预览功能以便实时查看生成效果
- 增加移动、删除及重置规则片段的操作按钮
- 更新本地存储键名以区分新旧配置数据结构
- 扩展日期与时间格式选项提高配置灵活性
- 优化字段截取逻辑支持起始位置与长度设定
master
zangch@mesnac.com 2 months ago
parent 87c3cd3753
commit e514f9c00a

@ -536,9 +536,9 @@
<!-- </el-form-item>-->
<!-- <el-form-item>
<el-form-item>
<el-button @click="batchConfigVisible = true">配置条码</el-button>
</el-form-item>-->
</el-form-item>
<el-form-item label="已包数量" prop="printedNum">
@ -607,13 +607,54 @@
</el-dialog>
<el-dialog v-model="batchConfigVisible" title="条码配置" width="40%">
<el-select v-model="selectedComponents" multiple placeholder="选择并排序组成部分">
<el-option v-for="comp in batchComponents" :key="comp" :label="comp" :value="comp" />
</el-select>
<el-dialog v-model="batchConfigVisible" title="条码配置" width="50%">
<div class="rule-builder">
<div class="rule-row" v-for="(seg, idx) in ruleSegments" :key="idx" style="display:flex; align-items:center; gap:8px; margin-bottom:8px;">
<el-select v-model="seg.type" placeholder="片段类型" style="width: 140px;">
<el-option v-for="t in segmentTypes" :key="t" :label="t" :value="t" />
</el-select>
<template v-if="seg.type === '文本'">
<el-input v-model="seg.text" placeholder="固定文本" style="width: 220px;" />
</template>
<template v-if="seg.type === '分隔符'">
<el-input v-model="seg.delimiter" placeholder="分隔符" style="width: 140px;" />
</template>
<template v-if="seg.type === '日期'">
<el-select v-model="seg.format" placeholder="日期格式" style="width: 180px;">
<el-option v-for="f in dateFormatOptions" :key="f" :label="f" :value="f" />
</el-select>
</template>
<template v-if="seg.type === '时间'">
<el-select v-model="seg.format" placeholder="时间格式" style="width: 180px;">
<el-option v-for="f in timeFormatOptions" :key="f" :label="f" :value="f" />
</el-select>
</template>
<template v-if="seg.type === '字段片段'">
<el-select v-model="seg.field" placeholder="来源字段" style="width: 160px;">
<el-option label="入库单号" value="入库单号" />
<el-option label="物料编码" value="物料编码" />
</el-select>
<el-input-number v-model="seg.start" :min="1" :max="200" controls-position="right" placeholder="起始(1基)" style="width: 140px;" />
<el-input-number v-model="seg.end" :min="1" :max="200" controls-position="right" placeholder="结束(包含)" style="width: 140px;" />
</template>
<el-button circle @click="moveUp(idx)" title="上移"></el-button>
<el-button circle @click="moveDown(idx)" title="下移"></el-button>
<el-button circle type="danger" @click="removeSegment(idx)" title="删除">×</el-button>
</div>
<div style="margin-top: 8px;">
<el-button type="primary" @click="addSegment"></el-button>
<el-button @click="resetSegments" style="margin-left: 8px;">重置</el-button>
</div>
<div class="preview" style="margin-top: 12px; padding: 8px; background: #f5f7fa; border: 1px solid #ebeef5; border-radius: 4px;">
预览{{ previewBatchCode }}
</div>
</div>
<template #footer>
<el-button @click="batchConfigVisible = false">取消</el-button>
<el-button type="primary" @click="saveBatchConfig"></el-button>
<el-button type="primary" @click="saveRuleSegments"></el-button>
</template>
</el-dialog>
@ -884,26 +925,84 @@ const submitForm = async() => {
//
const batchConfigVisible = ref(false)
const batchComponents = ref(['当前时间', '入库单号', '物料编码']) //
const selectedComponents = ref([]) //
//
type RuleSegment = {
type: '文本' | '日期' | '时间' | '字段片段' | '分隔符',
text?: string,
delimiter?: string,
format?: string,
field?: '入库单号' | '物料编码',
start?: number,
end?: number,
}
const segmentTypes = ['文本', '日期', '时间', '字段片段', '分隔符']
const dateFormatOptions = ['YYYYMMDD', 'YYMMDD', 'YYYY-MM-DD', 'YYYY/MM/DD']
const timeFormatOptions = ['HHmmss', 'HH:mm:ss']
const ruleSegments = ref<RuleSegment[]>([])
onMounted(() => {
const saved = localStorage.getItem('batchCodeConfig')
if (saved) selectedComponents.value = JSON.parse(saved)
const savedNew = localStorage.getItem('batchCodeRuleSegments')
if (savedNew) {
try { ruleSegments.value = JSON.parse(savedNew) || [] } catch {}
}
})
const saveBatchConfig = () => {
localStorage.setItem('batchCodeConfig', JSON.stringify(selectedComponents.value))
batchConfigVisible.value = false
const addSegment = () => { ruleSegments.value.push({ type: '文本', text: '' }) }
const removeSegment = (idx: number) => { ruleSegments.value.splice(idx, 1) }
const moveUp = (idx: number) => { if (idx <= 0) return; const t = ruleSegments.value[idx-1]; ruleSegments.value[idx-1] = ruleSegments.value[idx]; ruleSegments.value[idx] = t }
const moveDown = (idx: number) => { if (idx >= ruleSegments.value.length - 1) return; const t = ruleSegments.value[idx+1]; ruleSegments.value[idx+1] = ruleSegments.value[idx]; ruleSegments.value[idx] = t }
const resetSegments = () => { ruleSegments.value = [] }
const saveRuleSegments = () => { localStorage.setItem('batchCodeRuleSegments', JSON.stringify(ruleSegments.value)); batchConfigVisible.value = false }
const pad2 = (n: number) => (n < 10 ? '0' + n : '' + n)
const formatDateTime = (date: Date, fmt: string) => {
const YYYY = date.getFullYear().toString()
const YY = YYYY.slice(-2)
const MM = pad2(date.getMonth() + 1)
const DD = pad2(date.getDate())
const HH = pad2(date.getHours())
const mm = pad2(date.getMinutes())
const ss = pad2(date.getSeconds())
return fmt
.replace('YYYY', YYYY)
.replace('YY', YY)
.replace('MM', MM)
.replace('DD', DD)
.replace('HH', HH)
.replace('mm', mm)
.replace('ss', ss)
}
const generateBatchCode = (form) => {
if (!selectedComponents.value.length) return '' //
return selectedComponents.value.map(comp => {
if (comp === '当前时间') return new Date().toISOString().slice(0,10).replace(/-/g, '')
if (comp === '入库单号') return form.instockCode
if (comp === '物料编码') return form.materialCode
return ''
}).join('')
const extractFieldSlice = (form: any, field: '入库单号' | '物料编码', start?: number, end?: number) => {
const src = field === '入库单号' ? (form?.instockCode || '') : (form?.materialCode || '')
if (!src) return ''
const s = Math.max(0, (start || 1) - 1)
const e = Math.max(s, ((end || src.length)))
return src.substring(s, Math.min(e, src.length))
}
const previewBatchCode = computed(() => generateBatchCode(childrenTableInfoForm.value))
const generateBatchCode = (form: any) => {
if (ruleSegments.value.length) {
const now = new Date()
return ruleSegments.value.map(seg => {
switch (seg.type) {
case '文本': return seg.text || ''
case '分隔符': return seg.delimiter || ''
case '日期': return seg.format ? formatDateTime(now, seg.format) : formatDateTime(now, 'YYYYMMDD')
case '时间': return seg.format ? formatDateTime(now, seg.format) : formatDateTime(now, 'HHmmss')
case '字段片段': return extractFieldSlice(form, seg.field || '入库单号', seg.start, seg.end)
default: return ''
}
}).join('')
}
//
return ''
}
//
let mategoryOptions = ref([]);
const getMaterialCategorySelect = async () => {

Loading…
Cancel
Save