From 42e3694b8c48ef8d7b9cec3a8e48da666bcfcbe3 Mon Sep 17 00:00:00 2001
From: zhangxiao <898441624@qq.com>
Date: 星期五, 13 九月 2024 14:49:17 +0800
Subject: [PATCH] 增加权限管理-资源的拖拽功能锁定按钮

---
 src/views/authority/role/index.vue |  498 ++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 367 insertions(+), 131 deletions(-)

diff --git a/src/views/authority/role/index.vue b/src/views/authority/role/index.vue
index 2704363..d96e13b 100644
--- a/src/views/authority/role/index.vue
+++ b/src/views/authority/role/index.vue
@@ -77,9 +77,6 @@
         <template #index="{ rowIndex }">
           {{ rowIndex + 1 + (pagination.current - 1) * pagination.pageSize }}
         </template>
-        <template #dept="{ record }">{{
-          record.dept ? record.dept.deptName : ''
-        }}</template>
         <template #status="{ record }">
           <a-switch
             checked-value="1"
@@ -91,24 +88,25 @@
         <template #operations="{ record }">
           <a-space>
             <a-button type="outline" @click="operation(2, record)"
-              >缂栬緫</a-button
+            >缂栬緫</a-button
             >
+            <a-button
+              type="dashed"
+              status="warning"
+              @click="operation(4, record)"
+            >璧勬簮閰嶇疆</a-button>
+            <a-button
+              type="dashed"
+              status="success"
+              @click="operation(5, record)"
+            >閮ㄩ棬閰嶇疆</a-button>
             <a-popconfirm
-              content="Are you sure you want to delete?"
+              content="璇风‘璁ゆ槸鍚﹀垹闄わ紵"
               type="success"
               @ok="operation(3, record)"
             >
               <a-button type="outline" status="danger">鍒犻櫎</a-button>
             </a-popconfirm>
-            <a-button
-              type="dashed"
-              status="warning"
-              @click="operation(4, record)"
-              >鏉冮檺閰嶇疆</a-button
-            >
-            <a-button status="success" @click="operation(5, record)"
-              >閮ㄩ棬閰嶇疆</a-button
-            >
           </a-space>
         </template>
       </a-table>
@@ -119,60 +117,14 @@
       @cancel="handleCancel(1)"
       @ok="editHandleOk"
     >
-      <a-form :model="editform">
-        <a-form-item field="roleName" label="瑙掕壊鍚�">
+      <a-form  ref="formRef" :model="editform">
+        <a-form-item required field="roleName" label="瑙掕壊鍚�" :rules="[{required:true,message:'瑙掕壊鍚嶅繀濉�'},{maxLength:50,message:'闀垮害涓嶈秴杩�50'}]">
           <a-input v-model="editform.roleName" />
-        </a-form-item>
-        <a-form-item field="roleKey" label="鏉冮檺瀛楃涓�">
-          <a-input v-model="editform.roleKey" />
         </a-form-item>
         <a-form-item field="remark" label="澶囨敞">
           <a-input v-model="editform.remark" />
         </a-form-item>
       </a-form>
-    </a-modal>
-    <a-modal
-      width="50%"
-      v-model:visible="deptvisible"
-      title="閮ㄩ棬閰嶇疆"
-      @cancel="handleCancel(2)"
-      @ok="editDeptHandleOk"
-    >
-      <div :style="{ display: 'flex' }">
-        <a-card
-          :style="{ 'width': '460px', 'height': '500px', 'overflow-y': 'auto' }"
-          title="鏈烘瀯"
-          hoverable
-        >
-          <a-tree
-            class="tree-demo"
-            v-model:checked-keys="checkedKeys"
-            v-model:expanded-keys="expandKdys"
-            :checkable="true"
-            :data="treeData"
-            :show-line="showLine"
-            @check="onCheck"
-            :fieldNames="{
-              key: 'deptId',
-              title: 'deptName',
-              children: 'children',
-            }"
-            :check-strictly="checkStrictly"
-          >
-          </a-tree>
-        </a-card>
-        <a-card class="card-demo" title="鐢ㄦ埛鎵�灞炴満鏋�" hoverable>
-          <a-space wrap>
-            <a-tag
-              v-for="(tag, index) of checkStrictly"
-              :key="tag.deptId"
-              @close="handleRemove(tag)"
-            >
-              {{ tag.deptName }}
-            </a-tag>
-          </a-space>
-        </a-card>
-      </div>
     </a-modal>
     <a-modal
       width="30%"
