<template>
  <div class="app-container">
    <!-- 选项卡组件：增加 custom-tabs 类名 -->
    <el-tabs
        v-model="activeTab"
        type="card"
        @tab-change="handleTabChange"
        class="custom-tabs"
    >
      <!-- 用户权限选项卡 -->
      <el-tab-pane label="用户" name="user" class="tab-pane-content">
        <el-form :model="userQueryParams" ref="userQueryRef" v-show="userShowSearch" :inline="true" label-width="68px">
          <el-form-item label="账号" prop="userName">
            <el-input
                v-model="userQueryParams.userName"
                placeholder="请输入账号"
                clearable
                style="width: 240px"
                @keyup.enter="userHandleQuery"
            />
          </el-form-item>
          <el-form-item label="姓名" prop="realName">
            <el-input
                v-model="userQueryParams.realName"
                placeholder="请输入姓名"
                clearable
                style="width: 240px"
                @keyup.enter="userHandleQuery"
            />
          </el-form-item>
          <el-form-item label="手机号" prop="mobile">
            <el-input
                v-model="userQueryParams.mobile"
                placeholder="请输入手机号"
                clearable
                style="width: 240px"
                @keyup.enter="userHandleQuery"
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="Search" @click="userHandleQuery">搜索</el-button>
            <el-button icon="Refresh" @click="userResetQuery">重置</el-button>
            <el-button type="info" plain icon="Upload" @click="handleImportProjectUserList">导入</el-button>
          </el-form-item>
        </el-form>
        <!-- 表格数据 -->
        <el-table v-loading="userLoading" :data="projectUserList">
          <el-table-column label="账号" prop="userName" />
          <el-table-column label="姓名" prop="realName" />
          <el-table-column label="昵称" prop="nickName" />
          <el-table-column label="邮箱" prop="email" />
          <el-table-column label="手机号" prop="mobile" />
          <el-table-column prop="gender" label="性别">
            <template #default="scope">
              <dict-tag :options="sys_gender" :value="scope.row.gender" />
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="160px">
            <template #default="scope">
              <el-button link type="primary" icon="Edit" @click="openAssignRoleDialog(scope.row)" >分配角色</el-button>
              <el-button link type="primary" icon="Delete" @click="userHandleDelete(scope.row)" >删除</el-button>
            </template>
          </el-table-column>
        </el-table>

        <pagination
            v-show="userTotal > 0"
            :total="userTotal"
            v-model:page="userQueryParams.pageNum"
            v-model:limit="userQueryParams.pageSize"
            @pagination="getUserList"
        />

        <!-- 用户导入（根据权限从用户池导入进来） -->
        <el-dialog :title="importUserTitle" v-model="importProjectUserListOpen" width="800px" append-to-body>
          <el-form :model="importProjectUserListQueryParams" ref="importProjectUserListQueryRef" v-show="importProjectUserListShowSearch" :inline="true" label-width="55px">
            <el-form-item label="账号" prop="userName">
              <el-input
                  v-model="importProjectUserListQueryParams.userName"
                  placeholder="请输入账号"
                  clearable
                  style="width: 240px"
                  @keyup.enter="importProjectUserListHandleQuery"
              />
            </el-form-item>
            <el-form-item label="姓名" prop="realName">
              <el-input
                  v-model="importProjectUserListQueryParams.realName"
                  placeholder="请输入姓名"
                  clearable
                  style="width: 240px"
                  @keyup.enter="importProjectUserListHandleQuery"
              />
            </el-form-item>
            <el-form-item label="手机号" prop="mobile">
              <el-input
                  v-model="importProjectUserListQueryParams.mobile"
                  placeholder="请输入手机号"
                  clearable
                  style="width: 240px"
                  @keyup.enter="importProjectUserListHandleQuery"
              />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="importProjectUserListHandleQuery">搜索</el-button>
              <el-button icon="Refresh" @click="importProjectUserListResetQuery">重置</el-button>
            </el-form-item>
          </el-form>
          <!-- 表格数据 -->
          <el-table v-loading="importProjectUserListLoading" :data="importProjectUserList" @selection-change="importProjectUserListHandleSelectionChange">
            <el-table-column type="selection" width="55" align="center" />
            <el-table-column label="账号" prop="userName" />
            <el-table-column label="姓名" prop="realName" />
            <el-table-column label="昵称" prop="nickName" />
            <el-table-column label="邮箱" prop="email" />
            <el-table-column label="手机号" prop="mobile" />
            <el-table-column prop="gender" label="性别">
              <template #default="scope">
                <dict-tag :options="sys_gender" :value="scope.row.gender" />
              </template>
            </el-table-column>
          </el-table>
          <pagination
              v-show="importProjectUserListTotal > 0"
              :total="importProjectUserListTotal"
              v-model:page="importProjectUserListQueryParams.pageNum"
              v-model:limit="importProjectUserListQueryParams.pageSize"
              @pagination="getImportProjectUserList"
          />
          <template #footer>
            <div class="dialog-footer">
              <el-button type="primary" @click="importProjectUserListSubmitForm">确 定</el-button>
              <el-button @click="importProjectUserListCancel">取 消</el-button>
            </div>
          </template>
        </el-dialog>

        <!-- 用户分配角色弹窗 -->
        <el-dialog
            :title="assignRoleTitle"
            v-model="assignRoleDialogVisible"
            width="1100px"
            append-to-body
        >
          <!-- 弹窗内容：左侧可选角色 + 中间箭头 + 右侧已选角色 -->
          <div class="assign-role-container">
            <!-- 左侧：可选角色列表（带复选框） -->
            <div class="left-panel">
              <el-form :model="leftQuery" ref="leftQueryRef" :inline="true" label-width="68px" class="search-form">
                <el-form-item label="角色名称">
                  <el-input
                      v-model="leftQuery.roleName"
                      placeholder="请输入角色名称"
                      clearable
                      @keyup.enter="getLeftRoleList"
                  />
                </el-form-item>
                <el-form-item>
                  <el-button type="primary" icon="Search" @click="queryLeftRoleList">搜索</el-button>
                  <el-button icon="Refresh" @click="resetLeftRoleQuery">重置</el-button>
                </el-form-item>
              </el-form>

              <el-table
                  v-loading="leftLoading"
                  :data="leftRoleList"
                  @selection-change="handleLeftSelectionChange"
                  border
              >
                <el-table-column type="selection" align="center" />
                <el-table-column label="角色名称" prop="roleName" />
                <el-table-column prop="roleType" label="角色类型">
                  <template #default="scope">
                    <dict-tag :options="sys_role_type" :value="scope.row.roleType" />
                  </template>
                </el-table-column>
                <el-table-column prop="scope" label="作用域">
                  <template #default="scope">
                    <dict-tag :options="sys_scope" :value="scope.row.scope" />
                  </template>
                </el-table-column>
              </el-table>

              <pagination
                  v-show="leftTotal > 0"
                  :total="leftTotal"
                  v-model:page="leftQuery.pageNo"
                  v-model:limit="leftQuery.pageSize"
                  @pagination="getLeftRoleList"
              />
            </div>

            <!-- 中间：箭头按钮（带提示和高亮） -->
            <div class="center-panel">
              <div class="arrow-buttons-container">
                <!-- 向右箭头：添加到右侧 -->
                <el-tooltip content="添加选中角色到已选列表" placement="top">
                  <el-button
                      icon="ArrowRight"
                      @click="moveToRight"
                      :disabled="leftSelectedRoles.length === 0"
                      class="arrow-btn"
                  />
                </el-tooltip>

                <!-- 向左箭头：移除到左侧 -->
                <el-tooltip content="移除选中角色到可选列表" placement="top">
                  <el-button
                      icon="ArrowLeft"
                      @click="moveToLeft"
                      :disabled="rightSelectedRoles.length === 0"
                      class="arrow-btn"
                  />
                </el-tooltip>
              </div>
            </div>

            <!-- 右侧：已选角色列表（带复选框） -->
            <div class="right-panel">
              <div class="selected-title">已选角色（{{ rightRoleList.length }}个）</div>

              <el-form :model="rightQuery" ref="rightQueryRef" :inline="true" label-width="68px" class="search-form">
                <el-form-item label="角色名称">
                  <el-input
                      v-model="rightQuery.roleName"
                      placeholder="请输入角色名称"
                      clearable
                      @keyup.enter="getRightRoleList"
                  />
                </el-form-item>
                <el-form-item>
                  <el-button type="primary" icon="Search" @click="queryRightRoleList">搜索</el-button>
                  <el-button icon="Refresh" @click="resetRightRoleQuery">重置</el-button>
                </el-form-item>
              </el-form>

              <el-table
                  v-loading="rightLoading"
                  :data="rightRoleList"
                  @selection-change="handleRightSelectionChange"
                  border
              >
                <el-table-column type="selection" align="center" />
                <el-table-column label="角色名称" prop="roleName" />
                <el-table-column prop="roleType" label="角色类型">
                  <template #default="scope">
                    <dict-tag :options="sys_role_type" :value="scope.row.roleType" />
                  </template>
                </el-table-column>
                <el-table-column prop="scope" label="作用域">
                  <template #default="scope">
                    <dict-tag :options="sys_scope" :value="scope.row.scope" />
                  </template>
                </el-table-column>
              </el-table>

              <pagination
                  v-show="rightTotal > 0"
                  :total="rightTotal"
                  v-model:page="rightQuery.pageNo"
                  v-model:limit="rightQuery.pageSize"
                  @pagination="getRightRoleList"
              />
            </div>
          </div>

          <!-- 底部统一保存按钮 -->
          <template #footer>
            <div class="dialog-footer">
              <!--              <el-button type="primary" @click="saveAllRoles">确 定</el-button>-->
              <el-button @click="cancelAssignRole">取 消</el-button>
            </div>
          </template>
        </el-dialog>
      </el-tab-pane>
      <!-- 角色权限选项卡 -->
      <el-tab-pane label="角色" name="role" class="tab-pane-content">
        <el-form :model="roleQueryParams" ref="roleQueryRef" v-show="roleShowSearch" :inline="true" label-width="68px">
          <el-form-item label="角色名称" prop="roleName">
            <el-input
                v-model="roleQueryParams.roleName"
                placeholder="请输入角色名称"
                clearable
                style="width: 240px"
                @keyup.enter="roleHandleQuery"
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="Search" @click="roleHandleQuery">搜索</el-button>
            <el-button icon="Refresh" @click="roleResetQuery">重置</el-button>
            <el-button type="info" plain icon="Upload" @click="handleImportProjectRoleList">导入</el-button>
          </el-form-item>
        </el-form>

        <!-- 表格数据 -->
        <el-table v-loading="roleLoading" :data="projectRoleList">
          <el-table-column label="角色名称" prop="roleName" />
          <el-table-column prop="scope" label="作用域">
            <template #default="scope">
              <dict-tag :options="sys_scope" :value="scope.row.scope" />
            </template>
          </el-table-column>
          <el-table-column prop="roleType" label="角色类型">
            <template #default="scope">
              <dict-tag :options="sys_role_type" :value="scope.row.roleType" />
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="160px">
            <template #default="scope">
              <el-button link type="primary" icon="Edit" @click="handleFpMenu(scope.row)" >分配菜单</el-button>
              <el-button link type="primary" icon="Delete" @click="roleHandleDelete(scope.row)" >删除</el-button>
            </template>
          </el-table-column>
        </el-table>

        <pagination
            v-show="roleTotal > 0"
            :total="roleTotal"
            v-model:page="roleQueryParams.pageNum"
            v-model:limit="roleQueryParams.pageSize"
            @pagination="getRoleList"
        />

        <!-- 角色导入（根据权限从角色池导入进来） -->
        <el-dialog :title="importRoleTitle" v-model="importProjectRoleListOpen" width="800px" append-to-body>
          <el-form :model="importProjectRoleListQueryParams" ref="importProjectRoleListQueryRef" v-show="importProjectRoleListShowSearch" :inline="true" label-width="70px">
            <el-form-item label="角色名称" prop="roleName">
              <el-input
                  v-model="importProjectRoleListQueryParams.roleName"
                  placeholder="请输入角色名称"
                  clearable
                  style="width: 240px"
                  @keyup.enter="importProjectRoleListHandleQuery"
              />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="importProjectRoleListHandleQuery">搜索</el-button>
              <el-button icon="Refresh" @click="importProjectRoleListResetQuery">重置</el-button>
            </el-form-item>
          </el-form>
          <!-- 表格数据 -->
          <el-table v-loading="importProjectRoleListLoading" :data="importProjectRoleList" @selection-change="importProjectRoleListHandleSelectionChange">
            <el-table-column type="selection" width="55" align="center" />
            <el-table-column label="角色名称" prop="roleName" />
            <el-table-column prop="scope" label="作用域">
              <template #default="scope">
                <dict-tag :options="sys_scope" :value="scope.row.scope" />
              </template>
            </el-table-column>
            <el-table-column prop="roleType" label="角色类型">
              <template #default="scope">
                <dict-tag :options="sys_role_type" :value="scope.row.roleType" />
              </template>
            </el-table-column>
          </el-table>
          <pagination
              v-show="importProjectRoleListTotal > 0"
              :total="importProjectRoleListTotal"
              v-model:page="importProjectRoleListQueryParams.pageNum"
              v-model:limit="importProjectRoleListQueryParams.pageSize"
              @pagination="getImportProjectRoleList"
          />
          <template #footer>
            <div class="dialog-footer">
              <el-button type="primary" @click="importProjectRoleListSubmitForm">确 定</el-button>
              <el-button @click="importProjectRoleListCancel">取 消</el-button>
            </div>
          </template>
        </el-dialog>

        <!-- 角色配置-分配菜单弹出框 -->
        <el-dialog :title="fpMenuTitle" v-model="fpMenuOpen" width="500px" append-to-body>
          <!-- 权限分配区域 -->
          <div class="permission-section">
            <el-card header="分配菜单" class="mt-4">
              <el-tree
                  ref="fpMenuRef"
                  :data="fpMenuTree"
                  :props="fpMenuProps"
                  node-key="menuBizId"
                  show-checkbox
                  highlight-current
                  :check-strictly="fpMenuIsCheckStrictly"
                  :expand-on-click-node="false"
                  class="permission-tree"
              >
                <template #default="{ node, data }">
                  <span class="custom-tree-node">
                    <span>{{ data.menuName }}</span>
                  </span>
                </template>
              </el-tree>

              <div class="tree-actions mt-4">
                <el-button type="primary" @click="saveFpMenuList">确定</el-button>
              </div>
            </el-card>
          </div>
        </el-dialog>
      </el-tab-pane>
      <!-- 菜单权限选项卡 -->
      <el-tab-pane label="菜单" name="menu" class="tab-pane-content">
        <el-form :model="menuQueryParams" ref="menuQueryRef" v-show="menuShowSearch" :inline="true" label-width="68px">
          <el-form-item label="菜单名称" prop="menuName">
            <el-input
                v-model="menuQueryParams.menuName"
                placeholder="请输入菜单名称"
                clearable
                style="width: 240px"
                @keyup.enter="menuHandleQuery"
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="Search" @click="menuHandleQuery">搜索</el-button>
            <el-button icon="Refresh" @click="menuResetQuery">重置</el-button>
            <el-button type="info" plain icon="Upload" @click="handleImportProjectMenuList">导入</el-button>
          </el-form-item>
        </el-form>

        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button
                type="info"
                plain
                icon="Sort"
                @click="toggleExpandAll"
            >展开/折叠</el-button>
          </el-col>
          <right-toolbar v-model:showSearch="menuShowSearch" @queryTable="getMenuList"></right-toolbar>
        </el-row>

        <el-table
            v-if="refreshTable"
            v-loading="menuLoading"
            :data="menuList"
            row-key="menuBizId"
            :default-expand-all="isExpandAll"
            :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        >
          <el-table-column prop="menuName" label="菜单名称" :show-overflow-tooltip="true"></el-table-column>
          <el-table-column prop="icon" label="图标" align="center">
            <template #default="scope">
              <svg-icon :icon-class="scope.row.icon" />
            </template>
          </el-table-column>
          <el-table-column prop="menuType" label="菜单类型">
            <template #default="scope">
              <dict-tag :options="sys_menu_type" :value="scope.row.menuType" />
            </template>
          </el-table-column>
          <el-table-column prop="scope" label="作用域">
            <template #default="scope">
              <dict-tag :options="sys_scope" :value="scope.row.scope" />
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
            <template #default="scope">
              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-if="scope.row.parentBizId === '0'">删除</el-button>
            </template>
          </el-table-column>
        </el-table>


        <!-- 菜单导入（根据权限从菜单池导入进来） -->
        <el-dialog :title="importMenuTitle" v-model="importProjectMenuListOpen" width="500px" append-to-body>
          <!-- 权限分配区域 -->
          <div class="permission-section">
            <el-card header="导入菜单" class="mt-4">
              <el-tree
                  ref="treeRef"
                  :data="menuTree"
                  :props="defaultProps"
                  node-key="menuBizId"
                  show-checkbox
                  highlight-current
                  :check-strictly="isCheckStrictly"
                  :expand-on-click-node="false"
                  class="permission-tree"
              >
                <template #default="{ node, data }">
                  <span class="custom-tree-node">
                    <span>{{ data.menuName }}</span>
                  </span>
                </template>
              </el-tree>

              <div class="tree-actions mt-4">
                <el-button type="primary" @click="saveImportSelectedMenuList">确定</el-button>
              </div>
            </el-card>
          </div>
        </el-dialog>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script setup name="ProjectPermission">

