Newer
Older
smartwell_front / src / views / home / rule / special / components / editDialog.vue
liyaguang on 25 Dec 17 KB 需求与问题修改
<!--
  Description: 特殊报警规则-编辑新建
  Author: 李亚光
  Date: 2024-09-09
 -->
<script lang="ts" setup name="EditAlarmRuleSPecial">
import type { FormRules } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getDictByCode } from '@/api/system/dict'
import { getDeviceTypeListPage } from '@/api/home/device/type'
import { getAlarmLevelListPage, getAlarmTypeListPage, } from '@/api/home/rule/alarm'
import { getAlarmRuleListPage } from '@/api/home/rule/alarm'
import { addSpecialAlarmRule, editSpecialAlarmRule, getProductAlarmRule, } from '@/api/home/rule/special'
import { getDeviceListPage } from '@/api/home/device/device'
import { getProductListPage } from '@/api/home/device/product'
import { useCheckList } from '@/utils/useCheckList'
import indexDB from '@/utils/indexDB'
import { indexDBHandler } from '@/utils/sessionData'
const emits = defineEmits(['refresh'])
const deviceList = ref<any[]>([]) // 设备列表
const productList = ref<any[]>([]) // 产品
const alarmRuleList = ref<any[]>([]) // 报警规则
const alarmRuleAllList = ref<any[]>([]) // 报警规则
const alarmLevelList = ref<any[]>([]) // 报警等级
const dataFormRef = ref()
const dialogFormVisible = ref(false) // 对话框是否显示
const dialogStatus = ref('') // 对话框类型:create,update
const dataForm = ref({
  devcode: '', // 设备编号
  tagNumber: '', // 位号
  position: '', // 详细位置
  alarmLevelId: '', // 报警等级id
  alarmTypeId: '', // 报警类型
  alarmThreshold: '', // 报警阈值
  productId: '',
  alarmRule: '',
  id: '',
}) // 表单
const textMap: { [key: string]: string } = {
  edit: '编辑',
  create: '新增',
  detail: '',
} // 表头显示标题
const rules: FormRules = {
  devcode: [ { required: true, message: '设备编号不能为空', trigger: ['blur', 'change'] } ],
} // 前端校验规则

// 重置表单
const resetForm = () => {
  dataForm.value = {
    devcode: '', // 设备编号
    tagNumber: '', // 位号
    position: '', // 详细位置
    alarmLevelId: '', // 报警等级id
    alarmTypeId: '', // 报警类型
    alarmThreshold: '', // 报警阈值
    productId: '',
    alarmRule: '',
    id: '',
  }
}
const list = ref<any[]>([])
const columns = ref<any>([
  {
    text: '报警规则',
    value: 'alarmRuleId',
    align: 'center',
    type: 'select',
    code: 'alarm-rule',
    required: true,
  },
  {
    text: '报警等级',
    value: 'alarmLevelId',
    align: 'center',
    type: 'select',
    code: 'alarm-level',
    required: true,
  },
  {
    text: '报警阈值',
    value: 'alarmThreshold',
    align: 'center',
    type: 'input',
    required: true,
  },
])
// 初始化对话框
const isFirst = ref(true)
// 初始数据
const initDeviceCode = ref('')
const initAlarmRule = ref<any[]>([])
const initDialog = (dialogStatusValue: string, row: any) => {
  dialogStatus.value = dialogStatusValue
  isFirst.value = true
  dialogFormVisible.value = true
  if (dialogStatus.value === 'create') {
    // 如果是新增,清除验证
    resetForm()
    // nextTick(() => {
    //   dataFormRef.value.clearValidate()
    // })
    dataFormRef.value?.resetFields()
    list.value = []
    initDeviceCode.value = ''
    initAlarmRule.value = []
  }
  else if (dialogStatus.value === 'edit' || dialogStatus.value === 'detail') {
    // 如果是修改,将row中数据填写到输入框中
    dataForm.value = {
      ...JSON.parse(JSON.stringify(row)),
    }
    initDeviceCode.value = dataForm.value.devcode
    // console.log(row, '123')
    list.value = [
      {
        edit: dialogStatus.value === 'edit',
        alarmRuleId: row.alarmRuleId,
        alarmLevelId: row.alarmLevelId,
        alarmThreshold: row.alarmThreshold,
        alarmTypeId: row.alarmTypeId,
        isConcentration: row.alarmType.includes('浓度'),
      },
    ]
    initAlarmRule.value = JSON.parse(JSON.stringify(list.value))
  }
  setTimeout(() => {
    isFirst.value = false
  })
}
watch(() => dataForm.value.devcode, (newVal) => {
  if (newVal) {
    // console.log(newVal, isFirst.value, '设备编号')
    if (!isFirst.value) {
      if (newVal !== initDeviceCode.value) {
        getProductAlarmRule({ devCode: newVal }).then((res) => {
          // console.log(res.data, '报警规则')
          list.value = res.data.map((item: any) => ({
            edit: true,
            alarmTypeId: item.alarmTypeId,
            alarmThreshold: item.alarmThreshold,
            alarmLevelId: item.alarmLevelId,
            alarmRuleId: item.alarmRuleId,
            alarmRuleName: item.alarmRuleName,
            isConcentration: item.alarmTypeName.includes('浓度'),
          }))
        })
      }
      else {
        list.value = JSON.parse(JSON.stringify(initAlarmRule.value))
      }
    }
  }
})
defineExpose({
  initDialog,
})

