<!--
 * @Author: xiejiang
 * @Date: 2024-12-05 17:16:22
 * @LastEditors: xiejiang
 * @LastEditTime: 2024-12-06 15:17:15
 * @Description: 功能权限
 * Copyright（c）2024 by 好老师教育科技有限公司 All right Reserved.
-->
<template>
  <div class="p-[16px] capabilities" v-loading="loading">
    <t-collapse :borderless="true" default-expand-all :expand-on-row-click="false">
      <t-collapse-panel
        v-for="(item, index) in menuTree"
        :key="item.menuId"
        :class="index === 0 ? 'magrin-bottom' : ''"
      >
        <template #expandIcon><CaretDownSmallIcon class="text-[var(--td-brand-color)]" /></template>
        <template #header>
          <t-checkbox v-model="item.selected" @change="handleSelectAll(item)">{{ item.menuName }}</t-checkbox>
        </template>
        <div v-for="itx in item.children || []" :key="itx.menuId" class="flex">
          <div class="page-auth">
            <t-checkbox v-model="itx.selected" :label="itx.menuName" @change="handleSelectAll(itx)" />
          </div>
          <div class="page-btn">
            <t-checkbox
              :value="it.menuId"
              :label="it.menuName"
              v-for="it in itx.children || []"
              :key="it.menuId"
              v-model="it.selected"
              @change="handleSelectAll(it)"
              class="mr-[20px] my-[7px]"
            />
          </div>
        </div>
      </t-collapse-panel>
    </t-collapse>
  </div>
</template>

<script setup lang="ts" name="capabilities">
import { MessagePlugin } from 'tdesign-vue-next'
import { ResMenuTree } from '@/api/interface/menu/index'
import { getMenuTree, postSaveMenu } from '@/api/modules/menu/index'
const props = defineProps({
  roleId: {
    type: String,
    default: ''
  },
  condMenuName: {
    type: String,
    default: ''
  }
})

watch([toRef(props, 'roleId')], () => {
  try {
    getData()
  } catch {
    MessagePlugin.error('获取菜单树失败')
  }
})

const loading = ref(false)
const menuTree = ref<ResMenuTree[]>([])
// 勾选
function findNodeById(tree: ResMenuTree[], id: number) {
  tree.forEach(it => {
    if (it.menuId == id) {
      it.selected = true
    } else if (it.children) {
      it.children.forEach((v: ResMenuTree) => {
        if (v.menuId == id) {
          it.selected = true
          v.selected = true
        }
      })
    }
  })
}

const handleSelectAll = (itx: ResMenuTree) => {
  // 勾选则需要勾选父级
  if (itx.selected) {
    if (itx.parentId) {
      findNodeById(menuTree.value, itx.parentId as number)
    }
  } else {
    // 取消后面所有子集
    if (itx.children) {
      itx.children.forEach((v: ResMenuTree) => {
        v.selected = itx.selected
        if (v.children) {
          v.children.forEach((val: ResMenuTree) => {
            val.selected = itx.selected
          })
        }
      })
    }
  }
}

// 清空
const clear = () => {
  menuTree.value.forEach(it => {
    it.selected = false
    if (it.children) {
      it.children.forEach((v: ResMenuTree) => {
        v.selected = false
        if (v.children) {
          v.children.forEach((val: ResMenuTree) => {
            val.selected = false
          })
        }
      })
    }
  })
}

const getData = () => {
  loading.value = true
  getMenuTree({ roleId: props.roleId, condMenuName: props.condMenuName })
    .then(res => {
      if (Array.isArray(res.data)) {
        // 检查 res.data 是否为数组
        menuTree.value = res.data as ResMenuTree[]
      } else {
        menuTree.value = [] // 如果不是数组，设置为空数组
      }
    })
    .finally(() => {
      loading.value = false
    })
}

const submit = () => {
  emit('loading', true)
  postSaveMenu({ roleId: props.roleId, menus: menuTree.value })
    .then(() => {
      getData()
      MessagePlugin.success('保存成功')
    })
    .finally(() => {
      emit('loading', false)
    })
}

const emit = defineEmits(['loading'])

defineExpose({
  submit,
  clear,
  getData
})
</script>

<style lang="less" scoped>
.capabilities {
  padding: auto;

  .page-auth {
    border: 1px solid var(--td-border);
    padding: 10px 16px;
    min-width: 138px;
    margin-top: -1px;
    display: flex;
    align-items: center;
  }

  .page-btn {
    border: 1px solid var(--td-border);
    border-left: none;
    margin-top: -1px;
    padding: 7px 9px;
    flex: 1;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
  }

  :deep(.t-collapse-panel) {
    .t-collapse-panel__header {
      padding: 8px;
      margin-top: -1px;
      background: var(--td-brand-color-12);
      border: 1px solid var(--td-border);
    }

    .t-collapse-panel__content {
      padding: 0;
    }
  }

  .magrin-bottom {
    :deep(.t-collapse-panel__header) {
      margin: 0 !important;
    }
  }
}
</style>