import {listProjectUser,listImportProjectUser,
  addImportProjectUserList,delRelProjectUser,listProjectRole,
  delRelProjectRole,addImportProjectRoleList,listImportProjectRole,
  listMenu,getMenuTree,getImportSelectedMenuList,addImportProjectMenuList,
  listLeftRole, listRightRole, addRightRoleList,delRightRoleList,
  getFpMenuTree,getSelectedFpMenuList,addFpMenuList} from "@/api/system/projectPermission"

import { ref } from 'vue'

const { proxy } = getCurrentInstance()
const { sys_status,sys_scope,sys_no_yes,sys_user_status,sys_gender,sys_role_type,sys_menu_type } = proxy.useDict("sys_status","sys_scope","sys_no_yes","sys_user_status","sys_gender","sys_role_type","sys_menu_type")

const route = useRoute()
const activeTab = ref('user')
const refreshTable = ref(true)

const projectProjectList = ref([])
const importProjectProjectList = ref([])
const projectUserList = ref([])
const importProjectUserList = ref([])
const projectRoleList = ref([])
const importProjectRoleList = ref([])
const menuList = ref([])
const isExpandAll = ref(false)
const showSearch = ref(true)
const userShowSearch = ref(true)
const importProjectUserListShowSearch = ref(true)
const roleShowSearch = ref(true)
const importProjectRoleListShowSearch = ref(true)
const menuShowSearch = ref(true)
const loading = ref(true)
const importProjectProjectListLoading = ref(true)
const userLoading = ref(true)
const importProjectUserListLoading = ref(true)
const roleLoading = ref(true)
const importProjectRoleListLoading = ref(true)
const menuLoading = ref(true)
const total = ref(0)
const importProjectProjectListTotal = ref(0)
const userTotal = ref(0)
const importProjectUserListTotal = ref(0)
const roleTotal = ref(0)
const importProjectRoleListTotal = ref(0)
const title = ref("")
const importUserTitle = ref("")
const importRoleTitle = ref("")
const importMenuTitle = ref("")
const importProjectProjectListOpen = ref(false)
const importProjectUserListOpen = ref(false)
const importProjectRoleListOpen = ref(false)
const importProjectMenuListOpen = ref(false)
const importProjectProjectListIds = ref([])
const importProjectProjectListNames = ref([])
const importProjectUserListIds = ref([])
const importProjectUserListNames = ref([])
const importProjectRoleListIds = ref([])
const importProjectRoleListNames = ref([])


