Newer
Older
smartwell_front / src / views / home / device / instruction / index.vue
liyaguang on 26 Feb 15 KB 新装设备完成
<!--
  Description: 设备管理-指令下发
  Author: 李亚光
  Date: 2024-09-02
 -->
<script lang="ts" setup name="instructionIssued">
import { ElMessage, ElMessageBox } from 'element-plus'
import editDialog from './components/editDialog.vue'
import { getInstructionListPage, removeInstruction } from '@/api/home/device/instruction'
import { getDeviceTypeListPage } from '@/api/home/device/type'
import { getProductListPage } from '@/api/home/device/product'
import { getDictByCode } from '@/api/system/dict'
import { shortcuts } from '@/utils/common'
import { instructionProductList } from './components/instruction'
import { uniqueMultiArray } from '@/utils/Array'
import { encrypt, decrypt, isEncrypt } from '@/utils/security1'
const $route = useRoute()
// 字典
const deviceTypeList = ref<{ id: string; name: string; value: string }[]>([]) // 设备类型
const deviceTypeQueryList = ref<{ id: string; name: string; value: string }[]>([]) // 设备类型
const productList = ref<{ id: string; name: string; value: string }[]>([]) // 产品
const productAllList = ref<{ id: string; name: string; value: string }[]>([]) // 产品
const statusList = ref<{ id: string; name: string; value: string }[]>([]) // 下发状态
// 表格数据
const list = ref([
])
const total = ref(0)
// 初始展示列
const columns = ref<any>([
  { text: '设备编号', value: 'devcode', align: 'center', width: '180', isCustom: true },
  { text: '设备类型', value: 'deviceTypeName', align: 'center', width: '220' },
  { text: '指令内容', value: 'framecontentDesc', align: 'center' },
  { text: '下发状态', value: 'statusName', align: 'center', width: '120' },
  { text: '操作人员', value: 'operatorName', align: 'center', width: '120' },
  { text: '备注', value: 'maker', align: 'center', width: '180' },
  { text: '操作时间', value: 'writetime', align: 'center', width: '180' },
])
// 最终展示列
const columnsConfig = ref([])
// 修改列
const editColumns = (data: any) => {
  columnsConfig.value = data
}
const loadingTable = ref(true)
//  查询条件
const listQuery = ref({
  limit: 20,
  offset: 1,
  devcode: '', // 设备编号
  deviceType: '', // 设备类型
  productId: '', // 产品
  status: '', // 下发状态
  operatorName: '', // 操作人员
  beginTime: '',
  endTime: '',
})
// 开始结束时间
const datetimerange = ref()
watch(() => datetimerange.value, (newVal) => {
  listQuery.value.beginTime = ''
  listQuery.value.endTime = ''
  if (Array.isArray(newVal)) {
    if (newVal.length) {
      listQuery.value.beginTime = `${newVal[0]}`
      listQuery.value.endTime = `${newVal[1]}`
    }
  }
})
// 查询数据
const fetchData = () => {
  loadingTable.value = true
  //
  getInstructionListPage(listQuery.value).then((res) => {
    list.value = res.data.rows.map((item: any) => ({
      ...item,
      statusName: statusList.value[statusList.value.findIndex(citem => item.status === citem.value)].name,
      deviceTypeName: deviceTypeList.value[deviceTypeList.value.findIndex(citem => item.deviceType === citem.value)]?.name || '',
      framecontentDesc: item.framecontentDesc ? item.framecontentDesc : solveInstruction(item, item.framecontent, item.productId),
      instructionTypeCustrom: typeInstruction(item.productId), // 产品
      showDeviceTips: false, // 展示设备编号提示
      operatorName: isEncrypt(item.operatorName) ? decrypt(item.operatorName) : item.operatorName,
    }))
    // 设备类型和厂商
    list.value.forEach((item: any) => {
      if (productAllList.value.filter((citem) => citem.id === item.productId).length) {
        item.showDeviceTips = true
        item.deviceTips = {
          typeName: productAllList.value.filter((citem) => citem.id === item.productId)[0].deviceTypeName,
          manufactureName: productAllList.value.filter((citem) => citem.id === item.productId)[0].manufacturerName
        }
      }
    })
    total.value = res.data.total
    loadingTable.value = false
  }).catch(() => {
    loadingTable.value = false
  })

  // 解析指令内容成文字
  function solveInstruction(row: any, instruction: string, productId: string) {
    let result = ''
    //  判断产品和指令
    if (!instruction) {
      result = ''
      return result
    }
    // 当前指令类型
    const instructionDevice = {
      bjwxd: false,  // 北京无线电
      brsGwsb: false, // 百瑞生-管网哨兵
      bfmhkGwsb: false, // 北分麦哈克-管网哨兵
      ncxRqznjsz: false // 诺成新-燃气智能警示桩
    } as { [key: string]: boolean }
    // 当前支持下发配置的产品
    const productConfig = instructionProductList
    // 当前产品
    for (const i in instructionDevice) {
      instructionDevice[i] = false
    }
    const currentProduct = productAllList.value.filter((item) => item.id === productId)[0] as any
    const currentProductConfig = productConfig.filter((item: any) => currentProduct.deviceTypeName.includes(item.deviceName) && currentProduct.manufacturerName.includes(item.manufacturerName))
    if (currentProductConfig.length) {
      instructionDevice[currentProductConfig[0].value] = true
    }
    // 北京无线电
    if (instructionDevice.bjwxd) {
      result = row.framecontentDesc
    }
    // 百瑞生-管网哨兵
    else if (instructionDevice.brsGwsb) {
      const instructionContent = JSON.parse(instruction)
      const solve = instructionContent.map((item: { command: string, value: string }) => {
        const content = currentProductConfig[0].instruction[item.command] || ''
        const switch1 = { 0: '关', 1: '开' } as { [key: string]: string }
        return `${content.replace('-', '')}:${content.includes('-') ? (switch1[item.value] || '') : item.value}`
      })
      result = solve.join()
    }
    // 北分麦哈克-管网哨兵
    else if (instructionDevice.bfmhkGwsb) {
      const instructionContent = JSON.parse(instruction)
      const solve = instructionContent.map((item: { command: string, value: string }) => {
        const content = currentProductConfig[0].instruction[item.command] || ''
        const switch1 = { 0: '关', 1: '开' } as { [key: string]: string }
        return `${content.replace('-', '')}:${content.includes('-') ? (switch1[item.value] || '') : item.value}`
      })
      result = solve.join()
    }
    // 诺成新-燃气智能警示桩
    else if (instructionDevice.ncxRqznjsz) {
      const instructionContent = JSON.parse(instruction)
      const solve = instructionContent.map((item: { command: string, value: string }) => {
        if (item.command === 'switch') {
          let result = []
          for (let i = 0; i < item.value.length; i++) {
            result.push(item.value[i])
          }
          item.value = result.join()
        }
        const content = (currentProductConfig[0].instruction[item.command] || '').split(',')
        const value = item.value.split(',')
        const switch1 = { 0: '关', 1: '开' } as { [key: string]: string }
        const str = content.map((citem: string, index: number) => {
          if (item.command === 'time') {
            return `${citem}:${value[index].substring(0, 2)}点`
          }
          else {
            return `${citem.replace('-', '')}:${citem.includes('-') ? (switch1[value[index]] || '') : value[index]}`
          }
        })
        return str.join()
      })
      result = solve.join()
    }
    return result
  }
  // 当前产品
  function typeInstruction(productId: string) {
    let result = ''
    if (!productId) {
      result = ''
      return result
    }
    // 当前指令类型
    const instructionDevice = {
      bjwxd: false,  // 北京无线电
      brsGwsb: false, // 百瑞生-管网哨兵
      bfmhkGwsb: false, // 北分麦哈克-管网哨兵
      ncxRqznjsz: false // 诺成新-燃气智能警示桩
    } as { [key: string]: boolean }
    // 当前支持下发配置的产品
    const productConfig = instructionProductList
    // 当前产品
    for (const i in instructionDevice) {
      instructionDevice[i] = false
    }
    const currentProduct = productAllList.value.filter((item) => item.id === productId)[0] as any
    const currentProductConfig = productConfig.filter((item: any) => currentProduct.deviceTypeName.includes(item.deviceName) && currentProduct.manufacturerName.includes(item.manufacturerName))
    if (currentProductConfig.length) {
      instructionDevice[currentProductConfig[0].value] = true
      result = currentProductConfig[0].value
    }
    return result
  }
}
// 重置查询条件f
const reset = () => {
  datetimerange.value = []
  listQuery.value = {
    limit: 20,
    offset: 1,
    devcode: '', // 设备编号
    deviceType: '', // 设备类型
    productId: '', // 产品
    status: '', // 下发状态
    operatorName: '', // 操作人员
    beginTime: '',
    endTime: '',
  }
  fetchData()
}
// 页数发生变化后的操作,可能是页码变化,可能是每页容量变化,此函数必写
const changePage = (val: { size: number; page: number }) => {
  if (val && val.size) {
    listQuery.value.limit = val.size
  }
  if (val && val.page) {
    listQuery.value.offset = val.page
  }
  fetchData()
}
// 新建编辑操作
const editRef = ref()
const editRow = (type: string, row: any) => {
  editRef.value.initDialog(type, row)
}
// 删除
const removeRow = (row: any) => {
  ElMessageBox.confirm(
    '确定要删除该指令吗?',
    '确认操作',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    },
  ).then(() => {
    removeInstruction([row.id]).then((response) => {
      if (response.code === 200) {
        ElMessage({
          message: '删除成功',
          type: 'success',
        })
        fetchData()
      }
    })
  })
}