@@ -190,22 +142,23 @@
               <icon-calendar />
               鑿滃崟
             </template>
+            <div class="cdtree">
             <a-tree
               class="tree-demo"
               v-model:checked-keys="checkedKeysMenu"
               v-model:expanded-keys="expandKdysMenu"
+              :only-check-leaf=true
               :checkable="true"
               :data="treeDataMenu"
-              :show-line="showLineMenu"
               @check="onCheckMenu"
               :fieldNames="{
                 key: 'menuId',
                 title: 'menuName',
                 children: 'children',
               }"
-              :check-strictly="checkStrictlyMenu"
             >
             </a-tree>
+            </div>
           </a-tab-pane>
           <a-tab-pane key="2">
             <template #title>
@@ -215,7 +168,6 @@
             <a-space direction="vertical" size="large">
               <a-checkbox-group
                 v-model="checkedKeysKnowledge"
-                direction="vertical"
                 @change="onCheckKnowledge"
               >
                 <a-checkbox
@@ -223,7 +175,7 @@
                   :value="knowledg.id"
                   :lable="knowledg.name"
                   @change="onCheckKnowledge"
-                >
+                  style="width:150px">
                   {{ knowledg.name }}
                 </a-checkbox>
               </a-checkbox-group>
@@ -236,7 +188,6 @@
             </template>
             <a-checkbox-group
               v-model="checkedKeysDialog"
-              direction="vertical"
               @change="onCheckDialog"
             >
               <a-checkbox
@@ -244,8 +195,39 @@
                 :value="dialog.id"
                 :lable="dialog.name"
                 @change="onCheckDialog"
-              >
+                style="width:150px">
                 {{ dialog.name }}
+              </a-checkbox>
+            </a-checkbox-group>
+            <a-checkbox-group
+              v-model="checkedKeysAgent"
+              @change="onCheckAgent"
+            >
+              <a-checkbox
+                v-for="(agent, index) of AgentList"
+                :value="agent.id"
+                :lable="agent.title"
+                @change="onCheckAgent"
+                style="width:150px">
+                {{ agent.title }}
+              </a-checkbox>
+            </a-checkbox-group>
+          </a-tab-pane>
+          <a-tab-pane key="4">
+            <template #title>
+              <icon-user />
+              妯″瀷
+            </template>
+            <a-checkbox-group
+              v-model="checkedKeysModel"
+              @change="onCheckModel"
+            >
+              <a-checkbox
+                v-for="(model, index) of ModelList"
+                :value="model.id"
+                @change="onCheckModel"
+                style="width:100%">
+                {{ model.llm_factory+" "+model.llm_name+" "+model.model_type }}
               </a-checkbox>
             </a-checkbox-group>
           </a-tab-pane>
@@ -258,7 +240,7 @@
             'margin': '1px',
           }"
           class="card-demo"
-          title="鐢ㄦ埛鎵�鏈夋潈闄�"
+          title="瑙掕壊鎵�鏈夋潈闄�"
           hoverable
         >
           <a-space wrap>
@@ -292,6 +274,64 @@
             >
               {{ tag.dialogName }}
             </a-tag>