// 菜单树数据（直接从接口获取树形结构）
const menuTree = ref([])
// 当前项目绑定的选中菜单ID
const checkedKeys = ref([])
// 树组件引用
const treeRef = ref(null)
// 添加响应式变量控制严格模式
const isCheckStrictly = ref(false);  // 默认关闭严格模式（启用联动）
// 树形配置
const defaultProps = {
  children: 'children',
  label: 'menuName'
}

const data = reactive({
  form: {},
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    projectBizId: route.query.projectBizId,
    projectName: undefined
  },
  importProjectProjectListQueryParams: {
    pageNum: 1,
    pageSize: 10,
    projectBizId: route.query.projectBizId,
    projectName: undefined
  },
  userQueryParams: {
    pageNum: 1,
    pageSize: 10,
    projectBizId: route.query.projectBizId,
    userName: undefined,
    realName: undefined,
    mobile: undefined
  },
  importProjectUserListQueryParams: {
    pageNum: 1,
    pageSize: 10,
    projectBizId: route.query.projectBizId,
    userName: undefined,
    realName: undefined,
    mobile: undefined
  },
  roleQueryParams: {
    pageNum: 1,
    pageSize: 10,
    projectBizId: route.query.projectBizId,
    roleName: undefined
  },
  importProjectRoleListQueryParams: {
    pageNum: 1,
    pageSize: 10,
    projectBizId: route.query.projectBizId,
    roleName: undefined
  },
  menuQueryParams: {
    pageNum: 1,
    pageSize: 999999,
    projectBizId: route.query.projectBizId,
    menuName: undefined
  }
})
const { queryParams,importProjectProjectListQueryParams, userQueryParams,
  importProjectUserListQueryParams,roleQueryParams,importProjectRoleListQueryParams,
  menuQueryParams,form, rules } = toRefs(data)