// 新增数据
const createData = (data: any) => {
  dataFormRef.value.validate((valid: any) => {
    if (valid) {
      // 验证数据列
      if (useCheckList(list.value, columns.value, '报警规则')) {
        addSpecialAlarmRule(data)
          .then((response) => {
            if (response.code === 200) {
              ElMessage({
                message: '添加成功',
                type: 'success',
              })
              // 通知父组件刷新状态
              dialogFormVisible.value = false
              setTimeout(() => {
                emits('refresh')
              })
            }
          })
          .catch((_) => {
            // 异常情况,loading置为false
          })
      }
    }
  })
}

// 修改数据
const updateData = (data: any) => {
  dataFormRef.value.validate((valid: any) => {
    if (valid) {
      if (useCheckList(list.value, columns.value, '报警规则')) {
        editSpecialAlarmRule(data)
          .then((response) => {
            if (response.code === 200) {
              ElMessage({
                message: '修改成功',
                type: 'success',
              })
              setTimeout(() => {
                emits('refresh')
              })
              dialogFormVisible.value = false
            }
          })
          .catch((_) => {
            // 异常情况,loading置为false
          })
      }
    }
  })
}

// 保存数据
const saveData = () => {
  if (!list.value.length) {
    ElMessage.warning('报警规则为空')
    return
  }
  if (list.value.filter((item: any) => item.edit).length) {
    ElMessage.warning('请先保存报警规则')
    return
  }
  const data = list.value.map((item: any) => ({
    alarmLevelId: item.alarmLevelId,
    alarmTypeId: item.alarmTypeId,
    // alarmRule: item.alarmRule,
    alarmRuleId: item.alarmRuleId,
    alarmRuleName: alarmRuleList.value.filter((citem: any) => citem.id === item.alarmRuleId)[0]?.name || '',
    alarmThreshold: item.alarmThreshold,
    devcode: dataForm.value.devcode,
    id: dataForm.value.id,
    position: dataForm.value.position,
    tagNumber: dataForm.value.tagNumber,
    devTypeName: deviceList.value.filter((citem: any) => citem.value === dataForm.value.devcode)[0]?.name || '',
  }))
  console.log(data, 'data')
  if (dialogStatus.value === 'edit') {
    updateData(data)
  }
  else if (dialogStatus.value === 'create') {
    createData(data)
  }
}
const cancel = () => {
  dialogFormVisible.value = false
}
// 列表添加行
const addRow = () => {
  list.value.push({
    alarmThreshold: '',
    alarmLevelId: '',
    alarmRule: '',
    edit: true,
  })
}
// 保存行
const saveRow = (scope: any) => {
  const row = scope.row as any
  if (String(row.alarmThreshold) && row.alarmLevelId) {
    list.value[scope.$index].edit = false
  }
  else {
    ElMessage.warning('请先完善当前行数据')
  }
}
// 编辑行
const editRow = (scope: any) => {
  list.value[scope.$index].edit = true
}
// 删除行
const removeRow = (scope: any) => {
  ElMessageBox.confirm('确定要删除该数据吗?', '确认操作', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    list.value = list.value.filter((item, index) => index !== scope.$index)
    ElMessage.success('操作成功')
  })
}
// 字典
const fetchDict = () => {
  // 先从缓存中获取设备列表
  indexDB.getAll().then(allData => {
    if (allData.filter((item: any) => item.name === 'all-device-list').length) {
      deviceList.value = JSON.parse(allData.filter((item: any) => item.name === 'all-device-list')[0].data)
    }
    else {
      getDeviceListPage({ offset: 1, limit: 9999 }).then((res) => {
        deviceList.value = res.data.rows.map((item: any) => ({
          name: item.typeName,
          id: item.id,
          value: item.devcode,
          productId: item.productId,
          position: item.position,
          tagNumber: item.tagNumber,
          deviceType: item.deviceType,
        })).filter((item: any) => item.productId && item.value)
        indexDBHandler('all-device-list', JSON.stringify(deviceList.value))
      })
    }
  })
  // 产品
  getProductListPage({ limit: 9999, offset: 1 }).then((res) => {
    productList.value = res.data.rows.map((item: any) => ({
      name: `${item.productName}-${item.deviceModel}/${item.manufacturerName}`,
      value: item.id,
      id: item.id,
    }))
  })
  // 报警规则
  getAlarmRuleListPage({ limit: 9999, offset: 1 }).then((res) => {
    alarmRuleAllList.value = res.data.rows
    alarmRuleList.value = res.data.rows.map((item: any) => ({
      name: item.alarmName,
      id: item.id,
      value: item.id,
      alarmTypeId: item.alarmTypeId,
    }))
  })
  // 报警等级
  getAlarmLevelListPage({ limit: 9999, offset: 1 }).then((res) => {
    alarmLevelList.value = res.data.rows.map((item: any) => ({
      name: item.alarmLevel,
      id: item.id,
      value: item.id,
    }))
  })
}
fetchDict()

