Newer
Older
xc-metering-front / src / components / scanEquipmentDialog / index.vue
dutingting on 29 Nov 13 KB 临时提交
<!-- 扫描操作弹窗 -->
<script setup lang="ts" name="BarCodeBind">
import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import dayjs from 'dayjs'
import scanImg from '@/assets/images/scan.png'
import { getDictByCode } from '@/api/system/dict'
import { getReadList, getReaderEquipmentList } from '@/api/reader'
import useWebsocketStore from '@/store/modules/websocket'
import { devcieOrderSelect } from '@/api/eqpt/device/info'
// 扫描状态,未开始0,正在扫描1,扫描结束2

const props = defineProps({
  // 对话框标题
  title: {
    type: String,
    default: '扫描收入',
  },
  isMuit: {
    type: Boolean,
    default: false,
  },
})
const emits = defineEmits(['confirm'])
const $route = useRoute()
const dialogVisible = ref(false) // 弹窗显示
const multipleTableRef = ref()
const loading = ref(false)
const scanStatus = ref('0')
const isBinding = ref(false) // 是否是标签绑定
const pageType = ref('') // 页面类型、表格list、需要提醒是否绑定,detail详情不提醒
const singleChecked = ref('') // 单选选中id
const columns = ref([]) as any
const websocket = useWebsocketStore()
const columnsList = ref([

  {
    text: '智能模型名称',
    value: 'equipmentName',
    align: 'center',
    filters: true,
  },
  {
    text: '规格型号',
    value: 'model',
    align: 'center',
    sortable: 'custom',
    filters: true,
  },
  {
    text: '出厂编号',
    value: 'manufactureNo',
    align: 'center',
    sortable: 'custom',
    filters: true,
  },
  {
    text: '厂商',
    value: 'manufacturer',
    align: 'center',
    // sortable: 'custom',
    filters: true,
  },
  {
    text: '所在单位',
    value: 'companyName',
    align: 'center',
    // sortable: 'custom',
    filters: true,
  },
  {
    text: '使用部门',
    value: 'deptName',
    align: 'center',
    // sortable: 'custom',
    filters: true,
  },
  {
    text: '使用岗位',
    value: 'usePosition',
    align: 'center',
    filters: true,
  },
  {
    text: '计量标识',
    value: 'meterIdentifyName',
    align: 'center',
    filters: true,
  },
  // {
  //   text: '检定周期',
  //   value: 'checkCycle',
  //   align: 'center',
  // },
  {
    text: '证书有效期',
    value: 'certificateValid',
    align: 'center',
    sortable: 'custom',
    filters: true,
  },
  {
    text: '使用状态',
    value: 'usageStatusName',
    align: 'center',
    sortable: 'custom',
    filters: true,
  },
  {
    text: '标签信息',
    value: 'rfid',
    align: 'center',
    sortable: 'custom',
    filters: true,
  },
])
const columnsLabel = ref([
  { text: '标签信息', value: 'rfid', 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 checkList = ref([]) // 多选选中
// 多选
const handleSelectionChange = (val: any) => {
  checkList.value = val
}
// 关闭弹窗
const closeDialog = () => {
  list.value = []
  singleChecked.value = ''// 清除选中
  dialogVisible.value = false
}

// 点击确定,保存选择的成员配置
const confirm = () => {
  if (isBinding.value && (!singleChecked.value && !checkList.value.length)) { // 标签绑定
    ElMessage.warning('请选中')
    return false
  }
  const message = isBinding.value ? '确认绑定吗?' : `确认${props.title}列表中的智能模型吗?`
  if (list.value.length) {
    if (isBinding.value) { // 标签绑定
      // if (pageType.value === 'detail') {
      //   emits('confirm', singleChecked.value)
      //   singleChecked.value = '' // 清除单选选中
      // }
      // else {
      //   ElMessageBox.confirm(
      //     message,
      //     '提示',
      //     { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' },
      //   ).then(() => {
      //     emits('confirm', singleChecked.value)
      //     singleChecked.value = ''
      //   })
      // }
      emits('confirm', props.isMuit ? checkList.value : singleChecked.value)
      // singleChecked.value = '' // 清除单选选中
      checkList.value = []
      multipleTableRef.value.clearSelection()
    }
    else {
      emits('confirm', props.isMuit ? checkList.value : list.value)
      checkList.value = []
      multipleTableRef.value.clearSelection()
    }
  }
  else {
    ElMessage.warning('暂无样品数据, 请重新扫描或取消')
  }
}

// 扫描/ 重新扫描
const scan = (labelId: string) => {
  singleChecked.value = ''// 清除选中
  // 扫描到的标签及样品信息列表
  if (isBinding.value) { // 标签绑定
    list.value.push({
      rfid: labelId,
    })
    singleChecked.value = list.value[0].rfid
  }
  else {
    getReaderEquipmentList([labelId]).then(async (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],
            certificateValid: res.data[0].certificateValid ? dayjs(res.data[0].certificateValid).format('YYYY-MM-DD') : res.data[0].certificateValid,
          })
        }
        else {
          console.log(`${list.value[index].equipmentName}${list.value[index].model}${list.value[index].manufactureNo}已经添加过`)
        }
      }
      // 任务单-- 做校验全部勾选
      if ($route.path.includes('meteringtask')) {
        loading.value = true
        // 任务单添加智能模型需要判断符不符合送检要求
        const dataBak = JSON.parse(JSON.stringify(list.value))
        list.value = []
        await Promise.all(dataBak.map(async (item: any) => {
          await devcieOrderSelect({
            limit: 1,
            offset: 1,
            checkDestination: '1', // 鉴定去向 计量室
            equipmentName: item.equipmentName,
            directorName: item.directorName,
            manufactureNo: item.manufactureNo,
            manufacturer: item.manufacturer,
          }).then((res) => {
            if (res.data.rows.length) {
              list.value.push({
                ...item,
              })
            }
          })
        }))
        // 自动全部勾选
        multipleTableRef.value.toggleAllSelection()
        loading.value = false
        // 提示
        ElMessage.warning(`共扫描到${dataBak.length}台智能模型,其中${dataBak.length - list.value.length}台不符合送检要求`)
      }
    })
  }
}

