Sfoglia il codice sorgente

feat:添加用户组相关接口和页面,修改角色和知识库列表查询函数名,更新表格大小变化事件处理函数名,优化角色表单和权限配置模态框逻辑

张涛 1 anno fa
parent
commit
02d5946ab9

+ 15 - 2
src/apis/permission/common.js

@@ -1,7 +1,20 @@
 import request from '../../base/ajax';
 
+// 角色列表
+export function QueryAllRoleList() {
+  const params = {
+    current: 1,
+    pageSize: 999
+  };
+  return request({
+    url: '/api/role/list',
+    method: 'get',
+    params
+  });
+}
+
 // 知识库列表
-export function QueryknowledgeList() {
+export function QueryAllKnowledgeList() {
   const params = {
     current: 1,
     pageSize: 999
@@ -14,7 +27,7 @@ export function QueryknowledgeList() {
 }
 
 // 智能体列表
-export function QueryDialogList() {
+export function QueryAllDialogList() {
   const params = {
     current: 1,
     pageSize: 999

+ 69 - 0
src/apis/permission/gruop.js

@@ -0,0 +1,69 @@
+import request from '../../base/ajax';
+
+const prefix = '/api/group';
+
+// 查询用户组列表
+export function QueryGroupList(params) {
+  return request({
+    url: `${prefix}/list`,
+    method: 'get',
+    params
+  });
+}
+// 查询用户组成员
+export function QueryGroupUsers(groupId) {
+  return request({
+    url: `${prefix}/group_users`,
+    method: 'get',
+    params: { groupId }
+  });
+}
+// 保存用户组成员
+export function SaveGroupUsers(data) {
+  return request({
+    url: `${prefix}/save_group_user`,
+    method: 'post',
+    data
+  });
+}
+// 用户组配置资源
+export function ConfigGroupResource(data) {
+  return request({
+    url: `${prefix}/group_resource`,
+    method: 'put',
+    data
+  });
+}
+// 创建用户组
+export function CreateGroup(data) {
+  return request({
+    url: `${prefix}/add_group`,
+    method: 'post',
+    data
+  });
+}
+// 编辑用户组
+export function UpdateGroup(data) {
+  return request({
+    url: `${prefix}/edit_group`,
+    method: 'put',
+    data
+  });
+}
+
+// 切换用户组状态
+export function GroupStatusSwitch(data) {
+  return request({
+    url: `${prefix}/edit_group_status`,
+    method: 'put',
+    data
+  });
+}
+
+// 删除用户组
+export function DeleteGroup(groupId) {
+  return request({
+    url: `${prefix}/delete_group/${groupId}`,
+    method: 'delete'
+  });
+}

+ 3 - 3
src/apis/permission/role.js

@@ -27,7 +27,7 @@ export function UpdateRole(data) {
   });
 }
 
-// 切换用户状态
+// 切换角色状态
 export function RoleStatusSwitch(data) {
   return request({
     url: `${prefix}/change_status`,
@@ -37,9 +37,9 @@ export function RoleStatusSwitch(data) {
 }
 
 // 删除角色
-export function DeleteRole(userId) {
+export function DeleteRole(roleId) {
   return request({
-    url: `${prefix}/delete_role/${userId}`,
+    url: `${prefix}/delete_role/${roleId}`,
     method: 'delete'
   });
 }

+ 11 - 6
src/modules/permission/account/AccountForm.vue

@@ -38,8 +38,9 @@
         </a-form-item>
       </a-col>
       <a-col :span="12">
-        <a-form-item field="role" label="角色">
-          <a-select multiple v-model="edit_form.role" :options="roles" @change="roleChange">
+        <a-form-item field="roles" label="角色">
+          <a-select multiple v-model="edit_form.roles" :options="role_list" :default-value="edit_form_role_computed"
+            :field-names="{ value: 'roleId', label: 'roleName' }" @change="roleChange">
           </a-select>
         </a-form-item>
       </a-col>
@@ -48,19 +49,23 @@
 </template>
 
 <script setup>
-import { toRefs } from 'vue';
+import { toRefs, computed } from 'vue';
 
 const props = defineProps({
   edit_form: Object,
   is_edit_mode: Boolean,
-  roles: Array,
+  role_list: Array,
 });
 
-const { edit_form, is_edit_mode, roles } = toRefs(props);
+const { edit_form, is_edit_mode, role_list } = toRefs(props);
+
+const edit_form_role_computed = computed(() => {
+  // TODO高优先级 确定角色回显没问题之后 完成编辑和新增功能
+  return edit_form && edit_form.roles.map(role => role.roleId)
+});
 
 // 角色变化处理
 const roleChange = (selectedRoles) => {
-
   edit_form.role = selectedRoles;
 }
 </script>

+ 16 - 10
src/modules/permission/account/index.vue

@@ -1,7 +1,7 @@
 <template>
   <a-card class="account-page-card">
     <Action :btn_text="'新建账号'" @searchClick="searchClick" @resetClick="resetClick" @createClick="createClick"
-      @sizeChange="table_size_change" @refreshClick="refreshClick"></Action>
+      @sizeChange="tableSizeChange" @refreshClick="refreshClick"></Action>
     <DataTable :data="table_data" :columns="table_columns" row-key="userId" :size="table_size" :loading="table_loading"
       :pagination="pagination_props" @pageChange="handlePageChange">
       <template #status="{ record }">
@@ -23,11 +23,11 @@
 
   <Modal :visible.sync="edit_visible" @ok="modalSave" @cancel="handleEdit(null, false)"
     :title="is_edit_mode ? '编辑' : '新增'">
-    <AccountForm :edit_form="edit_form" :is_edit_mode="is_edit_mode" />
+    <AccountForm :edit_form="edit_form" :is_edit_mode="is_edit_mode" :role_list="role_list" />
   </Modal>
 
   <ViewPermission :visible.sync="view_permission_visible" @cancel="handleView(null, false)"
-    @close="handleView(null, false)" :view_form="view_form" :menu_permissions_list="menu_permissions_list"
+    @close="handleView(null, false)" :menu_permissions_list="menu_permissions_list"
     :knowledge_permissions_list="knowledge_permissions_list" :dialog_permissions_list="dialog_permissions_list"
     :agent_permissions_list="agent_permissions_list" />
 
@@ -47,6 +47,7 @@ import ViewPermission from './ViewPermission.vue';
 import DeptConfigModal from './DeptConfigModal.vue';
 
 import { QueryUserList, QueryUserDetail, QueryUserPermission, QueryUserDept, UserStatusSwitch, ResetPassword, DeleteUser } from '../../../apis/permission/account';
+import { QueryAllRoleList } from '../../../apis/permission/common';
 
 const keywords = ref('');
 // 表格相关
@@ -76,9 +77,9 @@ const edit_form = reactive({
   phone: '',
   email: '',
   pwd: '',
-  role: []
+  roles: []
 });
-
+const role_list = ref([]);
 // 查看权限相关
 const view_permission_visible = ref(false);
 const menu_permissions_list = ref([])
@@ -268,7 +269,7 @@ const createClick = () => {
   edit_form.phone = '';
   edit_form.email = '';
   edit_form.pwd = '';
-  edit_form.role = [];
+  edit_form.roles = [];
   is_edit_mode.value = false;
   edit_visible.value = true;
 }
@@ -322,16 +323,21 @@ const handleResetPassword = async (record) => {
   }
 }
 
-const handleEdit = (record, visible) => {
+const handleEdit = async (record, visible) => {
+
+  const { code, data } = await QueryAllRoleList();
+  if (code === 200) {
+    role_list.value = data.rows;
+  }
+
   if (record) {
     edit_form.userName = record.userName;
     edit_form.loginName = record.loginName;
     edit_form.phone = record.phone;
     edit_form.email = record.email;
     edit_form.pwd = record.pwd;
-    edit_form.role = record.role;
+    edit_form.roles = record.roles;
 
-    is_edit_mode.value = true;
   }
 
   edit_visible.value = visible;
@@ -381,7 +387,7 @@ const handleDelete = async (userId) => {
 const modalSave = () => {
   edit_visible.value = false;
 }
-const table_size_change = (size) => {
+const tableSizeChange = (size) => {
   table_size.value = size;
 }
 // 铺开路由菜单title

+ 30 - 0
src/modules/permission/group/GroupForm.vue

@@ -0,0 +1,30 @@
+<template>
+  <a-form :model="edit_form" auto-label-width>
+    <a-row :gutter="24">
+      <a-col :span="22">
+        <a-form-item field="groupName" label="组名称" :rules="[
+          { required: true, message: '组名称必填' },
+        ]">
+          <a-input v-model="edit_form.groupName" />
+        </a-form-item>
+      </a-col>
+    </a-row>
+    <a-row :gutter="24">
+      <a-col :span="22">
+        <a-form-item field="description" label="描述">
+          <a-textarea v-model="edit_form.description" />
+        </a-form-item>
+      </a-col>
+    </a-row>
+  </a-form>
+</template>
+
+<script setup>
+import { toRefs } from 'vue';
+const props = defineProps({
+  edit_form: Object,
+  is_edit_mode: Boolean,
+});
+
+const { edit_form } = toRefs(props);
+</script>

+ 32 - 23
src/modules/permission/group/MembertConfigModal.vue

@@ -1,13 +1,13 @@
 <template>
   <a-modal width="50%" v-model:visible="visible" title="权限配置" @cancel="handleCancel" @ok="ok">
     <div class="membert-config-modal">
-      <a-transfer show-search :data="memberList" :default-value="selectedMemberList" :source-input-search-props="{
+      <a-transfer show-search :data="memberList" :model-value="selectedMemberList" :source-input-search-props="{
         placeholder: '请输入用户名搜索',
       }" :target-input-search-props="{
         placeholder: '请输入用户名搜索',
-      }">
-        <template #source-title>可选列表</template>
-        <template #target-title>已选列表</template>
+      }" @change="handleChange">
+        <template #source-title>可选成员</template>
+        <template #target-title>已选成员</template>
       </a-transfer>
     </div>
 
@@ -20,35 +20,44 @@ import { ref, toRefs } from 'vue';
 // 定义组件的 props 和 emits
 const props = defineProps({
   visible: Boolean,
-});
-const { visible } = toRefs(props);
-
-const emit = defineEmits(['cancel', 'ok']);
-
-const memberList = ref([
-  {
-    label: '张三',
-    value: 'zhangsan',
-  },
-  {
-    label: ' 李四',
-    value: 'lisi',
+  memberList: {
+    type: Array,
+    default: () => [],
   },
-  {
-    label: '张三',
-    value: 'zhangsan',
+  selectedMemberList: {
+    type: Array,
+    default: () => [],
   },
-]);
+});
+const { visible, memberList, selectedMemberList } = toRefs(props);
+const emit = defineEmits(['cancel', 'ok']);
 
-const selectedMemberList = ref(['zhangsan']);
+const tempSelectedMemberList = ref([...selectedMemberList.value]);
 
 const handleCancel = () => {
   emit('close');
 };
-
 const ok = () => {
   emit('ok', selectedMemberList.value);
 };
+const handleChange = (selected) => {
+  // 计算新增的成员
+  const addedMembers = selected.filter(member => !tempSelectedMemberList.value.includes(member));
+  // 计算减少的成员
+  const removedMembers = tempSelectedMemberList.value.filter(member => !selected.includes(member));
+
+  // 根据需要处理增加和减少的成员
+  if (addedMembers.length > 0) {
+    tempSelectedMemberList.value = [...tempSelectedMemberList.value, ...addedMembers];
+  }
+  if (removedMembers.length > 0) {
+    tempSelectedMemberList.value = tempSelectedMemberList.value.filter(member => !removedMembers.includes(member));
+  }
+
+  // 更新父组件的 selectedMemberList
+  emit('update:selectedMemberList', tempSelectedMemberList.value);
+};
+
 </script>
 
 <style scoped>

+ 203 - 0
src/modules/permission/group/PermissionConfigModal.vue

@@ -0,0 +1,203 @@
+<template>
+  <a-modal width="50%" v-model:visible="visible" title="权限配置" @cancel="handleCancel" @ok="editDeptHandleOk">
+    <a-tabs :active-key="selected_tab_key" @change="handleTabChange">
+      <a-tab-pane v-for="tab in tabs" :key="tab.key">
+        <template #title>
+          <component :is="tab.icon" /> {{ tab.title }}
+        </template>
+      </a-tab-pane>
+    </a-tabs>
+    <div style="display: flex;">
+      <a-card class="card-body" :title="getCurrentTabTitle" hoverable>
+
+        <a-checkbox-group v-if="selected_tab_key === '1'" v-model="checked_knowledge" @change="onCheckKnowledge">
+          <a-checkbox v-for="(knowledg, index) of knowledge_list" :value="knowledg.id" :lable="knowledg.name"
+            style="width:150px">
+            {{ knowledg.name }}
+          </a-checkbox>
+        </a-checkbox-group>
+
+        <a-checkbox-group v-if="selected_tab_key === '2'" v-model="checked_agents" @change="onCheckAgents">
+          <a-checkbox v-for="(agents, index) of agents_list" :value="agents.id" :lable="agents.name"
+            style="width:150px">
+            {{ agents.name }}
+          </a-checkbox>
+        </a-checkbox-group>
+
+        <a-checkbox-group v-if="selected_tab_key === '3'" v-model="checked_model" @change="onCheckModel">
+          <a-checkbox v-for="(model, index) of model_list" :value="model.id" :lable="model.name" style="width:150px">
+            {{ model.name }}
+          </a-checkbox>
+        </a-checkbox-group>
+
+      </a-card>
+      <a-card class="card-body" title="角色所有权限">
+
+        <div style="margin: 8px 0;">知识库功能:</div>
+        <a-space wrap>
+          <a-tag v-for="(tag, index) of checked_knowledge_list" :key="tag.id">
+            {{ tag.name }}
+          </a-tag>
+        </a-space>
+        <a-divider />
+
+        <div style="margin: 8px 0;">智能体功能:</div>
+        <a-space wrap>
+          <a-tag v-for="(tag, index) of checked_agents_list" :key="tag.id">
+            {{ tag.name }}
+          </a-tag>
+        </a-space>
+        <a-divider />
+
+        <div style="margin: 8px 0;">模型功能:</div>
+        <a-space wrap>
+          <a-tag v-for="(tag, index) of checked_model_list" :key="tag.id">
+            {{ tag.name }}
+          </a-tag>
+        </a-space>
+      </a-card>
+    </div>
+  </a-modal>
+</template>
+
+<script setup>
+import { ref, toRefs, onMounted, computed } from 'vue';
+
+// 定义组件的 props 和 emits
+const props = defineProps({
+  visible: Boolean,
+  knowledge_list: {
+    type: Array,
+    default: () => []
+  },
+  agents_list: {
+    type: Array,
+    default: () => []
+  },
+  model_list: {
+    type: Array,
+    default: () => []
+  },
+  record: Object
+});
+
+const { visible, knowledge_list, agents_list, model_list, record } = toRefs(props);
+
+const emit = defineEmits(['getActiveTab', 'close', 'ok']);
+
+const tabs = [
+  { key: "1", icon: "icon-storage", title: "知识库" },
+  { key: "2", icon: "icon-robot", title: "智能体" },
+  { key: "3", icon: "icon-relation", title: "模型" }
+]
+const selected_tab_key = ref(tabs[0].key);
+
+// 组件内部状态
+// 默认展开第一节
+const expand_kdys = ref(['0']);
+
+const checked_knowledge = ref([]);
+const checked_knowledge_list = ref([]);
+const checked_agents = ref([]);
+const checked_agents_list = ref([])
+const checked_model = ref([]);
+const checked_model_list = ref([])
+
+
+// 递归取消所有子节点的选择
+const cancelChildSelection = (node, selectedNodes) => {
+  if (node.children && node.children.length > 0) {
+    node.children.forEach(child => {
+      const childIndex = selectedNodes.findIndex(val => val.menuId === child.menuId);
+      if (childIndex !== -1) {
+        // 取消子节点的选择
+        selectedNodes.splice(childIndex, 1);
+        // 递归取消子节点的选择
+        cancelChildSelection(child, selectedNodes);
+      }
+    });
+  }
+}
+
+const onCheckboxCheck = (newCheckedKeys, event, collection) => {
+  let o = {
+    id: event.target.value,
+    name: event.target.labels[0].innerText,
+  };
+  if (event.target.checked) {
+    collection.value.push(o);
+  } else {
+    collection.value.forEach((val, idx, array) => {
+      if (val['id'] == event.target.value) {
+        collection.value.splice(idx, 1);
+        return true;
+      }
+    });
+  }
+};
+
+const onCheckKnowledge = (newCheckedKeys, event) => {
+  onCheckboxCheck(newCheckedKeys, event, checked_knowledge_list);
+
+};
+const onCheckAgents = (newCheckedKeys, event) => {
+  onCheckboxCheck(newCheckedKeys, event, checked_agents_list);
+};
+const onCheckModel = (newCheckedKeys, event) => {
+  onCheckboxCheck(newCheckedKeys, event, checked_model_list);
+};
+
+const handleTabChange = (key) => {
+  const currentTab = tabs.find(tab => tab.key === key);
+  emit('getActiveTab', currentTab);
+  selected_tab_key.value = key;
+};
+// 处理取消事件
+const handleCancel = () => {
+  emit('cancel');
+};
+
+// 处理确认事件
+const editDeptHandleOk = () => {
+  emit('ok', {
+    checkedKeys: {
+      knowledge: checked_knowledge.value,
+      agents: checked_agents.value,
+      model: checked_model.value
+    }
+  });
+};
+
+const getCurrentTabTitle = computed(() => {
+  const currentTab = tabs.find(tab => tab.key === selected_tab_key.value);
+  return currentTab ? currentTab.title : '菜单';
+});
+
+onMounted(() => {
+  // 处理传入的部门数据
+  // TODO接口 回显问题
+  // if (record?.dept) {
+  //   record.dept.forEach((val) => {
+  //     checked_menu_list.value.push({
+  //       menuId: val.menuId,
+  //       menuName: val.menuName
+  //     });
+  //     checked_menu.value.push(val.menuId);
+  //     expand_kdys.value.push(val.menuId);
+  //   });
+  // }
+
+});
+</script>
+
+<style lang="css" scoped>
+.card-body {
+  width: 460px;
+  height: 500px;
+  overflow-y: auto;
+}
+
+.card-body:first-child {
+  margin-right: 16px;
+}
+</style>

+ 306 - 0
src/modules/permission/group/index.vue

@@ -0,0 +1,306 @@
+<template>
+  <a-card class="account-page-card">
+    <Action :btn_text="'新建用户组'" @searchClick="searchClick" @resetClick="resetClick" @createClick="createClick"
+      @sizeChange="tableSizeChange" @refreshClick="refreshClick"></Action>
+    <DataTable :data="table_data" :columns="table_columns" row-key="groupId" :size="table_size" :loading="table_loading"
+      :pagination="pagination_props" @pageChange="handlePageChange">
+      <template #status="{ record }">
+        <a-switch v-model="record.status" @change="statusChange(record)" checked-value="1" unchecked-value="0" />
+      </template>
+      <template #operationSlot="{ record }">
+        <a-button type="text" @click="handleEdit(record, true)">编辑</a-button>
+        <a-button type="text" @click="handleMembertConfig(record, true)">成员管理</a-button>
+        <a-button type="text" @click="handlePermissionConfig(record, true)">权限管理</a-button>
+        <a-popconfirm content="确定删除该条数据吗?" type="warning" @ok="handleDelete(record.groupId)">
+          <a-button type="text" status="warning">删除</a-button>
+        </a-popconfirm>
+      </template>
+    </DataTable>
+  </a-card>
+
+  <Modal :visible.sync="edit_visible" @ok="modalSave" @cancel="handleEdit(null, false)"
+    :title="is_edit_mode ? '编辑' : '新增'">
+    <GroupForm :edit_form="edit_form" :is_edit_mode="is_edit_mode" />
+  </Modal>
+
+  <MembertConfigModal :visible.sync="membert_config_visible" :memberList="memberList"
+    :selectedMemberList="selectedMemberList" @ok="membertConfigModalSave"
+    @update:selectedMemberList="updateSelectedMemberList" @cancel="handleMembertConfig(null, false)"
+    @close="handleMembertConfig(null, false)" />
+
+  <!-- TODO -->
+  <PermissionConfigModal :visible.sync="permission_config_visible" :knowledge_list="knowledge_list"
+    :agents_list="agents_list" @getActiveTab="handlePermissionModalTab" @ok="handlePermissionConfigSave"
+    @cancel="handlePermissionConfig(null, false)" />
+
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue';
+import { Message } from '@arco-design/web-vue';
+import DataTable from '../../../views/permission/DataTable.vue';
+import Action from '../../../views/permission/Action.vue';
+import Modal from '../Modal.vue';
+import GroupForm from './GroupForm.vue';
+import MembertConfigModal from './MembertConfigModal.vue';
+import PermissionConfigModal from './PermissionConfigModal.vue';
+
+import { QueryGroupList, QueryGroupUsers, SaveGroupUsers, ConfigGroupResource, GroupStatusSwitch, DeleteGroup, CreateGroup, UpdateGroup } from '../../../apis/permission/gruop';
+// TODO接口 模型tabs接口还没有
+import { QueryAllKnowledgeList, QueryAllDialogList } from '../../../apis/permission/common';
+
+const keywords = ref('');
+// 表格相关
+const table_data = ref([]);
+const table_columns = ref([
+  { title: '序号', width: 80, slotName: 'index' },
+  { title: '组名称', dataIndex: 'name', width: 150, titleSlotName: 'name' },
+  { title: '描述', dataIndex: 'description', ellipsis: true, tooltip: true, titleSlotName: 'description' },
+  { title: '状态', dataIndex: 'status', slotName: 'status' },
+  { title: '操作', dataIndex: 'operation', slotName: 'operationSlot' },
+]);
+const pagination_props = ref({
+  total: 10,
+  current: 1,
+  pageSize: 12,
+})
+const table_size = ref('medium');
+const table_loading = ref(false);
+const current_record = ref(null);
+
+// 编辑表单相关
+const edit_visible = ref(false);
+const is_edit_mode = ref(false);
+const edit_form = reactive({
+  groupName: '',
+  description: '',
+});
+
+// 成员管理相关
+const membert_config_visible = ref(false);
+const memberList = ref([]);
+const selectedMemberList = ref([]);
+
+// 权限管理相关
+const permission_config_visible = ref(false);
+const knowledge_list = ref([]);
+const agents_list = ref([]);
+
+const getGroupList = async () => {
+  const params = {
+    keyword: keywords.value,
+    current: pagination_props.value.current,
+    pageSize: pagination_props.value.pageSize,
+  };
+  table_loading.value = true
+  const { code, data } = await QueryGroupList(params);
+  if (code === 200) {
+
+    pagination_props.value.total = data.total;
+    table_data.value = data.items;
+
+    table_loading.value = false
+  } else {
+    table_loading.value = false
+  }
+}
+
+const searchClick = (value) => {
+  keywords.value = value;
+  getGroupList();
+}
+const resetClick = () => {
+  keywords.value = '';
+  getGroupList();
+}
+const createClick = () => {
+  edit_form.groupName = '';
+  edit_form.description = '';
+
+  is_edit_mode.value = false;
+  edit_visible.value = true;
+}
+const refreshClick = () => {
+  console.log('刷新')
+}
+
+// 切换页码
+const handlePageChange = (current) => {
+  pagination_props.value.current = current;
+  getGroupList();
+};
+
+// TODO功能 状态切换拦截
+const beforeStatusChange = async () => {
+  await new Promise((resolve, reject) => setTimeout(() => {
+    resolve()
+  }, 1000))
+}
+
+// 用户状态切换
+const statusChange = async (record) => {
+  const params = {
+    id: record.groupId,
+    status: record.status,
+  };
+  const { code } = await GroupStatusSwitch(params)
+  if (code === 200) {
+    Message.success({
+      title: '成功',
+      content: '状态切换成功.',
+    });
+  }
+
+};
+
+
+const handleEdit = (record, visible) => {
+  if (record) {
+    edit_form.groupId = record.groupId;
+    edit_form.groupName = record.name;
+    edit_form.description = record.description;
+    is_edit_mode.value = true;
+  }
+
+  edit_visible.value = visible;
+}
+// 成员管理
+const handleMembertConfig = async (record, visible) => {
+  if (record) {
+    current_record.value = record;
+    const { code, data: { inGroup, notInGroup } } = await QueryGroupUsers(record.groupId);
+    if (code === 200) {
+      const allUsers = [...inGroup, ...notInGroup];
+
+      memberList.value = allUsers.map((item) => {
+        return {
+          label: item.userName,
+          value: item.userId,
+        };
+      });
+      selectedMemberList.value = inGroup.map((item) => item.userId);
+    }
+  }
+
+  membert_config_visible.value = visible;
+}
+// 成员管理保存
+const membertConfigModalSave = async (selectedMemberList) => {
+  const data = {
+    id: current_record.value.groupId,
+    userList: selectedMemberList,
+  };
+  const { code } = await SaveGroupUsers(data);
+  if (code === 200) {
+    Message.success({
+      title: '成员管理',
+      content: '成员修改成功',
+    });
+    membert_config_visible.value = false;
+    getGroupList();
+  }
+}
+const updateSelectedMemberList = (newSelection) => {
+  selectedMemberList.value = newSelection;
+};
+
+// 权限配置
+const handlePermissionConfig = async (record, visible) => {
+  // TODO接口 回显问题
+  if (record) {
+    edit_form.groupId = record.groupId;
+    getConfigList('1');
+  }
+  permission_config_visible.value = visible;
+}
+
+const handlePermissionModalTab = (tab) => {
+  if (tab.key) getConfigList(tab.key);
+}
+
+const handlePermissionConfigSave = async ({ checkedKeys }) => {
+  permission_config_visible.value = false;
+  const { knowledge, agents, model } = checkedKeys;
+  const data = {
+    id: edit_form.groupId,
+    knowledges: knowledge,
+    dialogs: agents,
+    llms: model,
+  };
+  const { code } = await ConfigGroupResource(data);
+  if (code === 200) {
+    Message.success({
+      title: '权限配置',
+      content: '权限配置成功',
+    });
+    getGroupList();
+  }
+}
+
+// 删除用户
+const handleDelete = async (groupId) => {
+  const { code } = await DeleteGroup(groupId);
+  if (code === 200) {
+    Message.success({
+      title: '删除用户',
+      content: '删除成功',
+    });
+    getGroupList();
+  }
+}
+const modalSave = async () => {
+  edit_visible.value = false;
+  const data = {
+    id: is_edit_mode.value ? edit_form.groupId : undefined,
+    groupName: edit_form.groupName,
+    description: edit_form.description,
+  };
+
+  const apiCall = is_edit_mode.value ? UpdateGroup : CreateGroup;
+  const { code } = await apiCall(data);
+
+  if (code === 200) {
+    const action = is_edit_mode.value ? '编辑' : '新增';
+    Message.success({
+      title: `${action}用户`,
+      content: `${action}成功`,
+    });
+    getGroupList();
+  }
+}
+
+const tableSizeChange = (size) => {
+  table_size.value = size;
+}
+
+const getConfigList = async (tabsKey) => {
+  if (tabsKey === '1') {
+    const { code, data: { rows } } = await QueryAllKnowledgeList();
+    if (code === 200) {
+      knowledge_list.value = rows;
+    }
+  }
+  if (tabsKey === '2') {
+    const { code, data: { rows } } = await QueryAllDialogList();
+    if (code === 200) {
+      agents_list.value = rows;
+    }
+  }
+  if (tabsKey === '3') {
+    // const { code, data: { rows } } = await QueryAllDialogList();
+    // if (code === 200) {
+    //   agents_list.value = rows;
+    // }
+  }
+}
+
+onMounted(() => {
+  getGroupList()
+})
+</script>
+
+<style lang="css" scoped>
+.account-page-card {
+  height: calc(100% - 40px);
+}
+</style>

+ 5 - 6
src/modules/permission/role/index.vue

@@ -1,7 +1,7 @@
 <template>
   <a-card class="account-page-card">
     <Action :btn_text="'新建角色'" @searchClick="searchClick" @resetClick="resetClick" @createClick="createClick"
-      @sizeChange="table_size_change" @refreshClick="refreshClick"></Action>
+      @sizeChange="tableSizeChange" @refreshClick="refreshClick"></Action>
     <DataTable :data="table_data" :columns="table_columns" row-key="roleId" :size="table_size" :loading="table_loading"
       :pagination="pagination_props" @pageChange="handlePageChange">
       <template #status="{ record }">
@@ -45,8 +45,7 @@ import DeptConfigModal from './DeptConfigModal.vue';
 
 import { QueryRoleList, RoleStatusSwitch, DeleteRole, CreateRole, UpdateRole } from '../../../apis/permission/role';
 import { QueryMenuTree } from '../../../apis/permission/resource';
-// TODO接口 模型tabs接口还没有
-import { QueryknowledgeList, QueryDialogList } from '../../../apis/permission/common';
+import { QueryAllKnowledgeList, QueryAllDialogList } from '../../../apis/permission/common';
 
 const keywords = ref('');
 // 表格相关
@@ -363,7 +362,7 @@ const modalSave = async () => {
   }
 }
 
-const table_size_change = (size) => {
+const tableSizeChange = (size) => {
   table_size.value = size;
 }
 
@@ -375,13 +374,13 @@ const getConfigList = async (tabsKey) => {
     }
   }
   if (tabsKey === '2') {
-    const { code, data: { rows } } = await QueryknowledgeList();
+    const { code, data: { rows } } = await QueryAllKnowledgeList();
     if (code === 200) {
       knowledge_list.value = rows;
     }
   }
   if (tabsKey === '3') {
-    const { code, data: { rows } } = await QueryDialogList();
+    const { code, data: { rows } } = await QueryAllDialogList();
     if (code === 200) {
       agents_list.value = rows;
     }

+ 3 - 4
src/views/PermissionGroup.vue

@@ -1,7 +1,7 @@
 <template>
   <ContentContainer>
     <BreadCrumbMenu :current_label="'用户组'" />
-    <div class="permission-role">权限管理: 角色</div>
+    <GroupPage />
   </ContentContainer>
 </template>
 
@@ -9,7 +9,6 @@
 import ContentContainer from './layout/ContentContainer.vue';
 import BreadCrumbMenu from './common/BreadCrumbMenu.vue';
 
-const props = defineProps({
-  label: String
-});
+import GroupPage from '../modules/permission/group/index.vue';
+
 </script>

+ 1 - 1
src/views/permission/DataTable.vue

@@ -9,7 +9,7 @@
         <slot :name="item.slotName" v-bind="{ record, rowIndex, column }"></slot>
       </template>
       <template v-for="item in columns" :key="item.titleSlotName" #[item.titleSlotName]="{ record, rowIndex, column }">
-        <div class="title-tip">{{ item.title }}</div>
+        <div>{{ item.title }}</div>
       </template>
     </a-table>
     <a-pagination v-if="pagination.total" class="pagination" :current="pagination.current" :total="pagination.total"