//========用户-列表逻辑开始=========
/** 查询项目用户关系列表 */
function getUserList() {
  userLoading.value = true
  listProjectUser(userQueryParams.value).then(response => {
    projectUserList.value = response.data.records
    userTotal.value = response.data.total
    userLoading.value = false
  })
}
/** 用户列表-搜索 */
function userHandleQuery() {
  userQueryParams.value.pageNum = 1
  getUserList()
}
/** 用户列表-重置按钮操作 */
function userResetQuery() {
  proxy.resetForm("userQueryRef")
  userHandleQuery()
}
/** 删除项目用户关系 */
function userHandleDelete(row) {
  //项目和用户关系表主键id
  const relProjectUserId = row.id
  const userName = row.userName
  proxy.$modal.confirm('是否确认删除用户账号为"' + userName + '"的项目和用户关系的数据项?').then(function () {
    return delRelProjectUser(relProjectUserId)
  }).then(() => {
    getUserList()
    proxy.$modal.msgSuccess("删除成功")
  }).catch(() => {})
}
//========用户-列表逻辑结束=========


//========用户-导入逻辑开始=========
/** 用户列表-导入-查询导入项目用户关系列表 */
function getImportProjectUserList() {
  importProjectUserListLoading.value = true
  listImportProjectUser(importProjectUserListQueryParams.value).then(response => {
    importProjectUserList.value = response.data.records
    importProjectUserListTotal.value = response.data.total
    importProjectUserListLoading.value = false
  })
}
/** 用户列表-导入用户 */
function handleImportProjectUserList() {
  getImportProjectUserList()
  importProjectUserListOpen.value = true
  importUserTitle.value = "导入用户"
}
/** 用户列表-导入-搜索按钮操作 */
function importProjectUserListHandleQuery() {
  importProjectUserListQueryParams.value.pageNum = 1
  getImportProjectUserList()
}
/** 用户列表-导入-重置按钮操作 */
function importProjectUserListResetQuery() {
  proxy.resetForm("importProjectUserListQueryRef")
  importProjectUserListHandleQuery()
}
/** 用户列表-导入-多选框选中数据 */
function importProjectUserListHandleSelectionChange(selection) {
  importProjectUserListIds.value = selection.map(item => item.userBizId)
  importProjectUserListNames.value = selection.map(item => item.userName)
}
/** 用户列表-导入-导入用户提交 */
function importProjectUserListSubmitForm() {
  const importProjectUserListIdList = importProjectUserListIds.value
  const importProjectUserListNameList = importProjectUserListNames.value
  const projectBizId = route.query.projectBizId

  proxy.$modal.confirm('是否确认导入用户账号为"' + importProjectUserListNameList + '"的数据项?').then(function () {
    return addImportProjectUserList(importProjectUserListIdList,projectBizId)
  }).then(() => {
    importProjectUserListOpen.value = false
    getUserList()
    proxy.$modal.msgSuccess("导入成功")
  }).catch(() => {})
}
/** 用户列表-导入-取消 */
function importProjectUserListCancel() {
  importProjectUserListOpen.value = false
  proxy.resetForm("importProjectUserListQueryRef")
}
//========用户-导入逻辑结束=========


