Newer
Older
safe_production_front / src / views / ycjg / fzsq / edit.vue
wangxitong on 16 Aug 10 KB first commit
<script lang="ts" setup name="edit">
import type { Ref } from 'vue'
import { nextTick, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox, ElTree } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import { addGroup, editGroup, personTree, videoTree } from '@/api/ycjg/aqbb'
import { getDictByCode } from '@/api/system/dict'

// ----------------------- 以下是字段定义 emits props ---------------------
const emits = defineEmits(['closeRefresh'])
const treeRef = ref<InstanceType<typeof ElTree>>()
const treePersonRef = ref<InstanceType<typeof ElTree>>()
const data: any = ref([])
const dataPerson: any = ref([])

const defaultProps = ref({
  children: 'children',
  label: 'name',
  isDisabled: 'disabled',
})

// 对话框类型
const dialogStatus = ref('create')
const dialogVisible = ref(false)

// 显示标题
const textMap: { [key: string]: string } = {
  update: '编辑分组',
  create: '新增分组',
  detail: '分组详情',
}
// 表单数据对象
const formData: Ref<any> = ref({
  id: '',
  groupName: '',
  description: '',
  safe: '',
  cameraIds: '',
  personIds: '',
})
const filterCamera = ref('')
const filterPerson = ref('')

watch(filterCamera, (val) => {
  treeRef.value!.filter(val)
})

watch(filterPerson, (val) => {
  treePersonRef.value!.filter(val)
})

function filterNode(value: any, data: { name: string | any[] }) {
  if (value === '' || value === null) {
    return true
  }
  return data.name.includes(value)
}

const safeList = ref<any[]>([])

// 保存按钮加载状态
const btnLoading = ref(false)

// ---------------表单提交--------------------------------
// 表单对象
const dataFormRef = ref<FormInstance>()
// 校验规则
const rules = reactive<FormRules>({
  groupName: [{ required: true, message: '分组名称不可为空', trigger: ['blur', 'change'] }],
  // cameraIds: [{ required: true, message: '请选择授权相机', trigger: ['blur', 'change'] }],
  // safe: [{ required: true, message: '请选择密级', trigger: ['blur', 'change'] }],
})

function submitForm() {
  const checkedNodes = treeRef.value!.getCheckedNodes()
  const arr = checkedNodes.filter((item: any) => item.device !== '').map((item: any) => {
    return item.id
  })
  if (arr.length === 0) {
    ElMessage.warning('请选择授权相机')
    return
  }
  const checkedNodesPerson = treePersonRef.value!.getCheckedNodes()
  const arrPerson = checkedNodesPerson.filter((item: any) => item.device !== '').map((item: any) => {
    return item.id
  })
  if (arrPerson.length === 0) {
    ElMessage.warning('请选择授权人员')
    return
  }

  const params = {
    id: formData.value.id,
    groupName: formData.value.groupName,
    description: formData.value.description,
    safe: formData.value.safe,
    cameraIds: arr.toString(),
    personIds: arrPerson.toString(),
  }

  if (dataFormRef.value) {
    dataFormRef.value?.validate((valid: boolean) => {
      if (valid) {
        if (dialogStatus.value === 'create') {
          btnLoading.value = true
          addGroup(params).then((res) => {
            if (res.code === 200) {
              ElMessage.success('创建成功')
              closeRefresh()
              btnLoading.value = false
            }
          }).catch((_) => {
            btnLoading.value = false
          })
        }
        else if (dialogStatus.value === 'update') {
          btnLoading.value = true
          editGroup(params).then((res) => {
            if (res.code === 200) {
              ElMessage.success('修改成功')
              closeRefresh()
              btnLoading.value = false
            }
          }).catch((_) => { // 异常情况,loading置为false
            btnLoading.value = false
          })
        }
      }
    })
  }
}

// 重置表单
function resetForm() {
  formData.value = {
    id: '',
    groupName: '',
    description: '',
    safe: '',
    cameraIds: '',
    personIds: '',
  }
  console.log('resetForm')
  nextTick(() => {
    dataFormRef.value?.clearValidate()
  })
}

function traverseArray(arr: [], disabled: any) {
  arr.forEach((item: any) => {
    item.disabled = disabled
    if (item.children.length !== 0) {
      traverseArray(item.children, disabled)
    }
  })
  return arr
}

