647556386
昨天 b680585c3a6d43f0c72a83a115ea537ce8c91a07
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
<template>
    <vol-box v-model="show" title="空托入库" :width="800" :height="1200">
        <template #content>
            <el-form ref="form" :model="form" :rules="rules" label-width="90px">
                <el-form-item label="入库区域:" prop="locationType">
                    <el-select v-model="form.locationType" placeholder="请选择入库区域">
                        <el-option v-for="item in locationTypes" :key="item.locationType" :label="item.locationTypeDesc"
                            :value="item.locationType" />
                    </el-select>
                </el-form-item>
 
                <el-form-item label="托盘条码:" prop="palletCode">
                    <el-input v-model="form.palletCode" placeholder="请扫描/输入托盘条码(A开头,后跟数字)" @keyup.enter="submit" clearable
                        @paste="handlePaste" @input="handleInput" ref="boxCodeInput" />
                </el-form-item>
            </el-form>
        </template>
 
        <template #footer>
            <div class="dialog-footer">
                <el-button type="primary" @click="submit">确认</el-button>
                <el-button @click="show = false">关闭</el-button>
            </div>
        </template>
    </vol-box>
</template>
  
<script>
import VolBox from '@/components/basic/VolBox.vue'
 
export default {
    components: { VolBox },
    props: {
        value: { type: Boolean, default: false }
    },
    data() {
        // 自定义条码验证规则
        const validatePalletCode = (rule, value, callback) => {
            if (!value) {
                return callback(new Error('请输入托盘条码'));
            }
 
            // 验证条码格式:A开头,后面至少1位数字(不限制具体长度)
            const codePattern = /^A\d+$/;
            if (!codePattern.test(value)) {
                return callback(new Error('条码格式不正确!正确格式:A开头,后跟数字,如:A000008080'));
            }
 
            callback();
        };
 
        return {
            show: false,
            form: {
                palletCode: '',
                locationType: ''
            },
            locationTypes: [],
            // 表单验证规则
            rules: {
                locationType: [
                    { required: true, message: '请选择入库区域', trigger: 'change' }
                ],
                palletCode: [
                    { validator: validatePalletCode, trigger: ['blur', 'change'] }
                ]
            }
        }
    },
    methods: {
        open() {
            this.show = true
            this.getData();
            this.$nextTick(() => {
                this.focusInput()
            })
        },
 
        async getData() {
            try {
                const { data } = await this.http.post("api/LocationInfo/GetLocationTypes")
                this.locationTypes = data
            } catch (e) {
                this.$message.error('获取区域类型失败')
            }
        },
 
        async submit() {
            // 表单验证
            try {
                await this.$refs.form.validate();
            } catch (error) {
                // 验证失败,聚焦输入框
                this.focusAndSelectInput();
                return;
            }
 
            try {
                let param = {
                    WarehouseCode: this.form.locationType,
                    PalletCode: this.form.palletCode
                }
 
                const { status, message } = await this.http.post(
                    `/api/InboundOrder/EmptyMaterielGroup`,
                    param
                )
 
                if (status) {
                    this.$message.success("组盘成功");
                    // 清空输入框数据
                    this.form.palletCode = '';
                    // 重置验证状态
                    this.$refs.form.clearValidate('palletCode');
                    // 聚焦并选中输入框
                    this.focusAndSelectInput();
                } else {
                    this.$message.error(message || '操作失败');
                    // 失败时不清理数据,但聚焦并选中输入框,方便修改
                    this.focusAndSelectInput();
                }
            } catch (error) {
                this.$message.error('请求异常');
                // 异常时也不清理数据
                this.focusAndSelectInput();
            }
        },
 
        // 扫描枪优化处理
        handleInput(value) {
            // 过滤非数字和条码常用字符,允许A开头
            this.form.palletCode = value.replace(/[^a-zA-Z0-9]/g, '')
 
            // 自动转换为大写(条码通常为大写)
            this.form.palletCode = this.form.palletCode.toUpperCase();
 
            // 自动触发验证
            this.$nextTick(() => {
                this.$refs.form.validateField('palletCode');
            });
        },
 
        handlePaste(e) {
            // 获取粘贴的内容
            const clipboardData = e.clipboardData || window.clipboardData;
            const pastedText = clipboardData.getData('text');
 
            // 处理粘贴内容
            const cleanedText = pastedText.replace(/[^a-zA-Z0-9]/g, '').toUpperCase();
 
            // 如果粘贴内容符合条码格式,自动填充并提交
            if (cleanedText.startsWith('A')) {
                this.form.palletCode = cleanedText;
                // 延迟提交,确保表单已更新
                setTimeout(() => {
                    this.submit();
                }, 50);
            }
 
            // 阻止默认粘贴行为,使用我们处理后的值
            e.preventDefault();
        },
 
        // 聚焦并选中输入框
        focusAndSelectInput() {
            this.$nextTick(() => {
                setTimeout(() => {
                    const inputRef = this.$refs.boxCodeInput;
                    if (inputRef) {
                        // Element Plus/Element UI 的处理方式
                        const inputEl = inputRef.$el ? inputRef.$el.querySelector('input') : inputRef;
                        if (inputEl) {
                            inputEl.focus();
                            inputEl.select();
                        }
                    }
                }, 100);
            });
        },
 
        // 只聚焦输入框(不清空数据)
        focusInput() {
            this.$nextTick(() => {
                const inputRef = this.$refs.boxCodeInput;
                if (inputRef) {
                    const inputEl = inputRef.$el ? inputRef.$el.querySelector('input') : inputRef;
                    inputEl?.focus();
                }
            });
        },
 
        // 清空表单数据
        clearForm() {
            this.form.palletCode = '';
            // 重置验证状态
            if (this.$refs.form) {
                this.$refs.form.clearValidate();
            }
            // 不清空 locationType,保持区域选择
        }
    },
    watch: {
        show(val) {
            if (val) {
                this.$nextTick(() => {
                    this.focusInput()
                })
            } else {
                // 关闭弹窗时清空表单
                this.clearForm();
            }
        }
    }
}
</script>
  
<style scoped>
.dialog-footer {
    text-align: right;
}
</style>