Newer
Older
smartwell_front / src / views / home / device / instruction / components / editDialog.vue
lyg on 25 Sep 10 KB 事件地图
<!--
  Description: 产品管理-新建或编辑指令
  Author: 李亚光
  Date: 2024-07-15
 -->
<script lang="ts" setup name="EditInstruction">
import dayjs from 'dayjs'
import type { FormRules } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getDictByCode } from '@/api/system/dict'
import { addInstruction, removeInstruction } from '@/api/home/device/instruction'
import { getDeviceTypeListPage } from '@/api/home/device/type'
import { getProductListPage } from '@/api/home/device/product'
import { getDeviceListPage } from '@/api/home/device/device'
import useUserStore from '@/store/modules/user'
const emits = defineEmits(['refresh'])
const $route = useRoute()
const $router = useRouter()
const productList = ref<{ id: string; name: string; value: string }[]>([]) // 产品
const deviceList = ref<{ id: string; name: string; value: string }[]>([]) // 设备
const deviceAllList = ref<{ id: string; name: string; value: string }[]>([]) // 设备
const deviceTypeList = ref<{ id: string; name: string; value: string }[]>([]) // 设备类型
const user = useUserStore()
const dataFormRef = ref()
const dialogFormVisible = ref(false) // 对话框是否显示
const dialogStatus = ref('') // 对话框类型:create,update
const dataForm = ref({
  id: '',
  productId: '', // 产品
  // devcode: '', // 设备编号
  collectInterval: '', // 采集间隔
  uploadPeriod: '', // 上传周期
  reloadInterval: '', // 重传次数
  operator: '', // 操作员id
  operatorName: '', // 操作员名称
  maker: '', // 备注
  deviceType: '',
  deviceTypeName: '',
  framecontent: '',
  framecontentDesc: '',
  writetime: '',
  devCodeList: [],
}) // 表单
const textMap: { [key: string]: string } = {
  edit: '编辑',
  add: '新增',
  addOther: '新增',
  detail: '详情',
} // 表头显示标题
const rules: FormRules = {
  productId: [{ required: true, message: '产品必选', trigger: ['blur', 'change'] }],
  devCodeList: [{ required: true, message: '设备必选', trigger: ['blur', 'change'] }],
  collectInterval: [{ required: true, message: '采集间隔不能为空', trigger: ['blur', 'change'] }],
  reloadInterval: [{ required: true, message: '重传次数不能为空', trigger: ['blur', 'change'] }],
  uploadPeriod: [{ required: true, message: '上传周期不能为空', trigger: ['blur', 'change'] }],
} // 前端校验规则

// 重置表单
const resetForm = () => {
  dataForm.value = {
    id: '',
    productId: '', // 产品
    // devcode: '', // 设备编号
    collectInterval: '', // 采集间隔
    uploadPeriod: '', // 上传周期
    reloadInterval: '', // 重传次数
    operator: '', // 操作员id
    operatorName: '', // 操作员名称
    maker: '', // 备注
    deviceType: '',
    deviceTypeName: '',
    framecontent: '',
    framecontentDesc: '',
    writetime: '',
    devCodeList: [],
  }
}

// 初始化对话框
const isFirst = ref(true)
const initDialog = (dialogStatusValue: string, row: any) => {
  dialogStatus.value = dialogStatusValue
  dialogFormVisible.value = true
  if (dialogStatus.value === 'add') { // 如果是新增,清除验证
    resetForm()
    dataFormRef.value?.resetFields()
    dataForm.value.operator = user.id
    dataForm.value.operatorName = user.name
  }
  else if (dialogStatus.value === 'addOther') {
    resetForm()
    dataFormRef.value?.resetFields()
    const data = JSON.parse($route.query.row as string)
    dataForm.value = data
    // dataForm.value.devcode = data.devcode
    // dataForm.value.deviceType = data.deviceType
    dataForm.value.operator = user.id
    dataForm.value.operatorName = user.name
  }
  else if (dialogStatus.value === 'edit' || dialogStatus.value === 'detail') { // 如果是修改,将row中数据填写到输入框中
    dataForm.value = {
      ...JSON.parse(JSON.stringify(row)),
    }
  }
  setTimeout(() => {
    isFirst.value = false
  })
}
defineExpose({
  initDialog,
})

// 新增数据
const createData = () => {
  dataFormRef.value.validate((valid: any) => {
    if (valid) {
      dataForm.value.framecontent = `reloadInterval:${dataForm.value.reloadInterval};collectInterval:${dataForm.value.collectInterval};uploadPeriod:${dataForm.value.uploadPeriod}`
      dataForm.value.framecontentDesc = `重传次数:${dataForm.value.reloadInterval}次;采集间隔:${dataForm.value.collectInterval}分;上传周期:${dataForm.value.uploadPeriod}分`
      addInstruction(dataForm.value).then((response) => {
        if (response.code === 200) {
          ElMessage({
            message: '添加成功',
            type: 'success',
          })
          // 通知父组件刷新状态
          dialogFormVisible.value = false
          setTimeout(() => {
            emits('refresh')
          })
          if (dialogStatus.value === 'addOther') {
            $router.back()
          }
        }
      }).catch((_) => { // 异常情况,loading置为false
      })
    }
  })
}

