|
|
@@ -5,22 +5,29 @@
|
|
|
<el-input ref="deviceCodeInputRef" v-model="device_code" placeholder="设备编号(支持扫码枪/RFID批量录入,回车添加)" @keyup.enter="handleAddToBatch" :disabled="loading" />
|
|
|
<el-input v-model="check_no" placeholder="盘点编号" @keyup.enter="handleAddToBatch" :disabled="true" />
|
|
|
<el-button type="success" @click="handleAddToBatch" :disabled="loading">添加到待提交列表</el-button>
|
|
|
- <el-button type="primary" @click="handleBatchSubmit" :loading="loading" :disabled="pendingDeviceCodes.length === 0">批量提交({{ pendingDeviceCodes.length }})</el-button>
|
|
|
+ <el-button type="info" :icon="Setting" @click="showReadRuleDialog = true" :disabled="loading">读取规则</el-button>
|
|
|
</div>
|
|
|
|
|
|
<!-- 待提交设备编号列表 -->
|
|
|
<div v-if="pendingDeviceCodes.length > 0" class="pending-list" style="margin-top: 15px; margin-bottom: 15px;">
|
|
|
- <div class="pending-title">待提交设备编号 ({{ pendingDeviceCodes.length }}个):</div>
|
|
|
- <el-tag
|
|
|
- v-for="(code, index) in pendingDeviceCodes"
|
|
|
- :key="index"
|
|
|
- closable
|
|
|
- @close="removePendingCode(index)"
|
|
|
- style="margin-right: 8px; margin-bottom: 8px;"
|
|
|
- >
|
|
|
- {{ code }}
|
|
|
- </el-tag>
|
|
|
- <el-button type="text" size="small" @click="clearPendingCodes" style="margin-left: 10px;">清空</el-button>
|
|
|
+ <div class="pending-header">
|
|
|
+ <div class="pending-title">待提交设备编号 ({{ pendingDeviceCodes.length }}个):</div>
|
|
|
+ <div class="pending-actions">
|
|
|
+ <el-button type="primary" @click="handleBatchSubmit" :loading="loading" size="small">批量提交({{ pendingDeviceCodes.length }})</el-button>
|
|
|
+ <el-button type="text" size="small" @click="clearPendingCodes">清空</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="pending-tags">
|
|
|
+ <el-tag
|
|
|
+ v-for="(code, index) in pendingDeviceCodes"
|
|
|
+ :key="index"
|
|
|
+ closable
|
|
|
+ @close="removePendingCode(index)"
|
|
|
+ style="margin-right: 8px; margin-bottom: 8px;"
|
|
|
+ >
|
|
|
+ {{ code }}
|
|
|
+ </el-tag>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
<el-table :data="deviceList" v-loading="loading" style="margin-top: 20px">
|
|
|
@@ -42,12 +49,56 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
+
|
|
|
+ <!-- 读取规则设置对话框 -->
|
|
|
+ <el-dialog v-model="showReadRuleDialog" title="设置读取规则" width="600px">
|
|
|
+ <el-form :model="readRuleConfig" label-width="140px">
|
|
|
+ <el-form-item label="RFID标签长度">
|
|
|
+ <el-input-number v-model="readRuleConfig.rfidLength" :min="1" :max="100" style="width: 100%" />
|
|
|
+ <div class="form-tip">RFID标签的固定长度(字符数)</div>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="RFID标签前缀">
|
|
|
+ <el-input v-model="readRuleConfig.rfidPrefix" placeholder="例如:E280" style="width: 100%" />
|
|
|
+ <div class="form-tip">RFID标签的前缀(可选,留空则不限制前缀)</div>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="分隔符">
|
|
|
+ <el-select v-model="readRuleConfig.separator" placeholder="选择分隔符" style="width: 100%">
|
|
|
+ <el-option label="空格" value=" " />
|
|
|
+ <el-option label="逗号" value="," />
|
|
|
+ <el-option label="分号" value=";" />
|
|
|
+ <el-option label="制表符" value="\t" />
|
|
|
+ <el-option label="回车换行" value="\n" />
|
|
|
+ <el-option label="自定义" value="custom" />
|
|
|
+ </el-select>
|
|
|
+ <el-input
|
|
|
+ v-if="readRuleConfig.separator === 'custom'"
|
|
|
+ v-model="readRuleConfig.customSeparator"
|
|
|
+ placeholder="请输入自定义分隔符"
|
|
|
+ style="width: 100%; margin-top: 10px;"
|
|
|
+ />
|
|
|
+ <div class="form-tip">用于分割多个设备编号的分隔符</div>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="自动分割粘连">
|
|
|
+ <el-switch v-model="readRuleConfig.autoSplitSticky" />
|
|
|
+ <div class="form-tip">是否自动分割粘连在一起的RFID标签</div>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="允许重复添加">
|
|
|
+ <el-switch v-model="readRuleConfig.allowDuplicate" />
|
|
|
+ <div class="form-tip">是否允许添加重复的设备编号</div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="resetReadRule">重置默认</el-button>
|
|
|
+ <el-button type="primary" @click="saveReadRule">保存</el-button>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts" >
|
|
|
import { ref, nextTick } from 'vue';
|
|
|
import * as api from '../api';
|
|
|
import { ElMessage } from 'element-plus';
|
|
|
+ import { Setting } from '@element-plus/icons-vue';
|
|
|
const emit = defineEmits(['completed']);
|
|
|
|
|
|
const visible = ref(false);
|
|
|
@@ -59,11 +110,42 @@
|
|
|
const deviceCodeInputRef = ref<any>(null);
|
|
|
// 待提交的设备编号数组
|
|
|
const pendingDeviceCodes = ref<string[]>([]);
|
|
|
+ // 标记是否是正常完成/取消盘点关闭(避免重复调用取消接口)
|
|
|
+ const isNormalClose = ref(false);
|
|
|
+ // 读取规则设置对话框显示状态
|
|
|
+ const showReadRuleDialog = ref(false);
|
|
|
+ // 读取规则配置
|
|
|
+ const readRuleConfig = ref({
|
|
|
+ rfidLength: 24, // RFID标签长度
|
|
|
+ rfidPrefix: 'E280', // RFID标签前缀
|
|
|
+ separator: ' ', // 分隔符
|
|
|
+ customSeparator: '', // 自定义分隔符
|
|
|
+ autoSplitSticky: true, // 自动分割粘连
|
|
|
+ allowDuplicate: true, // 允许重复添加
|
|
|
+ });
|
|
|
// const btflag=ref(true);
|
|
|
|
|
|
- const setCheckNo = (val: string) => {
|
|
|
- console.log("val::::::",val)
|
|
|
- check_no.value = val;
|
|
|
+ const setCheckNo = async (checkNo: string, id?: number | null) => {
|
|
|
+ console.log("checkNo::::::", checkNo, "id::::::", id)
|
|
|
+ check_no.value = checkNo;
|
|
|
+
|
|
|
+ // 如果传递了 id,直接使用
|
|
|
+ if (id !== undefined && id !== null) {
|
|
|
+ currentRecordId.value = id;
|
|
|
+ } else {
|
|
|
+ // 如果没有传递 id,通过 check_no 查询记录获取 id
|
|
|
+ try {
|
|
|
+ const reslist = await api.GetPermission();
|
|
|
+ if (reslist?.code === 2000) {
|
|
|
+ const record = findCheckRecord(checkNo, reslist.data);
|
|
|
+ currentRecordId.value = record?.id ?? null;
|
|
|
+ console.log("通过 check_no 查询到的 id::", currentRecordId.value);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('查询盘点记录失败:', error);
|
|
|
+ currentRecordId.value = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
// 聚焦设备编号输入框
|
|
|
@@ -106,12 +188,41 @@
|
|
|
}, 100);
|
|
|
};
|
|
|
|
|
|
+ // 重置读取规则为默认值
|
|
|
+ const resetReadRule = () => {
|
|
|
+ readRuleConfig.value = {
|
|
|
+ rfidLength: 24,
|
|
|
+ rfidPrefix: 'E280',
|
|
|
+ separator: ' ',
|
|
|
+ customSeparator: '',
|
|
|
+ autoSplitSticky: true,
|
|
|
+ allowDuplicate: true,
|
|
|
+ };
|
|
|
+ ElMessage.success('已重置为默认规则');
|
|
|
+ };
|
|
|
+
|
|
|
+ // 保存读取规则
|
|
|
+ const saveReadRule = () => {
|
|
|
+ // 验证配置
|
|
|
+ if (readRuleConfig.value.rfidLength < 1) {
|
|
|
+ ElMessage.warning('RFID标签长度必须大于0');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (readRuleConfig.value.separator === 'custom' && !readRuleConfig.value.customSeparator) {
|
|
|
+ ElMessage.warning('请设置自定义分隔符');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ showReadRuleDialog.value = false;
|
|
|
+ ElMessage.success('读取规则已保存');
|
|
|
+ };
|
|
|
+
|
|
|
const onOpen = () => {
|
|
|
device_code.value = '';
|
|
|
// check_no.value = '';
|
|
|
deviceList.value = [];
|
|
|
currentRecordId.value = null;
|
|
|
pendingDeviceCodes.value = [];
|
|
|
+ isNormalClose.value = false; // 重置标志
|
|
|
};
|
|
|
|
|
|
// 对话框完全打开后聚焦输入框
|
|
|
@@ -160,22 +271,42 @@
|
|
|
const splitRFIDStickyCodes = (input: string): string[] => {
|
|
|
if (!input) return [];
|
|
|
|
|
|
- // 方法1: 使用正则表达式匹配RFID标签(E280开头,24字符)
|
|
|
- // 匹配以E280开头的24字符标签(E280 + 20个十六进制字符)
|
|
|
- const rfidPattern = /E280[0-9A-F]{20}/gi;
|
|
|
- const matches = input.match(rfidPattern);
|
|
|
+ const { rfidLength, rfidPrefix, autoSplitSticky } = readRuleConfig.value;
|
|
|
|
|
|
- // 如果匹配到多个RFID标签,说明是粘连的,返回分割后的数组
|
|
|
- if (matches && matches.length > 1) {
|
|
|
- return matches;
|
|
|
+ // 如果未启用自动分割粘连,直接返回
|
|
|
+ if (!autoSplitSticky) {
|
|
|
+ return [input];
|
|
|
}
|
|
|
|
|
|
- // 方法2: 如果长度是24的倍数且大于24,按固定长度分割
|
|
|
- // 这种情况适用于粘连的RFID标签(无论是否以E280开头)
|
|
|
- if (input.length > 24 && input.length % 24 === 0) {
|
|
|
+ // 方法1: 如果配置了前缀,使用正则表达式匹配RFID标签
|
|
|
+ if (rfidPrefix && rfidPrefix.trim()) {
|
|
|
+ const prefixLength = rfidPrefix.length;
|
|
|
+ const remainingLength = rfidLength - prefixLength;
|
|
|
+ if (remainingLength > 0) {
|
|
|
+ try {
|
|
|
+ // 转义前缀中的特殊字符,避免正则表达式错误
|
|
|
+ const escapedPrefix = rfidPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
|
+ // 构建正则表达式:前缀 + 剩余长度的十六进制字符
|
|
|
+ const rfidPattern = new RegExp(`${escapedPrefix}[0-9A-F]{${remainingLength}}`, 'gi');
|
|
|
+ const matches = input.match(rfidPattern);
|
|
|
+
|
|
|
+ // 如果匹配到多个RFID标签,说明是粘连的,返回分割后的数组
|
|
|
+ if (matches && matches.length > 1) {
|
|
|
+ return matches;
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.warn('RFID前缀正则表达式构建失败:', error);
|
|
|
+ // 如果正则构建失败,继续使用固定长度分割方法
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 方法2: 如果长度是配置长度的倍数且大于配置长度,按固定长度分割
|
|
|
+ // 这种情况适用于粘连的RFID标签(无论是否有前缀)
|
|
|
+ if (input.length > rfidLength && input.length % rfidLength === 0) {
|
|
|
const codes: string[] = [];
|
|
|
- for (let i = 0; i < input.length; i += 24) {
|
|
|
- const code = input.substring(i, i + 24);
|
|
|
+ for (let i = 0; i < input.length; i += rfidLength) {
|
|
|
+ const code = input.substring(i, i + rfidLength);
|
|
|
if (code.trim()) {
|
|
|
codes.push(code);
|
|
|
}
|
|
|
@@ -192,7 +323,7 @@
|
|
|
|
|
|
/**
|
|
|
* 分割RFID粘连的设备编号
|
|
|
- * 支持空格分隔和粘连两种情况
|
|
|
+ * 支持分隔符分隔和粘连两种情况
|
|
|
* RFID标签通常以特定前缀开头(如E280),且有固定长度(24字符)
|
|
|
* @param input 输入的设备编号字符串
|
|
|
* @returns 分割后的设备编号数组
|
|
|
@@ -201,28 +332,90 @@
|
|
|
const trimmed = input.trim();
|
|
|
if (!trimmed) return [];
|
|
|
|
|
|
- // 方法0: 优先处理空格分隔的情况
|
|
|
- // 如果输入中包含空格,先按空格分割,然后对每个部分处理粘连
|
|
|
- if (trimmed.includes(' ')) {
|
|
|
- const parts = trimmed.split(/\s+/).filter(part => part.trim()); // 按空格分割,过滤空字符串
|
|
|
- const result: string[] = [];
|
|
|
+ const { separator, customSeparator } = readRuleConfig.value;
|
|
|
+ const actualSeparator = separator === 'custom' ? customSeparator : separator;
|
|
|
+
|
|
|
+ console.log('splitRFIDCodes - 输入:', trimmed, '分隔符配置:', separator, '实际分隔符:', actualSeparator, '分隔符类型:', typeof actualSeparator, '长度:', actualSeparator?.length);
|
|
|
+
|
|
|
+ // 方法0: 优先处理分隔符分隔的情况
|
|
|
+ // 首先检查输入中是否包含空格(无论配置如何,空格都应该被识别)
|
|
|
+ const hasSpace = /\s/.test(trimmed);
|
|
|
+
|
|
|
+ if (hasSpace) {
|
|
|
+ // 如果输入包含空格,优先按空格分割
|
|
|
+ const parts = trimmed.split(/\s+/).filter(part => part.trim());
|
|
|
+ console.log('检测到空格,分割结果:', parts);
|
|
|
|
|
|
- // 对每个部分处理可能的粘连情况
|
|
|
- for (const part of parts) {
|
|
|
- const splitCodes = splitRFIDStickyCodes(part.trim());
|
|
|
- result.push(...splitCodes);
|
|
|
+ if (parts.length > 1) {
|
|
|
+ const result: string[] = [];
|
|
|
+ // 对每个部分处理可能的粘连情况
|
|
|
+ for (const part of parts) {
|
|
|
+ const trimmedPart = part.trim();
|
|
|
+ if (trimmedPart) {
|
|
|
+ const splitCodes = splitRFIDStickyCodes(trimmedPart);
|
|
|
+ result.push(...splitCodes);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ console.log('空格分割最终结果:', result);
|
|
|
+ return result.length > 0 ? result : [trimmed];
|
|
|
}
|
|
|
-
|
|
|
- // 如果分割出多个,返回结果
|
|
|
- if (result.length > 1) {
|
|
|
- return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果配置了分隔符且不是空格,按配置的分隔符处理
|
|
|
+ if (actualSeparator && actualSeparator.trim() !== '' && actualSeparator !== ' ') {
|
|
|
+ let parts: string[] = [];
|
|
|
+ let hasSeparator = false;
|
|
|
+
|
|
|
+ // 根据分隔符类型进行分割
|
|
|
+ if (actualSeparator === '\n') {
|
|
|
+ // 回车换行分隔符
|
|
|
+ hasSeparator = trimmed.includes('\n');
|
|
|
+ if (hasSeparator) {
|
|
|
+ parts = trimmed.split(/\n+/).filter(part => part.trim());
|
|
|
+ }
|
|
|
+ } else if (actualSeparator === '\t') {
|
|
|
+ // 制表符分隔符
|
|
|
+ hasSeparator = trimmed.includes('\t');
|
|
|
+ if (hasSeparator) {
|
|
|
+ parts = trimmed.split(/\t+/).filter(part => part.trim());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 其他分隔符
|
|
|
+ hasSeparator = trimmed.includes(actualSeparator);
|
|
|
+ if (hasSeparator) {
|
|
|
+ try {
|
|
|
+ // 转义特殊字符,匹配一个或多个连续的分隔符
|
|
|
+ const escapedSeparator = actualSeparator.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
|
+ const separatorPattern = new RegExp(escapedSeparator + '+', 'g');
|
|
|
+ parts = trimmed.split(separatorPattern).filter(part => part.trim());
|
|
|
+ } catch (error) {
|
|
|
+ console.warn('分隔符正则表达式构建失败,使用字符串分割:', error);
|
|
|
+ // 回退到简单的字符串分割
|
|
|
+ parts = trimmed.split(actualSeparator).filter(part => part.trim());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果检测到分隔符并成功分割,处理每个部分
|
|
|
+ if (hasSeparator && parts.length > 0) {
|
|
|
+ const result: string[] = [];
|
|
|
+ // 对每个部分处理可能的粘连情况
|
|
|
+ for (const part of parts) {
|
|
|
+ const trimmedPart = part.trim();
|
|
|
+ if (trimmedPart) {
|
|
|
+ const splitCodes = splitRFIDStickyCodes(trimmedPart);
|
|
|
+ result.push(...splitCodes);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ console.log('配置分隔符分割最终结果:', result);
|
|
|
+ return result.length > 0 ? result : [trimmed];
|
|
|
}
|
|
|
- // 如果只有一个结果,继续后续处理
|
|
|
- return result.length > 0 ? result : [trimmed];
|
|
|
}
|
|
|
|
|
|
- // 如果没有空格,直接处理粘连情况
|
|
|
- return splitRFIDStickyCodes(trimmed);
|
|
|
+ // 如果没有分隔符或分割失败,直接处理粘连情况
|
|
|
+ const stickyResult = splitRFIDStickyCodes(trimmed);
|
|
|
+ console.log('粘连处理结果:', stickyResult);
|
|
|
+ return stickyResult;
|
|
|
};
|
|
|
|
|
|
// 添加到待提交列表(不立即提交)
|
|
|
@@ -240,18 +433,37 @@
|
|
|
|
|
|
// 自动分割RFID粘连的设备编号
|
|
|
const codes = splitRFIDCodes(input);
|
|
|
+ console.log('分割结果:', codes, '输入:', input, '配置:', readRuleConfig.value);
|
|
|
|
|
|
if (codes.length === 0) {
|
|
|
ElMessage.warning('未识别到有效的设备编号');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 批量添加到待提交列表(允许重复)
|
|
|
- pendingDeviceCodes.value.push(...codes);
|
|
|
+ // 根据配置决定是否去重
|
|
|
+ let codesToAdd = codes;
|
|
|
+ if (!readRuleConfig.value.allowDuplicate) {
|
|
|
+ // 过滤掉已存在的设备编号
|
|
|
+ codesToAdd = codes.filter(code => !pendingDeviceCodes.value.includes(code));
|
|
|
+ if (codesToAdd.length < codes.length) {
|
|
|
+ const duplicateCount = codes.length - codesToAdd.length;
|
|
|
+ ElMessage.warning(`已过滤 ${duplicateCount} 个重复的设备编号`);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (codesToAdd.length === 0) {
|
|
|
+ ElMessage.warning('没有可添加的设备编号(可能全部重复)');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 批量添加到待提交列表
|
|
|
+ pendingDeviceCodes.value.push(...codesToAdd);
|
|
|
|
|
|
// 显示提示信息
|
|
|
if (codes.length > 1) {
|
|
|
- ElMessage.success(`已自动分割并添加 ${codes.length} 个设备编号`);
|
|
|
+ ElMessage.success(`已自动分割并添加 ${codesToAdd.length} 个设备编号`);
|
|
|
+ } else {
|
|
|
+ ElMessage.success('已添加到待提交列表');
|
|
|
}
|
|
|
|
|
|
device_code.value = '';
|
|
|
@@ -475,6 +687,8 @@
|
|
|
const res=await api.CompleteScan({ check_no: check_no.value });
|
|
|
if (res?.code===2000) {
|
|
|
ElMessage.success('完成盘点!');
|
|
|
+ // 标记为正常关闭,避免 onClose 中再次调用取消接口
|
|
|
+ isNormalClose.value = true;
|
|
|
visible.value = false;
|
|
|
emit('completed');
|
|
|
}
|
|
|
@@ -485,6 +699,8 @@
|
|
|
const res=await api.CancelScan(currentRecordId.value);
|
|
|
if (res?.code===2000) {
|
|
|
ElMessage.success('取消盘点成功!');
|
|
|
+ // 标记为正常关闭,避免 onClose 中再次调用取消接口
|
|
|
+ isNormalClose.value = true;
|
|
|
visible.value = false;
|
|
|
emit('completed');
|
|
|
}
|
|
|
@@ -525,9 +741,57 @@
|
|
|
|
|
|
defineExpose({ visible,setCheckNo});
|
|
|
|
|
|
- const onClose = () => {
|
|
|
+ const onClose = async () => {
|
|
|
+ // 如果是正常完成/取消盘点关闭,不调用取消接口,直接清理状态
|
|
|
+ if (isNormalClose.value) {
|
|
|
+ isNormalClose.value = false;
|
|
|
+ // 清理状态
|
|
|
+ check_no.value = '';
|
|
|
+ pendingDeviceCodes.value = [];
|
|
|
+ deviceList.value = [];
|
|
|
+ currentRecordId.value = null;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 用户直接关闭对话框时,调用取消盘点接口
|
|
|
+ console.log("currentRecordId.value::",currentRecordId.value, "check_no.value::", check_no.value)
|
|
|
+
|
|
|
+ let recordId = currentRecordId.value;
|
|
|
+
|
|
|
+ // 如果 currentRecordId 为 null,但 check_no 存在,尝试通过 check_no 查询获取 id
|
|
|
+ if (!recordId && check_no.value) {
|
|
|
+ try {
|
|
|
+ const reslist = await api.GetPermission();
|
|
|
+ if (reslist?.code === 2000) {
|
|
|
+ const record = findCheckRecord(check_no.value, reslist.data);
|
|
|
+ recordId = record?.id ?? null;
|
|
|
+ console.log("通过 check_no 查询到的 id::", recordId);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('查询盘点记录失败:', error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果存在盘点记录ID,调用取消盘点接口
|
|
|
+ if (recordId) {
|
|
|
+ try {
|
|
|
+ const res = await api.CancelScan(recordId);
|
|
|
+ if (res?.code === 2000) {
|
|
|
+ ElMessage.success('取消盘点成功!');
|
|
|
+ } else {
|
|
|
+ ElMessage.warning(res?.msg || '取消盘点失败');
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('取消盘点失败:', error);
|
|
|
+ ElMessage.error('取消盘点失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清理状态
|
|
|
check_no.value = '';
|
|
|
pendingDeviceCodes.value = [];
|
|
|
+ deviceList.value = [];
|
|
|
+ currentRecordId.value = null;
|
|
|
};
|
|
|
|
|
|
|
|
|
@@ -548,11 +812,34 @@
|
|
|
border: 1px solid #e4e7ed;
|
|
|
}
|
|
|
|
|
|
+.pending-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 8px;
|
|
|
+}
|
|
|
+
|
|
|
.pending-title {
|
|
|
font-size: 14px;
|
|
|
font-weight: 500;
|
|
|
color: #606266;
|
|
|
- margin-bottom: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.pending-actions {
|
|
|
+ display: flex;
|
|
|
+ gap: 8px;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.pending-tags {
|
|
|
+ margin-top: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.form-tip {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #909399;
|
|
|
+ margin-top: 4px;
|
|
|
+ line-height: 1.4;
|
|
|
}
|
|
|
</style>
|
|
|
|