// 获取字典
const fetchDict = async () => {
  // 设备类型
  const res = await getDeviceTypeListPage({ offset: 1, limit: 99999 })
  deviceTypeList.value = res.data.rows.map((item: any) => ({
    name: item.typeName || '',
    id: item.id,
    value: item.id,
  }))

  // 产品
  const res1 = await getProductListPage({ offset: 1, limit: 99999 })
  productAllList.value = res1.data.rows
  productList.value = res1.data.rows.filter((item: any) => instructionProductList.some((citem: any) => item.manufacturerName.includes(citem.manufacturerName) && item.deviceTypeName.includes(citem.deviceName))).map((item: any) => ({
    name: item.productName || '',
    id: item.id,
    value: item.id,
  }))
  deviceTypeQueryList.value = uniqueMultiArray(res1.data.rows.filter((item: any) => instructionProductList.some((citem: any) => item.manufacturerName.includes(citem.manufacturerName) && item.deviceTypeName.includes(citem.deviceName))).map((item: any) => ({
    name: item.deviceTypeName,
    id: item.deviceType,
    value: item.deviceType,
  })), 'value')
  // 下发状态
  const res2 = await getDictByCode('issuedStatus')
  statusList.value = res2.data
}
onMounted(async () => {
  await fetchDict()
  fetchData()
  // 判断是否 从别处跳转过来(设备详情-控制记录-新建)
  if ($route.query.row) {
    editRef.value.initDialog('addOther', {})
  }
})
const { proxy } = getCurrentInstance() as any