// 修改数据
const updateData = () => {
  dataFormRef.value.validate((valid: any) => {
    if (valid) {
      removeInstruction([dataForm.value.id]).then((res) => {
        dataForm.value.id = ''
        createData()
      })
    }
  })
}

// 保存数据
const saveData = () => {
  // dataForm.value.deviceTypeName = deviceTypeList.value[deviceTypeList.value.findIndex(citem => dataForm.value.deviceType === citem.value)]?.name
  // dataForm.value.deviceTypeName =
  dataForm.value.writetime = dayjs().format('YYYY-MM-DD HH:mm:ss')
  if (dialogStatus.value === 'edit') {
    updateData()
  }
  else if (dialogStatus.value === 'add' || dialogStatus.value === 'addOther') {
    createData()
  }
}
const cancel = () => {
  dialogFormVisible.value = false
  if (dialogStatus.value === 'addOther') {
    $router.back()
  }
}

// 获取字典
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,
  }))
  // 产品
  getProductListPage({ offset: 1, limit: 99999 }).then((res) => {
    productList.value = res.data.rows.map((item: any) => ({
      ...item,
      name: `${item.productName}-${item.deviceModel}/${item.manufacturerName}`,
      id: item.id,
      value: item.id,
    }))
  })
  // 设备
  getDeviceListPage({ offset: 1, limit: 99999 }).then((res) => {
    deviceList.value = res.data.rows.filter((item: any) => item.productId).map((item: any) => ({
      name: item.deviceName,
      id: item.devcode,
      value: item.devcode,
      deviceType: item.deviceType,
      productId: item.productId,
    }))
    deviceAllList.value = JSON.parse(JSON.stringify(deviceList.value))
  })
}
fetchDict()

watch(() => dataForm.value.productId, (newVal) => {
  if (dialogStatus.value === 'detail' || isFirst.value) { return }
  if (newVal) {
    // dataForm.value.devcode = ''
    dataForm.value.deviceType = productList.value.filter((item: any) => item.id === newVal)[0].deviceType
    dataForm.value.deviceTypeName = productList.value.filter((item: any) => item.id === newVal)[0].deviceTypeName
    deviceList.value = deviceAllList.value.filter((item: any) => item.productId === newVal)
  }
}, {
  deep: true,
})
// watch(() => dataForm.value.devcode, (newVal) => {
//   if (dialogStatus.value === 'detail' || isFirst.value) { return }
//   if (newVal) {
//     dataForm.value.deviceType = deviceList.value.filter((item: any) => item.value === newVal)[0].deviceType
//     dataForm.value.deviceTypeName = deviceTypeList.value[deviceTypeList.value.findIndex(citem => dataForm.value.deviceType === citem.value)].name
//   }
// }, {
//   deep: true,
// })
</script>

<template>
  <el-dialog v-model="dialogFormVisible" :title="`指令${textMap[dialogStatus]}`" append-to-body>
    <el-form
      ref="dataFormRef" :rules="rules" :model="dataForm" label-position="right" label-width="120px"
      :disabled="dialogStatus === 'detail'"
    >
      <el-row :gutter="24">
        <el-col :span="24">
          <el-form-item label="产品名称" prop="productId">
            <el-select v-model="dataForm.productId" placeholder="产品名称" style="width: 100%;" clearable filterable>
              <el-option v-for="item in productList" :key="item.id" :label="item.name" :value="item.value" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="设备编号" prop="devcode">
            <!-- multiple -->
            <el-select
              v-model="dataForm.devCodeList" placeholder="设备编号" style="width: 100%;" clearable filterable
              multiple
            >
              <el-option v-for="item in deviceList" :key="item.id" :label="item.name" :value="item.value" />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="24">
        <el-col :span="12">
          <el-form-item label="采集间隔(min)" prop="collectInterval">
            <el-input
              v-model.trim="dataForm.collectInterval" type="number" placeholder="采集间隔" style="width: 100%;"
              clearable
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="上传周期(min)" prop="uploadPeriod">
            <el-input
              v-model.trim="dataForm.uploadPeriod" type="number" placeholder="上传周期" style="width: 100%;"
              clearable
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="重传次数(次)" prop="reloadInterval">
            <el-input
              v-model.trim="dataForm.reloadInterval" type="number" placeholder="重传次数" style="width: 100%;"
              clearable
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="操作人" prop="operatorName">
            <el-input v-model.trim="dataForm.operatorName" type="text" style="width: 100%;" disabled clearable />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="24">
        <el-col :span="24">
          <el-form-item label="备注">
            <el-input
              v-model.trim="dataForm.maker" type="textarea" :rows="2" paceholder="备注" style="width: 100%;"
              clearable
            />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <div v-if="dialogStatus !== 'detail'" class="dialog-footer">
        <el-button type="primary" @click="saveData">
          确认
        </el-button>
        <el-button @click="cancel">
          取消
        </el-button>
      </div>
      <div v-else class="dialog-footer">
        <el-button type="primary" @click="cancel">
          确认
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.el-dialog {
  width: 700px;
}

.el-select {
  width: 100%;
}
</style>