+            <a-tag
+              v-for="(tag, index) of checkStrictlyAgent"
+              :key="tag.agentId"
+              @close="handleDialogRemove(tag)"
+            >
+              {{ tag.agentTitle }}
+            </a-tag>
+          </a-space>
+          <a-divider />
+          <a-space wrap>
+            妯″瀷:
+            <a-tag
+              v-for="(tag, index) of checkStrictlyModel"
+              :key="tag.modelId"
+            >
+              {{ tag.modelTitle }}
+            </a-tag>
+          </a-space>
+        </a-card>
+      </div>
+    </a-modal>
+    <a-modal
+      width="50%"
+      v-model:visible="deptvisible"
+      title="閮ㄩ棬閰嶇疆"
+      @cancel="handleCancel(3)"
+      @ok="editDeptHandleOk"
+    >
+      <div :style="{ display: 'flex' }">
+        <a-card
+          :style="{ 'width': '460px', 'height': '500px', 'overflow-y': 'auto' }"
+          title="閮ㄩ棬閰嶇疆"
+          hoverable
+        >
+          <a-tree
+            class="tree-demo"
+            v-model:checked-keys="checkedKeys"
+            v-model:expanded-keys="expandKdys"
+            :checkable="true"
+            :data="treeData"
+            :show-line="showLine"
+            @check="onCheck"
+            :fieldNames="{
+              key: 'deptId',
+              title: 'deptName',
+              children: 'children',
+            }"
+          >
+          </a-tree>
+        </a-card>
+        <a-card class="card-demo" title="瑙掕壊鎵�灞為儴闂�" hoverable>
+          <a-space wrap>
+            <a-tag
+              v-for="(tag, index) of checkStrictly"
+              :key="tag.deptId"
+            >
+              {{ tag.deptName }}
+            </a-tag>
           </a-space>
         </a-card>
       </div>
@@ -320,6 +360,10 @@
   } from "@/api/authority";
   import { Modal } from '@arco-design/web-vue';
   import Authheader from '@/views/authority/components/authheader.vue';
+  import router from "@/router";
+  import { queryCanvasList, queryModelList } from "@/api/Agent";
+  import { getUserInfo, getUserResources } from "@/utils/auth";
+  import { forEach } from "lodash";
 
   let treeData = ref([]);
   let checkedKeys = ref([]);
@@ -337,8 +381,17 @@
   let checkedKeysDialog = ref([]);
   let checkStrictlyDialog = ref([]);
 
+  let checkedKeysAgent = ref([]);
+  let checkStrictlyAgent = ref([]);
+  let checkStrictlyModel = ref([]);
+  let checkedKeysModel = ref([]);
+
+
   let knowledgeList = ref([]);
   let DialogsList = ref([]);
+  let AgentList = ref([]);
+  let ModelList = ref([]);
+
 
   let menuTips = ref(['鏉冮檺绠$悊', '瑙掕壊']);
   type SizeProps = 'mini' | 'small' | 'medium' | 'large';
@@ -373,32 +426,119 @@
   let resourcevisible = ref(false);
   let selectRole = ref({});
 