// 监听设备编号,自动填充产品,安装位号,详细地址
watch(() => dataForm.value.devcode, (newVal) => {
  if (newVal) {
    const current = deviceList.value.filter((item: any) => item.value === dataForm.value.devcode)
    if (current.length) {
      dataForm.value.productId = current[0].productId
      dataForm.value.tagNumber = current[0].tagNumber
      dataForm.value.position = current[0].position
      alarmRuleList.value = alarmRuleAllList.value.filter((item: any) => item.productId === dataForm.value.productId)
      .map((item:any) => ({
        name: item.alarmName,
        id: item.id,
        typeId: item.alarmTypeId
      }))
      // console.log(alarmRuleAllList.value.filter((item: any) => item.productId === dataForm.value.productId))
      // console.log(alarmRuleList.value, 'alarmRuleList.value')
      // 根据设备类型寻找报警类型
      // getAlarmTypeListPage({ limit: 9999, offset: 1 }).then((res) => {
      //   alarmRuleList.value = res.data.rows.filter((item: any) => item.deviceTypeName.includes(current[0].name))
      //     .map((item: any) => ({
      //       name: item.alarmType,
      //       id: item.id,
      //       value: item.id,
      //     }))
      // })
     return
    }
    if (isFirst.value) {
      return
    }
    alarmRuleList.value = []
    list.value = []
  }
},
  {
    deep: true,
    immediate: true,
  })
// 改变报警类型
const changeAlarmType = (value: string, index: number) => {
  const alarmTypeName = alarmRuleList.value.filter(item => item.id === value)[0]?.name || ''
  if (alarmTypeName.includes('浓度')) {
    list.value[index].isConcentration = true
  }
  else {
    list.value[index].isConcentration = false
  }
}
const computeOptions = (val: any) => {
  return val.map((item: any) => ({ label: `${item.value}-${item.name}`, value: item.value }))
}
</script>

