|
|
@ -1,22 +1,12 @@
|
|
|
|
<template>
|
|
|
|
<template>
|
|
|
|
<div class="main">
|
|
|
|
<div class="main">
|
|
|
|
<div class="top">
|
|
|
|
<div class="top">
|
|
|
|
<a-tooltip placement="top" :mouseEnterDelay="0.5">
|
|
|
|
<a-button type="link" @click="openRule"><i class="icon-fuzhi3 iconfont"></i>复制设置并应用</a-button>
|
|
|
|
<template #title>
|
|
|
|
|
|
|
|
<span>新建</span>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<span class="ds-action-svg-btn">
|
|
|
|
|
|
|
|
<a-button @click="GoDetailed(false)" v-repeat type="link">
|
|
|
|
|
|
|
|
<img src="../../../assets/svg/infoclient/baocun.svg" class="SvgImg" />
|
|
|
|
|
|
|
|
</a-button>
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a-tooltip>
|
|
|
|
|
|
|
|
<a-button>复制设置并应用</a-button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="tree-box">
|
|
|
|
<div class="tree-box">
|
|
|
|
<div class="tree-item">
|
|
|
|
<div class="tree-item border-left">
|
|
|
|
<div class="title">用户</div>
|
|
|
|
<div class="title">用户</div>
|
|
|
|
<BasicTree ref="treeRef" check-strictly :tree-data="treeData" @select="handleSelect">
|
|
|
|
<BasicTree ref="treeRef" check-strictly :treeData="treeData" @select="handleSelect">
|
|
|
|
<template #title="custom">
|
|
|
|
<template #title="custom">
|
|
|
|
<span>{{ custom.node.title }}</span>
|
|
|
|
<span>{{ custom.node.title }}</span>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
@ -24,52 +14,267 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="tree-item">
|
|
|
|
<div class="tree-item">
|
|
|
|
<div class="title">用户权限配置</div>
|
|
|
|
<div class="title">用户权限配置</div>
|
|
|
|
<BasicTree ref="menuTreeRef" check-strictly :tree-data="menuTree" @select="handleSelectMenu">
|
|
|
|
<a-spin :spinning="menuLoad">
|
|
|
|
|
|
|
|
<BasicTree ref="menuTreeRef" check-strictly :treeData="menuTree" @select="handleSelectMenu">
|
|
|
|
<template #title="custom">
|
|
|
|
<template #title="custom">
|
|
|
|
<span>{{ custom.node.name }}</span>
|
|
|
|
<span>{{ custom.node.name }}</span>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
</BasicTree>
|
|
|
|
</BasicTree>
|
|
|
|
|
|
|
|
</a-spin>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="table-item">
|
|
|
|
|
|
|
|
<BasicTable class="ds-table-detail" @register="registerTable">
|
|
|
|
|
|
|
|
<template #tableTitle>
|
|
|
|
|
|
|
|
<span style="font-size: 12px;font-weight: bold;color: black">数据权限列表</span>
|
|
|
|
|
|
|
|
<a-button type="link" @click="setLook(1)"><i class="icon-yulan1 iconfont"></i>应用可视范围</a-button>
|
|
|
|
|
|
|
|
<a-button type="link" @click="setLook(2)"><i class="icon-shichuang-duoge iconfont"></i>应用操作范围到当前页</a-button>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<template v-slot:bodyCell="{ column, record }">
|
|
|
|
|
|
|
|
<template v-if="column.key === 'visibleRuleScopeName'">
|
|
|
|
|
|
|
|
<a-select @change="handleChangeLook($event, record)" v-model:value="record.visibleTemplateId" size="small"
|
|
|
|
|
|
|
|
style="width: 100%">
|
|
|
|
|
|
|
|
<a-select-option v-for="(item, index) in lookSelect" :key="index" :value="item.id">{{ item.ruleScopeName
|
|
|
|
|
|
|
|
}}</a-select-option>
|
|
|
|
|
|
|
|
</a-select>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<template v-if="column.key === 'operateRuleScopeName'">
|
|
|
|
|
|
|
|
<a-select @change="handleChangeLook($event, record)" v-model:value="record.operateTemplateId" size="small"
|
|
|
|
|
|
|
|
style="width: 100%">
|
|
|
|
|
|
|
|
<a-select-option v-for="(item, index) in actionSelect" :key="index" :value="item.id">{{
|
|
|
|
|
|
|
|
item.ruleScopeName }}</a-select-option>
|
|
|
|
|
|
|
|
</a-select>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</BasicTable>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<a-modal @ok="handleCopy" width="800px" @cancel="openFlag = false" :visible="openFlag" title="选择用户复制">
|
|
|
|
|
|
|
|
<a-spin :spinning="copyLoad" >
|
|
|
|
|
|
|
|
<BasicTree key="value" v-model:checkedKeys="checkedKeys" checkable check-strictly :treeData="treeDataCopy">
|
|
|
|
|
|
|
|
<template #title="custom">
|
|
|
|
|
|
|
|
<span>{{ custom.node.title }}</span>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</BasicTree>
|
|
|
|
|
|
|
|
</a-spin>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</a-modal>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
|
|
<script lang="ts" setup>
|
|
|
|
import { defineComponent, onMounted, ref } from 'vue'
|
|
|
|
import { defineComponent, onMounted, ref } from 'vue'
|
|
|
|
import { BasicTable, useTable, TableAction } from '/@/components/Table'
|
|
|
|
import { BasicTable, useTable, TableAction } from '/@/components/Table'
|
|
|
|
import { getDataRuleList } from '/@/api/system/datarule'
|
|
|
|
import { getDataRuleList } from '/@/api/system/datarule'
|
|
|
|
import { useModal } from '/@/components/Modal'
|
|
|
|
import { useModal } from '/@/components/Modal'
|
|
|
|
import { GetOrgUserTree, GetClientUserPermissions,GetCodeDataRuleList } from './api'
|
|
|
|
import {
|
|
|
|
|
|
|
|
GetOrgUserTree, GetClientUserPermissions, GetCodeDataRuleList, UserVisibleDataRuleScopeApply,
|
|
|
|
|
|
|
|
GetDataRuleTemplateSelectList, AssignDataRuleScope, CopyDataRuleScope, UserOperateDataRuleScopeApply
|
|
|
|
|
|
|
|
} from './api'
|
|
|
|
import { BasicTree } from '/@/components/Tree/index'
|
|
|
|
import { BasicTree } from '/@/components/Tree/index'
|
|
|
|
|
|
|
|
import { useMessage } from '../../../hooks/web/useMessage'
|
|
|
|
|
|
|
|
const { createMessage } = useMessage()
|
|
|
|
// import { columns, searchFormSchema } from './columns'
|
|
|
|
// import { columns, searchFormSchema } from './columns'
|
|
|
|
const treeData = ref([])
|
|
|
|
const treeData = ref([])
|
|
|
|
|
|
|
|
const treeDataCopy = ref([])
|
|
|
|
const menuTree = ref([])
|
|
|
|
const menuTree = ref([])
|
|
|
|
|
|
|
|
const openFlag = ref(false)
|
|
|
|
onMounted(() => {
|
|
|
|
onMounted(() => {
|
|
|
|
GetOrgUserTree().then(res => {
|
|
|
|
GetOrgUserTree().then(res => {
|
|
|
|
treeData.value = res.data
|
|
|
|
treeData.value = res.data
|
|
|
|
|
|
|
|
treeDataCopy.value = JSON.parse(JSON.stringify(res.data))
|
|
|
|
treeData.value.forEach(item => {
|
|
|
|
treeData.value.forEach(item => {
|
|
|
|
processNode(item);
|
|
|
|
processNode(item);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
treeDataCopy.value.forEach(item => {
|
|
|
|
|
|
|
|
item.disabled = true
|
|
|
|
|
|
|
|
processNodeCheck(item);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
setProps({
|
|
|
|
|
|
|
|
rowSelection: {
|
|
|
|
|
|
|
|
onChange: onSelectChange
|
|
|
|
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
const menuLoad = ref(false)
|
|
|
|
const userId = ref('')
|
|
|
|
const userId = ref('')
|
|
|
|
|
|
|
|
const copyLoad = ref(false)
|
|
|
|
|
|
|
|
function onSelectChange() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const checkedKeys = ref([]) as any
|
|
|
|
|
|
|
|
function handleCopy() {
|
|
|
|
|
|
|
|
if (!checkedKeys.value.checked || checkedKeys.value.checked.length == 0) {
|
|
|
|
|
|
|
|
createMessage.warning('请选择要复制的用户')
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!userId.value) {
|
|
|
|
|
|
|
|
createMessage.warning('请选择要被复制的用户')
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
|
|
|
|
userId: userId.value,
|
|
|
|
|
|
|
|
copyUserIds: checkedKeys.value.checked
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
copyLoad.value = true
|
|
|
|
|
|
|
|
CopyDataRuleScope(data).then(res => {
|
|
|
|
|
|
|
|
if(res.succeeded){
|
|
|
|
|
|
|
|
createMessage.success('复制成功')
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
copyLoad.value = false
|
|
|
|
|
|
|
|
}).catch(err => {
|
|
|
|
|
|
|
|
copyLoad.value = false
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function setLook(type) {
|
|
|
|
|
|
|
|
if (!userId.value) {
|
|
|
|
|
|
|
|
createMessage.warning('请选择用户')
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getSelectRows().length == 0) {
|
|
|
|
|
|
|
|
createMessage.warning('请选择要应用的数据')
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getSelectRows().length > 1) {
|
|
|
|
|
|
|
|
createMessage.warning('只能选择一条')
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
|
|
|
|
userId: userId.value,
|
|
|
|
|
|
|
|
ruleId: getSelectRows()[0].id
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
setLoading(true)
|
|
|
|
|
|
|
|
if (type == 1) {
|
|
|
|
|
|
|
|
UserVisibleDataRuleScopeApply(data).then(res => {
|
|
|
|
|
|
|
|
if (res.succeeded) {
|
|
|
|
|
|
|
|
createMessage.success('应用成功')
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
setLoading(false)
|
|
|
|
|
|
|
|
}).catch(err => {
|
|
|
|
|
|
|
|
setLoading(false)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
UserOperateDataRuleScopeApply(data).then(res => {
|
|
|
|
|
|
|
|
if (res.succeeded) {
|
|
|
|
|
|
|
|
createMessage.success('应用成功')
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
setLoading(false)
|
|
|
|
|
|
|
|
}).catch(err => {
|
|
|
|
|
|
|
|
setLoading(false)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
function handleSelect(selectedKeys: any, info: any) {
|
|
|
|
function handleSelect(selectedKeys: any, info: any) {
|
|
|
|
if (info.node.id) {
|
|
|
|
if (info.node.id) {
|
|
|
|
userId.value = info.node.value
|
|
|
|
userId.value = info.node.value
|
|
|
|
|
|
|
|
menuLoad.value = true
|
|
|
|
GetClientUserPermissions({ id: info.node.value }).then(res => {
|
|
|
|
GetClientUserPermissions({ id: info.node.value }).then(res => {
|
|
|
|
menuTree.value = res.data
|
|
|
|
menuTree.value = res.data
|
|
|
|
|
|
|
|
menuLoad.value = false
|
|
|
|
|
|
|
|
}).catch(err => {
|
|
|
|
|
|
|
|
menuLoad.value = false
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function handleSelectMenu(selectedKeys: any, info: any){
|
|
|
|
const lookSelect = ref([]) as any
|
|
|
|
console.log(info)
|
|
|
|
const actionSelect = ref([]) as any
|
|
|
|
if(info.node.children==null || info.node.children.length==0){
|
|
|
|
function handleSelectMenu(selectedKeys: any, info: any) {
|
|
|
|
|
|
|
|
if (info.node.children == null || info.node.children.length == 0) {
|
|
|
|
const data = {
|
|
|
|
const data = {
|
|
|
|
permissionId: info.node.id,
|
|
|
|
permissionId: info.node.parentId,
|
|
|
|
id:userId.value
|
|
|
|
userId: userId.value
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
setLoading(true)
|
|
|
|
|
|
|
|
GetCodeDataRuleList(data).then(res => {
|
|
|
|
|
|
|
|
if (res.succeeded) {
|
|
|
|
|
|
|
|
setTableData(res.data)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
GetCodeDataRuleList(data).then(res=>{
|
|
|
|
setLoading(false)
|
|
|
|
|
|
|
|
}).catch(err => {
|
|
|
|
|
|
|
|
setLoading(false)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
GetDataRuleTemplateSelectList({ id: info.node.parentId, ruleType: 'visible' }).then(res => {
|
|
|
|
|
|
|
|
lookSelect.value = res.data
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
GetDataRuleTemplateSelectList({ id: info.node.parentId, ruleType: 'operate' }).then(res => {
|
|
|
|
|
|
|
|
actionSelect.value = res.data
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function openRule() {
|
|
|
|
|
|
|
|
openFlag.value = true
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const columns = [
|
|
|
|
|
|
|
|
{ dataIndex: 'templateName', width: 100, title: '权限模板类型' },
|
|
|
|
|
|
|
|
{ dataIndex: 'description', width: 100, title: '权限描述' },
|
|
|
|
|
|
|
|
{ dataIndex: 'note', width: 100, title: '备注' },
|
|
|
|
|
|
|
|
{ dataIndex: 'visibleRuleScopeName', width: 100, title: '可视范围' },
|
|
|
|
|
|
|
|
{ dataIndex: 'operateRuleScopeName', width: 100, title: '操作范围' },
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
const ruleList = ref([])
|
|
|
|
|
|
|
|
const [registerTable, { reload, setLoading, setTableData, getSelectRows, setProps }] = useTable({
|
|
|
|
|
|
|
|
immediate: false,
|
|
|
|
|
|
|
|
columns,
|
|
|
|
|
|
|
|
isTreeTable: false,
|
|
|
|
|
|
|
|
pagination: true,
|
|
|
|
|
|
|
|
striped: true,
|
|
|
|
|
|
|
|
useSearchForm: false,
|
|
|
|
|
|
|
|
bordered: true,
|
|
|
|
|
|
|
|
showIndexColumn: false,
|
|
|
|
|
|
|
|
canResize: true,
|
|
|
|
|
|
|
|
resizeHeightOffset: 35,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
function handleChangeLook(val, row) {
|
|
|
|
|
|
|
|
const data = {} as any
|
|
|
|
|
|
|
|
lookSelect.value.forEach(item => {
|
|
|
|
|
|
|
|
if (item.id == val) {
|
|
|
|
|
|
|
|
data.templateId = item.id
|
|
|
|
|
|
|
|
data.ruleType = item.ruleType
|
|
|
|
|
|
|
|
data.ruleScope = item.ruleScope
|
|
|
|
|
|
|
|
data.ruleScopeName = item.ruleScopeName
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
data.id = row.id
|
|
|
|
|
|
|
|
setLoading(true)
|
|
|
|
|
|
|
|
AssignDataRuleScope(data).then(res => {
|
|
|
|
|
|
|
|
if (res.succeeded) {
|
|
|
|
|
|
|
|
createMessage.success('更新成功')
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
setLoading(false)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function processNodeCheck(node) {
|
|
|
|
|
|
|
|
// 如果当前节点的 children 是空数组且 userList 有值,则进行赋值
|
|
|
|
|
|
|
|
if (node.children && node.children.length === 0 && node.userList) {
|
|
|
|
|
|
|
|
node.children = node.userList.map(user => {
|
|
|
|
|
|
|
|
// 添加 title 和 disabled 属性
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
...user,
|
|
|
|
|
|
|
|
title: user.userName,
|
|
|
|
|
|
|
|
disabled: false,
|
|
|
|
|
|
|
|
value: user.id,
|
|
|
|
|
|
|
|
key: user.id
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// 对于其他节点,设置 disabled 为 true
|
|
|
|
|
|
|
|
if (node.children) {
|
|
|
|
|
|
|
|
node.children = node.children.map(child => {
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
...child,
|
|
|
|
|
|
|
|
key: child.id,
|
|
|
|
|
|
|
|
disabled: true
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 递归处理每个子节点
|
|
|
|
|
|
|
|
if (node.children) {
|
|
|
|
|
|
|
|
node.children.forEach(child => {
|
|
|
|
|
|
|
|
processNodeCheck(child);
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -97,12 +302,12 @@ function processNode(node) {
|
|
|
|
</script>
|
|
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
|
|
<style lang="less" scoped>
|
|
|
|
.main {
|
|
|
|
.main {
|
|
|
|
height: 100vh;
|
|
|
|
height: 80vh;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.top {
|
|
|
|
.top {
|
|
|
|
background-color: rgba(245, 249, 252, 1);
|
|
|
|
background-color: rgba(245, 249, 252, 1);
|
|
|
|
padding: 10px;
|
|
|
|
padding: 8px 10px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.SvgImg {
|
|
|
|
.SvgImg {
|
|
|
@ -118,6 +323,7 @@ function processNode(node) {
|
|
|
|
|
|
|
|
|
|
|
|
.tree-item {
|
|
|
|
.tree-item {
|
|
|
|
width: 20%;
|
|
|
|
width: 20%;
|
|
|
|
|
|
|
|
padding: 0 15px;
|
|
|
|
|
|
|
|
|
|
|
|
.title {
|
|
|
|
.title {
|
|
|
|
font-size: 12px;
|
|
|
|
font-size: 12px;
|
|
|
@ -127,8 +333,20 @@ function processNode(node) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.border-left {
|
|
|
|
|
|
|
|
border-right: 1px solid #ebebeb;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.table-item {
|
|
|
|
|
|
|
|
width: 50%;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/deep/ .ant-tree-node-selected {
|
|
|
|
/deep/ .ant-tree-node-selected {
|
|
|
|
color: #257afa;
|
|
|
|
color: #257afa;
|
|
|
|
background-color: #f5f9fc !important;
|
|
|
|
background-color: #f5f9fc !important;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/deep/ .vben-basic-table .ant-table-wrapper .ant-table.ant-table-bordered .ant-table-title {
|
|
|
|
|
|
|
|
padding-top: 0px !important;
|
|
|
|
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
</style>
|
|
|
|