Browse Source

feat:更新用户和机构管理功能,新增用户和机构相关API,优化部门结构树,调整表单样式及数据处理逻辑

张涛 1 year ago
parent
commit
a3e7bdb10d

+ 19 - 14
src/apis/permission/account.js

@@ -9,17 +9,33 @@ export function QueryUserList(params) {
     params
   });
 }
-// TODO接口待定
 // 获取用户详情
 export function QueryUserDetail(userId) {
   return request({
-    url: `${prefix}/user_info`,
+    url: `${prefix}/dept`,
     method: 'get',
     params: {
-      userId: userId
+      userId
     }
   });
 }
+
+// 新增用户
+export function AddUser(data) {
+  return request({
+    url: `${prefix}/add_user`,
+    method: 'post',
+    data
+  });
+}
+// 修改用户
+export function UpdateUser(data) {
+  return request({
+    url: `${prefix}/edit_user`,
+    method: 'put',
+    data
+  });
+}
 // 切换用户状态
 export function UserStatusSwitch(data) {
   return request({
@@ -49,17 +65,6 @@ export function QueryUserPermission(userId) {
   });
 }
 
-// 机构列表
-export function QueryUserDept(userId) {
-  return request({
-    url: `${prefix}/dept`,
-    method: 'get',
-    params: {
-      userId
-    }
-  });
-}
-
 // 删除用户
 export function DeleteUser(userId) {
   return request({

+ 8 - 0
src/apis/permission/common.js

@@ -13,6 +13,14 @@ export function QueryAllRoleList() {
   });
 }
 
+// 部门列表
+export function QueryDeptTree() {
+  return request({
+    url: `/api/dept/list`,
+    method: 'get'
+  });
+}
+
 // 知识库列表
 export function QueryAllKnowledgeList() {
   const params = {

+ 48 - 0
src/apis/permission/org.js

@@ -0,0 +1,48 @@
+import request from '../../base/ajax';
+
+const prefix = '/api/dept';
+
+// 部门列表 在common里
+
+// 查询机构详情
+export function QueryDeptDetail(deptId) {
+  return request({
+    url: `${prefix}/${deptId}`,
+    method: 'get'
+  });
+}
+
+// 修改机构
+export function UpdateDept(data) {
+  return request({
+    url: `${prefix}/edit_dept`,
+    method: 'put',
+    data
+  });
+}
+
+// 修改机构的父级
+export function UpdateDeptParent(data) {
+  return request({
+    url: `${prefix}/dept_parent`,
+    method: 'put',
+    data
+  });
+}
+
+// 新增机构
+export function CreateDept(data) {
+  return request({
+    url: `${prefix}/add_dept`,
+    method: 'post',
+    data
+  });
+}
+
+// 删除机构
+export function DeleteDept(deptId) {
+  return request({
+    url: `${prefix}/${deptId}`,
+    method: 'delete'
+  });
+}

+ 6 - 39
src/modules/permission/TreeParts.vue

@@ -9,15 +9,14 @@
         </a-button>
       </a-tooltip>
     </template>
-    <a-tree :draggable="is_lock" blockNode :data="treeData" :show-line="true" :fieldNames="{
+    <a-tree :draggable="is_lock" blockNode :data="treeData" :show-line="true" :default-expand-all="true" :fieldNames="{
       key: 'deptId',
       title: 'deptName',
       children: 'children',
     }" @drop="onDrop" @select="nodeClick">
       <template #extra="nodeData">
         <IconPlus class="icon-plus" @click="() => onAddBtnClick(nodeData)" />
-        <a-popconfirm v-if="nodeData.deptName != 'root'" content="请确认是否删除?" type="success"
-          @ok="() => onDeleteBtnClickDelete(nodeData)">
+        <a-popconfirm v-if="nodeData.parentId" content="请确认是否删除?" type="success" @ok="() => onDeleteBtnClick(nodeData)">
           <IconDelete class="icon-delete" />
         </a-popconfirm>
       </template>
@@ -36,7 +35,7 @@ const props = defineProps({
 
 const { treeData } = toRefs(props);
 
-const emit = defineEmits(['nodeClick', 'onAddBtnClick', 'onDeleteBtnClickDelete']);
+const emit = defineEmits(['nodeClick', 'onAddBtnClick', 'onDrop', 'onDeleteBtnClick']);
 
 let is_lock = ref(false);
 
@@ -51,44 +50,12 @@ const nodeClick = (id) => {
 const onAddBtnClick = (nodeData) => {
   emit('addBtnClick', nodeData);
 }
-const onDeleteBtnClickDelete = (nodeData) => {
-  emit('deleteBtnClickDelete', nodeData);
+const onDeleteBtnClick = (nodeData) => {
+  emit('deleteBtnClick', nodeData);
 };
 
 const onDrop = ({ dragNode, dropNode, dropPosition }) => {
-  const data = treeData.value;
-  OrganizationUpdate({
-    orderNum: '0',
-    parentId: dropNode.deptId,
-    deptId: dragNode.deptId,
-  });
-  const loop = (data, key, callback) => {
-    data.some((item, index, arr) => {
-      if (item.deptId === key) {
-        callback(item, index, arr);
-        return true;
-      }
-      if (item.children) {
-        return loop(item.children, key, callback);
-      }
-      return false;
-    });
-  };
-
-  loop(data, dragNode.deptId, (_, index, arr) => {
-    arr.splice(index, 1);
-  });
-
-  if (dropPosition === 0) {
-    loop(data, dropNode.deptId, (item) => {
-      item.children = item.children || [];
-      item.children.push(dragNode);
-    });
-  } else {
-    loop(data, dropNode.deptId, (_, index, arr) => {
-      arr.splice(dropPosition < 0 ? index : index + 1, 0, dragNode);
-    });
-  }
+  emit('drop', { dragNode, dropNode, dropPosition });
 };
 </script>
 

+ 31 - 18
src/modules/permission/account/AccountForm.vue

@@ -1,7 +1,7 @@
 <template>
   <a-form :model="edit_form" auto-label-width>
-    <a-row :gutter="24">
-      <a-col :span="12">
+    <a-row :gutter="24" class="flex-row">
+      <a-col :span="12" v-if="!is_edit_mode" class="flex-col">
         <a-form-item field="userName" label="用户名" :rules="[
           { required: true, message: '用户名必填' },
           { maxLength: 50, message: '长度不超过50' },
@@ -9,19 +9,19 @@
           <a-input v-model="edit_form.userName" />
         </a-form-item>
       </a-col>
-      <a-col :span="12">
+      <a-col :span="12" class="flex-col">
         <a-form-item field="loginName" label="姓名">
           <a-input v-model="edit_form.loginName" />
         </a-form-item>
       </a-col>
     </a-row>
-    <a-row :gutter="24">
-      <a-col :span="12">
+    <a-row :gutter="24" class="flex-row">
+      <a-col :span="12" class="flex-col">
         <a-form-item field="phone" label="手机号">
           <a-input v-model="edit_form.phone" />
         </a-form-item>
       </a-col>
-      <a-col :span="12">
+      <a-col :span="12" class="flex-col">
         <a-form-item required field="email" label="邮箱" :rules="[
           { required: true, message: '邮箱必填' },
           { maxLength: 50, message: '长度不超过50' },
@@ -30,16 +30,15 @@
         </a-form-item>
       </a-col>
     </a-row>
-    <a-row :gutter="24">
-      <!-- 编辑则不显示密码 -->
-      <a-col v-if="!is_edit_mode" :span="12">
+    <a-row :gutter="24" class="flex-row">
+      <a-col v-if="!is_edit_mode" :span="12" class="flex-col">
         <a-form-item field="pwd" label="密码">
-          <a-input v-model="edit_form.pwd" type="pwd" />
+          <a-input v-model="edit_form.pwd" type="password" />
         </a-form-item>
       </a-col>
-      <a-col :span="12">
+      <a-col :span="12" class="flex-col">
         <a-form-item field="roles" label="角色">
-          <a-select multiple v-model="edit_form.roles" :options="role_list" :default-value="edit_form_role_computed"
+          <a-select multiple v-model="edit_form.roles" :options="role_list"
             :field-names="{ value: 'roleId', label: 'roleName' }" @change="roleChange">
           </a-select>
         </a-form-item>
@@ -49,7 +48,7 @@
 </template>
 
 <script setup>
-import { toRefs, computed } from 'vue';
+import { toRefs } from 'vue';
 
 const props = defineProps({
   edit_form: Object,
@@ -59,13 +58,27 @@ const props = defineProps({
 
 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>
+
+<style lang="css" scoped>
+.flex-row {
+  display: flex;
+  flex-wrap: wrap;
+  margin-left: -12px;
+  margin-right: -12px;
+  /* 调整为实际的gutter值 */
+}
+
+.flex-col {
+  padding-left: 12px;
+  padding-right: 12px;
+  /* 调整为实际的gutter值 */
+  flex: 1;
+  min-width: 0;
+  /* 防止flex项目收缩 */
+}
+</style>

+ 26 - 28
src/modules/permission/account/DeptConfigModal.vue

@@ -29,7 +29,7 @@
 </template>
 
 <script setup>
-import { ref, toRefs, onMounted } from 'vue';
+import { ref, toRefs, watch } from 'vue';
 
 // 定义组件的 props 和 emits
 const props = defineProps({
@@ -38,13 +38,13 @@ const props = defineProps({
     type: Array,
     default: () => []
   },
-  record: {
+  dept_detail: {
     type: Object,
-    default: () => { }
+    default: () => []
   }
 });
 
-const { visible, dept_list, record } = toRefs(props);
+const { visible, dept_list, dept_detail } = toRefs(props);
 
 const emit = defineEmits(['close', 'ok']);
 
@@ -103,32 +103,30 @@ const editDeptHandleOk = () => {
   emit('ok', { checked_keys: checked_keys.value });
 };
 
-onMounted(() => {
-  // 处理传入的部门数据
-  if (record?.dept) {
-    record.dept.forEach((val) => {
-      check_strictly.value.push({
-        deptId: val.deptId,
-        deptName: val.deptName
-      });
-      checked_keys.value.push(val.deptId);
-      expand_kdys.value.push(val.deptId);
-      record.roles.forEach(
-        (r) => {
-          if (r.dept) {
-            r.dept.forEach((d) => {
-              if (d.deptId == val.deptId) {
-                check_strictly_dept_role.value.push({
-                  roleId: r.roleId,
-                  roleName: r.roleName,
-                  deptId: d.deptId,
-                });
-              }
-            });
-          }
+watch(() => props.dept_detail, (newVal) => {
+  if (newVal) {
+    newVal.forEach(val => {
+      if (!checked_keys.value.includes(val.deptId)) {
+        check_strictly.value.push({
+          deptId: val.deptId,
+          deptName: val.deptName
+        });
+        checked_keys.value.push(val.deptId);
+        expand_kdys.value.push(val.deptId);
+      }
+
+      val.roles.forEach((role) => {
+        if (!check_strictly_dept_role.value.some(item => item.roleId === role.roleId && item.deptId === val.deptId)) {
+          check_strictly_dept_role.value.push({
+            roleId: role.roleId,
+            roleName: role.roleName,
+            deptId: val.deptId
+          });
         }
-      );
+      });
     });
+
+
   }
 });
 </script>

+ 55 - 152
src/modules/permission/account/index.vue

@@ -31,7 +31,7 @@
     :knowledge_permissions_list="knowledge_permissions_list" :dialog_permissions_list="dialog_permissions_list"
     :agent_permissions_list="agent_permissions_list" />
 
-  <DeptConfigModal :visible.sync="dept_config_visible" :dept_list="dept_list" :record="current_record" @ok=""
+  <DeptConfigModal :visible.sync="dept_config_visible" :dept_list="dept_list" :dept_detail="dept_detail" @ok=""
     @cancel="handleDeptConfig(null, false)" />
 
 </template>
@@ -46,8 +46,11 @@ import AccountForm from './AccountForm.vue';
 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';
+import {
+  QueryUserList, QueryUserDetail, AddUser,
+  UpdateUser, QueryUserPermission, UserStatusSwitch, ResetPassword, DeleteUser
+} from '../../../apis/permission/account';
+import { QueryAllRoleList, QueryDeptTree } from '../../../apis/permission/common';
 
 const keywords = ref('');
 // 表格相关
@@ -89,132 +92,8 @@ const agent_permissions_list = ref([])
 
 // 部门配置相关
 const dept_config_visible = ref(false);
-const current_record = ref(null);
-const dept_list = ref([
-  {
-    "address": null,
-    "children": [
-      {
-        "address": "",
-        "children": [],
-        "code": null,
-        "createTime": "Thu, 12 Sep 2024 14:56:43 GMT",
-        "deptId": "2af7cb5e-1178-4adc-8abb-9780f7543081",
-        "deptName": "成都",
-        "email": "",
-        "iconCls": null,
-        "leader": "成都",
-        "orderNum": 0,
-        "parentId": "0",
-        "parentName": "总部",
-        "phone": "成都",
-        "roles": [],
-        "status": "",
-        "updateTime": "Thu, 12 Sep 2024 14:56:43 GMT"
-      },
-      {
-        "address": null,
-        "children": [],
-        "code": null,
-        "createTime": "Sun, 22 May 2022 09:59:33 GMT",
-        "deptId": "5477d9a9-e41e-485f-bb08-697e8facef88",
-        "deptName": "南京分公司",
-        "email": "ss@ada.com",
-        "iconCls": null,
-        "leader": "dd",
-        "orderNum": 0,
-        "parentId": "0",
-        "parentName": "总部",
-        "phone": "18905189016",
-        "roles": [],
-        "status": "0",
-        "updateTime": "Tue, 12 Nov 2024 03:05:10 GMT"
-      },
-      {
-        "address": null,
-        "children": [
-          {
-            "address": "",
-            "children": [
-              {
-                "address": "",
-                "children": [],
-                "code": null,
-                "createTime": "Tue, 12 Nov 2024 03:09:57 GMT",
-                "deptId": "c6ae93de-2436-4090-b567-ec4835c74112",
-                "deptName": "成都",
-                "email": "",
-                "iconCls": null,
-                "leader": "柔柔弱弱",
-                "orderNum": 0,
-                "parentId": "f86724f0-94d9-445c-9d95-3ec2540da0f8",
-                "parentName": "太平洋派出所",
-                "phone": "1234242342",
-                "roles": [],
-                "status": "",
-                "updateTime": "Tue, 12 Nov 2024 06:58:15 GMT"
-              }
-            ],
-            "code": null,
-            "createTime": "Thu, 05 Sep 2024 03:15:13 GMT",
-            "deptId": "f86724f0-94d9-445c-9d95-3ec2540da0f8",
-            "deptName": "太平洋派出所",
-            "email": "",
-            "iconCls": null,
-            "leader": "12",
-            "orderNum": 0,
-            "parentId": "ce627e90-57d6-4ed4-a789-1f3dd467ae7d",
-            "parentName": "上海分公司",
-            "phone": "12",
-            "roles": [
-              {
-                "deptId": "f86724f0-94d9-445c-9d95-3ec2540da0f8",
-                "roleId": "19f00d46-8f1b-45b5-b7b7-6197d7b8cb33",
-                "roleName": "管理员1"
-              }
-            ],
-            "status": "0",
-            "updateTime": "Tue, 12 Nov 2024 06:58:07 GMT"
-          }
-        ],
-        "code": null,
-        "createTime": "Tue, 24 May 2022 23:54:10 GMT",
-        "deptId": "ce627e90-57d6-4ed4-a789-1f3dd467ae7d",
-        "deptName": "上海分公司",
-        "email": null,
-        "iconCls": null,
-        "leader": "jack",
-        "orderNum": 0,
-        "parentId": "0",
-        "parentName": "总部",
-        "phone": null,
-        "roles": [
-          {
-            "deptId": "ce627e90-57d6-4ed4-a789-1f3dd467ae7d",
-            "roleId": "301ca518-2ed0-4092-a2ee-e46c24a42c8a",
-            "roleName": "普通"
-          }
-        ],
-        "status": "0",
-        "updateTime": "Wed, 18 Sep 2024 09:58:16 GMT"
-      }
-    ],
-    "code": null,
-    "createTime": "Mon, 28 Nov 2016 10:34:54 GMT",
-    "deptId": "0",
-    "deptName": "总部",
-    "email": null,
-    "iconCls": "ext-icon-bricks",
-    "leader": null,
-    "orderNum": 100,
-    "parentId": "",
-    "parentName": "",
-    "phone": null,
-    "roles": [],
-    "status": "0",
-    "updateTime": "Mon, 28 Nov 2016 10:35:12 GMT"
-  }
-]);
+const dept_detail = ref([]);
+const dept_list = ref([]);
 
 const getUserList = async () => {
   const params = {
@@ -224,26 +103,24 @@ const getUserList = async () => {
   };
   table_loading.value = true
   const { code, data } = await QueryUserList(params);
+
   if (code === 200) {
+    // 处理部门名称和角色名称
     for (const user of data.rows) {
       if (user.dept) {
-        for (const d of user.dept) {
-          if (user.deptName) {
-            user.deptName += d.deptName + ',';
-          } else {
-            user.deptName = d.deptName + ',';
-          }
+        for (let i = 0; i < user.dept.length; i++) {
+          const d = user.dept[i];
+          user.deptName += d.deptName + (i < user.dept.length - 1 ? ', ' : '');
         }
       }
+
       if (user.roles) {
-        for (const r of user.roles) {
-          if (user.roleName) {
-            user.roleName += r.roleName + ',';
-          } else {
-            user.roleName = r.roleName + ',';
-          }
+        for (let i = 0; i < user.roles.length; i++) {
+          const r = user.roles[i];
+          user.roleName += r.roleName + (i < user.roles.length - 1 ? ', ' : '');
         }
       }
+
     }
 
     pagination_props.value.total = data.total;
@@ -264,6 +141,7 @@ const resetClick = () => {
   getUserList();
 }
 const createClick = () => {
+  edit_form.userId = '';
   edit_form.userName = '';
   edit_form.loginName = '';
   edit_form.phone = '';
@@ -271,7 +149,8 @@ const createClick = () => {
   edit_form.pwd = '';
   edit_form.roles = [];
   is_edit_mode.value = false;
-  edit_visible.value = true;
+
+  handleEdit(null, true)
 }
 const refreshClick = () => {
   console.log('刷新')
@@ -325,19 +204,23 @@ const handleResetPassword = async (record) => {
 
 const handleEdit = async (record, visible) => {
 
-  const { code, data } = await QueryAllRoleList();
-  if (code === 200) {
-    role_list.value = data.rows;
+  if (visible) {
+    const { code, data } = await QueryAllRoleList();
+    if (code === 200) {
+      role_list.value = data.rows;
+    }
   }
 
   if (record) {
+    edit_form.userId = record.userId;
     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.roles = record.roles;
+    edit_form.roles = record.roles.map(role => role.roleId);
 
+    is_edit_mode.value = true;
   }
 
   edit_visible.value = visible;
@@ -362,12 +245,10 @@ const handleView = async (record, visible) => {
 // 部门配置
 const handleDeptConfig = async (record, visible) => {
   if (record) {
-    current_record.value = record;
-    const { code, data: { rows } } = await QueryUserDept(record.userId);
+    // const { code, data } = await QueryUserDetail(record.userId);
+    const { code, data: { rows } } = await QueryUserDetail(77);
     if (code === 200) {
-      // TODO接口 机构接上再接这个
-      console.log('rows', rows)
-      // dept_list.value = rows;
+      dept_detail.value = rows;
     }
   }
   dept_config_visible.value = visible;
@@ -384,8 +265,23 @@ const handleDelete = async (userId) => {
     getUserList();
   }
 }
-const modalSave = () => {
+const modalSave = async () => {
   edit_visible.value = false;
+  const data = {
+    userId: is_edit_mode.value ? edit_form.userId : undefined,
+    ...edit_form,
+  }
+  const apiCall = is_edit_mode.value ? UpdateUser : AddUser;
+  const { code } = await apiCall(data);
+
+  if (code === 200) {
+    const action = is_edit_mode.value ? '编辑' : '新增';
+    Message.success({
+      title: `${action}账号`,
+      content: `${action}成功`,
+    });
+    getUserList();
+  }
 }
 const tableSizeChange = (size) => {
   table_size.value = size;
@@ -405,8 +301,15 @@ const getMenuTitles = (data, result = []) => {
   return result;
 }
 
+const getDeptTree = async () => {
+  const { code, data: { rows } } = await QueryDeptTree();
+  if (code == 200) {
+    dept_list.value = rows;
+  }
+}
 onMounted(() => {
   getUserList()
+  getDeptTree()
 })
 </script>
 

+ 18 - 15
src/modules/permission/group/PermissionConfigModal.vue

@@ -61,7 +61,7 @@
 </template>
 
 <script setup>
-import { ref, toRefs, onMounted, computed } from 'vue';
+import { ref, toRefs, watch, computed } from 'vue';
 
 // 定义组件的 props 和 emits
 const props = defineProps({
@@ -173,21 +173,24 @@ const getCurrentTabTitle = computed(() => {
   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);
-  //   });
-  // }
-
+watch(() => props.record, (newVal) => {
+  if (newVal) {
+    const { knowledges, dialogs, llms } = newVal;
+    checked_knowledge.value = knowledges.map(k => k.id);
+    checked_agents.value = dialogs.map(a => a.id);
+    checked_model.value = llms.map(m => m.id);
+    checked_knowledge_list.value = knowledges.map(k => {
+      return { id: k.id, name: k.name };
+    });
+    checked_agents_list.value = dialogs.map(a => {
+      return { id: a.id, name: a.name };
+    });
+    checked_model_list.value = llms.map(m => {
+      return { id: m.id, name: m.name };
+    });
+  }
 });
+
 </script>
 
 <style lang="css" scoped>

+ 7 - 7
src/modules/permission/group/index.vue

@@ -30,7 +30,8 @@
 
   <!-- TODO -->
   <PermissionConfigModal :visible.sync="permission_config_visible" :knowledge_list="knowledge_list"
-    :agents_list="agents_list" @getActiveTab="handlePermissionModalTab" @ok="handlePermissionConfigSave"
+    :agents_list="agents_list" :model_list="model_list" :record="current_record"
+    @getActiveTab="handlePermissionModalTab" @ok="handlePermissionConfigSave"
     @cancel="handlePermissionConfig(null, false)" />
 
 </template>
@@ -54,7 +55,7 @@ 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: 'groupName', width: 150, titleSlotName: 'groupName' },
   { title: '描述', dataIndex: 'description', ellipsis: true, tooltip: true, titleSlotName: 'description' },
   { title: '状态', dataIndex: 'status', slotName: 'status' },
   { title: '操作', dataIndex: 'operation', slotName: 'operationSlot' },
@@ -85,6 +86,7 @@ const selectedMemberList = ref([]);
 const permission_config_visible = ref(false);
 const knowledge_list = ref([]);
 const agents_list = ref([]);
+const model_list = ref([]);
 
 const getGroupList = async () => {
   const params = {
@@ -157,7 +159,7 @@ const statusChange = async (record) => {
 const handleEdit = (record, visible) => {
   if (record) {
     edit_form.groupId = record.groupId;
-    edit_form.groupName = record.name;
+    edit_form.groupName = record.groupName;
     edit_form.description = record.description;
     is_edit_mode.value = true;
   }
@@ -167,7 +169,6 @@ const handleEdit = (record, 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];
@@ -206,8 +207,8 @@ const updateSelectedMemberList = (newSelection) => {
 
 // 权限配置
 const handlePermissionConfig = async (record, visible) => {
-  // TODO接口 回显问题
   if (record) {
+    current_record.value = record;
     edit_form.groupId = record.groupId;
     getConfigList('1');
   }
@@ -252,8 +253,7 @@ 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,
+    ...edit_form
   };
 
   const apiCall = is_edit_mode.value ? UpdateGroup : CreateGroup;

+ 3 - 3
src/modules/permission/org/OrgForm.vue

@@ -14,9 +14,9 @@
       :rules="[{ required: true, message: '联系人必填' }, { maxLength: 50, message: '长度不超过50' }]">
       <a-input v-model="org_form.leader" />
     </a-form-item>
-    <a-form-item field="phone" label="联系电话"
+    <a-form-item field="orderNum" label="联系电话"
       :rules="[{ required: true, message: '联系电话必填' }, { maxLength: 50, message: '长度不超过50' }]">
-      <a-input v-model="org_form.phone" />
+      <a-input v-model="org_form.orderNum" />
     </a-form-item>
     <a-form-item field="address" label="机构地址">
       <a-input v-model="org_form.address" />
@@ -42,7 +42,7 @@ const props = defineProps({
       status: 0,
       deptName: '',
       leader: '',
-      phone: '',
+      orderNum: '',
       address: ''
     })
   }

+ 118 - 139
src/modules/permission/org/index.vue

@@ -2,7 +2,7 @@
   <div class="organization-container">
     <div class="left">
       <TreeParts :treeData="org_tree_data" @nodeClick="onNodeClick" @addBtnClick="onAddBtnClick"
-        @deleteBtnClick="onDeleteBtnClick" />
+        @deleteBtnClick="onDeleteBtnClick" @drop="onNodeDrop" />
     </div>
     <div class="right">
       <a-card title="详情" style="height: 100%;">
@@ -15,178 +15,157 @@
       </a-card>
     </div>
 
-    <Modal :visible.sync="org_visible" @ok="orgFromSave" @cancel="org_visible = false" :title="'新增'">
-      <OrgForm></OrgForm>
+    <Modal :visible.sync="org_visible" @ok="orgFromSave" @cancel="orgFromCancel" :title="'新增'">
+      <OrgForm :org_form="org_form"></OrgForm>
     </Modal>
   </div>
 </template>
 
 <script setup>
-import { ref, reactive, toRefs } from 'vue';
+import { ref, reactive, onMounted } from 'vue';
+import { Message } from '@arco-design/web-vue';
 import TreeParts from '../TreeParts.vue';
 import OrgForm from './OrgForm.vue';
 import Modal from '../Modal.vue';
 
-const org_visible = ref(false);
+import {
+  QueryDeptDetail, UpdateDept, UpdateDeptParent, CreateDept, DeleteDept
+} from '../../../apis/permission/org';
 
-const org_tree_data = ref([
-  {
-    "address": null,
-    "children": [
-      {
-        "address": "",
-        "children": [],
-        "code": null,
-        "createTime": "Thu, 12 Sep 2024 14:56:43 GMT",
-        "deptId": "2af7cb5e-1178-4adc-8abb-9780f7543081",
-        "deptName": "成都",
-        "email": "",
-        "iconCls": null,
-        "leader": "成都",
-        "orderNum": 0,
-        "parentId": "0",
-        "parentName": "总部",
-        "phone": "成都",
-        "roles": [],
-        "status": "",
-        "updateTime": "Thu, 12 Sep 2024 14:56:43 GMT"
-      },
-      {
-        "address": null,
-        "children": [],
-        "code": null,
-        "createTime": "Sun, 22 May 2022 09:59:33 GMT",
-        "deptId": "5477d9a9-e41e-485f-bb08-697e8facef88",
-        "deptName": "南京分公司",
-        "email": "ss@ada.com",
-        "iconCls": null,
-        "leader": "dd",
-        "orderNum": 0,
-        "parentId": "0",
-        "parentName": "总部",
-        "phone": "18905189016",
-        "roles": [],
-        "status": "0",
-        "updateTime": "Tue, 12 Nov 2024 03:05:10 GMT"
-      },
-      {
-        "address": null,
-        "children": [
-          {
-            "address": "",
-            "children": [
-              {
-                "address": "",
-                "children": [],
-                "code": null,
-                "createTime": "Tue, 12 Nov 2024 03:09:57 GMT",
-                "deptId": "c6ae93de-2436-4090-b567-ec4835c74112",
-                "deptName": "成都",
-                "email": "",
-                "iconCls": null,
-                "leader": "柔柔弱弱",
-                "orderNum": 0,
-                "parentId": "f86724f0-94d9-445c-9d95-3ec2540da0f8",
-                "parentName": "太平洋派出所",
-                "phone": "1234242342",
-                "roles": [],
-                "status": "",
-                "updateTime": "Tue, 12 Nov 2024 06:58:15 GMT"
-              }
-            ],
-            "code": null,
-            "createTime": "Thu, 05 Sep 2024 03:15:13 GMT",
-            "deptId": "f86724f0-94d9-445c-9d95-3ec2540da0f8",
-            "deptName": "太平洋派出所",
-            "email": "",
-            "iconCls": null,
-            "leader": "12",
-            "orderNum": 0,
-            "parentId": "ce627e90-57d6-4ed4-a789-1f3dd467ae7d",
-            "parentName": "上海分公司",
-            "phone": "12",
-            "roles": [
-              {
-                "deptId": "f86724f0-94d9-445c-9d95-3ec2540da0f8",
-                "roleId": "19f00d46-8f1b-45b5-b7b7-6197d7b8cb33",
-                "roleName": "管理员1"
-              }
-            ],
-            "status": "0",
-            "updateTime": "Tue, 12 Nov 2024 06:58:07 GMT"
-          }
-        ],
-        "code": null,
-        "createTime": "Tue, 24 May 2022 23:54:10 GMT",
-        "deptId": "ce627e90-57d6-4ed4-a789-1f3dd467ae7d",
-        "deptName": "上海分公司",
-        "email": null,
-        "iconCls": null,
-        "leader": "jack",
-        "orderNum": 0,
-        "parentId": "0",
-        "parentName": "总部",
-        "phone": null,
-        "roles": [
-          {
-            "deptId": "ce627e90-57d6-4ed4-a789-1f3dd467ae7d",
-            "roleId": "301ca518-2ed0-4092-a2ee-e46c24a42c8a",
-            "roleName": "普通"
-          }
-        ],
-        "status": "0",
-        "updateTime": "Wed, 18 Sep 2024 09:58:16 GMT"
-      }
-    ],
-    "code": null,
-    "createTime": "Mon, 28 Nov 2016 10:34:54 GMT",
-    "deptId": "0",
-    "deptName": "总部",
-    "email": null,
-    "iconCls": "ext-icon-bricks",
-    "leader": null,
-    "orderNum": 100,
-    "parentId": "",
-    "parentName": "",
-    "phone": null,
-    "roles": [],
-    "status": "0",
-    "updateTime": "Mon, 28 Nov 2016 10:35:12 GMT"
-  }
-]);
+import { QueryDeptTree } from '../../../apis/permission/common';
+
+const org_visible = ref(false);
+const is_edit_mode = ref(true);
+const org_tree_data = ref([]);
 
 const org_form = reactive({
   parentName: '',
   status: 0,
   deptName: '',
   leader: '',
-  phone: '',
+  orderNum: '',
   address: ''
 });
+
+const getDeptTree = async () => {
+  const { code, data: { rows } } = await QueryDeptTree();
+  if (code == 200) {
+    org_tree_data.value = rows;
+  }
+}
+
+
 // 树节点操作相关
-const onNodeClick = (id) => {
-  console.log('id', id)
+const onNodeClick = async (id) => {
+  const { data: { data } } = await QueryDeptDetail(id);
+  org_form.deptId = id;
+  org_form.parentName = data.parentName;
+  org_form.status = data.status;
+  org_form.deptName = data.deptName;
+  org_form.leader = data.leader;
+  org_form.orderNum = data.orderNum;
+  org_form.address = data.address;
+
 }
 const onAddBtnClick = (nodeData) => {
-  console.log('nodeData', nodeData)
+  org_form.deptId = '';
+  org_form.parentName = nodeData.deptName;
+  org_form.parentId = nodeData.deptId
+  org_form.status = 0;
+  org_form.deptName = '';
+  org_form.leader = '';
+  org_form.orderNum = '';
+  org_form.address = '';
+
   org_visible.value = true;
+  is_edit_mode.value = false;
 }
-const onDeleteBtnClick = (nodeData) => {
-  console.log('nodeData', nodeData)
+
+const onDeleteBtnClick = async ({ deptId }) => {
+  const { code } = await DeleteDept(deptId);
+  if (code === 200) {
+    Message.success({
+      title: '删除',
+      content: '删除成功',
+    });
+  }
+  getDeptTree();
 }
 
-const orgFromSave = (data) => {
-  console.log(data);
+const orgFromSave = async () => {
+  const data = {
+    ...org_form,
+    deptId: (is_edit_mode.value && org_form.deptId) ? org_form.deptId[0] : null
+  }
+
+  const apiCall = is_edit_mode.value ? UpdateDept : CreateDept;
+  const { code } = await apiCall(data);
+
+  if (code === 200) {
+    const action = is_edit_mode.value ? '编辑' : '新增';
+    Message.success({
+      title: `${action}账号`,
+      content: `${action}成功`,
+    });
+
+    getDeptTree()
+    org_visible = false;
+  }
 }
 
 const orgFromReset = () => {
+  org_form.deptId = null;
   org_form.parentName = '';
   org_form.status = 0;
   org_form.deptName = '';
   org_form.leader = '';
-  org_form.phone = '';
+  org_form.orderNum = '';
   org_form.address = '';
 }
+
+const orgFromCancel = () => {
+  is_edit_mode.value = true;
+  org_visible.value = false;
+}
+
+const onNodeDrop = async ({ dropNode, dragNode, dropPosition }) => {
+  const data = org_tree_data.value;
+  UpdateDeptParent({
+    orderNum: '0',
+    parentId: dropNode.deptId,
+    deptId: dragNode.deptId,
+  });
+  const loop = (data, key, callback) => {
+    data.some((item, index, arr) => {
+      if (item.deptId === key) {
+        callback(item, index, arr);
+        return true;
+      }
+      if (item.children) {
+        return loop(item.children, key, callback);
+      }
+      return false;
+    });
+  };
+
+  loop(data, dragNode.deptId, (_, index, arr) => {
+    arr.splice(index, 1);
+  });
+
+  if (dropPosition === 0) {
+    loop(data, dropNode.deptId, (item) => {
+      item.children = item.children || [];
+      item.children.push(dragNode);
+    });
+  } else {
+    loop(data, dropNode.deptId, (_, index, arr) => {
+      arr.splice(dropPosition < 0 ? index : index + 1, 0, dragNode);
+    });
+  }
+}
+onMounted(() => {
+  getDeptTree();
+})
 </script>
 
 <style lang="css" scoped>