<!-- 扫描操作弹窗--标签绑定和智能模型列表页 --> <script setup lang="ts" name="BarCodeBind"> import { ref } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import dayjs from 'dayjs' import type { IEquipmentScan } from './scan-interface' import scanImg from '@/assets/images/scan.png' import { getDictByCode } from '@/api/system/dict' import useWebsocketStore from '@/store/modules/websocket' import { getReadList, getReaderEquipmentList } from '@/api/reader' // 扫描状态,未开始0,正在扫描1,扫描结束2 const props = defineProps({ // 对话框标题 title: { type: String, default: '扫描收入', }, }) const emits = defineEmits(['confirm']) const dialogVisible = ref(false) // 弹窗显示 const scanStatus = ref('1') const isBinding = ref(false) // 是否是标签绑定 const pageType = ref('') // 页面类型、表格list、需要提醒是否绑定,detail详情不提醒 const singleChecked = ref('') // 单选选中id const websocket = useWebsocketStore() const columns = ref([]) as any const columnsList = ref([ { text: '智能模型名称', value: 'equipmentName', align: 'center' }, { text: '规格型号', value: 'model', align: 'center' }, { text: '出厂编号', value: 'manufactureNo', align: 'center' }, { text: '厂商', value: 'manufacturer', align: 'center' }, { text: '实验室', value: 'labCodeName', align: 'center' }, { text: '部门', value: 'groupCodeName', align: 'center' }, { text: '智能模型单价(万元)', value: 'unitPrice', align: 'center' }, { text: '负责人', value: 'directorName', align: 'center', width: '120' }, { text: '使用状态', value: 'usageStatusName', align: 'center', width: '90' }, { text: '溯源单位', value: 'traceCompany', align: 'center' }, { text: '检定有效期', value: 'measureValidDate', align: 'center', width: '120' }, { text: '所属标准装置', value: 'meterStandardName', align: 'center', width: '120' }, { text: '标签信息', value: 'label', align: 'center' }, ]) const columnsLabel = ref([ { text: '标签信息', value: 'label', align: 'center' }, ]) // 扫描到的标签列表 const list = ref([]) as any // 获取数据 const mesureTypeMap = ref({}) as any const managerStateMap = ref({}) as any const getDict = async () => { // 获取检定方式 const responseMeasureType = await getDictByCode('measureType') responseMeasureType.data.forEach((item: { value: string; name: string }) => { mesureTypeMap.value[item.value] = item.name }) // 获取管理状态 const responseManagerState = await getDictByCode('managerState') responseManagerState.data.forEach((item: { value: string; name: string }) => { managerStateMap.value[item.value] = item.name }) } // 关闭弹窗 const closeDialog = () => { list.value = [] singleChecked.value = ''// 清除选中 dialogVisible.value = false } // 点击确定,保存选择的成员配置 const confirm = () => { if (isBinding.value && !singleChecked.value) { // 标签绑定 ElMessage.warning('请选中') return false } if (list.value.length) { if (isBinding.value) { // 标签绑定 emits('confirm', singleChecked.value) singleChecked.value = '' // 清除单选选中 } else { emits('confirm', list.value) } } else { ElMessage.warning('暂无样品数据, 请重新扫描或取消') } } // 扫描/ 重新扫描 const scan = (labelId: string) => { singleChecked.value = ''// 清除选中 // 扫描到的标签及样品信息列表 if (isBinding.value) { // 标签绑定 list.value.push({ label: labelId, }) singleChecked.value = list.value[0].label } else { getReaderEquipmentList([labelId]).then((res) => { if (res && res.data && res.data.length) { const index = list.value.findIndex((item: { id: string }) => item.id === res.data[0].id) if (index === -1) { list.value.push({ ...res.data[0], validDate: res.data[0].validDate ? dayjs(res.data[0].validDate).format('YYYY-MM-DD') : res.data[0].validDate, compulsoryVerification: res.data[0].compulsoryVerification === 1 ? '是' : res.data[0].compulsoryVerification === 0 ? '否' : '', mesureTypeName: mesureTypeMap.value[res.data[0].mesureType], // 检定方式 managerStateName: managerStateMap.value[res.data[0].managerState], // 管理状态 }) } else { console.log(`${list.value[index].equipmentName}${list.value[index].model}${list.value[index].manufactureNo}已经添加过`) } } }) } } /** * 打开弹窗 * @param isBindingValue 是否标签绑定 */ const initDialog = (isBindingValue = false, pageTypeParam = '') => { getDict().then(() => { isBinding.value = isBindingValue columns.value = isBindingValue ? columnsLabel.value : columnsList.value pageType.value = pageTypeParam scanStatus.value = '1' websocket.initWebSocket() dialogVisible.value = true }) } // 断开websocket function stopWebScket() { websocket.destroyWebSocket() } // 重连 const reStartWebScket = () => { websocket.reConnectWebsocket() } // 重新扫描 const reScan = () => { list.value = [] scanStatus.value = '1' stopWebScket() websocket.initWebSocket() } onBeforeMount(() => { stopWebScket() }) // 监听消息列表变化 watch(() => websocket.labelId, (newVal) => { console.log('监听到了标签数据', newVal) if (newVal) { scan(newVal) } }, { immediate: true }) // 监听websocket是否连接 watch(() => websocket.wsStatus, (newVal) => { console.log('监听到websocket是否连接', newVal) if (newVal) { // 连上 scanStatus.value = '2' } else { // 断开 scanStatus.value = '1' } }, { immediate: true, }) // ----定义对外暴露的方法 初始化弹窗, 关闭弹窗 defineExpose({ initDialog, closeDialog }) </script> <template> <el-dialog v-model="dialogVisible" :title="title" width="80%" append-to-body :before-close="closeDialog"> <div style="margin-top: -20px;width: 100%;"> <div v-if="scanStatus === '1'" class="wait-scan"> <div>请使读写器扫描标签</div> <el-image :src="scanImg" class="scan-img" /> </div> <!-- 扫描结果 --> <div v-else-if="scanStatus === '2'"> <div v-if="!isBinding" style="margin-top: 20px;"> 扫描到 <span style="font-weight: 600;">{{ list.length }} </span>个智能模型 </div> <div v-if="isBinding" style="margin-top: 20px;"> 扫描到 <span style="font-weight: 600;">{{ list.length }} </span> 个标签{{ list.length > 1 ? ',请选择需要绑定的标签' : '' }} </div> <el-table ref="multipleTableRef" :data="list" style="width: 100%;margin-top: 10px;" border stripe> <el-table-column type="index" label="序号" width="55" align="center" /> <el-table-column v-if="isBinding" label="" width="60" align="center"> <template #default="scope"> <el-radio v-model="singleChecked" :label="scope.row.label" class="radio" /> </template> </el-table-column> <el-table-column v-for="item in columns" :key="item.value" :prop="item.value" :label="item.text" :width="item.width" align="center" > <template #header> <span>{{ item.text }}</span> </template> </el-table-column> </el-table> </div> </div> <template #footer> <el-button v-if="websocket.wsStatus" type="danger" @click="stopWebScket"> 断开连接 </el-button> <!-- <el-button v-if="scanStatus === '1'" type="primary" @click="reScan"> 重新扫描 </el-button> --> <el-button v-if="isBinding" @click="closeDialog"> 取 消 </el-button> <el-button v-if="isBinding" type="primary" @click="confirm"> 确 定 </el-button> <el-button v-if="!isBinding" @click="closeDialog"> 关 闭 </el-button> </template> </el-dialog> </template> <style lang="scss"> .wait-scan { font-size: 18px; font-weight: bold; text-align: center; line-height: 3; .scan-img { margin-top: 20px; width: 128px; height: 128px; } } .el-radio__label { display: none !important; } </style>