<template>
  <el-dialog v-model="dialogFormVisible" :title="`${textMap[dialogStatus]}特殊报警规则`" append-to-body width="900px">
    <el-form ref="dataFormRef" :rules="rules" :model="dataForm" label-position="right"
      :disabled="dialogStatus === 'detail'" label-width="110px">
      <el-row :gutter="24">
        <el-col :span="12">
          <el-form-item label="设备编号" prop="devcode">
            <!-- <el-select v-model.trim="dataForm.devcode" placeholder="设备编号" style="width: 100%;" clearable filterable>
              <el-option v-for="item in deviceList" :key="item.id" :label="`${item.name}-${item.value}`"
                :value="item.value" />
            </el-select> -->
            <el-select-v2 v-model="dataForm.devcode" :options="computeOptions(deviceList)" style="width: 100%;"
              clearable filterable>
            </el-select-v2>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="产品" prop="productId">
            <el-select v-model.trim="dataForm.productId" placeholder="产品" style="width: 100%;" clearable filterable
              disabled>
              <el-option v-for="item in productList" :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="安装位号" prop="tagNumber">
            <el-input v-model.trim="dataForm.tagNumber" type="text" placeholder="安装位号" style="width: 100%;" disabled
              clearable />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="详细地址" prop="position">
            <el-input v-model.trim="dataForm.position" type="text" placeholder="详细地址" style="width: 100%;" disabled
              clearable />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="24">
        <!-- <el-col :span="24">
          <el-form-item label="报警规则" prop="">

          </el-form-item>
        </el-col> -->
        <el-col :span="24">
          <div class="table-custom-edit" style="width: 100%;">
            <table-container title="报警规则">
              <template #btns-right>
                <!-- 操作 -->
                <!-- <div>
                  <el-button v-if="dialogStatus === 'create'" type="primary" @click="addRow">
                    新增
                  </el-button>
                </div> -->
              </template>
              <!-- 查询结果Table显示 -->
              <normal-table :data="list" :total="0" :columns="[]" :query="{}" :pagination="false">
                <template #preColumns>
                  <el-table-column label="序号" width="55" align="center">
                    <template #default="scope">
                      {{ scope.$index + 1 }}
                    </template>
                  </el-table-column>
                </template>
                <template #columns>
                  <el-table-column v-for="item in columns" :key="item.text" :label="item.text" align="center">
                    <template #default="scope">
                      <!-- 报警规则 -->
                      <template v-if="item.type === 'select' && item.code === 'alarm-rule'">
                        <el-select v-model.trim="scope.row[item.value]" placeholder="报警规则" style="width: 100%;"
                          clearable filterable :disabled="!scope.row.edit"
                          @change="() => { changeAlarmType(scope.row[item.value], scope.$index,) }">
                          <el-option v-for="item in alarmRuleList" :key="item.id" :label="item.name" :value="item.id" />
                        </el-select>
                      </template>
                      <!-- 报警等级 -->
                      <template v-if="item.type === 'select' && item.code === 'alarm-level'">
                        <el-select v-model.trim="scope.row[item.value]" placeholder="报警等级" style="width: 100%;"
                          clearable filterable :disabled="!scope.row.edit">
                          <el-option v-for="item in alarmLevelList" :key="item.id" :label="item.name"
                            :value="item.value" />
                        </el-select>
                      </template>
                      <!-- 报警阈值 -->
                      <div v-if="item.type === 'input'" style="width: 100%;">
                        <el-input v-model.trim="scope.row[item.value]" placeholder="报警阈值" clearable type="number"
                          style="width: 60%;" :disabled="!scope.row.edit || !scope.row.isConcentration" />
                        <span>%LEL</span>
                      </div>
                    </template>
                  </el-table-column>
                  <el-table-column v-if="dialogStatus === 'create' || dialogStatus === 'edit'" label="操作" width="140"
                    align="center">
                    <template #default="scope">
                      <el-button v-if="scope.row.edit === true" type="primary" link size="small"
                        @click="saveRow(scope)">
                        保存
                      </el-button>
                      <el-button v-if="scope.row.edit === false" type="primary" link size="small"
                        @click="editRow(scope)">
                        编辑
                      </el-button>
                      <el-button v-if="scope.row.edit === true" type="danger" link size="small"
                        @click="removeRow(scope)">
                        删除
                      </el-button>
                    </template>
                  </el-table-column>
                </template>
              </normal-table>
            </table-container>
          </div>
        </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%;
}

.table-custom-edit {
  ::v-deep(.table-container) {
    margin-top: 0;
    padding: 0;
    padding-left: 38px;
  }
}
</style>