✨ feat: 乱起八糟的东西
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
<el-button v-if="canAdd" @click="add" icon="el-icon-plus">未搜索到原材料,点击添加</el-button>
|
<el-button v-if="canAdd" @click="add" icon="el-icon-plus">未搜索到原材料,点击添加</el-button>
|
||||||
<div v-else style="padding: 10px;">未搜索到原材料</div>
|
<div v-else style="padding: 10px;">未搜索到原材料</div>
|
||||||
</template>
|
</template>
|
||||||
<el-option v-for="item in options" :key="item.rawMaterialId"
|
<el-option v-for="item in rawMaterialList" :key="item.rawMaterialId"
|
||||||
:label="`${item.rawMaterialName}(${item.rawMaterialCode})`" :value="item.rawMaterialId">
|
:label="`${item.rawMaterialName}(${item.rawMaterialCode})`" :value="item.rawMaterialId">
|
||||||
<div class="option-label">
|
<div class="option-label">
|
||||||
<span class="material-name">{{ item.rawMaterialName }}</span>
|
<span class="material-name">{{ item.rawMaterialName }}</span>
|
||||||
@@ -117,7 +117,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.options = this.rawMaterialList;
|
if (this.rawMaterialList.length < 0) {
|
||||||
|
this.$store.dispatch('category/getRawMaterialMap')
|
||||||
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['rawMaterialList'])
|
...mapGetters(['rawMaterialList'])
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<!-- 仅保留预览区 -->
|
<!-- 仅保留预览区 -->
|
||||||
<div class="barcode-preview-area">
|
<div class="barcode-preview-area">
|
||||||
<div class="iframe-wrapper">
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,13 +9,13 @@
|
|||||||
清空所有
|
清空所有
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<!-- <el-tooltip content="仅对完整配置的二维码进行打印预览" placement="top"
|
<el-tooltip content="仅对完整配置的二维码进行打印预览" placement="top"
|
||||||
:disabled="drawerBarcodeData.length === 0 || !isAllValid">
|
:disabled="drawerBarcodeData.length === 0 || !isAllValid">
|
||||||
<el-button type="success" icon="el-icon-printer" @click="handlePrintPreview"
|
<el-button type="success" icon="el-icon-printer" @click="handlePrintPreview"
|
||||||
:disabled="drawerBarcodeData.length === 0 || !isAllValid" class="btn-print">
|
:disabled="drawerBarcodeData.length === 0 || !isAllValid" class="btn-print">
|
||||||
打印预览
|
打印预览
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip> -->
|
</el-tooltip>
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">
|
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">
|
||||||
添加二维码
|
添加二维码
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -142,11 +142,19 @@
|
|||||||
<el-input-number v-model="cfg.count" :min="1" :max="100" size="mini" placeholder="请输入数量" />
|
<el-input-number v-model="cfg.count" :min="1" :max="100" size="mini" placeholder="请输入数量" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="8">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="下方文字" class="form-item">
|
<el-form-item label="下方文字" class="form-item">
|
||||||
<el-input v-model="cfg.text" size="mini" placeholder="例如:产品入库二维码" />
|
<el-input v-model="cfg.text" size="mini" placeholder="例如:产品入库二维码" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</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>
|
</el-row>
|
||||||
|
|
||||||
<!-- 配置状态提示 - 优化背景色和图标 -->
|
<!-- 配置状态提示 - 优化背景色和图标 -->
|
||||||
@@ -251,10 +259,9 @@ export default {
|
|||||||
itemId: b.itemId,
|
itemId: b.itemId,
|
||||||
batchNo: b.batchNo || 'auto',
|
batchNo: b.batchNo || 'auto',
|
||||||
quantity: b.count || 1,
|
quantity: b.count || 1,
|
||||||
unit: b.unit || '',
|
|
||||||
recordType: 1,
|
recordType: 1,
|
||||||
}),
|
}),
|
||||||
count: 1,
|
count: b.totalCount,
|
||||||
textTpl: b.text || '二维码'
|
textTpl: b.text || '二维码'
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -263,7 +270,7 @@ export default {
|
|||||||
// 物料选择变更
|
// 物料选择变更
|
||||||
onItemChange(item, idx) {
|
onItemChange(item, idx) {
|
||||||
if (item && this.drawerBarcodeData[idx]) {
|
if (item && this.drawerBarcodeData[idx]) {
|
||||||
this.drawerBarcodeData[idx].unit = item.unit;
|
// this.drawerBarcodeData[idx].unit = item.unit;
|
||||||
// 如果未设置数量,默认设置为1
|
// 如果未设置数量,默认设置为1
|
||||||
if (!this.drawerBarcodeData[idx].count) {
|
if (!this.drawerBarcodeData[idx].count) {
|
||||||
this.drawerBarcodeData[idx].count = 1;
|
this.drawerBarcodeData[idx].count = 1;
|
||||||
@@ -316,6 +323,7 @@ export default {
|
|||||||
itemId: undefined,
|
itemId: undefined,
|
||||||
batchNo: 'auto',
|
batchNo: 'auto',
|
||||||
count: 1, // 默认数量1
|
count: 1, // 默认数量1
|
||||||
|
totalCount: 1, // 默认数量1
|
||||||
unit: '',
|
unit: '',
|
||||||
text: '二维码', // 默认文字
|
text: '二维码', // 默认文字
|
||||||
hovered: false // 新增hover状态,用于交互反馈
|
hovered: false // 新增hover状态,用于交互反馈
|
||||||
@@ -368,18 +376,7 @@ export default {
|
|||||||
},
|
},
|
||||||
// 打印预览 - 增加加载状态提示
|
// 打印预览 - 增加加载状态提示
|
||||||
handlePrintPreview() {
|
handlePrintPreview() {
|
||||||
const printLoading = this.$loading({
|
document.querySelector('#previewIframe').contentWindow.print();
|
||||||
lock: true,
|
|
||||||
text: '正在准备打印预览...',
|
|
||||||
spinner: 'el-icon-loading',
|
|
||||||
background: 'rgba(255, 255, 255, 0.8)'
|
|
||||||
});
|
|
||||||
|
|
||||||
// 模拟预览准备时间(实际项目可替换为真实接口请求)
|
|
||||||
setTimeout(() => {
|
|
||||||
window.print();
|
|
||||||
printLoading.close();
|
|
||||||
}, 1000);
|
|
||||||
},
|
},
|
||||||
// 验证单个配置是否有效
|
// 验证单个配置是否有效
|
||||||
isConfigValid(cfg) {
|
isConfigValid(cfg) {
|
||||||
|
|||||||
@@ -1,49 +1,35 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="qr-parser-container">
|
<div class="qr-parser-container">
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<el-alert title="请将当前输入法切换到英文输入后再进行扫码操作" type="warning"></el-alert>
|
<el-alert title="请将当前输入法切换到英文输入后再进行扫码操作" type="warning"></el-alert>
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h2 class="title">二维码解析器</h2>
|
<h2 class="title">二维码解析器</h2>
|
||||||
<p class="subtitle">扫描或输入二维码内容进行解析</p>
|
<p class="subtitle">扫描或输入二维码内容进行解析</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-section">
|
<div class="input-section">
|
||||||
<el-input
|
<el-input v-model="text" @input="handleInput" @blur="handleBlur" ref="textarea"
|
||||||
v-model="text"
|
placeholder="请扫描二维码或粘贴二维码文本内容..." :rows="3" type="textarea"
|
||||||
@change="handleChange"
|
:class="{ 'invalid-input': !isValid && text.length > 0 }" />
|
||||||
@blur="handleBlur"
|
|
||||||
ref="textarea"
|
|
||||||
placeholder="请扫描二维码或粘贴二维码文本内容..."
|
|
||||||
:rows="3"
|
|
||||||
type="textarea"
|
|
||||||
:class="{ 'invalid-input': !isValid && text.length > 0 }"
|
|
||||||
/>
|
|
||||||
<div class="input-hint">
|
<div class="input-hint">
|
||||||
<i class="el-icon-info-circle"></i>
|
<i class="el-icon-info-circle"></i>
|
||||||
<span>{{ inputHint }}</span>
|
<span>{{ inputHint }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 加载状态 -->
|
<!-- 加载状态 -->
|
||||||
<el-loading
|
<el-loading v-if="isLoading" text="正在解析数据..." class="loading-overlay"></el-loading>
|
||||||
v-if="isLoading"
|
|
||||||
text="正在解析数据..."
|
|
||||||
class="loading-overlay"
|
|
||||||
></el-loading>
|
|
||||||
|
|
||||||
<!-- 二维码解析结果 - 只有数据有效时才显示 -->
|
<!-- 二维码解析结果 - 只有数据有效时才显示 -->
|
||||||
<div v-if="isValid" class="result-section fade-in">
|
<div v-if="isValid" class="result-section fade-in">
|
||||||
<div class="result-header">
|
<div class="result-header">
|
||||||
<h3>解析结果</h3>
|
<h3>解析结果</h3>
|
||||||
<el-tag
|
<el-tag :type="result.ioType === 'in' ? 'success' : 'warning'" size="small">
|
||||||
:type="result.ioType === 'in' ? 'success' : 'warning'"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
{{ result.ioType === 'in' ? '入库' : '出库' }}
|
{{ result.ioType === 'in' ? '入库' : '出库' }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-descriptions :column="1" border class="result-table">
|
<el-descriptions :column="1" border class="result-table">
|
||||||
<el-descriptions-item label="出入库类型" :span="1">
|
<el-descriptions-item label="出入库类型" :span="1">
|
||||||
{{ result.ioType === 'in' ? '入库' : '出库' }}
|
{{ result.ioType === 'in' ? '入库' : '出库' }}
|
||||||
@@ -52,32 +38,22 @@
|
|||||||
{{ formatItemType(result.itemType) }}
|
{{ formatItemType(result.itemType) }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="物料信息" :span="1">
|
<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" />
|
<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>
|
||||||
<el-descriptions-item label="数量" :span="1">
|
<el-descriptions-item label="数量" :span="1">
|
||||||
{{ result.quantity }}
|
{{ result.quantity }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="计量单位" :span="1">
|
|
||||||
{{ result.unit }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
|
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<el-button
|
<el-button type="primary" @click="handleSubmit" :loading="isSubmitting" icon="el-icon-check">
|
||||||
type="primary"
|
|
||||||
@click="handleSubmit"
|
|
||||||
:loading="isSubmitting"
|
|
||||||
icon="el-icon-check"
|
|
||||||
>
|
|
||||||
确认执行
|
确认执行
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button type="default" @click="handleReset" icon="el-icon-refresh-right">
|
||||||
type="default"
|
|
||||||
@click="handleReset"
|
|
||||||
icon="el-icon-refresh-right"
|
|
||||||
>
|
|
||||||
重置
|
重置
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -91,6 +67,24 @@ import ProductInfo from '@/components/KLPService/Renderer/ProductInfo';
|
|||||||
import RawMaterialInfo from '@/components/KLPService/Renderer/RawMaterialInfo';
|
import RawMaterialInfo from '@/components/KLPService/Renderer/RawMaterialInfo';
|
||||||
import { addStockIoDetail } from '@/api/wms/stockIoDetail';
|
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 {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -104,17 +98,25 @@ export default {
|
|||||||
ProductInfo,
|
ProductInfo,
|
||||||
RawMaterialInfo,
|
RawMaterialInfo,
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
// 包装“输入解析+提交”的业务函数,生成带防抖的版本
|
||||||
|
this.debouncedHandleInput = debounce(
|
||||||
|
this.actualParseAndSubmit, // 实际的业务逻辑函数
|
||||||
|
500 // 防抖延迟时间
|
||||||
|
);
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
result() {
|
result() {
|
||||||
try {
|
try {
|
||||||
return JSON.parse(this.text);
|
const text = JSON.parse(this.text)
|
||||||
|
return text;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 验证数据是否有效
|
// 验证数据是否有效
|
||||||
isValid() {
|
isValid() {
|
||||||
const requiredFields = ['ioType', 'itemType', 'itemId', 'quantity', 'unit'];
|
const requiredFields = ['ioType', 'itemType', 'itemId', 'quantity'];
|
||||||
// 检查是否包含所有必要字段
|
// 检查是否包含所有必要字段
|
||||||
const hasAllFields = requiredFields.every(field => this.result.hasOwnProperty(field));
|
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 isItemTypeValid = ['product', 'semi', 'raw_material'].includes(this.result.itemType);
|
||||||
// 检查数量是否为有效数字
|
// 检查数量是否为有效数字
|
||||||
const isQuantityValid = !isNaN(Number(this.result.quantity)) && Number(this.result.quantity) > 0;
|
const isQuantityValid = !isNaN(Number(this.result.quantity)) && Number(this.result.quantity) > 0;
|
||||||
|
|
||||||
return hasAllFields && isIoTypeValid && isItemTypeValid && isQuantityValid;
|
return hasAllFields && isIoTypeValid && isItemTypeValid && isQuantityValid;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleChange(value) {
|
handleInput(value) {
|
||||||
if (!value) {
|
const trimmedValue = value.trim();
|
||||||
this.inputHint = '请输入二维码内容,系统将自动解析';
|
|
||||||
|
// 空值场景:立即反馈,不触发防抖逻辑
|
||||||
|
if (!trimmedValue) {
|
||||||
|
this.inputHint = "请输入二维码内容,系统将自动解析";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isLoading = true;
|
// 基础校验不通过:立即反馈,不触发防抖逻辑
|
||||||
|
if (!this.isValid) {
|
||||||
// 模拟解析延迟,提升用户体验
|
this.inputHint = "输入内容不符合基础格式要求,请检查";
|
||||||
setTimeout(() => {
|
return;
|
||||||
try {
|
}
|
||||||
const parsed = JSON.parse(value);
|
|
||||||
if (this.isValid) {
|
// 触发防抖后的业务逻辑(此时已自动防抖)
|
||||||
this.inputHint = '数据解析成功,可以提交操作';
|
this.debouncedHandleInput(trimmedValue);
|
||||||
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);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 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() {
|
handleBlur() {
|
||||||
// 自动重新聚焦,方便连续扫描
|
// 自动重新聚焦,方便连续扫描
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
@@ -176,9 +193,9 @@ export default {
|
|||||||
},
|
},
|
||||||
handleSubmit() {
|
handleSubmit() {
|
||||||
if (!this.isValid) return;
|
if (!this.isValid) return;
|
||||||
|
|
||||||
this.isSubmitting = true;
|
this.isSubmitting = true;
|
||||||
|
|
||||||
addStockIoDetail(this.result)
|
addStockIoDetail(this.result)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
this.$message.success({
|
this.$message.success({
|
||||||
@@ -337,6 +354,7 @@ export default {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(10px);
|
transform: translateY(10px);
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
|
|||||||
@@ -208,9 +208,9 @@
|
|||||||
<el-form-item label="数量" prop="quantity">
|
<el-form-item label="数量" prop="quantity">
|
||||||
<el-input v-model="form.quantity" placeholder="请输入数量" />
|
<el-input v-model="form.quantity" placeholder="请输入数量" />
|
||||||
</el-form-item>
|
</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-input v-model="form.unit" placeholder="请输入单位" :disabled="unitDisabled" />
|
||||||
</el-form-item>
|
</el-form-item> -->
|
||||||
<!-- <el-form-item label="批次号" prop="batchNo">
|
<!-- <el-form-item label="批次号" prop="batchNo">
|
||||||
<el-input v-model="form.batchNo" placeholder="请输入批次号" />
|
<el-input v-model="form.batchNo" placeholder="请输入批次号" />
|
||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
@@ -290,9 +290,9 @@ export default {
|
|||||||
quantity: [
|
quantity: [
|
||||||
{ required: true, message: "数量不能为空", trigger: "blur" }
|
{ required: true, message: "数量不能为空", trigger: "blur" }
|
||||||
],
|
],
|
||||||
unit: [
|
// unit: [
|
||||||
{ required: true, message: "单位不能为空", trigger: "blur" }
|
// { required: true, message: "单位不能为空", trigger: "blur" }
|
||||||
]
|
// ]
|
||||||
},
|
},
|
||||||
ids: [],
|
ids: [],
|
||||||
single: true,
|
single: true,
|
||||||
@@ -467,7 +467,7 @@ export default {
|
|||||||
itemType: undefined,
|
itemType: undefined,
|
||||||
itemId: undefined,
|
itemId: undefined,
|
||||||
quantity: undefined,
|
quantity: undefined,
|
||||||
unit: undefined,
|
// unit: undefined,
|
||||||
batchNo: 'auto',
|
batchNo: 'auto',
|
||||||
remark: undefined
|
remark: undefined
|
||||||
};
|
};
|
||||||
@@ -594,12 +594,12 @@ export default {
|
|||||||
if (type === 'relocation') return 'info';
|
if (type === 'relocation') return 'info';
|
||||||
return 'default';
|
return 'default';
|
||||||
},
|
},
|
||||||
onItemChange(e) {
|
// onItemChange(e) {
|
||||||
if (e && e.unit) {
|
// if (e && e.unit) {
|
||||||
this.form.unit = e.unit;
|
// this.form.unit = e.unit;
|
||||||
this.unitDisabled = true;
|
// this.unitDisabled = true;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -56,12 +56,23 @@
|
|||||||
</build>
|
</build>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<!-- Maven依赖 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.java.dev.jna</groupId>
|
||||||
|
<artifactId>jna</artifactId>
|
||||||
|
<version>5.17.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.java.dev.jna</groupId>
|
||||||
|
<artifactId>jna-platform</artifactId>
|
||||||
|
<version>5.17.0</version>
|
||||||
|
</dependency>
|
||||||
<!-- MQTT dependency removed -->
|
<!-- MQTT dependency removed -->
|
||||||
<dependency>
|
<!-- <dependency>-->
|
||||||
<groupId>com.klp</groupId>
|
<!-- <groupId>com.klp</groupId>-->
|
||||||
<artifactId>mv-code-reader-ctrl-wrapper</artifactId>
|
<!-- <artifactId>mv-code-reader-ctrl-wrapper</artifactId>-->
|
||||||
<version>1.0.0</version>
|
<!-- <version>1.0.0</version>-->
|
||||||
</dependency>
|
<!-- </dependency>-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.json</groupId>
|
<groupId>org.json</groupId>
|
||||||
<artifactId>json</artifactId>
|
<artifactId>json</artifactId>
|
||||||
@@ -89,4 +100,4 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import org.json.JSONException;
|
|||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
static HttpRequestUtil http = null;
|
|
||||||
private static String userIdentity;
|
private static String userIdentity;
|
||||||
// 存储扫码枪输入的字符
|
// 存储扫码枪输入的字符
|
||||||
private static final BlockingQueue<Character> inputQueue = new ArrayBlockingQueue<>(4096);
|
private static final BlockingQueue<Character> inputQueue = new ArrayBlockingQueue<>(4096);
|
||||||
@@ -24,7 +23,7 @@ public class Main {
|
|||||||
public static void main(String[] args) throws InterruptedException {
|
public static void main(String[] args) throws InterruptedException {
|
||||||
System.out.print(" ***************程序开始****************** \r\n");
|
System.out.print(" ***************程序开始****************** \r\n");
|
||||||
|
|
||||||
lockEnglishInputMethod();
|
SCTool.lockEnglishInputMethod();
|
||||||
|
|
||||||
// 使用BufferedReader获取用户身份,避免关闭System.in
|
// 使用BufferedReader获取用户身份,避免关闭System.in
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
||||||
@@ -45,9 +44,6 @@ public class Main {
|
|||||||
startRawInputListener();
|
startRawInputListener();
|
||||||
startScanDataProcessor();
|
startScanDataProcessor();
|
||||||
|
|
||||||
// 初始化HTTP请求工具
|
|
||||||
http = new HttpRequestUtil();
|
|
||||||
System.out.println("HTTP请求工具创建完成");
|
|
||||||
System.out.println("提示:1. 使用扫码枪扫描JSON数据;2. 输入 'exit' 并回车退出程序\n");
|
System.out.println("提示:1. 使用扫码枪扫描JSON数据;2. 输入 'exit' 并回车退出程序\n");
|
||||||
|
|
||||||
// 主线程阻塞(直到isExit被标记为true)
|
// 主线程阻塞(直到isExit被标记为true)
|
||||||
@@ -121,9 +117,9 @@ public class Main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 校验JSON格式
|
// 校验JSON格式
|
||||||
if (isValidJson(scanInput)) {
|
if (SCTool.isValidJson(scanInput)) {
|
||||||
System.out.println("JSON格式校验通过,开始处理...");
|
System.out.println("JSON格式校验通过,开始处理...");
|
||||||
sendDataToServer(scanInput);
|
SCTool.sendDataToServer(scanInput, userIdentity);
|
||||||
} else {
|
} else {
|
||||||
System.out.println("错误:输入不是有效JSON格式\n");
|
System.out.println("错误:输入不是有效JSON格式\n");
|
||||||
}
|
}
|
||||||
@@ -144,98 +140,4 @@ public class Main {
|
|||||||
processorThread.setDaemon(true);
|
processorThread.setDaemon(true);
|
||||||
processorThread.start();
|
processorThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验字符串是否为有效JSON
|
|
||||||
*/
|
|
||||||
private static boolean isValidJson(String input) {
|
|
||||||
try {
|
|
||||||
new JSONObject(input);
|
|
||||||
return true;
|
|
||||||
} catch (JSONException e) {
|
|
||||||
System.out.println("JSON解析失败原因: " + e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 锁定英文输入法(Windows系统专用)
|
|
||||||
*/
|
|
||||||
private static void lockEnglishInputMethod() {
|
|
||||||
try {
|
|
||||||
String powerShellCmd = "powershell -Command \"$im = Get-WinUserLanguageList | Where-Object LanguageTag -eq 'en-US'; " +
|
|
||||||
"if ($im) { Set-WinUserLanguageList -LanguageList $im -Force; Write-Host 'Success' }\"";
|
|
||||||
|
|
||||||
Process process = Runtime.getRuntime().exec(powerShellCmd);
|
|
||||||
process.waitFor();
|
|
||||||
|
|
||||||
if (process.exitValue() == 0) {
|
|
||||||
System.out.println("英文输入法已锁定(en-US)");
|
|
||||||
} else {
|
|
||||||
System.out.println("PowerShell切换输入法失败,尝试备选方案(Ctrl+空格)");
|
|
||||||
sendKeyStroke(0x11, 0x20);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.out.println("设置英文输入法异常: " + e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送键盘组合键(用于输入法切换备选方案)
|
|
||||||
*/
|
|
||||||
private static void sendKeyStroke(int modifier, int key) {
|
|
||||||
try {
|
|
||||||
Robot robot = new Robot();
|
|
||||||
robot.keyPress(modifier);
|
|
||||||
robot.keyPress(key);
|
|
||||||
robot.keyRelease(key);
|
|
||||||
robot.keyRelease(modifier);
|
|
||||||
System.out.println("已尝试Ctrl+空格切换输入法");
|
|
||||||
} catch (AWTException e) {
|
|
||||||
System.out.println("发送键盘事件失败: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理JSON数据并发送POST请求
|
|
||||||
*/
|
|
||||||
private static void sendDataToServer(String jsonInput) {
|
|
||||||
try {
|
|
||||||
JSONObject json = new JSONObject(jsonInput);
|
|
||||||
json.put("createBy", userIdentity);
|
|
||||||
String finalJson = json.toString(2);
|
|
||||||
|
|
||||||
System.out.println("最终发送的JSON数据: ");
|
|
||||||
System.out.println(finalJson + "\n");
|
|
||||||
|
|
||||||
// 取消注释以下代码以启用HTTP请求
|
|
||||||
String response = HttpRequestUtil.postJson(
|
|
||||||
"http://140.143.206.120:8080/wms/stockIoDetail",
|
|
||||||
finalJson
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response == null || response.isEmpty()) {
|
|
||||||
System.out.println("服务器无响应,请检查接口连接\n");
|
|
||||||
} else {
|
|
||||||
System.out.println("服务器返回结果: ");
|
|
||||||
String formattedResponse = isJson(response) ? new JSONObject(response).toString(2) : response;
|
|
||||||
System.out.println(formattedResponse + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (JSONException e) {
|
|
||||||
System.out.println("JSON处理异常: " + e.getMessage() + "\n");
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.out.println("发送请求异常: " + e.getMessage() + "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断字符串是否为JSON格式
|
|
||||||
*/
|
|
||||||
private static boolean isJson(String str) {
|
|
||||||
if (str == null || str.isEmpty()) return false;
|
|
||||||
str = str.trim();
|
|
||||||
return (str.startsWith("{") && str.endsWith("}")) || (str.startsWith("[") && str.endsWith("]"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
102
scaner/src/main/java/org/example/SCTool.java
Normal file
102
scaner/src/main/java/org/example/SCTool.java
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
package org.example;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
public class SCTool {
|
||||||
|
/**
|
||||||
|
* 判断字符串是否为JSON格式
|
||||||
|
*/
|
||||||
|
public static boolean isJson(String str) {
|
||||||
|
if (str == null || str.isEmpty()) return false;
|
||||||
|
str = str.trim();
|
||||||
|
return (str.startsWith("{") && str.endsWith("}")) || (str.startsWith("[") && str.endsWith("]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验字符串是否为有效JSON
|
||||||
|
*/
|
||||||
|
public static boolean isValidJson(String input) {
|
||||||
|
try {
|
||||||
|
new JSONObject(input);
|
||||||
|
return true;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
System.out.println("JSON解析失败原因: " + e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 锁定英文输入法(Windows系统专用)
|
||||||
|
*/
|
||||||
|
public static void lockEnglishInputMethod() {
|
||||||
|
try {
|
||||||
|
String powerShellCmd = "powershell -Command \"$im = Get-WinUserLanguageList | Where-Object LanguageTag -eq 'en-US'; " +
|
||||||
|
"if ($im) { Set-WinUserLanguageList -LanguageList $im -Force; Write-Host 'Success' }\"";
|
||||||
|
|
||||||
|
Process process = Runtime.getRuntime().exec(powerShellCmd);
|
||||||
|
process.waitFor();
|
||||||
|
|
||||||
|
if (process.exitValue() == 0) {
|
||||||
|
System.out.println("英文输入法已锁定(en-US)");
|
||||||
|
} else {
|
||||||
|
System.out.println("PowerShell切换输入法失败,尝试备选方案(Ctrl+空格)");
|
||||||
|
sendKeyStroke(0x11, 0x20);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("设置英文输入法异常: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送键盘组合键(用于输入法切换备选方案)
|
||||||
|
*/
|
||||||
|
public static void sendKeyStroke(int modifier, int key) {
|
||||||
|
try {
|
||||||
|
Robot robot = new Robot();
|
||||||
|
robot.keyPress(modifier);
|
||||||
|
robot.keyPress(key);
|
||||||
|
robot.keyRelease(key);
|
||||||
|
robot.keyRelease(modifier);
|
||||||
|
System.out.println("已尝试Ctrl+空格切换输入法");
|
||||||
|
} catch (AWTException e) {
|
||||||
|
System.out.println("发送键盘事件失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理JSON数据并发送POST请求
|
||||||
|
*/
|
||||||
|
public static void sendDataToServer(String jsonInput, String userIdentity) {
|
||||||
|
try {
|
||||||
|
JSONObject json = new JSONObject(jsonInput);
|
||||||
|
json.put("createBy", userIdentity);
|
||||||
|
String finalJson = json.toString(2);
|
||||||
|
|
||||||
|
System.out.println("最终发送的JSON数据: ");
|
||||||
|
System.out.println(finalJson + "\n");
|
||||||
|
|
||||||
|
// 取消注释以下代码以启用HTTP请求
|
||||||
|
String response = HttpRequestUtil.postJson(
|
||||||
|
"http://140.143.206.120:8080/wms/stockIoDetail",
|
||||||
|
finalJson
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response == null || response.isEmpty()) {
|
||||||
|
System.out.println("服务器无响应,请检查接口连接\n");
|
||||||
|
} else {
|
||||||
|
System.out.println("服务器返回结果: ");
|
||||||
|
String formattedResponse = SCTool.isJson(response) ? new JSONObject(response).toString(2) : response;
|
||||||
|
System.out.println(formattedResponse + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (JSONException e) {
|
||||||
|
System.out.println("JSON处理异常: " + e.getMessage() + "\n");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("发送请求异常: " + e.getMessage() + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user