+  let u =JSON.parse(getUserInfo());
+
+
+  const editDeptHandleOk = async () => {
+    let depts: Array = [],
+      role: Role = { roleId: selectRole.value.roleId };
+    checkStrictly.value.forEach((val) => {
+      depts.push(val.deptId);
+    });
+    role.dept = depts;
+    await RoleEdit(role).then((res) => {
+      fetchData();
+    });
+  };
+
   const onCheck = (newCheckedKeys, event) => {
-    let o = { deptId: event.node.deptId, deptName: event.node.deptName };
     if (event.checked) {
-      checkStrictly.value.push(o);
+      if (event.node.children.length > 0) {
+        event.checkedNodes.forEach((node) => {
+          let o = { deptId: node.deptId, deptName: node.deptName,parentId: node.parentId };
+          checkStrictly.value.push(o);
+        });
+      } else {
+        let o = { deptId: event.node.deptId, deptName: event.node.deptName,parentId: event.node.parentId };
+        checkStrictly.value.push(o);
+      }
     } else {
+      let depts = [];
+      let isParent = false;
+      let parentNode;
       checkStrictly.value.forEach((val, idx, array) => {
-        // val: 褰撳墠鍊�
-        if (val.deptId == event.node.deptId) {
-          checkStrictly.value.splice(idx, 1);
-          return true;
+        if (val.deptId == event.node.parentId) {
+          parentNode = { deptId: val.deptId, deptName: val.deptName, parentId: val.parentId };
+        } else {
+          if (val.deptId != event.node.deptId && !findDeptChild(event.node, val)) {
+            depts.push({ deptId: val.deptId, deptName: val.deptName, parentId: val.parentId });
+            if (val.parentId == event.node.parentId && val.parentId.length>0) {
+              isParent = true;
+            }
+          }
+        }
+      });
+      if (isParent && parentNode) {
+        depts.push(parentNode);
+      }
+      checkStrictly.value = depts;
+    }
+  };
+
+  const findDeptChild = (node, val): boolean => {
+    let isExist = false;
+    if (node.children?.length > 0) {
+      node.children.forEach((child) => {
+        if (val.deptId == child.deptId) {
+          isExist = isExist || true;
+        } else {
+          isExist = isExist || findDeptChild(child, val);
         }
       });
     }
+    return isExist;
   };
+
+  const OrganizationData = async (key) => {
+    await OrganizationList(key).then((res) => {
+      treeData.value = [...res.rows];
+    });
+  };
+
+  const eachChildrenAdd=(node)=>{
+    if (node.children?.length > 0) {
+      node.children.forEach((child) => {
+        checkStrictlyMenu.value.push({ menuId: child.menuId, menuName: child.menuName });
+        eachChildrenAdd(child);
+      });
+    }
+  }
+
+  const findChild = (node, val): boolean => {
+    let isExist = false;
+    if (node.children?.length > 0) {
+      node.children.forEach((child) => {
+        if (val.menuId == child.menuId) {
+          isExist = isExist || true;
+        } else {
+          isExist = isExist || findChild(child, val);
+        }
+      });
+    }
+    return isExist;
+  };
+
   const onCheckMenu = (newCheckedKeys, event) => {
     let o = { menuId: event.node.menuId, menuName: event.node.menuName };
     if (event.checked) {
       checkStrictlyMenu.value.push(o);
+      eachChildrenAdd(event.node);
+      if (event.halfCheckedNodes?.length > 0) {
+        event.halfCheckedNodes.forEach((child) => {
+          let e = { menuId: child.menuId, menuName: child.menuName };
+          if (checkStrictlyMenu.value.find((item) => item.menuId === e.menuId) == undefined) {
+            checkStrictlyMenu.value.push(e);
+          }
+        });
+      }
     } else {
+      let menus=[];
       checkStrictlyMenu.value.forEach((val, idx, array) => {
-        // val: 褰撳墠鍊�
-        if (val.menuId == event.node.menuId) {
-          checkStrictlyMenu.value.splice(idx, 1);
-          return true;
+        if (val.menuId != event.node.menuId && !findChild(event.node, val)) {
+          menus.push({ menuId: val.menuId, menuName: val.menuName });
         }
       });
+      checkStrictlyMenu.value = menus;
     }
   };
   const onCheckKnowledge = (newCheckedKeys, event) => {
@@ -418,6 +558,41 @@
       });
     }
   };
+  const onCheckAgent = (newCheckedKeys, event) => {
+    let o = {
+      agentId: event.target.value,
+      agentTitle: event.target.labels[0].innerText,
+    };
+    if (event.target.checked) {
+      checkStrictlyAgent.value.push(o);
+    } else {
+      checkStrictlyAgent.value.forEach((val, idx, array) => {
+        // val: 褰撳墠鍊�
+        if (val.agentId == event.target.value) {
+          checkStrictlyAgent.value.splice(idx, 1);
+          return true;
+        }
+      });
+    }
+  };
+  const onCheckModel = (newCheckedKeys, event) => {
+    let o = {
+      modelId: event.target.value,
+      modelTitle: event.target.labels[0].innerText,
+    };
+    if (event.target.checked) {
+      checkStrictlyModel.value.push(o);
+    } else {
+      checkStrictlyModel.value.forEach((val, idx, array) => {
+        // val: 褰撳墠鍊�
+        if (val.modelId == event.target.value) {
+          checkStrictlyModel.value.splice(idx, 1);
+          return true;
+        }
+      });
+    }
+  };
+
   const onCheckDialog = (newCheckedKeys, event) => {
     let o = {
       dialogId: event.target.value,
@@ -436,9 +611,7 @@
     }
   };
 