//========角色-列表逻辑开始=========
/** 查询项目角色关系列表 */
function getRoleList() {
  roleLoading.value = true
  listProjectRole(roleQueryParams.value).then(response => {
    projectRoleList.value = response.data.records
    roleTotal.value = response.data.total
    roleLoading.value = false
  })
}
/** 角色列表-搜索 */
function roleHandleQuery() {
  roleQueryParams.value.pageNum = 1
  getRoleList()
}
/** 角色列表-重置按钮操作 */
function roleResetQuery() {
  proxy.resetForm("roleQueryRef")
  roleHandleQuery()
}
/** 删除项目角色关系 */
function roleHandleDelete(row) {
  //项目和角色关系表主键id
  const relProjectRoleId = row.id
  const roleName = row.roleName
  proxy.$modal.confirm('是否确认删除角色名称为"' + roleName + '"的项目和角色关系的数据项?').then(function () {
    return delRelProjectRole(relProjectRoleId)
  }).then(() => {
    getRoleList()
    proxy.$modal.msgSuccess("删除成功")
  }).catch(() => {})
}
//========角色-列表逻辑结束=========


//========角色-导入逻辑开始=========
/** 角色列表-导入-查询导入项目角色关系列表 */
function getImportProjectRoleList() {
  importProjectRoleListLoading.value = true
  listImportProjectRole(importProjectRoleListQueryParams.value).then(response => {
    importProjectRoleList.value = response.data.records
    importProjectRoleListTotal.value = response.data.total
    importProjectRoleListLoading.value = false
  })
}
/** 角色列表-导入角色 */
function handleImportProjectRoleList() {
  getImportProjectRoleList()
  importProjectRoleListOpen.value = true
  importRoleTitle.value = "导入角色"
}
/** 角色列表-导入-搜索按钮操作 */
function importProjectRoleListHandleQuery() {
  importProjectRoleListQueryParams.value.pageNum = 1
  getImportProjectRoleList()
}
/** 角色列表-导入-重置按钮操作 */
function importProjectRoleListResetQuery() {
  proxy.resetForm("importProjectRoleListQueryRef")
  importProjectRoleListHandleQuery()
}
/** 角色列表-导入-多选框选中数据 */
function importProjectRoleListHandleSelectionChange(selection) {
  importProjectRoleListIds.value = selection.map(item => item.roleBizId)
  importProjectRoleListNames.value = selection.map(item => item.roleName)
}
/** 角色列表-导入-导入角色提交 */
function importProjectRoleListSubmitForm() {
  const importProjectRoleListIdList = importProjectRoleListIds.value
  const importProjectRoleListNameList = importProjectRoleListNames.value
  const projectBizId = route.query.projectBizId

  proxy.$modal.confirm('是否确认导入角色名称为"' + importProjectRoleListNameList + '"的数据项?').then(function () {
    return addImportProjectRoleList(importProjectRoleListIdList,projectBizId)
  }).then(() => {
    importProjectRoleListOpen.value = false
    getRoleList()
    proxy.$modal.msgSuccess("导入成功")
  }).catch(() => {})
}
/** 角色列表-导入-取消 */
function importProjectRoleListCancel() {
  importProjectRoleListOpen.value = false
  proxy.resetForm("importProjectRoleListQueryRef")
}
//========角色-导入逻辑结束=========


//========菜单-列表逻辑结束=========
/** 查询菜单列表 */
function getMenuList() {
  menuLoading.value = true
  listMenu(menuQueryParams.value).then(response => {
    menuList.value = proxy.handleTree(response.data.records, "menuBizId")
    menuLoading.value = false
  })
}
/** 菜单展开/折叠操作 */
function toggleExpandAll() {
  refreshTable.value = false
  isExpandAll.value = !isExpandAll.value
  nextTick(() => {
    refreshTable.value = true
  })
}
/** 菜单列表-搜索 */
function menuHandleQuery() {
  menuQueryParams.value.pageNum = 1
  getMenuList()
}
/** 菜单列表-重置按钮操作 */
function menuResetQuery() {
  proxy.resetForm("menuQueryRef")
  menuHandleQuery()
}
//========菜单-列表逻辑结束=========


