|
|
|
|
@ -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 () => {
|
|
|
|
|
|