-  const handleRemove = (key) => {
-    checkStrictly.value = checkStrictly.value.filter((tag) => tag !== key);
-  };
+
   const handleMenuRemove = (key) => {
     checkStrictlyMenu.value = checkStrictlyMenu.value.filter(
       (tag) => tag !== key
@@ -454,7 +627,7 @@
       (tag) => tag !== key
     );
   };
-
+  let formRef = ref();
   const basePagination: Pagination = {
     current: 1,
     pageSize: 15,
@@ -492,15 +665,6 @@
       dataIndex: 'roleName',
     },
     {
-      title: t('鍒涘缓鏃堕棿'),
-      dataIndex: 'createTime',
-    },
-    {
-      title: t('鏉冮檺瀛楃涓�'),
-      dataIndex: 'roleKey',
-      slotName: 'roleKey',
-    },
-    {
       title: t('鐘舵��'),
       dataIndex: 'status',
       slotName: 'status',
@@ -521,29 +685,20 @@
       visible.value = false;
     }
     if (type == 2) {
-      deptvisible.value = false;
-    }
-    if (type == 2) {
       resourcevisible.value = false;
+    }
+    if (type == 3) {
+      deptvisible.value = false;
     }
   };
 
-  const editDeptHandleOk = async () => {
-    let depts: Array = [],
-      role: Role = { roleId: selectRole.value.roleId };
-    checkStrictly.value.forEach((val) => {
-      depts.push(val.deptId);
-    });
-    role.dept = depts;
-    await RoleEdit(role).then((res) => {
-      fetchData();
-    });
-  };
 
   const editResourceHandleOk = async () => {
     let resources: Array = [],
       dialogs: Array = [],
+      agents: Array = [],
       Knowledges: Array = [],
+      llms: Array = [],
       role: Role = { roleId: selectRole.value.roleId };
     checkStrictlyMenu.value.forEach((val) => {
       resources.push(val.menuId);
@@ -560,25 +715,44 @@
     });
     role.dialogs = dialogs;
 
+    checkStrictlyAgent.value.forEach((val) => {
+      agents.push(val.agentId);
+    });
+    role.agents = agents;
+
+    checkStrictlyModel.value.forEach((val) => {
+      llms.push(val.modelId);
+    });
+    role.llms = llms;
+
     await RoleEdit(role).then((res) => {
       fetchData();
     });
   };
 
