<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>