Browse Source

Merge branch 'space2'

qin_26
han2015 3 months ago
parent
commit
efadde0bb6
  1. 13
      src/api/doc/type.ts
  2. 51
      src/api/hr/people/share_ctrol.ts
  3. 36
      src/store/modules/orgMember.ts
  4. 4
      src/views/doc/agent.vue
  5. 226
      src/views/doc/manage.vue
  6. 2
      src/views/doc/onlyoffice.vue
  7. 2
      src/views/doc/sharePermission.vue
  8. 228
      src/views/doc/space.vue
  9. 348
      src/views/doc/spacePermission.vue

13
src/api/doc/type.ts

@ -15,6 +15,7 @@ export interface matterPage{
deleted?:boolean;
orderDir?:string;
name?:string;
space?:string;
orderCreateTime?:string;
}
@ -31,8 +32,14 @@ export interface matterInfo{
deleted?:boolean;
expireInfinity?:boolean;
expireTime?:string;
permitVal?:number; //该值是当前用户permits的解析结果
permits?:matterPermit;
}
export interface matterPermit{
id:number;
MatterUuid:string;
data:string;
}
export interface shareItem{
name?:string;
updateTime?:string;
@ -47,6 +54,7 @@ export interface shareItem{
}
export interface matterTree extends matterInfo {
manager?:boolean;
children:matterTree[]
}
@ -55,9 +63,10 @@ export type matterTreeList = PageResult<matterTree[]>
export type matterResutList = PageResult<matterInfo[]>
export interface createDir{
userUuid:string;
userUuid?:string;
puuid:string;
name:string;
space?:string;
}
export interface createShare{

51
src/api/hr/people/share_ctrol.ts

@ -74,7 +74,12 @@ export function getPermitedList(uid:string,data:{uuid:string}): AxiosPromise<{pe
/**
*
*/
export function getSpaceMemberList(uid:string,data:{space?:string}): AxiosPromise<{members:string[],dprts:string[]}> {
export function getSpaceMemberList(uid:string,data:{space?:string,matter:string}): AxiosPromise<{
members:string[],
dprts:string[],
managers:string,
permits:Object,
}> {
return request({
url: '/hxpan/api/space/members',
method: 'post',
@ -86,6 +91,50 @@ export function getSpaceMemberList(uid:string,data:{space?:string}): AxiosPromis
});
}
/**
*
*/
export function addSpaceManager(uid:string,data:{space:string,mangers:string}): AxiosPromise<{members:string[],dprts:string[]}> {
return request({
url: '/hxpan/api/space/addmanagers',
method: 'post',
headers: {
'Identifier':uid,
'Content-Type': 'application/x-www-form-urlencoded'
},
data: data
});
}
/**
* matter权限
*/
export function updateSpaceMetterPermit(uid:string,data:{space:string,matter:string,permits:Object}): AxiosPromise<{members:string[],dprts:string[]}> {
return request({
url: '/hxpan/api/space/permit/update',
method: 'post',
headers: {
'Identifier':uid,
},
data: data
});
}
/**
* matter特定权限
*/
export function resetSpaceMatterPermit(uid:string,data:{space:string,matter:string}): AxiosPromise<{members:string[],dprts:string[]}> {
return request({
url: '/hxpan/api/space/permit/reset',
method: 'post',
headers: {
'Identifier':uid,
'Content-Type': 'application/x-www-form-urlencoded'
},
data: data
});
}
/**
*
*/

36
src/store/modules/orgMember.ts

@ -0,0 +1,36 @@
import { defineStore } from 'pinia'
import { ref} from 'vue';
import request from "@/utils/request";
export const useOrgMemberStore = defineStore('orgMember', () => {
interface OrgMemberItem {
id: string;
label: string;
children?:OrgMemberItem[];
}
const listMap = ref<Record<string, string>>({})
const dataTree = ref<OrgMemberItem>({ id: '', label: '', children: [] })
async function init() {
await request({
url: "/javasys/lowCode/transfer/getOrgAndManTree",
method: "post",
}).then((response) => {
// assuming response.data is an array of OrgMemberItem
dataTree.value=response.data
handleChildren(response.data.children)
});
}
function handleChildren(childs:any[]){
childs.forEach(item => {
listMap.value[item.id] = item.label;
if(item.children){
handleChildren(item.children)
}
});
}
init()
return { listMap,dataTree }
})

4
src/views/doc/agent.vue

@ -230,7 +230,7 @@ onMounted(() => {
<VueMarkdown :markdown="respMsg" :rehype-plugins="[rehypeRaw]" class="t_resp"></VueMarkdown>
</div>
<div class="question_com" :class="{newquestion:conversation!='' || !inputState}">
<h1 v-show="conversation =='' && inputState" style="font-size: 78px;margin: 10px;">恒信高科AI平台</h1>
<h1 v-show="conversation =='' && inputState" style="font-size: 56px;margin: 10px;">恒信高科AI平台</h1>
<el-checkbox-group v-model="checkedModel" style="display:flex; margin-bottom: 10px;">
<el-checkbox-button v-for="mod in aimodels" :value="mod.key">
{{ mod.name }}
@ -288,7 +288,7 @@ onMounted(() => {
align-self: start;
line-height: 30px;
margin: 20px 33px;
font-size: 18px;
font-size: 16px;
color: black;
}
.dynamic-width-message-box-byme .el-message-box__message{

226
src/views/doc/manage.vue

@ -8,26 +8,22 @@ import { getExpirTime, getFileIcon, readableSize,fileType} from "./tools"
import sharePermission from './sharePermission.vue';
import { useUserStore } from "@/store/modules/user";
import { getMatterList,postCreateDir,postDelMatter,postCreateShare,postMatterRename,postDelMatBatch,getMySpaces,doCreateSpace} from "@/api/doc/index"
import { matterPage,matterInfo,respCreateShare,matterTree, doFileUpload} from "@/api/doc/type"
import { matterPage,matterInfo,respCreateShare,matterTree, doFileUpload,matterPermit} from "@/api/doc/type"
import { h } from 'vue'
import router from "@/router";
import {
Delete,
View,
Download,
Share,
Search,
Edit,
Promotion,
Folder,
Avatar,
Plus,
Grid,
List,
Delete,View,Download,Share,Search,Edit,
Avatar,Plus,Grid,List,
Setting,
} from '@element-plus/icons-vue'
import {ElSelect,ElOption, ElText,ElInput,TableInstance,ElMessage,UploadFile,UploadFiles,ElPagination,ElTree,TreeNode} from "element-plus";
import {ElSelect,ElOption, ElText,ElInput,TableInstance,ElMessage,UploadFile,
UploadFiles,ElPagination,ElTree,TreeNode,ElDropdown,ElDropdownItem} from "element-plus";
import preview from './preview.vue';
import space from './space.vue';
import spacePermission from './spacePermission.vue';
import SvgIcon from "@/components/SvgIcon/index.vue";
import {doDelSpace} from "@/api/doc/space"
import Space from "./space.vue";
//TODO: add file icons done!
//TODO: click on table-item 1preview on file .....................
@ -44,12 +40,13 @@ import SvgIcon from "@/components/SvgIcon/index.vue";
const userStore = useUserStore();
const uid=btoa("p0"+userStore.userInfoCont.userId);
const rawUid="p0"+userStore.userInfoCont.userId
const siteHost=document.location.origin;
const apiURL=import.meta.env.VITE_APP_BASE_API+"/hxpan/api"
const matterList = ref<matterInfo[]>([])
const searchname=ref("")
const newdir=ref("") //
const newdirName=ref("") //
const currentHoverRow=ref("") //table
const selectedValue = ref("sixhour") //
const tabSelected=ref<matterInfo[]>([]) //table
@ -65,8 +62,7 @@ const multipleTableRef = ref<TableInstance>()
const paginInfo = ref({ page: 0, total: 0 })
const PRIVATESPACE = ref(true) // 2
const SpaceID= ref<{name:string,uuid:string,userUuid:string}>({}) //spaceid
const SpaceList=ref<{name:string,uuid:string,userUuid:string}[]>([])
const SpaceID= ref<{name:string,uuid:string,userUuid:string,manager:boolean,permits:matterPermit}>({}) //spaceid
const spaceEleRef = ref() //space,spaceTreeRefspaceTree
const spaceTreeData=ref<matterTree[]>([])//{name:'',uuid:'root',children:[]}
const spaceTreeRef = ref(); //space
@ -75,7 +71,7 @@ let spaceNodeUid="" //用来判断树组件的展开和关闭,如何只是展
const modListOrGrild=ref(true)
const Departs = computed(() => {
return `${userStore.userInfoCont.company},${userStore.userInfoCont.department},${userStore.userInfoCont.organization}`
return `${'p0'+userStore.userInfoCont.userId},${userStore.userInfoCont.company},${userStore.userInfoCont.department},${userStore.userInfoCont.organization}`
})
const uploadFormData = computed(() => {
@ -210,15 +206,17 @@ function onDelMatter(row:matterInfo){
}
function onDelMatBatch(){
ElMessageBox.confirm("确认删除选择的内容?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
ElMessageBox.confirm("确认删除选择的内容?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(()=>{
postDelMatBatch(uid,{
"uuids":tabSelected.value.map((item:matterInfo)=>item.uuid).join(",")
}).then(()=>{
postDelMatBatch(uid,{
"uuids":tabSelected.value.map((item:matterInfo)=>item.uuid).join(",")
}).then(()=>onLoadMatterList())
router.replace({ query: { t: Date.now() } })
})
})
}
function onDownload(row:matterInfo){
@ -323,21 +321,30 @@ function onCreateDir(){
postCreateDir(uid,{
userUuid:uid,
puuid:currentNode.value.uuid,
name:newdir.value,
name:newdirName.value,
}).then((resp)=> {
newdir.value=""
newdirName.value=""
//treeappend
treeRef.value.append(
{uuid:resp.data.uuid,dir:false,name:resp.data.name,puuid:resp.data.puuid},
currentNode.value.uuid
)
//onLoadMatterList()
matterList.value?.shift() //
matterList.value?.push(resp.data) //
})
.catch((e)=>{
ElMessage.error(e.msg)
})
}
function onDBclickMatter(row:matterInfo){
if(row.dir){
onNodeClick(row as matterTree,null,null,null)
}else{
onPrivateView(row)
}
}
//
function onNodeExpand(node: TreeNode, resolve: (data: matterTree[]) => void, reject: () => void) {
if ((node.data as matterTree).uuid) {
@ -607,7 +614,8 @@ function onNewSpace(){
}).then(() => {
if(newname.value!==""){
doCreateSpace(uid,newname.value).then((resp)=>{
SpaceList.value.push({name:resp.data.name,uuid:resp.data.uuid,userUuid:"p0"+userStore.userInfoCont.userId})
//spaceTreeRef.value.append({name:resp.data.name,uuid:resp.data.uuid,dir:false,userUuid:resp.data.userUuid})
router.replace({ query: { t: Date.now() } }) //
})
}
})
@ -625,7 +633,9 @@ function onSpaceNodeClick(data:matterTree,node:TreeNode,self:any,env:any){
SpaceID.value={
name: data.name ?? "",
uuid: data.uuid ?? "",
userUuid: data.userUuid ?? ""
userUuid: data.userUuid ?? "",
manager: data.manager ?? false,
permits:data.permits ?? { id: 0, MatterUuid: '', data: '' }
};
PRIVATESPACE.value=false;
}else{
@ -634,7 +644,9 @@ function onSpaceNodeClick(data:matterTree,node:TreeNode,self:any,env:any){
puuid: data.puuid,
name:data.name,
agent:data.agent,
dir:true
dir:true,
permits:data.permits,
path:data.path
}
//
spaceEleRef.value.handleDoubleClick(matter)
@ -646,6 +658,41 @@ function flushSpaceTree(uuid:string,data:matterTree[]){
spaceTreeRef.value.updateKeyChildren(uuid,data)
}
//
function onDeleteSpace(row:matterInfo){
ElMessageBox.confirm(`确认删除空间 ( ${row.name}) ? 空间内所有文件将不可恢复!取消则放弃删除操作。`, "警告", {
confirmButtonText: "确定删除",
cancelButtonText: "取消",
type: "warning",
}).then(()=>{
doDelSpace(uid,{
"space":row.uuid,
}).then(()=>{
router.replace({ query: { t: Date.now() } })
})
})
}
//matter
function onDelSpaceMatter(row:matterInfo){
if(row.puuid){
spaceEleRef.value.onDelMatter(row)
}else{
onDeleteSpace(row)
}
}
//
function onSpacePManage(row:matterInfo){
dynamicVNode.value=h(spacePermission,{
uid:rawUid, //uuid
uuid:row.uuid, //uuid
suid:SpaceID.value.userUuid,
spaceid:SpaceID.value.uuid, //uuid
closeFunc:()=>dynamicVNode.value=null
})
}
//------------------------------------------------------
//http://172.20.2.87:6010/api/alien/preview/5a10aaf6-396e-4d9a-7e87-3c5c8029d4db/123.png?ir=fill_100_100
//
@ -654,12 +701,12 @@ onMounted(() => {
{name:'个人空间',uuid:'root',dir:false},
currentNode.value.uuid
)
//
getMySpaces(uid,{roles:Departs}).then((resp)=>{
//SpaceList.value=resp.data
getMySpaces(uid,{roles:Departs.value}).then((resp)=>{
resp.data.forEach((item)=>{
spaceTreeRef.value.append({name:item.name,uuid:item.uuid,dir:false,userUuid:item.userUuid})
let ismanager=false
if(item.userUuid==rawUid || item.managers.includes(rawUid)) ismanager=true;
spaceTreeRef.value.append({name:item.name,uuid:item.uuid,dir:false,userUuid:item.userUuid,manager:ismanager,permits:item.permits})
})
})
let val =localStorage.getItem("listOrGrid")
@ -690,28 +737,47 @@ const handleSelectionChange = (val:matterInfo[]) => {
:load="onNodeExpand"
:default-expanded-keys="['root']"
@node-click="onNodeClick"
/>
<el-button style="margin: 10px 0;" :icon="Plus" @click="onNewSpace"> 共享空间</el-button>
>
<template #default="{ node, data }">
<div class="tree-item">
<span>{{ node.label }}</span>
<el-button size="small" :icon="Delete" circle @click="(e)=>{ e.stopPropagation(); onDelMatter(data)}"></el-button>
</div>
</template>
</el-tree>
<div style="display:flex;margin-top: 9px;background-color: white;"><span style="align-content: center;margin-left: 21px;color: #686854;">共享空间</span> <el-button style="margin: 10px 0px 10px auto;" :icon="Plus" @click="onNewSpace"> </el-button></div>
<el-tree
ref="spaceTreeRef"
style="max-width: 600px"
:data="spaceTreeData"
node-key="uuid"
accordion
highlight-current
lazy
:props="{label: 'name',children:'children',isLeaf:'dir'}"
@node-click="onSpaceNodeClick"
/>
<ul style="background-color: white;max-width: 600px;">
<li class="spaceitem" v-for="sp in SpaceList" @click="()=>{SpaceID=sp; PRIVATESPACE=false;}">{{ sp.name }}</li>
</ul>
>
<template #default="{ node, data }">
<div class="tree-item">
<span>{{ node.label}}</span>
<el-dropdown v-if="SpaceID.manager">
<el-button size="small" :icon="Setting" circle ></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="(e)=>{ e.stopPropagation(); onDelSpaceMatter(data)}">删除</el-dropdown-item>
<el-dropdown-item @click="(e)=>{ e.stopPropagation(); onSpacePManage(data)}">权限管理</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</template>
</el-tree>
</div>
<div v-if="PRIVATESPACE" class="app_container">
<el-row :gutter="24" style="margin: 12px 0px;">
<el-link v-if="currentNode.name!=='root'" @click="onNodeClick(treeData[0], null as unknown as TreeNode, null, null)">
<span style="font-weight: bold;margin-right: 5px;">根目录</span>/
<span style="font-weight: bold;margin-right: 5px;align-content: center;">根目录</span>/
</el-link>
<span style="font-weight: bold;margin:0 5px;align-content:center;">{{ currentNode.name }}</span>
@ -742,9 +808,6 @@ const handleSelectionChange = (val:matterInfo[]) => {
<el-button @click="onShareMatter()">分享</el-button>
<el-button @click="onDelMatBatch">删除</el-button>
</span>
<el-button type="danger" plain @click="onShareMatter({uuid:currentNode.uuid,name:currentNode.name})">分享目录</el-button>
<el-button type="danger" plain @click="onDelMatter({uuid:currentNode.uuid,name:currentNode.name,dir:true,
puuid:currentNode.puuid,path:currentNode.path})">删除目录</el-button>
</el-col>
<el-button-group style="margin:0 50px 0 auto;">
<el-button :icon="List" @click="updateListOrGrid(true)"></el-button>
@ -766,8 +829,8 @@ const handleSelectionChange = (val:matterInfo[]) => {
<el-table-column type="selection" width="50" />
<el-table-column width="450" property="name" label="文件名">
<template #default="scope">
<input type="text" autofocus placeholder="文件夹名" style="border:groove;height:30px;" v-model="newdir" @change="onCreateDir" v-if="scope.row.name===''" />
<div v-if="scope.row.name" style="display: flex; align-items: center;">
<input v-if="scope.row.name===''" v-model="newdirName" type="text" autofocus placeholder="文件夹名" style="border:groove;height:30px;" @change="onCreateDir" />
<div v-else style="display: flex; align-items: center;" @dblclick="onDBclickMatter(scope.row)">
<svg-icon v-if="scope.row.dir" icon-class="folder-icon" size="30px"/>
<el-image v-else-if="getFileIcon(scope.row.name)==='img'" style="width: 30px;" :preview-src-list="[getImageDownloadURL(scope.row.uuid,scope.row.name)]" :src="getImagePreivewURL(scope.row.uuid,scope.row.name)" />
<svg-icon v-else :icon-class="getFileIcon(scope.row.name)+'-icon'" size="30px" />
@ -799,20 +862,25 @@ const handleSelectionChange = (val:matterInfo[]) => {
<div class="table-grid" v-else>
<div class="grid-item" v-for="row in matterList">
<div class="grid">
<div class="grid-box" @click="handleMouseEnter(row)">
<div v-if="row.name===''">
<svg-icon icon-class="folder-icon" size="80px"/>
<input v-model="newdirName" type="text" autofocus placeholder="文件夹名" style="border:groove;height:30px;" @change="onCreateDir" />
</div>
<div v-else class="grid-box" @dblclick="onDBclickMatter(row)" @contextmenu.prevent="handleMouseEnter(row)" >
<svg-icon v-if="row.dir" icon-class="folder-icon" size="80px"/>
<el-image v-else-if="getFileIcon(row.name)==='img'" style="width: 80px;" :preview-src-list="[getImageDownloadURL(row.uuid,row.name)]" :src="getImagePreivewURL(row.uuid,row.name)" />
<svg-icon v-else :icon-class="getFileIcon(row.name)+'-icon'" size="80px"/>
<span style="margin: 5px 0;text-wrap-mode:nowrap;">{{ row.name }}</span>
</div>
</div>
<div class="grid-menus" v-show="currentHoverRow === row.name">
<el-button v-if="getFileIcon(row.name)!='img'" size="small" :icon="View" circle @click="onPrivateView(row)"></el-button>
<el-button size="small" :icon="Share" circle @click="onShareMatter(row)"></el-button>
<el-button size="small" :icon="Download" circle @click="onDownload(row)"></el-button>
<el-button size="small" :icon="Edit" circle @click="onlyOfficeEdit(row)"></el-button>
<el-button size="small" :icon="Delete" circle @click="onDelMatter(row)"></el-button>
</div>
<ul v-if="row.name!=''" class="grid-menus" v-show="currentHoverRow === row.name" @mouseleave="currentHoverRow=''">
<li v-if="getFileIcon(row.name)!='img'" @click="onPrivateView(row)">预览</li>
<li size="small" :icon="Share" @click="onShareMatter(row)">分享</li>
<li size="small" :icon="Download" @click="onDownload(row)">下载</li>
<li size="small" :icon="Edit" @click="onlyOfficeEdit(row)">编辑</li>
<li size="small" :icon="Delete" @click="onDelMatter(row)">删除</li>
</ul>
</div>
</div>
</el-row>
@ -822,13 +890,13 @@ const handleSelectionChange = (val:matterInfo[]) => {
</el-row>
</div>
<div v-else class="app_container">
<space ref="spaceEleRef" :uid="uid" :tree="spaceTreeRef" :listOrGrid="modListOrGrild"
:spaceid="SpaceID.uuid" :roles="Departs" :spacename="SpaceID.name" :owner="SpaceID.userUuid"
<space ref="spaceEleRef" :uid="uid" :raw-uid="rawUid" :listOrGrid="modListOrGrild"
:spaceid="SpaceID.uuid" :roles="Departs" :spacename="SpaceID.name" :space-permit="SpaceID.permits"
:owner="SpaceID.userUuid" :ismanager="SpaceID.manager"
:officeHost="officeHost" :site-host="siteHost" :api-u-r-l="apiURL"
:flushSpaceTree="flushSpaceTree"></space>
</div>
<div v-if="dynamicVNode">
<component :is="dynamicVNode" />
</div>
@ -837,6 +905,8 @@ const handleSelectionChange = (val:matterInfo[]) => {
<style lang="scss" scoped>
.menus_tree{
display: flex;
flex-direction: column;
padding: 20px 0px 0px 15px;
height: 100%;
overflow-y: auto;
@ -845,9 +915,26 @@ const handleSelectionChange = (val:matterInfo[]) => {
--el-tree-node-hover-bg-color:#a1c7ee;
--el-tree-node-content-height:43px;
--el-tree-expand-icon-color:#4c4c4e;
}
}
}
.tree-item{
display: flex;
width: 100%;
button{
display: none;
margin: 0 5px 0 auto;
}
}
.tree-item:hover button{
display: block;
}
.el-dropdown{
margin: 0 5px 0 auto;
}
.app_container {
padding: 10px 30px 0px 30px;
height: calc(100% - 10px);
@ -891,10 +978,10 @@ const handleSelectionChange = (val:matterInfo[]) => {
flex-wrap: wrap; /* 关键属性,允许子元素自动换行 */
.grid-item{
position: relative;
height: 134px;
width: 134px;
width: 134px;
margin: 5px;
.grid-box{
height: 150px;
display: flex;
flex-direction: column;
overflow: hidden;
@ -904,9 +991,16 @@ const handleSelectionChange = (val:matterInfo[]) => {
.grid-menus{
position: absolute;
top: 10px;
button{
color: #000000;
margin: 4px;
left: 72px;
background-color: #ffffff;
width: 60px;
line-height: 27px;
text-align: center;
color: #878989;
box-shadow:0px 0px 12px rgba(0,0,0,0.12);
li{
cursor: pointer;
border-bottom: 1px solid #ccc;
}
}
.grid{

2
src/views/doc/onlyoffice.vue

@ -58,7 +58,7 @@ onMounted(()=>{
config.value.document.url=_url
config.value.document.title=name
const _key=_url.match(/(\w+-\w+-\w+)/)![0]
if(_key) config.value.document.key=_key //unique key
if(_key) config.value.document.key=_key+(new Date().getTime().toString()) //unique key
config.value.documentType=dtype
config.value.editorConfig.callbackUrl+=`?info=${_info}`
//

2
src/views/doc/sharePermission.vue

@ -151,7 +151,7 @@ onMounted(()=>{
<template>
<el-dialog :model-value="true" :style="{'max-height': '650px'}" v-on:close="closeFunc()">
<template #header>
<span>权限管理</span>
<span>成员管理</span>
</template>
<div style="display: grid;width: 100%;grid-template-columns:1fr 1fr;">
<div class="menus_tree">

228
src/views/doc/space.vue

@ -6,8 +6,9 @@
<script lang="ts" setup>
import { getFileIcon, readableSize,fileType} from "./tools"
import sharePermission from './sharePermission.vue';
import { matterPage,matterInfo,matterTree,doFileUpload} from "@/api/doc/type"
import { doAccessManage,getSpaceMatterList,doCreateSpaceDir,doDelSpaceMatter,doDelSpace,
import spacePermission from './spacePermission.vue';
import { matterPage,matterInfo,matterTree,doFileUpload,matterPermit} from "@/api/doc/type"
import { doAccessManage,getSpaceMatterList,doCreateSpaceDir,doDelSpaceMatter,
doAiTraining ,doCreateAiagent} from "@/api/doc/space"
import { h } from 'vue'
import {
@ -16,16 +17,18 @@ import {
Download,
Plus,
Edit,
Folder,
Setting,
} from '@element-plus/icons-vue'
import {ElMessage,UploadFile,UploadFiles,ElPagination} from "element-plus";
import aiagent from './agent.vue';
import router from "@/router";
import SvgIcon from "@/components/SvgIcon/index.vue";
import { useOrgMemberStore } from "@/store/modules/orgMember";
const orgMembers = useOrgMemberStore() //
const defaultAiAgent=import.meta.env.VITE_DEFAULT_AI_AGENT
const matterList = ref<matterInfo[]>([])
const newdir=ref("") //
const newdirName=ref("") //
const currentHoverRow=ref("") //table
const breadcrumbList=ref<matterInfo[]>([{name:"根目录",uuid:"root", dir:true}]) //
@ -36,23 +39,35 @@ let isNewNode=true //用来减少父组件树的重置
const dynamicVNode = ref<VNode | null>(null) //permission
const paginInfo = ref({ page: 0, total: 0 })
const CutLevelPermit=ref(0)
enum PERMITS {
FORBID, //0
VIEW, //1
DOWNLOAD, //2
UPLOAD, //3
UPANDDOWNLOAD, //4
EDIT, //5
MANAGER, //6
}
//-----------AI---------------------
//const agent=ref<{model:boolean,name:string}>({})
const currentAgent=ref<{model:boolean,name:string,uuid:string}>({})
const currentAgent=ref<{model:boolean,name:string,uuid:string,path:string}>({})
//---------------------------------
const props = withDefaults(defineProps<{
uid:string, //uuid,base64,Identifierbase64
tree:object,
rawUid:string,
//tree:object,
spaceid:string,
spacename:string,
officeHost:string,
siteHost:string,
owner:string,
apiURL:string,
roles:string,
listOrGrid:boolean,
ismanager:boolean,
spacePermit:matterPermit,
flushSpaceTree:(uuid:string,data:matterTree[])=>void
}>(),{})
@ -61,6 +76,7 @@ const props = withDefaults(defineProps<{
watch(props,()=>{
currentNode.value.uuid="root"
currentNode.value.name="根目录"
currentAgent.value.path="root"
onLoadMatterList()
})
@ -83,7 +99,7 @@ function onAccessManage(){
let permited = btoa(_list.join("|"))
doAccessManage(props.uid,{
"space":props.spaceid,
"roles":permited,
"roles":permited,
"owner":props.owner,
"len":_list.length
}).then(()=>{
@ -96,21 +112,18 @@ function onAccessManage(){
})
}
//
function onDeleteSpace(){
ElMessageBox.confirm(`确认删除空间 ( ${props.spacename}) ? 空间内所有文件将不可恢复!取消则放弃删除操作。`, "警告", {
confirmButtonText: "确定删除",
cancelButtonText: "取消",
type: "warning",
}).then(()=>{
doDelSpace(props.uid,{
"space":props.spaceid,
}).then(()=>{
router.replace({ query: { t: Date.now() } })
})
//
function onSpacePManage(row:matterInfo){
dynamicVNode.value=h(spacePermission,{
uid:props.rawUid, //uuid
uuid:row.uuid, //uuid
suid:props.owner,
spaceid:props.spaceid, //uuid
closeFunc:()=>dynamicVNode.value=null
})
}
//----------------------------------------
//
function onDelMatter(row:matterInfo){
@ -123,7 +136,6 @@ function onDelMatter(row:matterInfo){
doDelSpaceMatter(props.uid,{
"uuid":row.uuid,
"space":props.spaceid,
"roles":props.roles,
}).then(()=>{
currentNode.value.uuid = row.puuid ?? ""
currentNode.value.name = row.path ? row.path.replace(`/${row.name}`,'').match(/[^/]+$/g)?.pop() :"上级目录"
@ -157,19 +169,47 @@ function onLoadMatterList(){
puuid:currentNode.value.uuid,
deleted:false,
space:props.spaceid,
roles:props.roles,
};
getSpaceMatterList(props.uid,_page).then((resp)=>{
//page+1 index1apiindex0
paginInfo.value={total:resp.data.totalPages, page:resp.data.page}
matterList.value=resp.data.data
if (props.ismanager) {
resp.data.data.forEach(item => {
item.permitVal=PERMITS.MANAGER
})
matterList.value=resp.data.data
}else{
matterList.value=resp.data.data.filter(item=>{ //
if(item.permits.ID==0){
item.permitVal=CutLevelPermit.value
}else{
//
let _pert: Record<string, number>
_pert = JSON.parse(item.permits!.data)
let val=_pert[props.rawUid.replace("p0","")]
if(val){
item.permitVal = val
}else{
item.permitVal = PERMITS.FORBID //
}
}
if(item.permitVal>0){
return true
}
return false
})
}
//使
let node_data = resp.data.data.filter((item) => {
let node_data = matterList.value.filter(item=> {
return item.dir
}).map(val => {
const copy = structuredClone(val)
const copy = structuredClone(toRaw(val))
copy.dir = !copy.dir
return copy
})
@ -199,28 +239,46 @@ function createDir(){
function onCreateDir(){
doCreateSpaceDir(props.uid,{
puuid:currentNode.value.uuid,
name:newdir.value,
name:newdirName.value,
space:props.spaceid,
roles:props.roles,
}).then((resp)=> {
newdir.value=""
newdirName.value=""
onLoadMatterList()
})
.catch((e)=>{
ElMessage.error(e.msg)
})
}
//------------------------------------------
// @cell-dblclick="handleDoubleClick"
//
function handleDoubleClick(row:matterInfo,ind?:number){
if(row.dir){
//
if(row.permitVal){
CutLevelPermit.value=row.permitVal
}else{
if (props.ismanager) {
CutLevelPermit.value=9
}else{
let _pert: Record<string, number>
_pert = JSON.parse(row.permits!.data)
let val=_pert[props.rawUid.replace("p0","")]
if(val){
CutLevelPermit.value = val
}else{
CutLevelPermit.value = PERMITS.FORBID //
}
}
}
if(row.agent){
currentAgent.value={name:row.name,model:false,uuid:row.uuid}
currentAgent.value={name:row.name,model:false,uuid:row.uuid,path:row.path}
}
isNewNode=true
//1
//2:
//2:
if(currentNode.value.puuid==row.uuid || row.uuid=="root") isNewNode=false
currentNode.value=row
onLoadMatterList()
@ -237,15 +295,13 @@ function handleDoubleClick(row:matterInfo,ind?:number){
}else{
//
//
if(row.agent){
currentAgent.value={name:row.name,model:false,uuid:row.uuid}
}
currentNode.value=row
breadcrumbList.value.push(row)
onLoadMatterList()
}
*/
}else{
onPrivateView(row)
}
}
@ -350,7 +406,6 @@ async function doCreateMultyDir(path:string,uuid:string){
puuid:uuid,
name:dirs[i],
space:props.spaceid,
roles:props.roles,
}).then((resp)=> {
uuid=resp.data.uuid //uuid, puuid
list.push(resp.data)
@ -387,7 +442,7 @@ function onAiAgent(){
}
function handleAiUpload(info:matterInfo){
//
if (currentNode.value.agent){
if (info.path?.startsWith(currentAgent.value.path)){
doAiTraining(`/agents/${currentAgent.value.uuid}/updates`,{"matter":info.uuid}).then(resp=>{
console.log(resp)
})
@ -429,6 +484,8 @@ async function onlyOfficeEdit(row:matterInfo){
const info =btoa(encodeURIComponent(`${row.userUuid}/root${row.path}`)) //
const _url=`${props.siteHost}${props.apiURL}/space/download/${row.uuid}/${row.name}?space=${props.spaceid}`
window.open(`/#/onlyoffice?name=${row.name}&dtype=${_type}&info=${info}&verify=${_verify}&fileurl=`+window.btoa(encodeURIComponent(_url)),"_blank")
}).catch(()=>{
console.log("close")
})
}
@ -446,8 +503,21 @@ function getSpaceImageDURL(_uuid:string,_name:string){
onMounted(() => {
currentNode.value.uuid="root"
//AI
currentAgent.value={name:"通用AI",model:false,uuid:defaultAiAgent}
currentAgent.value={name:"通用AI",model:false,uuid:defaultAiAgent,path:"root"}
if (props.ismanager) {
CutLevelPermit.value=PERMITS.MANAGER
}else{
let _pert: Record<string, number>
_pert = JSON.parse(props.spacePermit.data)
let val=_pert[props.rawUid.replace("p0","")]
if(val){
CutLevelPermit.value = val
}else{
CutLevelPermit.value = PERMITS.FORBID //
}
}
onLoadMatterList()
});
@ -455,7 +525,7 @@ const handleSelectionChange = (val:matterInfo[]) => {
tabSelected.value = val
}
defineExpose({handleDoubleClick})
defineExpose({handleDoubleClick,onDelMatter})
//
function isOwner(){
@ -464,20 +534,20 @@ function isOwner(){
</script>
<template>
<div>
<el-row :gutter="24" style="margin: 12px 0px;">
<span class="el-breadcrumb" style="font-weight: bold;">[ {{ props.spacename }} ] : </span>
<el-breadcrumb separator="/">
<span class="el-breadcrumb" style="font-weight: bold; align-content: center;">[ {{ props.spacename }} ] : </span>
<el-breadcrumb separator="/" style="align-content: center;">
<el-breadcrumb-item v-for="(item,index) in breadcrumbList"
:key="index" @click="handleDoubleClick(item,index)">
<span style="font-weight: bold;">{{ item.name }}</span>
<span style="font-weight: bold;cursor: pointer;">{{ item.name }}</span>
</el-breadcrumb-item>
</el-breadcrumb>
<span v-if="currentNode.uuid!='root'" style="font-weight: bold;margin:0 5px;align-content:center;">/ {{ currentNode.name }}</span>
</el-row>
<el-row :gutter="24">
<el-col :span="14">
<el-col :span="14" v-if="CutLevelPermit>=PERMITS.UPLOAD">
<div class="el-button el-button--default" style="position: relative;">
<input type="file" style="position: absolute;opacity: 0;width: 50px;"
@change="onCustomUpload" multiple />
@ -493,14 +563,12 @@ function isOwner(){
文件夹上传
</div>
<el-button @click="createDir">新建目录</el-button>
<el-button type="danger" plain @click="onDelMatter({uuid:currentNode.uuid,name:currentNode.name,dir:true,
puuid:currentNode.puuid,path:currentNode.path})">删除目录</el-button>
</el-col>
<el-button style="margin-left: auto;" @click="()=>currentAgent.model=true">AI助手</el-button>
<el-button-group v-if="isOwner()" class="control" style="margin: 0 10px;">
<el-button :icon="Plus" @click="onAccessManage">成员</el-button>
<el-button :icon="Plus" @click="onAiAgent">创建智能体</el-button>
<el-button :icon="Delete" @click="onDeleteSpace">删除</el-button>
<!-- <el-button :icon="Delete" @click="onDeleteSpace">删除</el-button> -->
</el-button-group>
</el-row>
@ -517,8 +585,8 @@ function isOwner(){
<!-- <el-table-column type="selection" width="50" /> -->
<el-table-column width="450" property="name" label="文件名">
<template #default="scope">
<input type="text" autofocus placeholder="文件夹名" style="border:groove;height:30px;" v-model="newdir" @change="onCreateDir" v-if="scope.row.name===''" />
<div v-if="scope.row.name" style="display: flex; align-items: center;">
<input v-if="scope.row.name===''" v-model="newdirName" type="text" autofocus placeholder="文件夹名" style="border:groove;height:30px;" @change="onCreateDir" />
<div v-else style="display: flex; align-items: center;" @dblclick="handleDoubleClick(scope.row)" >
<svg-icon v-if="scope.row.dir" icon-class="folder-icon" :size="30"/>
<el-image v-else-if="getFileIcon(scope.row.name)==='img'" style="width: 30px;" :preview-src-list="[getSpaceImageDURL(scope.row.uuid,scope.row.name)]" :src="getSpaceImageViewURL(scope.row.uuid,scope.row.name)" />
<svg-icon v-else :icon-class="getFileIcon(scope.row.name)+'-icon'" :size="30" />
@ -526,15 +594,18 @@ function isOwner(){
</div>
</template>
</el-table-column>
<el-table-column width="250">
<el-table-column width="350">
<template #default="scope" >
<el-tag v-if="scope.row.agent" effect="dark" size="small" type="success" round >智能体</el-tag>
<div v-show="currentHoverRow === scope.row.name" style="display:inline; margin-left:15px">
<el-button size="small" :icon="Edit" circle @click="onlyOfficeEdit(scope.row)"></el-button>
<el-button size="small" :icon="View" circle @click="onPrivateView(scope.row)"></el-button>
<el-button size="small" :icon="Download" circle @click="onDownload(scope.row)"></el-button>
<el-button size="small" :icon="Delete" circle @click="onDelMatter(scope.row)"></el-button>
</div>
<div v-show="currentHoverRow === scope.row.name" style="display:inline; margin-left:15px">
<el-button v-if="getFileIcon(scope.row.name)!='img'" size="small" :icon="View" circle @click="onPrivateView(scope.row)"></el-button>
<el-button v-if="scope.row.permitVal>=PERMITS.DOWNLOAD" size="small" :icon="Download" circle @click="onDownload(scope.row)"></el-button>
<el-button v-if="scope.row.permitVal>=PERMITS.EDIT" size="small" :icon="Edit" circle @click="onlyOfficeEdit(scope.row)"></el-button>
<span v-if="scope.row.permitVal>=PERMITS.MANAGER" class="manager_span" >
<el-button size="small" :icon="Delete" circle @click="onDelMatter(scope.row)"></el-button>
<el-button size="small" :icon="Setting" circle @click="onSpacePManage(scope.row)"></el-button>
</span>
</div>
</template>
</el-table-column>
<el-table-column prop="size" width="100" :formatter="readableSize" label="大小" />
@ -549,19 +620,28 @@ function isOwner(){
<div class="table-grid" v-else>
<div class="grid-item" v-for="row in matterList">
<div class="grid">
<div class="grid-box" @click="handleMouseEnter(row)">
<div v-if="row.name===''">
<svg-icon icon-class="folder-icon" size="80px"/>
<input v-model="newdirName" type="text" autofocus placeholder="文件夹名" style="border:groove;height:30px;" @change="onCreateDir" />
</div>
<div v-else class="grid-box" @dblclick="handleDoubleClick(row)" @contextmenu.prevent="handleMouseEnter(row)" >
<svg-icon v-if="row.dir" icon-class="folder-icon" size="80px"/>
<el-image v-else-if="getFileIcon(row.name)==='img'" style="width: 80px;" :preview-src-list="[getSpaceImageDURL(row.uuid,row.name)]" :src="getSpaceImageViewURL(row.uuid,row.name)" />
<svg-icon v-else :icon-class="getFileIcon(row.name)+'-icon'" size="80px"/>
<span style="margin: 5px 0;text-wrap-mode:nowrap;">{{ row.name }}</span>
<el-tag v-if="row.agent" effect="dark" size="small" type="success" round >智能体</el-tag>
</div>
</div>
<div class="grid-menus" v-show="currentHoverRow === row.name">
<el-button size="small" :icon="Edit" circle @click="onlyOfficeEdit(row)"></el-button>
<el-button v-if="getFileIcon(row.name)!='img'" size="small" :icon="View" circle @click="onPrivateView(row)"></el-button>
<el-button size="small" :icon="Download" circle @click="onDownload(row)"></el-button>
<el-button size="small" :icon="Delete" circle @click="onDelMatter(row)"></el-button>
</div>
<ul v-if="row.name!=''" class="grid-menus" v-show="currentHoverRow === row.name" @mouseleave="currentHoverRow=''">
<li v-if="getFileIcon(row.name)!='img'" @click="onPrivateView(row)">预览</li>
<li v-if="row.permitVal! >= PERMITS.DOWNLOAD" @click="onDownload(row)">下载</li>
<li v-if="row.permitVal! >= PERMITS.EDIT" @click="onlyOfficeEdit(row)">编辑</li>
<span v-if="row.permitVal! >= PERMITS.MANAGER" >
<li @click="onDelMatter(row)">删除</li>
<li @click="onSpacePManage(row)">权限</li>
</span>
</ul>
</div>
</div>
</el-row>
@ -593,10 +673,10 @@ function isOwner(){
flex-wrap: wrap; /* 关键属性,允许子元素自动换行 */
.grid-item{
position: relative;
height: 134px;
width: 134px;
margin: 5px;
.grid-box{
height: 150px;
display: flex;
flex-direction: column;
overflow: hidden;
@ -606,9 +686,17 @@ function isOwner(){
.grid-menus{
position: absolute;
top: 10px;
button{
color: black;
margin: 4px;
left: 72px;
background-color: #ffffff;
width: 60px;
line-height: 27px;
text-align: center;
color: #878989;
z-index: 999;
box-shadow:0px 0px 12px rgba(0,0,0,0.12);
li{
cursor: pointer;
border-bottom: 1px solid #ccc;
}
}
.grid{
@ -619,6 +707,10 @@ function isOwner(){
}
}
.manager_span{
margin-left: 10px;
}
.dynamic-width-message-box-byme .el-message-box__message{
width: 100%;
}

348
src/views/doc/spacePermission.vue

@ -0,0 +1,348 @@
<script lang="ts" setup>
import {
resetSpaceMatterPermit,
getSpaceMemberList,
addSpaceManager,
updateSpaceMetterPermit,
} from '@/api/hr/people/share_ctrol'
import { ElDialog, ElMessageBox,ElStep,TreeInstance} from 'element-plus';
import { useOrgMemberStore } from "@/store/modules/orgMember";
const props = withDefaults(defineProps<{
uid:string, //uuid
uuid:string, //uuid
suid:string, //
spaceid:string, //uuid
closeFunc:(refresh?:boolean)=>void, //
}>(),{})
const orgMembers = useOrgMemberStore()
const spacePermit=ref<{id:number,data:string,matterUid:string}>({}) //
const treeRef=ref<TreeInstance>() //tree
const managerMode=ref(false)
const managers=ref<string[]>([])
let resultPermits: Record<string, number> = {};
interface Tree {
id: string
label:string
parentId?:string
indeterminate?:boolean,
radio?:number[];
children?: Tree[]
ismanager?:boolean,
}
const dataSource = ref<Tree[]>([])
//
async function onSavePermChange(){
resultPermits={}
//
if (managerMode.value){
managers.value=[] //
dataSource.value.forEach(item=>{
if(item.ismanager){
managers.value.push("p0"+item.id)
}
if(item.children) collectManager(item)
})
await addSpaceManager(btoa(props.uid),{
space:props.spaceid,
mangers:managers.value.join("|")
}).then(resp=>{
console.log(resp)
})
props.closeFunc()
return
}
dataSource.value.forEach(item=>{
if(item.radio&&item.radio.length>0){
if(item.indeterminate) {
item.radio[0]+=10
}
resultPermits[item.id]=item.radio[0]
}
if(item.children) collectNodePermits(item)
})
spacePermit.value.data=JSON.stringify(resultPermits)
updateSpaceMetterPermit(btoa(props.uid),{
space:props.spaceid,
matter:props.uuid,
permits:spacePermit.value
}).then(resp=>{
console.log(resp)
})
props.closeFunc()
}
function collectManager(node:Tree){
node.children?.forEach(ele => {
if(ele.ismanager){
managers.value.push("p0"+ele.id)
}
if(ele.children) collectManager(ele)
});
}
//
function collectNodePermits(node:Tree){
node.children?.forEach(ele => {
if(ele.radio&&ele.radio.length>0){
if(ele.indeterminate) {
ele.radio[0]+=10
}
resultPermits[ele.id]=ele.radio[0]
}
if(ele.children){
collectNodePermits(ele)
}
});
}
//
function onGroupValueChange(node:Tree, val:number[]){
if(node.indeterminate) node.indeterminate=false;
node.children?.forEach(ele => {
ele.radio=val
if(ele.children){
onGroupValueChange(ele,val)
}
});
if(node.parentId){
updateParentNode(node)
}
}
//
function updateParentNode(node:Tree){
if(node.parentId){
const pnode = treeRef.value?.getNode(node.parentId);
if(pnode){
const tdata=pnode.data as Tree
if (tdata.children?.every(ele=>{
if(ele.indeterminate) return !ele.indeterminate;//
if(ele.radio?.length==0) return ele.radio.length==tdata.radio?.length;
return ele.radio?.length==tdata.radio?.length && ele.radio[0]==tdata.radio[0]
})) {
tdata.indeterminate=false
}else{
tdata.indeterminate=true
}
updateParentNode(tdata)
}
}
}
//
function delMatterPermit(matter_uuid:string){
resetSpaceMatterPermit(btoa(props.uid),{
space:props.spaceid,
matter:matter_uuid,
}).then(()=>{
refreshSpaceData()
})
}
function onShowManagers(){
managers.value.forEach(item=>{
const node = treeRef.value?.getNode(item.replace("p0",""));
if(node && node.data){
node.data.ismanager=true
}
})
}
function refreshSpaceData(){
getSpaceMemberList(
btoa(props.uid),
{space:props.spaceid,matter:props.uuid}
).then(resp=>{
resp.data?.dprts?.forEach(item=>{
for(let data of dataSource.value){
if (data.id==item) return;
if (checkNode(item,data)) return;
}
addNode(item,orgMembers.dataTree)
});
resp.data?.members?.forEach(item=>{
const mid=item.replace("p0","")
for(let data of dataSource.value){
if(checkNode(mid,data)) return;
}
dataSource.value.push({id:mid,label:orgMembers.listMap[mid],radio:[2]})
});
managers.value=resp.data?.managers.split("|")
spacePermit.value.id=resp.data?.permits.ID
spacePermit.value.matterUid=resp.data?.permits.MatterUuid
spacePermit.value.data=resp.data.permits.data!="" ? resp.data.permits.data : "{}"
nextTick(() => {
const permitJson = JSON.parse(spacePermit.value.data) //object
Object.keys(permitJson).forEach(key=>{
const node = treeRef.value?.getNode(key);
if(node && node.data){
if(permitJson[key]>10){
node.data.radio = [permitJson[key]%10]
node.data.indeterminate=true
}else{
node.data.radio = [permitJson[key]]
}
}
})
});
})
}
function addNode(key:string,node:Tree){
node.children?.forEach(ele => {
if(ele.id==key){
const eleClone=structuredClone(toRaw(ele)) //eleProxyclonetoRawobject
eleClone.radio=[2]
eleClone.parentId=ele.parentId
dataSource.value.push(eleClone) //{id:ele.id,label:ele.label,radio:2,stage:level,children:ele.children}
return
}
if(ele.children){
addNode(key,ele)
}
});
}
function checkNode(key:string,node:Tree):boolean{
for (const child of node.children||[]) {
if(child.id==key){
return true
}
if(child.children){
//returnreturnfortruereturn
if(checkNode(key,child)) return true;
}
}
return false;
}
onMounted(()=>{
refreshSpaceData()
})
</script>
<template>
<el-dialog :model-value="true" :style="{'max-height': '750px'}" v-on:close="closeFunc()">
<template #header>
<el-button link @click="managerMode=false;">文档权限管理</el-button>
<el-button v-if="spacePermit.matterUid==spaceid&&uid==suid" link @click="managerMode=true; onShowManagers()">管理员管理</el-button>
</template>
<div v-if="uuid==spacePermit.matterUid&&uuid!=spaceid" class="tips">当前文档存在定制权限,与空间权限不一致。<el-button size="small" @click="delMatterPermit(uuid)">恢复</el-button></div>
<div class="tree-node" style="width:93%;font-weight: bold;position: sticky;">
<span style="width: 200px;text-align: center;">名称</span>
<div v-if="managerMode" class="buttons">
<span>管理员</span>
</div>
<div v-else class="buttons">
<span>禁止</span>
<span>仅预览</span>
<span>可下载</span>
<span>上传下载</span>
<span>编辑</span>
</div>
</div>
<div class="tablelist">
<el-tree
ref="treeRef"
:data="dataSource"
node-key="id"
default-expand-all
:expand-on-click-node="false"
>
<template #default="{ node, data }">
<div class="tree-node">
<span>{{ node.label }}</span>
<div v-if="managerMode" class="buttons">
<el-checkbox v-if="!data.children" v-model="data.ismanager" />
</div>
<div v-else class="buttons">
<el-checkbox-group :min="0" :max="1" v-model="data.radio" @change="(val)=>onGroupValueChange(data,val)">
<el-checkbox key="forbid" :indeterminate="data.indeterminate" :value="0" />
<el-checkbox key="view" :indeterminate="data.indeterminate" :value="1" />
<el-checkbox key="download" :indeterminate="data.indeterminate" :value="2" />
<el-checkbox key="updown" :indeterminate="data.indeterminate" :value="3" />
<el-checkbox key="edit" :indeterminate="data.indeterminate" :value="4" />
</el-checkbox-group>
</div>
</div>
</template>
</el-tree>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeFunc()">取消</el-button>
<el-button type="primary" @click="onSavePermChange">保存</el-button>
</div>
</template>
</el-dialog>
</template>
<style lang="scss" scoped>
.tablelist{
width: 94%;
height: 565px;
overflow-y: scroll
}
.tips{
display: flex;
align-items: center;
margin: 5px;
padding: 5px 32px;
background-color: #d7d1ca;
}
.tree-node{
display: flex;
flex-direction: row;
width: 100%;
align-items: center;
.buttons{
margin: 0 50px 0 auto;
span{
width: 26px;
margin: 0 7px;
}
}
}
.el-checkbox{
width: 26px;
}
.el-tree{
/* 让整个弹出窗口位置更高一些*/
--el-tree-node-content-height:33px;
}
</style>
Loading…
Cancel
Save