-  const editHandleOk = async () => {
-    if (editform.value.roleId.length > 0) {
-      await RoleEdit({
-        ...editform.value,
-      } as unknown as Role).then((res) => {
-        fetchData();
-      });
+  const cb = async (err) => {
+    if (err) {
+      visible.value = true;
     } else {
-      await RoleAdd({
-        ...editform.value,
-      } as unknown as Role).then((res) => {
-        fetchData();
-      });
+      if (editform.value.roleId.length > 0) {
+        await RoleEdit({
+          ...editform.value,
+        } as unknown as Role).then((res) => {
+          fetchData();
+        });
+      } else {
+        await RoleAdd({
+          ...editform.value,
+        } as unknown as Role).then((res) => {
+          fetchData();
+        });
+      }
     }
+
+  };
+
+  const editHandleOk =  () => {
+    formRef.value.validate(cb);
   };
   const operation = async (t, record) => {
     if (t == 0) {
@@ -588,15 +762,15 @@
       editform.value.roleKey = "";
       editform.value.remark = "";
     }
-    //缂栬緫
+
     if (t == 2) {
       visible.value = true;
+      formRef.value?.resetFields();
       save.value = '缂栬緫';
       editform.value.roleId=record.roleId
       editform.value.roleName = record.roleName;
-      editform.value.roleKey = record.roleKey;
-      editform.value.remark = record.remark;
     }
+
     //鍒犻櫎
     if (t == 3) {
       await RoleDelete(record.roleId).then((res) => {
@@ -614,6 +788,8 @@
       checkStrictlyKnowledge.value = [];
       checkedKeysKnowledge.value = [];
       checkStrictlyDialog.value = [];
+      checkStrictlyAgent.value = [];
+      checkStrictlyModel.value = [];
       checkedKeysDialog.value = [];
       selectRole.value = record;
       if (record.resources) {
@@ -644,8 +820,27 @@
           checkedKeysDialog.value.push(val.id);
         });
       }
+      if (record.agents) {
+        record.agents.forEach((val) => {
+          checkStrictlyAgent.value.push({
+            agentId: val.id,
+            agentTitle: val.title,
+          });
+          checkedKeysAgent.value.push(val.id);
+        });
+      }
+      if (record.llms) {
+        record.llms.forEach((val) => {
+          checkStrictlyModel.value.push({
+            modelId: val.id,
+            modelTitle: val.llm_name,
+          });
+          checkedKeysModel.value.push(val.id);
+        });
+      }
+
     }
-    //鏈烘瀯
+    //閮ㄩ棬閰嶇疆
     if (t == 5) {
       deptvisible.value = true;
       checkedKeys.value = [];
@@ -653,7 +848,7 @@
       checkStrictly.value = [];
       selectRole.value = record;
       expandKdys.value.push('0');
-      if (record.dept) {
+      if (record?.dept) {
         record.dept.forEach((val) => {
           checkStrictly.value.push({
             deptId: val.deptId,
@@ -695,27 +890,57 @@
     fetchData({ ...basePagination, current });
   };
 
-  const OrganizationData = async (key) => {
-    await OrganizationList(key).then((res) => {
-      treeData.value = [...res.rows];
+
+  let userResources = JSON.parse(getUserResources());
+  const isExist = (val): boolean => {
+    let isok = false;
+    userResources.forEach((r) => {
+      if (val == r.menuId) {
+        isok = true;
+      }
+    });
+    return isok;
+  };
+  const removeChild = (nodes,newT) => {
+    nodes.forEach((child) => {
+      if (isExist(child.menuId)){
+        newT.push(child);
+        let nt = [];
+        if (child.children?.length > 0) {
+          removeChild(child.children, nt);
+          child.children = nt;
+        }
+      }
     });
   };
+
   const MenuData = async (key) => {
     await ResourceList(key).then((res) => {
+      let newTree = [];
+      if (u.role != "admin") {
+        removeChild(res.rows, newTree);
+      }
       treeDataMenu.value = [...res.rows];
     });
   };
 
-  KnowledgeList().then((res) => {
-    knowledgeList.value = res.rows;
+  KnowledgeList(u.role).then((res) => {
+    knowledgeList.value = res.data;
   });
 
-  DialogList().then((res) => {
-    DialogsList.value = res.rows;
+  DialogList(u.role).then((res) => {
+    DialogsList.value = res.data;
   });
+  queryCanvasList(null).then((canvas) => {
+    AgentList= canvas.data
+  });
+  queryModelList().then((models) => {
+    ModelList = models.data;
+  });
+
   fetchData();
-  OrganizationData('');
   MenuData();
+  OrganizationData("");
 
   const reset = () => {
     formModel.value = generateFormModel();
@@ -727,6 +952,7 @@
   ) => {
     size.value = val as SizeProps;
   };
+
 </script>
 
 <style scoped lang="less">
@@ -807,3 +1033,13 @@
     }
   }
 </style>
+<style>
+.cdtree {
+  .arco-tree-node-is-leaf {
+    display: inline-flex;
+  }
+  div[data-level="1"] {
+    width: 100%;
+  }
+}
+</style>
\ No newline at end of file

--
Gitblit v1.8.0