//========菜单-导入逻辑开始=========
/** 菜单列表-导入菜单 */
function handleImportProjectMenuList() {
  loadMenuTree()
  importProjectMenuListOpen.value = true
  importMenuTitle.value = "导入菜单"
}
// 加载菜单树
const loadMenuTree = async () => {
  try {
    const res = await getMenuTree(route.query.projectBizId)
    menuTree.value = res.data // 直接使用后端返回的树形结构
    loadImportSelectedMenuList() // 加载选中的菜单列表，更新树勾选
  } catch (error) {
    console.error('加载菜单树失败:', error)
    ElMessage.error('菜单加载失败')
  }
}
// 修改加载选中菜单列表的逻辑
const loadImportSelectedMenuList = async () => {
  try {
    const res = await getImportSelectedMenuList(route.query.projectBizId);
    const targetKeys = res.data || [];

    // 开启严格模式（禁用联动）
    isCheckStrictly.value = true;

    // 等待DOM更新（确保严格模式生效）
    await nextTick();

    //清空并设置选中状态（此时不会触发联动）
    if (treeRef.value) {
      treeRef.value.setCheckedKeys([]);
      treeRef.value.setCheckedKeys(targetKeys);
    }

    //等待选中状态渲染完成
    await nextTick();

    //关闭严格模式（恢复联动）
    isCheckStrictly.value = false;

  } catch (error) {
    console.error('加载选中的菜单列表失败:', error);
    ElMessage.error('加载选中的菜单列表失败');
    // 异常时也要恢复严格模式状态
    isCheckStrictly.value = false;
  }
}
// 保存
const saveImportSelectedMenuList = async () => {
  try {
    // 获取当前选中的节点
    const checkedKeys = treeRef.value.getCheckedKeys()
    // 获取半选中的节点（下级勾选，上级没勾选，把上级没勾选带出来）
    const halfCheckedKeys = treeRef.value.getHalfCheckedKeys()

    // 合并选中节点（根据业务需求选择是否包含半选节点）
    const allCheckedKeys = [...checkedKeys, ...halfCheckedKeys]

    await addImportProjectMenuList({
      projectBizId: route.query.projectBizId,
      menuBizIdList: allCheckedKeys
    })
    getMenuList()
    importProjectMenuListOpen.value = false
    ElMessage.success('更新成功')

  } catch (error) {
    console.error('更新失败:', error)
    ElMessage.error('更新失败')
  }
}
//========菜单-导入逻辑结束=========



//========分配角色-导入逻辑开始=========
// 弹窗显隐与标题
const assignRoleDialogVisible = ref(false)
const assignRoleTitle = ref("分配角色")

// 左侧可选角色（查询参数 + 列表数据）
const leftQuery = reactive({
  pageNo: 1,
  pageSize: 10,
  projectBizId: route.query.projectBizId,
  userBizId: '',
  roleName: ''
})
const leftRoleList = ref([])
const leftLoading = ref(false)
const leftTotal = ref(0)
const leftSelectedRoles = ref([]) // 左侧选中的角色


// 右侧可选角色（查询参数 + 列表数据）
const rightQuery = reactive({
  pageNo: 1,
  pageSize: 10,
  projectBizId: route.query.projectBizId,
  userBizId: '',
  roleName: ''
})
// 右侧已选角色（列表数据 + 选中项）
const rightRoleList = ref([])
const rightLoading = ref(false)
const rightTotal = ref(0)
const rightSelectedRoles = ref([]) // 右侧选中的角色

/** 打开分配角色弹窗 */
function openAssignRoleDialog(userRow) {
  // 初始化状态
  leftQuery.userBizId = userRow.userBizId
  rightQuery.userBizId = userRow.userBizId
  leftSelectedRoles.value = []
  rightSelectedRoles.value = []
  leftRoleList.value = []
  rightRoleList.value = []

  // 加载左侧待选角色分页列表（排除已选）
  getLeftRoleList()
  // 加载右侧已选角色分页列表
  getRightRoleList()

  // 显示弹窗
  assignRoleDialogVisible.value = true
}

/** 获取左侧待选角色分页列表（排除已选角色） */
function getLeftRoleList() {
  leftLoading.value = true
  listLeftRole({
    ...leftQuery
  }).then(res => {
    leftRoleList.value = res.data.records
    leftTotal.value = res.data.total
    leftLoading.value = false
  }).catch(() => {
    leftLoading.value = false
  })
}

/** 获取右侧已选角色分页列表 */
function getRightRoleList() {
  rightLoading.value = true
  listRightRole({
    ...rightQuery
  }).then(res => {
    rightRoleList.value = res.data.records
    rightTotal.value = res.data.total
    rightLoading.value = false
  }).catch(() => {
    rightLoading.value = false
  })
}

/** 左侧表格选中事件 */
function handleLeftSelectionChange(selection) {
  leftSelectedRoles.value = selection
}

/** 右侧表格选中事件 */
function handleRightSelectionChange(selection) {
  rightSelectedRoles.value = selection
}

/** 左侧搜索 */
function queryLeftRoleList() {
  leftQuery.pageNo = 1
  getLeftRoleList()
}

/** 重置左侧搜索 */
function resetLeftRoleQuery() {
  proxy.resetForm("leftQueryRef")
  leftQuery.pageNo = 1
  leftQuery.roleName = ''
  getLeftRoleList()
}

/** 右侧搜索 */
function queryRightRoleList() {
  rightQuery.pageNo = 1
  getRightRoleList()
}

/** 重置右侧搜索 */
function resetRightRoleQuery() {
  proxy.resetForm("rightQueryRef")
  rightQuery.pageNo = 1
  rightQuery.roleName = ''
  getRightRoleList()
}