/**
 * 打开弹窗
 * @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()
    // scan('E280689420005022C6508CBC')
    // scan('E280689420004022C655309D')
    // scanStatus.value = '2'
    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 v-if="$route.path.includes('meteringtask')" ref="multipleTableRef" v-loading="loading" :data="list" style="width: 100%;margin-top: 10px;" border stripe @selection-change="handleSelectionChange">
          <el-table-column type="index" label="序号" width="55" align="center" />
          <el-table-column v-if="isBinding && !props.isMuit" label="" width="60" align="center">
            <template #default="scope">
              <el-radio v-model="singleChecked" :label="scope.row.rfid" class="radio" />
            </template>
          </el-table-column>
          <el-table-column v-if="isBinding && props.isMuit" type="selection" width="60" align="center" />
          <el-table-column v-if="!isBinding && props.isMuit" type="selection" width="60" align="center" />
          <el-table-column v-if="!isBinding" show-overflow-tooltip prop="equipmentNo" label="智能模型编号" align="center" width="160px" />
          <el-table-column v-if="!isBinding" show-overflow-tooltip prop="equipmentName" label="名称" align="center" />
          <el-table-column v-if="!isBinding" show-overflow-tooltip prop="model" label="型号规格" align="center" />
          <el-table-column v-if="!isBinding" show-overflow-tooltip prop="manufactureNo" label="出厂编号" align="center" width="90px" />
          <el-table-column v-if="!isBinding" show-overflow-tooltip prop="checkCycle" label="检定周期" align="center" width="120px" />
          <el-table-column v-if="!isBinding" show-overflow-tooltip prop="usePosition" label="使用岗位" align="center" width="120px" />
          <el-table-column v-if="!isBinding" show-overflow-tooltip prop="directorName" label="负责人" align="center" />
          <!-- <el-table-column v-if="!isBinding" show-overflow-tooltip prop="certificateValid" label="证书有效期" align="center" width="120px" /> -->
          <el-table-column show-overflow-tooltip prop="rfid" label="标签信息" align="center" />
          <!-- <el-table-column v-if="!isBinding" label="操作" align="center" width="60px" fixed="right">
            <template #default="scope">
              <el-button size="small" link type="primary" @click="deleteRow (scope.$index)">
                详情
              </el-button>
            </template>
          </el-table-column> -->
        </el-table>
        <el-table v-else 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.rfid" 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>
    <!-- </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" scoped>
.wait-scan {
  font-size: 18px;
  font-weight: bold;
  text-align: center;
  line-height: 3;

  .scan-img {
    margin-top: 20px;
    width: 128px;
    height: 128px;
  }
}

.radio {
  ::v-deep(.el-radio__label) {
    display: none !important;
  }
}
</style>