// 跳转设备详情
const $router = useRouter()
const toDeviceDetail = (row: any) => {
  // console.log(row, 'row')
  if (!row.devcode || !row.deviceTypeName) {
    ElMessage.warning('缺少设备关键信息')
    return
  }
  $router.push({
    name: 'DeviceManageDetail',
    params: {
      type: 'detail',
    },
    query: {
      row: JSON.stringify({
        devcode: row.devcode,
        deviceType: row.deviceTypeName,
        deviceTypeName: row.deviceTypeName,
        devTypeName: row.deviceTypeName,
      }),
    },
  })
}
</script>

<template>
  <!-- 布局 -->
  <app-container>
    <!-- 新建编辑弹窗 -->
    <edit-dialog ref="editRef" @refresh="fetchData" />
    <!-- 筛选条件 -->
    <search-area :need-clear="true" @search="fetchData" @clear="reset">
      <search-item>
        <el-input v-model="listQuery.devcode" placeholder="设备编号" clearable />
      </search-item>
      <search-item>
        <el-select v-model="listQuery.deviceType" placeholder="设备类型" clearable filterable class="select"
          style="width: 192px;">
          <el-option v-for="item in deviceTypeQueryList" :key="item.id" :label="item.name" :value="item.value" />
        </el-select>
      </search-item>
      <search-item>
        <el-select v-model="listQuery.productId" placeholder="产品" clearable filterable class="select"
          style="width: 192px;">
          <el-option v-for="item in productList" :key="item.id" :label="item.name" :value="item.value" />
        </el-select>
      </search-item>
      <search-item>
        <el-select v-model="listQuery.status" placeholder="下发状态" clearable filterable class="select"
          style="width: 192px;">
          <el-option v-for="item in statusList" :key="item.id" :label="item.name" :value="item.value" />
        </el-select>
      </search-item>
      <search-item>
        <el-input v-model="listQuery.operatorName" placeholder="操作人员" clearable />
      </search-item>
      <search-item>
        <el-date-picker v-model="datetimerange" type="datetimerange" format="YYYY-MM-DD HH:mm:ss" :shortcuts="shortcuts"
          value-format="YYYY-MM-DD HH:mm:ss" range-separator="至" start-placeholder="操作开始时间" end-placeholder="操作结束时间"
          clearable />
      </search-item>
    </search-area>
    <!-- 表头标题 -->
    <table-container :is-config="true" config-title="device-instruction" :columns="columns"
      :config-columns="columnsConfig" :edit="editColumns">
      <template #btns-right>
        <!-- 操作 -->
        <div>
          <!-- <el-button v-if="proxy.hasPerm('/device/instruction/batch')" type="primary">
            批量下发
          </el-button> -->
          <el-button v-if="proxy.hasPerm('/device/instruction/add')" type="primary" @click="editRow('add', {})">
            新建
          </el-button>
        </div>
      </template>
      <!-- 查询结果Table显示 -->
      <normal-table :data="list" :total="total" :columns="columnsConfig" :query="listQuery" :list-loading="loadingTable"
        @change="changePage">
        <template #preColumns>
          <el-table-column label="序号" width="55" align="center">
            <template #default="scope">
              {{ (listQuery.offset - 1) * listQuery.limit + scope.$index + 1 }}
            </template>
          </el-table-column>
        </template>
        <template #isCustom="{ scope, column }">
          <!-- 设备编号 -->
          <span v-if="column.text === '设备编号'" class="pointer link" @click="toDeviceDetail(scope.row)">
            <el-tooltip v-if="scope.row.showDeviceTips" class="box-item" effect="dark"
              :content="`${scope.row.deviceTips.typeName}(${scope.row.deviceTips.manufactureName})`" placement="top">
              {{ scope.row[column.value] }}
            </el-tooltip>
            <template v-else>
              {{ scope.row[column.value] }}
            </template>
          </span>
        </template>
        <template #columns>
          <el-table-column label="操作" align="center" width="120">
            <template #default="scope">
              <el-button v-if="proxy.hasPerm('/device/instruction/detail')" type="primary" link size="small"
                @click="editRow('detail', scope.row)">
                查看
              </el-button>
              <el-button v-if="proxy.hasPerm('/device/instruction/again') && scope.row.status === '2'" type="primary"
                link size="small" @click="editRow('edit', scope.row)">
                重新下发
              </el-button>
              <el-button v-if="proxy.hasPerm('/device/instruction/delete')" type="danger" link size="small"
                @click="removeRow(scope.row)">
                删除
              </el-button>
            </template>
          </el-table-column>
        </template>
      </normal-table>
    </table-container>
  </app-container>
</template>

<style lang="scss" scoped>
.pointer {
  &:hover {
    cursor: pointer;
  }
}

.link {
  color: #0d76d4 !important;

  &:hover {
    text-decoration: underline !important;
  }
}
</style>