/** 向右箭头：将左侧选中角色移到右侧-调接口添加关系 */
function moveToRight() {
  const roleBizIdList = []
  const leftRoleNameList = []
  leftSelectedRoles.value.forEach(r => {
    roleBizIdList.push(r.roleBizId)
    leftRoleNameList.push(r.roleName)
  })
  const data = {
    projectBizId: route.query.projectBizId,
    userBizId: leftQuery.userBizId,
    roleBizIdList: roleBizIdList
  }
  proxy.$modal.confirm('是否向右移动角色名称为"' + leftRoleNameList + '"的数据项?').then(function () {
    return addRightRoleList(data)
  }).then(() => {
    // 加载左侧待选角色分页列表（排除已选）
    getLeftRoleList()
    // 加载右侧已选角色分页列表
    getRightRoleList()
    proxy.$modal.msgSuccess("添加成功")
  }).catch(() => {})
}

/** 向左箭头：将右侧选中角色移除左侧，删除关系*/
function moveToLeft() {
  const roleBizIdList = []
  const rightRoleNameList = []
  rightSelectedRoles.value.forEach(r => {
    roleBizIdList.push(r.roleBizId)
    rightRoleNameList.push(r.roleName)
  })
  const data = {
    projectBizId: route.query.projectBizId,
    userBizId: rightQuery.userBizId,
    roleBizIdList: roleBizIdList
  }
  proxy.$modal.confirm('是否向左移除角色名称为"' + rightRoleNameList + '"的数据项?').then(function () {
    return delRightRoleList(data)
  }).then(() => {
    // 加载左侧待选角色分页列表（排除已选）
    getLeftRoleList()
    // 加载右侧已选角色分页列表
    getRightRoleList()
    proxy.$modal.msgSuccess("移除成功")
  }).catch(() => {})
}
/** 取消操作 */
function cancelAssignRole() {
  assignRoleDialogVisible.value = false
}
//========分配角色-导入逻辑结束=========



//========分配菜单-导入逻辑开始=========
// 菜单树数据（直接从接口获取树形结构）
const fpMenuTree = ref([])
// 树组件引用
const fpMenuRef = ref(null)
// 添加响应式变量控制严格模式
const fpMenuIsCheckStrictly = ref(false);  // 默认关闭严格模式（启用联动）
// 树形配置
const fpMenuProps = {
  children: 'children',
  label: 'menuName'
}
const getSelectedFpMenuListParams = reactive({
  projectBizId: route.query.projectBizId,
  roleBizId: ''
})
const addFpMenuParams = reactive({
  roleBizId: ''
})
const getFpMenuTreeParams = reactive({
  pageNo: 1,
  pageSize: 10,
  projectBizId: route.query.projectBizId,
  menuName: undefined
})
const fpMenuTitle = ref("")
const fpMenuOpen = ref(false)

/** 分配菜单弹出 */
function handleFpMenu(row) {
  addFpMenuParams.roleBizId = row.roleBizId
  getSelectedFpMenuListParams.roleBizId = row.roleBizId
  loadFpMenuTree()
  fpMenuOpen.value = true
  fpMenuTitle.value = "分配菜单"
}
// 加载菜单树
const loadFpMenuTree = async () => {
  try {
    const res = await getFpMenuTree({...getFpMenuTreeParams})
    fpMenuTree.value = res.data // 直接使用后端返回的树形结构
    loadSelectedFpMenuList() // 加载选中的菜单列表，更新树勾选
  } catch (error) {
    console.error('加载菜单树失败:', error)
    proxy.$modal.msgSuccess("菜单加载失败")
  }
}
// 修改加载选中菜单列表的逻辑
const loadSelectedFpMenuList = async () => {
  try {
    const res = await getSelectedFpMenuList({...getSelectedFpMenuListParams});
    const targetKeys = res.data || [];

    // 开启严格模式（禁用联动）
    fpMenuIsCheckStrictly.value = true;

    // 等待DOM更新（确保严格模式生效）
    await nextTick();

    //清空并设置选中状态（此时不会触发联动）
    if (fpMenuRef.value) {
      fpMenuRef.value.setCheckedKeys([]);
      fpMenuRef.value.setCheckedKeys(targetKeys);
    }

    //等待选中状态渲染完成
    await nextTick();

    //关闭严格模式（恢复联动）
    fpMenuIsCheckStrictly.value = false;

  } catch (error) {
    console.error('加载选中的菜单列表失败:', error);
    proxy.$modal.msgSuccess("加载选中的菜单列表失败")
    // 异常时也要恢复严格模式状态
    fpMenuIsCheckStrictly.value = false;
  }
}
// 保存
const saveFpMenuList = async () => {
  try {
    // 获取当前选中的节点
    const checkedKeys = fpMenuRef.value.getCheckedKeys()
    // 获取半选中的节点（下级勾选，上级没勾选，把上级没勾选带出来）
    const halfCheckedKeys = fpMenuRef.value.getHalfCheckedKeys()

    // 合并选中节点（根据业务需求选择是否包含半选节点）
    const allCheckedKeys = [...checkedKeys, ...halfCheckedKeys]

    await addFpMenuList({
      projectBizId: route.query.projectBizId,
      roleBizId: addFpMenuParams.roleBizId,
      menuBizIdList: allCheckedKeys
    })

    getRoleList()
    fpMenuOpen.value = false
    proxy.$modal.msgSuccess("更新成功")

  } catch (error) {
    console.error('更新失败:', error)
    proxy.$modal.msgSuccess("更新失败")
  }
}
//========分配菜单-导入逻辑结束=========



const handleTabChange = (tabName) => {
  console.log('切换到:', tabName)
  if (tabName === "user"){
    //用户tab获取用户列表数据
    getUserList()
  }else if (tabName === "role"){
    //用户tab获取角色列表数据
    getRoleList()
  }else if (tabName === "menu"){
    //用户tab获取菜单树数据
    getMenuList()
  }

}

