<template>
  <el-form ref="formRef" v-loading="formLoading" :model="formData" label-width="80px">
    <el-form-item label="权限范围">
      <el-select v-model="formData.dataScope">
        <el-option
          v-for="item in dataScopeOptions"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
    </el-form-item>
    <el-form-item
      v-if="formData.dataScope === SystemDataScopeEnum.DEPT_CUSTOM"
      label="权限范围"
      style="display: flex"
    >
      <el-card class="card" shadow="never">
        <template #header>
          全选/全不选:
          <el-switch
            v-model="treeNodeAll"
            active-text="是"
            inactive-text="否"
            inline-prompt
            @change="handleCheckedTreeNodeAll()"
          />
          全部展开/折叠:
          <el-switch
            v-model="deptExpand"
            active-text="展开"
            inactive-text="折叠"
            inline-prompt
            @change="handleCheckedTreeExpand"
          />
          父子联动(选中父节点，自动选择子节点):
          <el-switch v-model="checkStrictly" active-text="是" inactive-text="否" inline-prompt />
        </template>
        <el-tree
          ref="treeRef"
          :check-strictly="!checkStrictly"
          :data="deptOptions"
          :props="defaultProps"
          default-expand-all
          empty-text="加载中，请稍后"
          node-key="id"
          show-checkbox
        />
      </el-card>
    </el-form-item>
    <el-form-item label-width="0">
      <el-button
        :disabled="formLoading"
        type="primary"
        @click="submitForm"
        v-hasPermi="['basic:role:update-data']"
        >保存权限</el-button
      >
    </el-form-item>
  </el-form>
</template>
<script lang="ts" name="RoleDataPermissionForm" setup>
import { defaultProps, handleTree } from '@/utils/tree'
import { SystemDataScopeEnum } from '@/utils/constants'

import * as DeptApi from '@/api/system/dept'
import * as PermissionApi from '@/api/system/permission'
import * as RoleApi from '@/api/system/role'

const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗

const props = defineProps({
  roleId: {
    type: Number
  }
})

watch(
  () => props.roleId,
  (newValue) => {
    getRoleInfo(newValue)
  }
)

const formLoading = ref(false) // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
const formData = ref({
  id: 0,
  name: '',
  dataScope: undefined,
  dataScopeDeptIds: []
})
const formRef = ref() // 表单 Ref
const deptOptions = ref<any[]>([]) // 部门树形结构
const deptExpand = ref(false) // 展开/折叠
const treeRef = ref() // 菜单树组件 Ref
const treeNodeAll = ref(false) // 全选/全不选
const checkStrictly = ref(true) // 是否严格模式，即父子不关联

// const dataScopeOptions = getIntDictOptions(DICT_TYPE.SYSTEM_DATA_SCOPE)
const dataScopeOptions = [
  { label: '全部数据权限', value: 1 },
  { label: '指定部门数据权限', value: 2 },
  { label: '部门数据权限', value: 3 },
  { label: '部门及以下数据权限', value: 4 },
  { label: '仅本人数据权限', value: 5 }
]

async function getRoleInfo(id) {
  formData.value = await RoleApi.getRole(id)
}

/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件，用于操作成功后的回调
const submitForm = async () => {
  formLoading.value = true
  try {
    const data = {
      roleId: formData.value.id,
      dataScope: formData.value.dataScope,
      dataScopeDeptIds:
        formData.value.dataScope !== SystemDataScopeEnum.DEPT_CUSTOM
          ? []
          : treeRef.value.getCheckedKeys(false)
    }
    await PermissionApi.assignRoleDataScope(data)
    message.success(t('common.updateSuccess'))
    // 发送操作成功的事件
    emit('success')
  } finally {
    formLoading.value = false
  }
}

/** 全选/全不选 */
const handleCheckedTreeNodeAll = () => {
  treeRef.value.setCheckedNodes(treeNodeAll.value ? deptOptions.value : [])
}

/** 展开/折叠全部 */
const handleCheckedTreeExpand = () => {
  const nodes = treeRef.value?.store.nodesMap
  for (let node in nodes) {
    if (nodes[node].expanded === deptExpand.value) {
      continue
    }
    nodes[node].expanded = deptExpand.value
  }
}

async function init() {
  getRoleInfo(props.roleId)
  deptOptions.value = handleTree(await DeptApi.getSimpleDeptList())
}

onMounted(() => {
  init()
})
</script>
