<!-- 系统权限 -->
<template>
  <div class="gl-page-content-full">
    <div class="content">
      <DragSplit :leftContentWidth="400">
        <template #left>
          <div class="box-content">
            <div class="role-list">
              <div
                class="item"
                v-for="item in roleList"
                :key="item.roleId"
                :class="activeRole.roleId === item.roleId ? 'active' : ''"
                @click="selectRoleFun(item)"
              >
                <div class="title">
                  <el-icon><User /></el-icon>
                  <div class="name">{{ item.roleName }}</div>
                </div>
                <div class="tip">{{ item.description }}</div>
              </div>
            </div>
          </div>
        </template>
        <template #right>
          <div class="box-content">
            <div class="role-name">
              <span class="name">{{ activeRole.roleName }}</span>
              <span>按钮权限设置</span>
              <el-button
                class="btn"
                type="primary"
                :disabled="chosenData.length === 0"
                @click="savePermission"
                >保存</el-button
              >
            </div>
            <div class="btn-list">
              <div v-for="(group, index) in permissionGroups" :key="index" class="permission-group">
                <div class="group-name">
                  <el-checkbox
                    :model-value="isGroupAllChecked(group)"
                    :indeterminate="isGroupIndeterminate(group)"
                    @change="(checked: boolean) => handleGroupCheck(group, checked)"
                  >
                    {{ group.name }}
                  </el-checkbox>
                </div>
                <div class="group-list">
                  <el-checkbox-group v-model="chosenData">
                    <el-checkbox
                      v-for="permission in group.permissions"
                      :key="permission.code"
                      :title="permission.btn"
                      class="item"
                      :label="permission.btn"
                      :value="permission.code"
                    />
                  </el-checkbox-group>
                </div>
              </div>
            </div>
          </div>
        </template>
      </DragSplit>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { User } from '@element-plus/icons-vue';
import DragSplit from '@/components/common/dragSplit/index.vue';
import { roleListRolesApi } from '@/api/system/role';
import { getUserTenantId } from '@/utils/user';
import { permissionGroups } from '@/utils/enum/permission';
import { assignPermissionsApi, getRolePermissionsApi } from '@/api/system/role';
import { getUserPermissionsFun } from '@/utils/common';
import { ElMessage } from 'element-plus';

// 左侧角色列表
const roleList = ref<any>([]);
const getRoleList = async () => {
  const params = {
    tenantId: getUserTenantId(),
    current: 1,
    size: 100,
  };
  const { data } = await roleListRolesApi(params);
  roleList.value = data.data;
  activeRole.value = roleList.value[0];
  getRolePermissionsFun();
};
const activeRole = ref<any>({});
// 切换角色
const selectRoleFun = (item: any) => {
  activeRole.value = item;
  chosenData.value = [];
  getRolePermissionsFun();
};
const getRolePermissionsFun = () => {
  const params = {
    roleId: activeRole.value.roleId,
  };
  getRolePermissionsApi(params).then((res: any) => {
    // 过滤掉不在当前权限组中的脏数据
    const validPermissions = permissionGroups.flatMap((group) =>
      group.permissions.map((p) => p.code)
    );
    chosenData.value = res.data.filter((permission: string) =>
      validPermissions.includes(permission)
    );
  });
};

onMounted(() => {
  getRoleList();
});

// 所有选中的权限
const chosenData = ref<string[]>([]);

const savePermission = () => {
  // 保存权限
  const params = {
    roleId: activeRole.value.roleId,
    permissionCodes: chosenData.value,
  };
  assignPermissionsApi(params).then(() => {
    ElMessage.success('保存成功');
    // 更新用户权限
    getUserPermissionsFun();
  });
};

// #region 多选框的逻辑
// 计算每个权限组是否全选
const isGroupAllChecked = (group: any) => {
  return group.permissions.every((permission: any) => chosenData.value.includes(permission.code));
};
// 计算每个权限组是否半选
const isGroupIndeterminate = (group: any) => {
  const checkedCount = group.permissions.filter((permission: any) =>
    chosenData.value.includes(permission.code)
  ).length;
  return checkedCount > 0 && checkedCount < group.permissions.length;
};
// 处理权限组全选/取消全选
const handleGroupCheck = (group: any, checked: boolean) => {
  if (checked) {
    // 添加该组的所有权限
    chosenData.value = [
      ...new Set([...chosenData.value, ...group.permissions.map((p: any) => p.code)]),
    ];
  } else {
    // 移除该组的所有权限
    chosenData.value = chosenData.value.filter(
      (permission) => !group.permissions.some((p: any) => p.code === permission)
    );
  }
};
// #endregion
</script>

<style lang="scss" scoped>
.content {
  width: 100%;
  height: 100%;
  .box-content {
    width: 100%;
    height: 100%;
    overflow-y: auto;
    .role-list {
      padding: 0 16px 0 0;
      .item {
        padding: 8px;
        padding-top: 12px;
        border-bottom: solid 1px var(--el-border-color-lighter);
        cursor: pointer;
        &:hover {
          background-color: var(--el-fill-color-extra-light);
          // 添加阴影
          box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
        }
        .title {
          display: flex;
          font-size: 16px;
          color: var(--el-text-color-primary);
          margin-bottom: 12px;
          .name {
            margin-left: 8px;
            line-height: 16px;
          }
        }
        .tip {
          font-size: 12px;
          color: var(--el-text-color-secondary);
          opacity: 0.65;
          margin-bottom: 6px;
        }
      }
      .active {
        .title {
          color: var(--el-color-primary);
        }
        .tip {
          color: var(--el-color-primary);
        }
      }
    }
    .role-name {
      height: 40px;
      position: relative;
      font-size: 18px;
      padding: 0 16px;
      margin-bottom: 10px;
      line-height: 32px;
      .name {
        display: inline-block;
        font-weight: bold;
        margin-right: 6px;
      }
      .btn {
        position: absolute;
        top: 0;
        right: 16px;
      }
    }
    .btn-list {
      height: calc(100% - 60px);
      overflow-y: auto;
    }
    .permission-group {
      padding: 0 16px;
      margin-bottom: 20px;
      .group-name {
        line-height: 30px;
        font-weight: bold;
        color: var(--el-text-color-secondary);
        border-bottom: solid 1px var(--el-border-color);
      }
    }
  }
}
</style>

<style lang="scss">
.group-list {
  display: flex;
  flex-wrap: wrap;
  .el-checkbox {
    width: 200px;
    .el-checkbox__label {
      width: calc(100% - 10px);
      overflow: hidden;
      text-overflow: ellipsis;
    }
  }
}
</style>