getUserList()
</script>

<style scoped>
/* 全局容器 */
.app-container {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: calc(100vh - 60px); /* 适配布局 */
}

/* 自定义选项卡：核心样式 */
.custom-tabs {
  --active-tab-color: #fff;          /* 激活选项卡文字颜色 */
  --active-tab-bg: #409eff;          /* 激活选项卡背景色 */
  --inactive-tab-color: #606266;     /* 未激活文字颜色 */
  --inactive-tab-bg: #f5f7fa;        /* 未激活背景色 */
  --border-color: #dcdfe6;           /* 边框颜色 */
  --radius: 8px;                     /* 圆角 */
  width: 100%;
}

/* 选项卡头部：消除默认样式，重构凹陷效果 */
:deep(.el-tabs__header ) {
  line-height: 1; /* 重置行高，避免影响高度计算 */
  padding: 0;     /* 清除默认内边距 */
}

/* 选项卡导航容器：核心凹陷逻辑 */
 :deep(.el-tabs__nav ) {
  display: flex;
  margin: 0; /* 清除默认 margin */
  border-bottom: 1px solid var(--border-color); /* 底部边框 */
}

/* 选项卡 item 基础样式 */
 :deep(.el-tabs__item ) {
  position: relative;
  padding: 12px 24px;
  margin-right: 0; /* 清除默认间距 */
  font-size: 14px;
  color: var(--inactive-tab-color);
  background-color: var(--inactive-tab-bg);
  border: 1px solid var(--border-color);
  border-bottom: none; /* 隐藏底部边框，通过父容器 border 实现分割 */
  cursor: pointer;
  transition: all 0.3s ease;
}

/* 激活态：凹陷 + 高亮 */
 :deep(.el-tabs__item.is-active ) {
  color: var(--active-tab-color);
  background-color: var(--active-tab-bg);
  /* 上、左、右边框 + 底部无边框，模拟“凹陷” */
  border: 1px solid var(--border-color);
  border-bottom-color: var(--active-tab-bg); /* 与背景色一致，视觉上“凹陷” */
  /* 调整层级，避免底部边框遮挡 */
  z-index: 1;
  /* 细微阴影增强立体 */
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* 未激活态：悬浮效果 */
 :deep(.el-tabs__item:not(.is-active):hover ) {
  color: #409eff;
  background-color: #eaf2ff;
}

/* 左侧边框处理（仅第一个 tab 左侧圆角） */
 :deep(.el-tabs__item:first-child ) {
  border-top-left-radius: var(--radius);
}

/* 右侧边框处理（仅最后一个 tab 右侧圆角） */
 :deep(.el-tabs__item:last-child ) {
  border-top-right-radius: var(--radius);
}

/* 激活态：覆盖父容器的底部边框，实现“凹陷” */
 :deep(.el-tabs__item.is-active::before ) {   
  content: "";
  position: absolute;
  bottom: -1px; /* 覆盖父容器的 border-bottom */
  left: 0;
  width: 100%;
  height: 1px;
  background-color: var(--active-tab-bg); /* 与激活态背景一致 */
}

/* 内容区域：和选项卡无缝衔接 */
 :deep(.el-tabs__content ) {
  padding: 20px;
  background-color: #fff;
  border: 1px solid var(--border-color);
  border-top: none; /* 消除顶部边框，与选项卡衔接 */
  border-bottom-left-radius: var(--radius);
  border-bottom-right-radius: var(--radius);
}

/* 空数据提示 */
.empty-tip {
  text-align: center;
  padding: 40px 0;
  color: #909399;
}



.permission-section {
  margin-top: 20px;
}

.permission-tree {
  max-height: 500px;
  overflow-y: auto;
  padding: 10px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}

.perm-tag {
  margin-left: 10px;
  padding: 0 5px;
  background-color: #ecf5ff;
  color: #409eff;
  border-radius: 3px;
  font-size: 12px;
}

.tree-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

/* 分配角色弹窗布局 */
.assign-role-container {
  display: flex;
  height: 450px;
  padding: 15px 0;
  box-sizing: border-box;
}

/* 左侧面板 */
.left-panel {
  flex: 1;
  height: 100%;
  overflow: auto;
  border: 1px solid #e5e7eb;
  border-radius: 4px;
  padding: 15px;
  background-color: #fff;
}

/* 搜索表单样式 */
.search-form {
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px dashed #f0f0f0;
}

/* 中间箭头区域 */
.center-panel {
  width: 60px;
  display: flex;
  flex-direction: column;
  justify-content: center; /* 垂直居中 */
  align-items: center; /* 水平居中 */
  height: 100%;
  padding: 0 10px;
}

.arrow-buttons-container {
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: center; /* 确保按钮水平居中 */
}
/* 箭头按钮样式（基础 + 高亮） */
.arrow-btn {
  width: 36px;
  height: 36px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #409eff;
  border: none;
  color: white;
  font-size: 16px;
  border-radius: 50%;
  transition: all 0.2s ease;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}

.arrow-btn {
  display: inline-flex;
  margin: 0 auto;
}

.arrow-btn:hover {
  background-color: #66b1ff;
  transform: scale(1.1);
}
.arrow-btn:disabled {
  background-color: #c0c4cc;
  cursor: not-allowed;
  opacity: 0.6;
  transform: none;
}

/* 右侧面板（带边框） */
.right-panel {
  flex: 1;
  height: 100%;
  overflow: auto;
  border: 1px solid #e5e7eb;
  border-radius: 4px;
  padding: 15px;
  background-color: #fff;
}


/* 右侧标题 */
.selected-title {
  font-size: 14px;
  font-weight: 500;
  color: #374151;
  padding-bottom: 10px;
  border-bottom: 1px dashed #f0f0f0;
}
</style>
