feat: 乱起八糟的东西

This commit is contained in:
砂糖
2025-08-23 17:22:06 +08:00
parent 5ed6436713
commit c1f3c2d7d6
8 changed files with 254 additions and 222 deletions

View File

@@ -3,7 +3,7 @@
<!-- 仅保留预览区 -->
<div class="barcode-preview-area">
<div class="iframe-wrapper">
<iframe ref="previewIframe" class="barcode-iframe" frameborder="0" :style="iframeStyle"></iframe>
<iframe ref="previewIframe" id="previewIframe" class="barcode-iframe" frameborder="0" :style="iframeStyle"></iframe>
</div>
</div>
</div>

View File

@@ -9,13 +9,13 @@
清空所有
</el-button>
</el-tooltip>
<!-- <el-tooltip content="仅对完整配置的二维码进行打印预览" placement="top"
<el-tooltip content="仅对完整配置的二维码进行打印预览" placement="top"
:disabled="drawerBarcodeData.length === 0 || !isAllValid">
<el-button type="success" icon="el-icon-printer" @click="handlePrintPreview"
:disabled="drawerBarcodeData.length === 0 || !isAllValid" class="btn-print">
打印预览
</el-button>
</el-tooltip> -->
</el-tooltip>
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">
添加二维码
</el-button>
@@ -142,11 +142,19 @@
<el-input-number v-model="cfg.count" :min="1" :max="100" size="mini" placeholder="请输入数量" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="8">
<el-col :span="12">
<el-form-item label="下方文字" class="form-item">
<el-input v-model="cfg.text" size="mini" placeholder="例如:产品入库二维码" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生成数量" class="form-item">
<el-input v-model="cfg.totalCount" size="mini" placeholder="例如:产品入库二维码" />
</el-form-item>
</el-col>
</el-row>
<!-- 配置状态提示 - 优化背景色和图标 -->
@@ -251,10 +259,9 @@ export default {
itemId: b.itemId,
batchNo: b.batchNo || 'auto',
quantity: b.count || 1,
unit: b.unit || '',
recordType: 1,
}),
count: 1,
count: b.totalCount,
textTpl: b.text || '二维码'
}));
}
@@ -263,7 +270,7 @@ export default {
// 物料选择变更
onItemChange(item, idx) {
if (item && this.drawerBarcodeData[idx]) {
this.drawerBarcodeData[idx].unit = item.unit;
// this.drawerBarcodeData[idx].unit = item.unit;
// 如果未设置数量默认设置为1
if (!this.drawerBarcodeData[idx].count) {
this.drawerBarcodeData[idx].count = 1;
@@ -316,6 +323,7 @@ export default {
itemId: undefined,
batchNo: 'auto',
count: 1, // 默认数量1
totalCount: 1, // 默认数量1
unit: '',
text: '二维码', // 默认文字
hovered: false // 新增hover状态用于交互反馈
@@ -368,18 +376,7 @@ export default {
},
// 打印预览 - 增加加载状态提示
handlePrintPreview() {
const printLoading = this.$loading({
lock: true,
text: '正在准备打印预览...',
spinner: 'el-icon-loading',
background: 'rgba(255, 255, 255, 0.8)'
});
// 模拟预览准备时间(实际项目可替换为真实接口请求)
setTimeout(() => {
window.print();
printLoading.close();
}, 1000);
document.querySelector('#previewIframe').contentWindow.print();
},
// 验证单个配置是否有效
isConfigValid(cfg) {

View File

@@ -1,49 +1,35 @@
<template>
<div class="qr-parser-container">
<div class="card">
<el-alert title="请将当前输入法切换到英文输入后再进行扫码操作" type="warning"></el-alert>
<div class="card-header">
<h2 class="title">二维码解析器</h2>
<p class="subtitle">扫描或输入二维码内容进行解析</p>
</div>
<div class="input-section">
<el-input
v-model="text"
@change="handleChange"
@blur="handleBlur"
ref="textarea"
placeholder="请扫描二维码或粘贴二维码文本内容..."
:rows="3"
type="textarea"
:class="{ 'invalid-input': !isValid && text.length > 0 }"
/>
<el-input v-model="text" @input="handleInput" @blur="handleBlur" ref="textarea"
placeholder="请扫描二维码或粘贴二维码文本内容..." :rows="3" type="textarea"
:class="{ 'invalid-input': !isValid && text.length > 0 }" />
<div class="input-hint">
<i class="el-icon-info-circle"></i>
<span>{{ inputHint }}</span>
</div>
</div>
<!-- 加载状态 -->
<el-loading
v-if="isLoading"
text="正在解析数据..."
class="loading-overlay"
></el-loading>
<el-loading v-if="isLoading" text="正在解析数据..." class="loading-overlay"></el-loading>
<!-- 二维码解析结果 - 只有数据有效时才显示 -->
<div v-if="isValid" class="result-section fade-in">
<div class="result-header">
<h3>解析结果</h3>
<el-tag
:type="result.ioType === 'in' ? 'success' : 'warning'"
size="small"
>
<el-tag :type="result.ioType === 'in' ? 'success' : 'warning'" size="small">
{{ result.ioType === 'in' ? '入库' : '出库' }}
</el-tag>
</div>
<el-descriptions :column="1" border class="result-table">
<el-descriptions-item label="出入库类型" :span="1">
{{ result.ioType === 'in' ? '入库' : '出库' }}
@@ -52,32 +38,22 @@
{{ formatItemType(result.itemType) }}
</el-descriptions-item>
<el-descriptions-item label="物料信息" :span="1">
<ProductInfo v-if="result.itemType === 'product' || result.itemType === 'semi'" :productId="result.itemId" />
<ProductInfo v-if="result.itemType === 'product' || result.itemType === 'semi'"
:productId="result.itemId" />
<RawMaterialInfo v-else-if="result.itemType === 'raw_material'" :materialId="result.itemId" />
<el-input v-else disabled v-model="result.itemId" placeholder="未知物料" :disabled="true" style="width: 100%;" />
<el-input v-else disabled v-model="result.itemId" placeholder="未知物料" :disabled="true"
style="width: 100%;" />
</el-descriptions-item>
<el-descriptions-item label="数量" :span="1">
{{ result.quantity }}
</el-descriptions-item>
<el-descriptions-item label="计量单位" :span="1">
{{ result.unit }}
</el-descriptions-item>
</el-descriptions>
<div class="action-buttons">
<el-button
type="primary"
@click="handleSubmit"
:loading="isSubmitting"
icon="el-icon-check"
>
<el-button type="primary" @click="handleSubmit" :loading="isSubmitting" icon="el-icon-check">
确认执行
</el-button>
<el-button
type="default"
@click="handleReset"
icon="el-icon-refresh-right"
>
<el-button type="default" @click="handleReset" icon="el-icon-refresh-right">
重置
</el-button>
</div>
@@ -91,6 +67,24 @@ import ProductInfo from '@/components/KLPService/Renderer/ProductInfo';
import RawMaterialInfo from '@/components/KLPService/Renderer/RawMaterialInfo';
import { addStockIoDetail } from '@/api/wms/stockIoDetail';
// 通用防抖高阶函数(可放在工具类中全局复用)
function debounce(fn, delay = 300) {
let debounceTimer = null; // 闭包保存定时器,避免重复创建
// 返回被包装后的函数(支持传递参数给业务函数)
return function (...args) {
// 1. 清除上一次未执行的定时器(核心:避免短时间内重复触发)
if (debounceTimer) {
clearTimeout(debounceTimer);
}
// 2. 延迟执行业务函数this 绑定到调用者(适配 Vue 组件上下文)
debounceTimer = setTimeout(() => {
fn.apply(this, args); // 传递参数+保持this指向Vue组件实例
}, delay);
};
}
export default {
data() {
return {
@@ -104,17 +98,25 @@ export default {
ProductInfo,
RawMaterialInfo,
},
created() {
// 包装“输入解析+提交”的业务函数,生成带防抖的版本
this.debouncedHandleInput = debounce(
this.actualParseAndSubmit, // 实际的业务逻辑函数
500 // 防抖延迟时间
);
},
computed: {
result() {
try {
return JSON.parse(this.text);
const text = JSON.parse(this.text)
return text;
} catch (error) {
return {};
}
},
// 验证数据是否有效
isValid() {
const requiredFields = ['ioType', 'itemType', 'itemId', 'quantity', 'unit'];
const requiredFields = ['ioType', 'itemType', 'itemId', 'quantity'];
// 检查是否包含所有必要字段
const hasAllFields = requiredFields.every(field => this.result.hasOwnProperty(field));
// 检查出入库类型是否有效
@@ -123,51 +125,66 @@ export default {
const isItemTypeValid = ['product', 'semi', 'raw_material'].includes(this.result.itemType);
// 检查数量是否为有效数字
const isQuantityValid = !isNaN(Number(this.result.quantity)) && Number(this.result.quantity) > 0;
return hasAllFields && isIoTypeValid && isItemTypeValid && isQuantityValid;
}
},
methods: {
handleChange(value) {
if (!value) {
this.inputHint = '请输入二维码内容,系统将自动解析';
handleInput(value) {
const trimmedValue = value.trim();
// 空值场景:立即反馈,不触发防抖逻辑
if (!trimmedValue) {
this.inputHint = "请输入二维码内容,系统将自动解析";
return;
}
this.isLoading = true;
// 模拟解析延迟,提升用户体验
setTimeout(() => {
try {
const parsed = JSON.parse(value);
if (this.isValid) {
this.inputHint = '数据解析成功,可以提交操作';
this.$message.success({
message: '数据解析成功',
duration: 1500
});
// 解析成功后禁用输入框
this.handleSubmit();
// this.$refs.textarea.disabled = true;
console.log(this.$refs.textarea.disabled, '禁用输入框');
} else {
this.inputHint = '解析的数据格式不完整,请检查二维码是否正确';
this.$message.warning({
message: '数据格式不完整',
duration: 2000
});
}
} catch (error) {
this.inputHint = '无法解析数据,请确保输入的是有效的二维码内容';
this.$message.error({
message: '解析失败,请检查输入内容',
duration: 2000
});
} finally {
this.isLoading = false;
}
}, 500);
// 基础校验不通过:立即反馈,不触发防抖逻辑
if (!this.isValid) {
this.inputHint = "输入内容不符合基础格式要求,请检查";
return;
}
// 触发防抖后的业务逻辑(此时已自动防抖)
this.debouncedHandleInput(trimmedValue);
},
// 5. 实际的“JSON解析+提交”业务逻辑(纯业务,无防抖代码)
actualParseAndSubmit(validValue) {
this.isLoading = true;
try {
// 1. 解析JSON
const parsedData = JSON.parse(validValue);
// if (!this.isValid) {
// this.inputHint = "解析的数据格式不完整,请检查二维码是否正确";
// this.$message.warning({
// message: "数据格式不完整",
// duration: 2000,
// });
// return;
// }
// 3. 解析成功:反馈+提交
this.inputHint = "数据解析成功,可以提交操作";
this.$message.success({
message: "数据解析成功",
duration: 1500,
});
this.handleSubmit(parsedData); // 调用提交接口
} catch (error) {
// 6. 解析失败:错误处理
this.inputHint = "无法解析数据,请确保输入的是有效的二维码内容";
this.$message.error({
message: "解析失败,请检查输入内容",
duration: 2000,
});
} finally {
// 7. 无论成功/失败,结束加载状态
this.isLoading = false;
}
},
handleBlur() {
// 自动重新聚焦,方便连续扫描
this.$nextTick(() => {
@@ -176,9 +193,9 @@ export default {
},
handleSubmit() {
if (!this.isValid) return;
this.isSubmitting = true;
addStockIoDetail(this.result)
.then(res => {
this.$message.success({
@@ -337,6 +354,7 @@ export default {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);

View File

@@ -208,9 +208,9 @@
<el-form-item label="数量" prop="quantity">
<el-input v-model="form.quantity" placeholder="请输入数量" />
</el-form-item>
<el-form-item label="单位" prop="unit">
<!-- <el-form-item label="单位" prop="unit">
<el-input v-model="form.unit" placeholder="请输入单位" :disabled="unitDisabled" />
</el-form-item>
</el-form-item> -->
<!-- <el-form-item label="批次号" prop="batchNo">
<el-input v-model="form.batchNo" placeholder="请输入批次号" />
</el-form-item> -->
@@ -290,9 +290,9 @@ export default {
quantity: [
{ required: true, message: "数量不能为空", trigger: "blur" }
],
unit: [
{ required: true, message: "单位不能为空", trigger: "blur" }
]
// unit: [
// { required: true, message: "单位不能为空", trigger: "blur" }
// ]
},
ids: [],
single: true,
@@ -467,7 +467,7 @@ export default {
itemType: undefined,
itemId: undefined,
quantity: undefined,
unit: undefined,
// unit: undefined,
batchNo: 'auto',
remark: undefined
};
@@ -594,12 +594,12 @@ export default {
if (type === 'relocation') return 'info';
return 'default';
},
onItemChange(e) {
if (e && e.unit) {
this.form.unit = e.unit;
this.unitDisabled = true;
}
}
// onItemChange(e) {
// if (e && e.unit) {
// this.form.unit = e.unit;
// this.unitDisabled = true;
// }
// }
}
}
</script>