<template>
  <div class="system-role-container layout-padding">
    <div class="system-role-padding layout-padding-auto layout-padding-view">
      <div class="system-user-search mb15">
        <el-input v-model="state.formQuery.roleName"  clearable size="default"
                  placeholder="请输入角色名称" style="max-width: 180px"></el-input>

        <ext-button icon="ele-Search" type="success" plain class="ml10" @click="loadData"  name="查询"/>
        <!--        <el-button size="default" type="primary" class="ml10">-->
        <!--          <el-icon>-->
        <!--            <ele-Search/>-->
        <!--          </el-icon>-->
        <!--          查询-->
        <!--        </el-button>-->
        <el-button v-auth="'role.add'"  size="default" type="success" class="ml10" @click="handleOpenDialog(0,false)">
          <el-icon>
            <ele-FolderAdd/>
          </el-icon>
          新增角色
        </el-button>
        <el-button v-auth="'role.modify'"   v-if="state.changed" size="default" type="success" class="ml10" @click="handleSaveRolePermission">
          <SvgIcon name="ele-Printer"/>
          保存设置
        </el-button>
      </div>
      <el-table
          ref="tableRef"
          :data="state.tableData.data"
          v-loading="state.tableData.loading"
          border
          row-key="id"
          :tree-props="{children:'children'}"
          @cell-click="handleToggleRoleCheck"
          style="width: 100%">
        <template #empty>
          <el-empty></el-empty>
        </template>
        <el-table-column
            v-for="(col,idx) in state.columns"
            :key="col.prop"
            :label="col.label"
            :width="col.width"
            :min-width="col.minWidth"
            show-overflow-tooltip
            :fixed="col.fixed"
            :align="col.prop==='permName'?'left':'center'">
          <template #header>
            <template v-if="idx>0">
              <div class="role-header-item">{{ col.label }}
                <SvgIcon v-if="!state.immutableRoleList.includes(col.prop)" name="ele-Setting"
                         @click="handleOpenDialog(col.prop.split('_')[1],false)"/>
              </div>
            </template>
            <template v-if="idx===0">
              权限
              <span style="cursor: pointer;font-size: 12px;margin-left: 8px;color:#ccc" @click="handleExpandSwitch">{{state.expandAll?'收起':'展开'}} </span>
            </template>
          </template>
          <template #default="scope">
            <template v-if="scope.column.label!=='权限'">
              <el-icon color="#5FB878" v-if="scope.row[col.prop]">
                <CircleCheckFilled/>
              </el-icon>
              <span v-else>
                  <SvgIcon name="ele-CircleCheck"></SvgIcon>
                </span>
            </template>
            <template v-else ><span :title="scope.row.perm">{{ scope.row[col.prop] }}</span></template>
          </template>
        </el-table-column>
      </el-table>
    </div>


    <RoleDialog ref="roleDialogRef" @refresh="loadData()"/>
  </div>
</template>

<script setup lang="ts" name="orgRole">
import {defineAsyncComponent, reactive, onMounted, ref,nextTick} from 'vue';
import {$body, $get} from "/@/utils/request";
import u from "/@/utils/u";
import {Msg} from "/@/utils/message";
import {CircleCheckFilled} from '@element-plus/icons-vue'
import ExtButton from "/@/components/form/ExtButton.vue";

// 引入组件
const RoleDialog = defineAsyncComponent(() => import('/@/views/admin/role/dialog.vue'));

const tableRef = ref();
// 定义变量内容
const roleDialogRef = ref();
const state = reactive({
  tableData: {
    data: [] as Array<any>,
    loading: false,
  },
  pageQuery: {
    pageNum: 1,
    pageSize: 20,
  },
  formQuery: {
    roleName: null,
  },
  columns: [{label: '权限', prop: 'permName', width: 200, fixed: 'left'}] as Array<IBaseField>,
  expandAll: false,
  immutableRoleList: [] as Array<string>,
  changed : false
});

const handleExpandSwitch = ()=>{
  state.expandAll = !state.expandAll;
  nextTick(()=>{
    state.tableData.data.forEach(row=>{
      tableRef.value.toggleRowExpansion(row,state.expandAll);
    })
  })
}

