|
|
|
|
<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";
|
|
|
|
|
import { dataTool } from 'echarts';
|
|
|
|
|
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[]>([])
|
|
|
|
|
const firstLevelKeys = ref<string[]>([]) //默认展开的部门
|
|
|
|
|
|
|
|
|
|
let resultPermits: Record<string, number> = {};
|
|
|
|
|
|
|
|
|
|
interface Tree {
|
|
|
|
|
id: string
|
|
|
|
|
name:string
|
|
|
|
|
superior?:string
|
|
|
|
|
indeterminate?:boolean,
|
|
|
|
|
radio?:number[];
|
|
|
|
|
child?: Tree[]
|
|
|
|
|
ismanager?:boolean,
|
|
|
|
|
indeterminate2?:boolean,//for manager member
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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.child) 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.child) 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.child?.forEach(ele => {
|
|
|
|
|
if(ele.ismanager){
|
|
|
|
|
managers.value.push("p0"+ele.id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(ele.child) collectManager(ele)
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//去遍历查找特殊设置的节点,并保存
|
|
|
|
|
function collectNodePermits(node:Tree){
|
|
|
|
|
node.child?.forEach(ele => {
|
|
|
|
|
if(ele.radio&&ele.radio.length>0){
|
|
|
|
|
if(ele.indeterminate) {
|
|
|
|
|
ele.radio[0]+=10
|
|
|
|
|
}
|
|
|
|
|
resultPermits[ele.id]=ele.radio[0]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(ele.child){
|
|
|
|
|
collectNodePermits(ele)
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//递归修改子级元素
|
|
|
|
|
function onGroupValueChange(node:Tree, val:number[]){
|
|
|
|
|
//if(node.indeterminate) node.indeterminate=false;
|
|
|
|
|
updateChildNode(node, val)
|
|
|
|
|
if(node.superior){
|
|
|
|
|
updateParentNode(node)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function updateChildNode(node:Tree, val:number[]){
|
|
|
|
|
if(node.indeterminate) node.indeterminate=false;
|
|
|
|
|
node.child?.forEach(ele => {
|
|
|
|
|
ele.radio=val
|
|
|
|
|
if(ele.child){
|
|
|
|
|
updateChildNode(ele,val)
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//递归更新父级
|
|
|
|
|
function updateParentNode(node:Tree){
|
|
|
|
|
if(node.superior){
|
|
|
|
|
|
|
|
|
|
const pnode = treeRef.value?.getNode(node.superior);
|
|
|
|
|
if(pnode){
|
|
|
|
|
const tdata=pnode.data as Tree
|
|
|
|
|
if (tdata.child?.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
|
|
|
|
|
setParentIndeterminate(node.data as Tree)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function setParentIndeterminate(node:Tree){
|
|
|
|
|
if(node.superior){
|
|
|
|
|
const pnode = treeRef.value?.getNode(node.superior);
|
|
|
|
|
if(pnode){
|
|
|
|
|
const tdata=pnode.data as Tree
|
|
|
|
|
tdata.indeterminate2=true
|
|
|
|
|
|
|
|
|
|
setParentIndeterminate(tdata)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if(dataSource.value.length>0){//只添加第一个最顶级部门
|
|
|
|
|
firstLevelKeys.value.push(dataSource.value[0].id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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,name:orgMembers.listMap[mid],radio:[]})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
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.child?.forEach(ele => {
|
|
|
|
|
if(ele.id==key){
|
|
|
|
|
const eleClone=structuredClone(toRaw(ele)) //这里ele是Proxy,无法clone,所以要toRaw拿到原始object
|
|
|
|
|
//eleClone.radio=[2]
|
|
|
|
|
eleClone.superior=ele.superior
|
|
|
|
|
dataSource.value.push(eleClone) //{id:ele.id,name:ele.name,radio:2,stage:level,children:ele.children}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if(ele.child){
|
|
|
|
|
addNode(key,ele)
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkNode(key:string,node:Tree):boolean{
|
|
|
|
|
for (const ch of node.child||[]) {
|
|
|
|
|
if(ch.id==key){
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
if(ch.child){
|
|
|
|
|
//这里不能直接return,因为return后,就中断了for循环,但是true的情况下可以直接return
|
|
|
|
|
if(checkNode(key,ch)) 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 :class="managerMode ? '' :'moveon'" @click="managerMode=false;" >文档权限管理</el-button>
|
|
|
|
|
<el-button v-if="spacePermit.matterUid==spaceid&&uid==suid" :class="managerMode ? 'moveon' :''" 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">
|
|
|
|
|
<el-tooltip placement="top" effect="dark"
|
|
|
|
|
content="禁止访问">
|
|
|
|
|
<span>不可见</span>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
<el-tooltip placement="top" effect="dark"
|
|
|
|
|
content="仅可预览,不可下载">
|
|
|
|
|
<span>仅预览</span>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
<el-tooltip placement="top" effect="dark"
|
|
|
|
|
content="可下载可见文件,不可上传文件">
|
|
|
|
|
<span>可下载</span>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
<el-tooltip placement="top" effect="dark"
|
|
|
|
|
content="可上传和下载可见文件">
|
|
|
|
|
<span>上传下载</span>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
<el-tooltip placement="top" effect="dark"
|
|
|
|
|
content="可上传、下载、编辑文档">
|
|
|
|
|
<span>编辑</span>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="tablelist">
|
|
|
|
|
<el-tree
|
|
|
|
|
ref="treeRef"
|
|
|
|
|
:data="dataSource"
|
|
|
|
|
node-key="id"
|
|
|
|
|
accordion
|
|
|
|
|
:props="{label: 'name',children:'child'}"
|
|
|
|
|
:default-expanded-keys="firstLevelKeys"
|
|
|
|
|
:expand-on-click-node="false"
|
|
|
|
|
>
|
|
|
|
|
<template #default="{ node, data }">
|
|
|
|
|
<div class="tree-node">
|
|
|
|
|
<span>{{ data.name }}</span>
|
|
|
|
|
|
|
|
|
|
<div v-if="managerMode" class="buttons">
|
|
|
|
|
<el-checkbox v-model="data.ismanager" :indeterminate="data.indeterminate2" />
|
|
|
|
|
</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;
|
|
|
|
|
}
|
|
|
|
|
.moveon{
|
|
|
|
|
background-color: rgb(109, 187, 238);
|
|
|
|
|
}
|
|
|
|
|
.el-tree{
|
|
|
|
|
/* 让整个弹出窗口位置更高一些*/
|
|
|
|
|
--el-tree-node-content-height:33px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|