|
|
|
|
@ -6,7 +6,7 @@
|
|
|
|
|
<template v-if="!scanning">
|
|
|
|
|
<el-button type="primary" size="large" @click="startScanner">
|
|
|
|
|
<el-icon><Camera /></el-icon>
|
|
|
|
|
启动扫码枪
|
|
|
|
|
开启扫码枪
|
|
|
|
|
</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
<template v-else>
|
|
|
|
|
@ -27,13 +27,44 @@
|
|
|
|
|
<el-card class="code-card" shadow="hover">
|
|
|
|
|
<div class="code-section">
|
|
|
|
|
<div class="code-item">
|
|
|
|
|
<label class="code-label">SN码</label>
|
|
|
|
|
<label class="code-label">A码(SN码)</label>
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="form.snCode"
|
|
|
|
|
placeholder="请输入SN码"
|
|
|
|
|
placeholder="扫码自动获取"
|
|
|
|
|
size="large"
|
|
|
|
|
clearable
|
|
|
|
|
class="code-input"
|
|
|
|
|
readonly
|
|
|
|
|
>
|
|
|
|
|
<template #prefix>
|
|
|
|
|
<el-icon><Barcode /></el-icon>
|
|
|
|
|
</template>
|
|
|
|
|
</el-input>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="code-item">
|
|
|
|
|
<label class="code-label">B码</label>
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="bCode"
|
|
|
|
|
placeholder="扫码自动获取"
|
|
|
|
|
size="large"
|
|
|
|
|
clearable
|
|
|
|
|
class="code-input"
|
|
|
|
|
readonly
|
|
|
|
|
>
|
|
|
|
|
<template #prefix>
|
|
|
|
|
<el-icon><Barcode /></el-icon>
|
|
|
|
|
</template>
|
|
|
|
|
</el-input>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="code-item">
|
|
|
|
|
<label class="code-label">C码</label>
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="cCode"
|
|
|
|
|
placeholder="扫码自动获取"
|
|
|
|
|
size="large"
|
|
|
|
|
clearable
|
|
|
|
|
class="code-input"
|
|
|
|
|
readonly
|
|
|
|
|
>
|
|
|
|
|
<template #prefix>
|
|
|
|
|
<el-icon><Barcode /></el-icon>
|
|
|
|
|
@ -116,12 +147,12 @@
|
|
|
|
|
<el-row :gutter="24">
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="SerialNumber" prop="serialNumber">
|
|
|
|
|
<el-input disabled v-model="form.serialNumber" placeholder="Please enter" />
|
|
|
|
|
<el-input disabled v-model="form.serialNumber" placeholder="自动填入A码" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="AssemblyNumber" prop="assemblyNumber">
|
|
|
|
|
<el-input disabled v-model="form.assemblyNumber" placeholder="Please enter" />
|
|
|
|
|
<el-input disabled v-model="form.assemblyNumber" placeholder="自动获取Model码" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
@ -202,7 +233,7 @@ import { useRouter } from 'vue-router'
|
|
|
|
|
import { ElMessage } from 'element-plus'
|
|
|
|
|
import WebSocketClient from '@/utils/websocket'
|
|
|
|
|
import fileHttp from '@/utils/fileHttp'
|
|
|
|
|
import { getSnApi, okToTestApi } from '@/api'
|
|
|
|
|
import { getSnApi, okToTestApi, saveReportApi } from '@/api'
|
|
|
|
|
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
|
|
|
|
|
@ -216,6 +247,14 @@ const countdown = ref(3)
|
|
|
|
|
const progressPercent = ref(0)
|
|
|
|
|
let countdownTimer = null
|
|
|
|
|
|
|
|
|
|
// A码、B码、C码
|
|
|
|
|
const bCode = ref('')
|
|
|
|
|
const cCode = ref('')
|
|
|
|
|
|
|
|
|
|
// 扫码开始/结束时间
|
|
|
|
|
const scanStartTime = ref('')
|
|
|
|
|
const scanEndTime = ref('')
|
|
|
|
|
|
|
|
|
|
const form = reactive({
|
|
|
|
|
snCode: '',
|
|
|
|
|
customer: '',
|
|
|
|
|
@ -240,9 +279,26 @@ const rules = {
|
|
|
|
|
processStep: [{ required: true, message: '请输入ProcessStep', trigger: 'blur' }]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============ 扫码逻辑 ============
|
|
|
|
|
|
|
|
|
|
function classifyCode(code) {
|
|
|
|
|
if (!code) return null
|
|
|
|
|
// 以 POS 开头 → B码
|
|
|
|
|
if (code.startsWith('POS')) return 'B'
|
|
|
|
|
// 以 4 开头 → C码
|
|
|
|
|
if (/^4/.test(code)) return 'C'
|
|
|
|
|
// 以 620 开头 → 排除
|
|
|
|
|
if (code.startsWith('620')) return 'IGNORE'
|
|
|
|
|
// 其余为 A码
|
|
|
|
|
return 'A'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 扫码枪 WebSocket 连接
|
|
|
|
|
function startScanner() {
|
|
|
|
|
scanning.value = true
|
|
|
|
|
// 记录扫码开始时间
|
|
|
|
|
scanStartTime.value = formatNow()
|
|
|
|
|
|
|
|
|
|
wsClient.value = new WebSocketClient({
|
|
|
|
|
url: `ws://${fileHttp.mesPtApi}/api/ws/camera`,
|
|
|
|
|
autoReconnect: false,
|
|
|
|
|
@ -254,11 +310,28 @@ function startScanner() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
wsClient.value.on('message', (data) => {
|
|
|
|
|
// 服务端返回的 data 只有一个 sn 码
|
|
|
|
|
const sn = typeof data === 'string' ? data : data.sn
|
|
|
|
|
if (sn) {
|
|
|
|
|
form.snCode = sn
|
|
|
|
|
form.serialNumber = sn
|
|
|
|
|
// 服务端返回的 data 可能为字符串或对象
|
|
|
|
|
const code = typeof data === 'string' ? data : data.sn
|
|
|
|
|
if (!code) return
|
|
|
|
|
|
|
|
|
|
const type = classifyCode(code)
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'A':
|
|
|
|
|
form.snCode = code
|
|
|
|
|
form.serialNumber = code
|
|
|
|
|
ElMessage.success(`识别到A码(SN码): ${code}`)
|
|
|
|
|
break
|
|
|
|
|
case 'B':
|
|
|
|
|
bCode.value = code
|
|
|
|
|
ElMessage.success(`识别到B码: ${code}`)
|
|
|
|
|
break
|
|
|
|
|
case 'C':
|
|
|
|
|
cCode.value = code
|
|
|
|
|
ElMessage.success(`识别到C码: ${code}`)
|
|
|
|
|
break
|
|
|
|
|
case 'IGNORE':
|
|
|
|
|
// 620 开头的码忽略
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
@ -287,6 +360,24 @@ function stopScanner() {
|
|
|
|
|
ElMessage.info('已关闭扫码功能')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function formatNow() {
|
|
|
|
|
const d = new Date()
|
|
|
|
|
const pad = (n) => String(n).padStart(2, '0')
|
|
|
|
|
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============ 根据B码/C码推导型号 ============
|
|
|
|
|
|
|
|
|
|
function getModelByBCode() {
|
|
|
|
|
// 如果B码为 "POS-REG-019" 则为 STI-01173,反之为 STI-01176
|
|
|
|
|
return bCode.value === 'POS-REG-019' ? 'STI-01173' : 'STI-01176'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getModelByCCode() {
|
|
|
|
|
// 如果C码为 "4260325425247" 则为 STI-01174,反之为 SIT-01175
|
|
|
|
|
return cCode.value === '4260325425247' ? 'STI-01174' : 'SIT-01175'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 组件销毁时自动断开连接
|
|
|
|
|
onBeforeUnmount(() => {
|
|
|
|
|
stopScanner()
|
|
|
|
|
@ -298,7 +389,7 @@ onBeforeUnmount(() => {
|
|
|
|
|
|
|
|
|
|
// 获取Model码
|
|
|
|
|
async function fetchModelCode() {
|
|
|
|
|
if (!form.serialNumber) {
|
|
|
|
|
if (!form.snCode) {
|
|
|
|
|
ElMessage.warning('请先输入SN码')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -308,7 +399,7 @@ async function fetchModelCode() {
|
|
|
|
|
}
|
|
|
|
|
loading.value = true
|
|
|
|
|
try {
|
|
|
|
|
const data = await getSnApi({ customer: form.customer, serialNumber: form.serialNumber })
|
|
|
|
|
const data = await getSnApi({ customer: form.customer, serialNumber: form.snCode })
|
|
|
|
|
if (data) {
|
|
|
|
|
form.modelCode = data
|
|
|
|
|
form.assemblyNumber = data
|
|
|
|
|
@ -317,7 +408,7 @@ async function fetchModelCode() {
|
|
|
|
|
ElMessage.error('未获取到Model码数据')
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
ElMessage.error('获取Model码失败')
|
|
|
|
|
// ElMessage.error('获取Model码失败')
|
|
|
|
|
} finally {
|
|
|
|
|
loading.value = false
|
|
|
|
|
}
|
|
|
|
|
@ -331,8 +422,13 @@ async function handleInvoke() {
|
|
|
|
|
} catch {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 记录扫码结束时间
|
|
|
|
|
scanEndTime.value = formatNow()
|
|
|
|
|
|
|
|
|
|
invokeLoading.value = true
|
|
|
|
|
try {
|
|
|
|
|
// 调用 okToTestApi
|
|
|
|
|
await okToTestApi({
|
|
|
|
|
customerName: form.customerName,
|
|
|
|
|
division: form.division,
|
|
|
|
|
@ -341,11 +437,36 @@ async function handleInvoke() {
|
|
|
|
|
testerName: form.testerName,
|
|
|
|
|
processStep: form.processStep
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 组装规则内容
|
|
|
|
|
const modelByB = getModelByBCode()
|
|
|
|
|
const modelByC = getModelByCCode()
|
|
|
|
|
|
|
|
|
|
const ruleContent = `
|
|
|
|
|
${form.snCode}
|
|
|
|
|
${form.customerName}
|
|
|
|
|
${form.testerName}
|
|
|
|
|
BayE168
|
|
|
|
|
P
|
|
|
|
|
${scanStartTime.value}
|
|
|
|
|
${scanEndTime.value}
|
|
|
|
|
${bCode.value}
|
|
|
|
|
${modelByB}
|
|
|
|
|
${cCode.value}
|
|
|
|
|
${modelByC}`
|
|
|
|
|
|
|
|
|
|
// 调用 saveReportApi 将规则内容存储到后端
|
|
|
|
|
await saveReportApi({
|
|
|
|
|
message: [ruleContent],
|
|
|
|
|
sn: form.snCode,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
result.value = {
|
|
|
|
|
status: 'Success',
|
|
|
|
|
code: '200',
|
|
|
|
|
message: '检测流程已成功启动'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 显示成功动画,3 秒倒计时后跳转
|
|
|
|
|
invokeSuccess.value = true
|
|
|
|
|
countdown.value = 3
|
|
|
|
|
@ -360,7 +481,7 @@ async function handleInvoke() {
|
|
|
|
|
}
|
|
|
|
|
}, 1000)
|
|
|
|
|
} catch (error) {
|
|
|
|
|
ElMessage.error('Invoke调用失败')
|
|
|
|
|
// ElMessage.error('Invoke调用失败')
|
|
|
|
|
} finally {
|
|
|
|
|
invokeLoading.value = false
|
|
|
|
|
}
|
|
|
|
|
@ -377,6 +498,10 @@ function handleReset() {
|
|
|
|
|
form.assemblyNumber = ''
|
|
|
|
|
form.testerName = ''
|
|
|
|
|
form.processStep = ''
|
|
|
|
|
bCode.value = ''
|
|
|
|
|
cCode.value = ''
|
|
|
|
|
scanStartTime.value = ''
|
|
|
|
|
scanEndTime.value = ''
|
|
|
|
|
result.value = null
|
|
|
|
|
ElMessage.info('表单已重置')
|
|
|
|
|
}
|
|
|
|
|
@ -434,7 +559,7 @@ function handleReset() {
|
|
|
|
|
|
|
|
|
|
.code-item {
|
|
|
|
|
flex: 1;
|
|
|
|
|
min-width: 300px;
|
|
|
|
|
min-width: 280px;
|
|
|
|
|
|
|
|
|
|
.code-label {
|
|
|
|
|
display: block;
|
|
|
|
|
|