const loadPermissionList = (roleList: Array<any>) => {
  $get(`/permission/listPermission`, {pageSize: -1}).then((res: any) => {
    //构造权限数组
    let data = [] as Array<any>;
    var permMap = u.groupByKey(res, "pid");
    //console.log(permMap)
    let roleMap = new Map();
    state.immutableRoleList = [] as Array<string>;
    roleList.forEach(role => {
      state.columns.push({
        label: role.roleName,
        prop: 'role_' + role.id,
        width: (role.roleName).length * 60 + 45,
      });
      roleMap.set(role.id, role)
    });
    //console.log(state.columns)
    let topPermissionList = permMap['0']
    if (u.isEmptyOrNull(topPermissionList)) {
      Msg.message("没有权限数据", 'error')
      state.tableData.loading = false;
      return;
    }

    topPermissionList.forEach((top: any) => {
      let {id, name, value} = top;
      let childrenPermissionList = permMap[id.toString()];
      let record = {
        children: [] as Array<any>,
        permName: name,
        id: id,
        perm: value,
        // hasChildren: !u.isEmptyOrNull(childrenPermissionList)
      } as any;
      roleList.forEach(role => {
        let permArr = role.permissions ? role.permissions.split("|") : [];
        record['role_' + role.id] = permArr.includes(value);
      })

      let children = [] as Array<any>;
      if (!u.isEmptyOrNull(childrenPermissionList)) {
        childrenPermissionList.forEach((child: any) => {
          let childRecord = {
            permName: child.name,
            id: child.id,
            perm: child.value,
          } as any;
          roleList.forEach(role => {
            let permArr = role.permissions ? role.permissions.split("|") : [];
            childRecord['role_' + role.id] = permArr.includes(child.value);
          })
          children.push(childRecord);
        });
        //
        record.children = children;
      }
      data.push(record);
    })


    state.tableData.data = data;
    //console.log(state.tableData.data)
    state.tableData.loading = false;
  }).catch(e => {
    ////console.log(e)
    state.tableData.loading = false;
  })
}
// 初始化表格数据
const loadData = () => {
  state.columns = [{label: '权限', prop: 'permName', width: 120, fixed: 'left'}];
  state.tableData.data = [];
  state.tableData.loading = true;
  $get(`/role/list`, {...state.formQuery}).then((res: any) => {
    //构造权限数组
    loadPermissionList(res);
  }).catch(e => {
    //console.error(e)
    state.tableData.loading = false;
  })
};
// 打开新增角色弹窗
const handleOpenDialog = (id: number, readonly: boolean) => {
  roleDialogRef.value.openDialog(id, readonly);
};

const handleToggleRoleCheck = (row, column, cell, event) => {
  state.changed = true;
  //console.log(row, column, cell)
  if(column.rawColumnKey==='permName'){
    // tableRef.value
    return;
  }

  let index = state.tableData.data.findIndex(k => k.id === row.id);
  if (index >= 0) {
    let record = state.tableData.data[index];
    ////console.log(record)
    let bol = !record[column.rawColumnKey];
    state.tableData.data[index][column.rawColumnKey] = bol;
    if (!u.isEmptyOrNull(record.children)) {
      record.children.forEach((r:any)=>{
        r[column.rawColumnKey]= bol;
      })
    }
  } else {
    state.tableData.data.forEach(record => {
      if (!u.isEmptyOrNull(record.children)) {
        let r = record.children.find((k: any) => k.id === row.id);
        if (r) {
          r[column.rawColumnKey] = !r[column.rawColumnKey]
          return;
        }
      }
    })
  }
}


const handleSaveRolePermission = () => {
  let updateRoles = [] as Array<any>;
  let map = new Map();

  // 从 columns 定义获取角色列名，避免 Object.keys 采集到 Vue/ElementPlus 注入的脏属性
  let roleColumns = state.columns
      .filter(col => col.prop && col.prop.startsWith("role_"))
      .map(col => col.prop);

  state.tableData.data.forEach(record => {
    roleColumns.forEach((k: string) => {
      if (record[k]) {
        let roleId = k.split("_")[1];
        let perms = map.get(roleId);
        if (!perms) {
          map.set(roleId, [record.perm]);
        } else {
          perms.push(record.perm);
        }
      }
      if (!u.isEmptyOrNull(record.children)) {
        record.children.forEach((child: any) => {
          if (child[k]) {
            let roleId = k.split("_")[1];
            let perms = map.get(roleId);
            if (!perms) {
              map.set(roleId, [child.perm]);
            } else {
              perms.push(child.perm);
            }
          }
        });
      }
    });
  });

  ////console.log(map)
  map.forEach((value: Array<string>, key: any) => {
    updateRoles.push({
      id: key,
      permissions: value.join("|")
    });
  })

  $body(`/role/saveList`,updateRoles).then(()=>{
    Msg.message("更新成功","success");
    state.changed = false;
    nextTick(()=>{
      loadData();
    })
  }).catch(() => {
    Msg.message("保存失败，请稍后重试", "error");
  })
}

// 页面加载时
onMounted(() => {
  loadData();
});
</script>

<style scoped lang="scss">
.role-header-item {
  display: inline-flex;
  justify-content: space-around;
  align-items: center;

  i {
    margin-left: 3px;
    cursor: pointer;
  }
}

.permission-box {
}

.system-role-container {
  .system-role-padding {
    padding: 15px;

    .el-table {
      flex: 1;
    }
  }
}

:deep(.el-table thead th.el-table__cell ) {
  background: var(--el-fill-color-light);
}
</style>