// ----------初始化、关闭对话框相关-----------------
function initDialog(dialogstatus: string, row: any) {
  dialogStatus.value = dialogstatus
  dialogVisible.value = true
  btnLoading.value = false
  // 获取权属
  if (dialogstatus === 'create') {
    resetForm()
    nextTick(() => {
      dataFormRef.value?.clearValidate()
    })
    data.value = traverseArray(data.value, false)
    dataPerson.value = traverseArray(dataPerson.value, false)
  }
  else if (dialogstatus === 'update') {
    setTimeout(() => {
      dataFormRef.value?.clearValidate()
    }, 1000)
    const cameras = row.cameraIds.split(',')
    const arr = row.cameraIds.split(',').filter((item: any) => cameras.includes(item))
    const personArr = row.personIds.split(',')
    formData.value = {
      id: row.id,
      groupName: row.groupName,
      description: row.description,
      safe: row.safe.toString(),
      cameraIds: arr,
      personIds: personArr,
    }
    data.value = traverseArray(data.value, false)
    dataPerson.value = traverseArray(dataPerson.value, false)
  }
  else {
    setTimeout(() => {
      dataFormRef.value?.clearValidate()
    }, 1000)
    const cameras = row.cameraIds.split(',')
    const arr = row.cameraIds.split(',').filter((item: any) => cameras.includes(item))
    const personArr = row.personIds.split(',')
    formData.value = {
      id: row.id,
      groupName: row.groupName,
      description: row.description,
      safe: row.safe.toString(),
      cameraIds: arr,
      personIds: personArr,
    }
    data.value = traverseArray(data.value, true)
    dataPerson.value = traverseArray(dataPerson.value, false)
  }
}

// 关闭并刷新
function closeRefresh() {
  dialogVisible.value = false
  resetForm()
  emits('closeRefresh')
}

// 关闭弹窗
function dialogClose() {
  dialogVisible.value = false
  resetForm()
}

onMounted(() => {
  getDictByCode('secretLevel').then((response) => {
    if (response.code === 200) {
      safeList.value = response.data
    }
  })
  videoTree().then((response) => {
    if (response.code === 200) {
      data.value = response.data
    }
  })
  personTree().then((response) => {
    if (response.code === 200) {
      dataPerson.value = response.data
    }
  })
})

// ----------------------- 以下是暴露的方法内容 ----------------------------
defineExpose({ initDialog })
</script>

<template>
  <el-dialog
    v-model="dialogVisible"
    :title="textMap[dialogStatus]"
    width="700"
    :before-close="dialogClose"
    append-to-body
    :open-delay="0"
    :close-on-click-modal="false"
  >
    <el-form
      ref="dataFormRef" :model="formData" :rules="rules" label-position="right" label-width="80px" class="form-container"
      size="default" @submit.prevent
    >
      <el-row :gutter="10">
        <el-col :span="24" class="grid-cell">
          <el-form-item label="分组名称" prop="groupName" class="required">
            <el-input v-model="formData.groupName" :disabled="dialogStatus === 'detail'" type="text" placeholder="必填" clearable />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="10">
        <el-col :span="12" class="grid-cell">
          <span style="color: red">*</span>
          <el-form-item label="授权相机" class="required" style="margin-top: -25px">
            <el-input v-model="filterCamera" placeholder="授权相机过滤" />
            <el-tree
              ref="treeRef"
              v-if="dialogVisible"
              :disabled="dialogStatus === 'detail'"
              style="max-height: 200px;overflow-y: scroll;width: 100%;"
              :data="data"
              show-checkbox
              node-key="id"
              accordion
              :default-expand-all="false"
              :default-checked-keys="formData.cameraIds"
              :filter-node-method="filterNode"
              :props="defaultProps"/>
          </el-form-item>
        </el-col>
        <el-col :span="12" class="grid-cell">
          <span style="color: red">*</span>
          <el-form-item label="授权人员" class="required" style="margin-top: -25px">
            <el-input v-model="filterPerson" placeholder="授权人员过滤" />
            <el-tree
              ref="treePersonRef"
              v-if="dialogVisible"
              :disabled="dialogStatus === 'detail'"
              style="max-height: 200px;overflow-y: scroll;width: 100%;"
              :data="dataPerson"
              show-checkbox
              node-key="id"
              accordion
              :default-expand-all="false"
              :default-checked-keys="formData.personIds"
              :filter-node-method="filterNode"
              :props="defaultProps"/>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="10">
        <el-col :span="24" class="grid-cell">
          <el-form-item label="分组描述" class="required">
            <el-input v-model="formData.description" :disabled="dialogStatus === 'detail'" type="text" placeholder="分组描述" clearable />
          </el-form-item>
        </el-col>
      </el-row>
<!--      <el-row :gutter="10">-->
<!--        <el-col :span="24" class="grid-cell">-->
<!--          <el-form-item label="密 级" class="required">-->
<!--            <el-select v-model="formData.safe" :disabled="dialogStatus === 'detail'" placeholder="必选" style="width: 100%">-->
<!--              <el-option-->
<!--                v-for="item in safeList"-->
<!--                :key="item.value"-->
<!--                :label="item.name"-->
<!--                :value="item.value"-->
<!--              />-->
<!--            </el-select>-->
<!--          </el-form-item>-->
<!--        </el-col>-->
<!--      </el-row>-->
    </el-form>
    <template #footer>
      <div class="dialog-footer" v-show="dialogStatus !== 'detail'">
        <el-button :loading="btnLoading" type="primary" @click="submitForm">
          保存
        </el-button>
        <el-button @click="dialogClose">
          取消
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.form-container {
  width: 100%;

  .full-width-input {
    width: 100%;
  }
}
</style>