mirror of
https://github.com/dataease/dataease.git
synced 2025-02-25 20:42:55 +08:00
fix: 无效代码删除 文件大小写 地图bug修复
This commit is contained in:
parent
a55959f4f7
commit
16dcda863a
@ -1,263 +0,0 @@
|
|||||||
<template>
|
|
||||||
<de-container style="height: auto">
|
|
||||||
<de-aside-container style="height: auto">
|
|
||||||
<el-button
|
|
||||||
v-show="!showTargetSearchInput"
|
|
||||||
class="de-icon"
|
|
||||||
icon="el-icon-search"
|
|
||||||
circle
|
|
||||||
size="mini"
|
|
||||||
@click="showTargetSearchWidget"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
v-show="showTargetSearchInput"
|
|
||||||
class="de-input"
|
|
||||||
>
|
|
||||||
<el-input v-model="targetFilterText">
|
|
||||||
<el-button
|
|
||||||
slot="append"
|
|
||||||
icon="el-icon-close"
|
|
||||||
@click="closeTargetSearchWidget"
|
|
||||||
/>
|
|
||||||
</el-input>
|
|
||||||
</div>
|
|
||||||
<el-tabs
|
|
||||||
v-model="targetActiveName"
|
|
||||||
:class="{'de-search-header': showTargetSearchInput}"
|
|
||||||
@tab-click="handleClick"
|
|
||||||
>
|
|
||||||
<el-tab-pane
|
|
||||||
v-for="(targetInfo, index) in targetInfoArray"
|
|
||||||
:key="index"
|
|
||||||
:lazy="true"
|
|
||||||
:label="targetInfo.tabName"
|
|
||||||
:name="targetInfo.authType"
|
|
||||||
>
|
|
||||||
<lazy-tree
|
|
||||||
v-if="targetActiveName===targetInfo.authType"
|
|
||||||
:active-name="targetActiveName"
|
|
||||||
:filter-text="targetFilterText"
|
|
||||||
:data-info="targetInfo"
|
|
||||||
highlight-current
|
|
||||||
@nodeClick="authNodeClick"
|
|
||||||
/>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
</de-aside-container>
|
|
||||||
<de-main-container class="de-main-container-auth">
|
|
||||||
<el-button
|
|
||||||
v-show="!showSourceSearchInput"
|
|
||||||
class="de-icon"
|
|
||||||
icon="el-icon-search"
|
|
||||||
circle
|
|
||||||
size="mini"
|
|
||||||
@click="showSourceSearchWidget"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
v-show="showSourceSearchInput"
|
|
||||||
class="de-input"
|
|
||||||
>
|
|
||||||
<el-input v-model="sourceFilterText">
|
|
||||||
<el-button
|
|
||||||
slot="append"
|
|
||||||
icon="el-icon-close"
|
|
||||||
@click="closeSourceSearchWidget"
|
|
||||||
/>
|
|
||||||
</el-input>
|
|
||||||
</div>
|
|
||||||
<el-tabs
|
|
||||||
v-model="sourceActiveName"
|
|
||||||
:class="{'de-search-header': showSourceSearchInput}"
|
|
||||||
@tab-click="handleClick"
|
|
||||||
>
|
|
||||||
<el-tab-pane
|
|
||||||
v-for="(sourceInfo, index) in sourceInfoTabs"
|
|
||||||
:key="index"
|
|
||||||
:lazy="true"
|
|
||||||
:label="sourceInfo.tabName"
|
|
||||||
:name="sourceInfo.authType"
|
|
||||||
>
|
|
||||||
<lazy-tree
|
|
||||||
v-if="authCondition"
|
|
||||||
:active-name="sourceActiveName"
|
|
||||||
:filter-text="sourceFilterText"
|
|
||||||
:data-info="sourceInfo"
|
|
||||||
show-extent
|
|
||||||
:auth-condition="authCondition"
|
|
||||||
:attach-active-name="targetActiveName"
|
|
||||||
/>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
</de-main-container>
|
|
||||||
</de-container>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import DeContainer from '../../../components/dataease/DeContainer'
|
|
||||||
import DeAsideContainer from '../../../components/dataease/DeAsideContainer'
|
|
||||||
import DeMainContainer from '../../../components/dataease/DeMainContainer'
|
|
||||||
import LazyTree from './components/LazyTree'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Authority',
|
|
||||||
components: { LazyTree, DeMainContainer, DeAsideContainer, DeContainer },
|
|
||||||
props: {
|
|
||||||
resourceId: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
targetInfoArray:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
tabName: this.$t('auth.dept'),
|
|
||||||
head: this.$t('auth.deptHead'),
|
|
||||||
direction: 'target',
|
|
||||||
authType: 'dept'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tabName: this.$t('auth.role'),
|
|
||||||
head: this.$t('auth.roleHead'),
|
|
||||||
direction: 'target',
|
|
||||||
authType: 'role'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tabName: this.$t('auth.user'),
|
|
||||||
head: this.$t('auth.userHead'),
|
|
||||||
direction: 'target',
|
|
||||||
authType: 'user'
|
|
||||||
}],
|
|
||||||
sourceInfoArray:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
tabName: this.$t('auth.linkAuth'),
|
|
||||||
head: this.$t('auth.linkAuthHead'),
|
|
||||||
direction: 'source',
|
|
||||||
authType: 'link',
|
|
||||||
authTargets: 'dept,role,user'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tabName: this.$t('auth.datasetAuth'),
|
|
||||||
head: this.$t('auth.datasetAuthHead'),
|
|
||||||
direction: 'source',
|
|
||||||
authType: 'dataset',
|
|
||||||
authTargets: 'dept,role,user'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tabName: this.$t('auth.chartAuth'),
|
|
||||||
head: this.$t('auth.chartAuthHead'),
|
|
||||||
direction: 'source',
|
|
||||||
authType: 'chart',
|
|
||||||
authTargets: 'dept,role,user'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tabName: this.$t('auth.panelAuth'),
|
|
||||||
head: this.$t('auth.panelAuthHead'),
|
|
||||||
direction: 'source',
|
|
||||||
authType: 'panel',
|
|
||||||
authTargets: 'dept,role,user'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tabName: this.$t('auth.menuAuth'),
|
|
||||||
head: this.$t('auth.menuAuthHead'),
|
|
||||||
direction: 'source',
|
|
||||||
authType: 'menu',
|
|
||||||
authTargets: 'dept,role,user'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
targetActiveName: null,
|
|
||||||
sourceActiveName: null,
|
|
||||||
showSourceSearchInput: false,
|
|
||||||
showTargetSearchInput: false,
|
|
||||||
sourceFilterText: '',
|
|
||||||
targetFilterText: '',
|
|
||||||
timeMachine: null,
|
|
||||||
authCondition: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
sourceInfoTabs() {
|
|
||||||
const tabs = []
|
|
||||||
this.sourceInfoArray.forEach(item => {
|
|
||||||
if (item.authTargets.indexOf(this.targetActiveName) > -1) {
|
|
||||||
tabs.push(item)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return tabs
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.targetActiveName = this.targetInfoArray[0].authType
|
|
||||||
this.sourceActiveName = this.sourceInfoArray[0].authType
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
handleClick(tab, event) {
|
|
||||||
},
|
|
||||||
showSourceSearchWidget() {
|
|
||||||
this.showSourceSearchInput = true
|
|
||||||
},
|
|
||||||
closeSourceSearchWidget() {
|
|
||||||
this.sourceFilterText = ''
|
|
||||||
this.showSourceSearchInput = false
|
|
||||||
},
|
|
||||||
showTargetSearchWidget() {
|
|
||||||
this.showTargetSearchInput = true
|
|
||||||
},
|
|
||||||
closeTargetSearchWidget() {
|
|
||||||
this.targetFilterText = ''
|
|
||||||
this.showTargetSearchInput = false
|
|
||||||
},
|
|
||||||
save() {
|
|
||||||
this.$refs[this.activeName].save()
|
|
||||||
this.$emit('close-grant', 0)
|
|
||||||
},
|
|
||||||
cancel() {
|
|
||||||
this.$refs[this.activeName].cancel()
|
|
||||||
this.$emit('close-grant', 0)
|
|
||||||
},
|
|
||||||
authNodeClick(val) {
|
|
||||||
this.authCondition = val
|
|
||||||
},
|
|
||||||
clickAuth(auth) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.de-tab {
|
|
||||||
border:1px solid #E6E6E6;
|
|
||||||
min-height:200px !important;
|
|
||||||
max-height:300px !important;
|
|
||||||
overflow:auto;
|
|
||||||
}
|
|
||||||
.de-icon {
|
|
||||||
position: absolute;
|
|
||||||
right: 10px;
|
|
||||||
top: 15px;
|
|
||||||
z-index: 99;
|
|
||||||
}
|
|
||||||
.el-input-group__append{
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
.el-input__inner{
|
|
||||||
border-right: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.auth-root-class {
|
|
||||||
margin: 15px 0px 5px;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
.de-main-container-auth{
|
|
||||||
border: 1px solid #E6E6E6;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ::-webkit-scrollbar {
|
|
||||||
|
|
||||||
// }
|
|
||||||
</style>
|
|
@ -1,190 +0,0 @@
|
|||||||
<template>
|
|
||||||
<de-container>
|
|
||||||
<span>敬请期待</span>
|
|
||||||
<!-- <de-aside-container>-->
|
|
||||||
<!-- <el-button v-show="!showSourceSearchInput" class="de-icon" icon="el-icon-search" circle size="mini" @click="showSourceSearchWidget" />-->
|
|
||||||
<!-- <div v-show="showSourceSearchInput" class="de-input">-->
|
|
||||||
<!-- <el-input v-model="sourceFilterText">-->
|
|
||||||
<!-- <el-button slot="append" icon="el-icon-close" @click="closeSourceSearchWidget" />-->
|
|
||||||
<!-- </el-input>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <el-tabs v-model="sourceActiveName" :class="{'de-search-header': showSourceSearchInput}" @tab-click="handleClick">-->
|
|
||||||
<!-- <el-tab-pane v-for="(sourceInfo, index) in sourceInfoArray" :key="index" :lazy="true" :label="sourceInfo.tabName" :name="sourceInfo.authType">-->
|
|
||||||
<!-- <lazy-tree-->
|
|
||||||
<!-- v-if="authCondition"-->
|
|
||||||
<!-- :active-name="sourceActiveName"-->
|
|
||||||
<!-- :filter-text="sourceFilterText"-->
|
|
||||||
<!-- :data-info="sourceInfo"-->
|
|
||||||
<!-- highlight-current-->
|
|
||||||
<!-- @nodeClick="authNodeClick"-->
|
|
||||||
<!-- />-->
|
|
||||||
<!-- </el-tab-pane>-->
|
|
||||||
<!-- </el-tabs>-->
|
|
||||||
<!-- </de-aside-container>-->
|
|
||||||
<!-- <de-main-container class="de-main-container-auth">-->
|
|
||||||
<!-- <el-button v-show="!showTargetSearchInput" class="de-icon" icon="el-icon-search" circle size="mini" @click="showTargetSearchWidget" />-->
|
|
||||||
<!-- <div v-show="showTargetSearchInput" class="de-input">-->
|
|
||||||
<!-- <el-input v-model="targetFilterText">-->
|
|
||||||
<!-- <el-button slot="append" icon="el-icon-close" @click="closeTargetSearchWidget" />-->
|
|
||||||
<!-- </el-input>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <el-tabs v-model="targetActiveName" :class="{'de-search-header': showTargetSearchInput}" @tab-click="handleClick">-->
|
|
||||||
<!-- <el-tab-pane v-for="(targetInfo, index) in targetInfoArray" :key="index" :lazy="true" :label="targetInfo.tabName" :name="targetInfo.authType">-->
|
|
||||||
<!-- <lazy-tree-->
|
|
||||||
<!-- :active-name="targetActiveName"-->
|
|
||||||
<!-- :filter-text="targetFilterText"-->
|
|
||||||
<!-- :data-info="targetInfo"-->
|
|
||||||
<!-- show-extent-->
|
|
||||||
<!-- :auth-condition="authCondition"-->
|
|
||||||
<!-- />-->
|
|
||||||
<!-- </el-tab-pane>-->
|
|
||||||
<!-- </el-tabs>-->
|
|
||||||
<!-- </de-main-container>-->
|
|
||||||
</de-container>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import DeContainer from '../../../components/dataease/DeContainer'
|
|
||||||
import DeAsideContainer from '../../../components/dataease/DeAsideContainer'
|
|
||||||
import DeMainContainer from '../../../components/dataease/DeMainContainer'
|
|
||||||
import LazyTree from './components/LazyTree'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Authority',
|
|
||||||
// eslint-disable-next-line vue/no-unused-components
|
|
||||||
components: { LazyTree, DeMainContainer, DeAsideContainer, DeContainer },
|
|
||||||
props: {
|
|
||||||
resourceId: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
targetInfoArray:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
tabName: '部门权限',
|
|
||||||
head: '所有部门',
|
|
||||||
direction: 'target',
|
|
||||||
authType: 'dept'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tabName: '角色权限',
|
|
||||||
head: '所有角色',
|
|
||||||
direction: 'target',
|
|
||||||
authType: 'role'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tabName: '用户权限',
|
|
||||||
head: '所有用户',
|
|
||||||
direction: 'target',
|
|
||||||
authType: 'user'
|
|
||||||
}],
|
|
||||||
sourceInfoArray:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
tabName: '数据源',
|
|
||||||
head: '所有数据源',
|
|
||||||
direction: 'source',
|
|
||||||
authType: 'link'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tabName: '数据集',
|
|
||||||
head: '所有数据集',
|
|
||||||
direction: 'source',
|
|
||||||
authType: 'dataset'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tabName: '视图',
|
|
||||||
head: '所有视图',
|
|
||||||
direction: 'source',
|
|
||||||
authType: 'chart'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tabName: '仪表板',
|
|
||||||
head: '所有仪表板',
|
|
||||||
direction: 'source',
|
|
||||||
authType: 'panel'
|
|
||||||
}],
|
|
||||||
targetActiveName: null,
|
|
||||||
sourceActiveName: null,
|
|
||||||
showSourceSearchInput: false,
|
|
||||||
showTargetSearchInput: false,
|
|
||||||
sourceFilterText: '',
|
|
||||||
targetFilterText: '',
|
|
||||||
timeMachine: null,
|
|
||||||
authCondition: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.targetActiveName = this.targetInfoArray[0].authType
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
handleClick(tab, event) {
|
|
||||||
},
|
|
||||||
showSourceSearchWidget() {
|
|
||||||
this.showSourceSearchInput = true
|
|
||||||
},
|
|
||||||
closeSourceSearchWidget() {
|
|
||||||
this.sourceFilterText = ''
|
|
||||||
this.showSourceSearchInput = false
|
|
||||||
},
|
|
||||||
showTargetSearchWidget() {
|
|
||||||
this.showTargetSearchInput = true
|
|
||||||
},
|
|
||||||
closeTargetSearchWidget() {
|
|
||||||
this.targetFilterText = ''
|
|
||||||
this.showTargetSearchInput = false
|
|
||||||
},
|
|
||||||
save() {
|
|
||||||
this.$refs[this.activeName].save()
|
|
||||||
this.$emit('close-grant', 0)
|
|
||||||
},
|
|
||||||
cancel() {
|
|
||||||
this.$refs[this.activeName].cancel()
|
|
||||||
this.$emit('close-grant', 0)
|
|
||||||
},
|
|
||||||
authNodeClick(val) {
|
|
||||||
this.authCondition = val
|
|
||||||
},
|
|
||||||
clickAuth(auth) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.de-tab {
|
|
||||||
border:1px solid #E6E6E6;
|
|
||||||
min-height:200px !important;
|
|
||||||
max-height:300px !important;
|
|
||||||
overflow:auto;
|
|
||||||
}
|
|
||||||
.de-icon {
|
|
||||||
position: absolute;
|
|
||||||
right: 10px;
|
|
||||||
top: 15px;
|
|
||||||
z-index: 99;
|
|
||||||
}
|
|
||||||
.el-input-group__append{
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
.el-input__inner{
|
|
||||||
border-right: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.auth-root-class {
|
|
||||||
margin: 15px 0px 5px;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
.de-main-container-auth{
|
|
||||||
border: 1px solid #E6E6E6;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ::-webkit-scrollbar {
|
|
||||||
|
|
||||||
// }
|
|
||||||
</style>
|
|
@ -1,366 +0,0 @@
|
|||||||
<template xmlns:el-col="http://www.w3.org/1999/html">
|
|
||||||
<el-col
|
|
||||||
v-loading="loading"
|
|
||||||
class="tree-main"
|
|
||||||
>
|
|
||||||
<el-row
|
|
||||||
v-if="showExtent"
|
|
||||||
class="tree-head"
|
|
||||||
>
|
|
||||||
<span style="float: left;padding-left: 10px">{{ dataInfo.head }}</span>
|
|
||||||
<span
|
|
||||||
v-for="auth in defaultAuthDetails"
|
|
||||||
:key="auth.privilegeName"
|
|
||||||
class="auth-span"
|
|
||||||
>
|
|
||||||
{{ auth.privilegeName }}
|
|
||||||
</span>
|
|
||||||
</el-row>
|
|
||||||
<el-row style="margin-top: 5px">
|
|
||||||
<el-tree
|
|
||||||
:props="defaultProps"
|
|
||||||
:load="loadNodes"
|
|
||||||
:data="treeData"
|
|
||||||
:node-key="defaultProps.id"
|
|
||||||
:highlight-current="highlightCurrent"
|
|
||||||
:default-expanded-keys="expandedKey"
|
|
||||||
lazy
|
|
||||||
@node-click="nodeClick"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
slot-scope="{ data }"
|
|
||||||
class="custom-tree-node"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
<span
|
|
||||||
style="margin-left: 6px"
|
|
||||||
v-html="data.name"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
v-if="showExtent"
|
|
||||||
@click.stop
|
|
||||||
>
|
|
||||||
<div v-if="authDetails[data.id]">
|
|
||||||
<span
|
|
||||||
v-for="auth in authDetails[data.id]"
|
|
||||||
:key="auth.privilegeType"
|
|
||||||
class="auth-span"
|
|
||||||
>
|
|
||||||
<!-- 1-{{ auth.privilegeType }}-{{ auth.privilegeValue }}-->
|
|
||||||
<a
|
|
||||||
href="javascript:;"
|
|
||||||
@click="clickAuth(data.id,auth)"
|
|
||||||
>
|
|
||||||
<svg-icon
|
|
||||||
style="width: 22px;height: 22px"
|
|
||||||
:icon-class="auth.privilegeValue===1?'lock_open':'lock_closed'"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<span
|
|
||||||
v-for="auth in defaultAuthDetails"
|
|
||||||
:key="auth.privilegeType"
|
|
||||||
class="auth-span"
|
|
||||||
>
|
|
||||||
<!--2-{{ auth.privilegeType }}-{{ auth.privilegeValue }}-->
|
|
||||||
<a
|
|
||||||
href="javascript:;"
|
|
||||||
@click="clickAuth(data.id,auth)"
|
|
||||||
>
|
|
||||||
<svg-icon
|
|
||||||
style="width: 22px;height: 22px"
|
|
||||||
:icon-class="auth.privilegeValue===1?'lock_open':'lock_closed'"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</div></span>
|
|
||||||
</span>
|
|
||||||
</el-tree>
|
|
||||||
</el-row>
|
|
||||||
</el-col>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { authChange, authDetails, authDetailsModel, authModel } from '@/api/system/sysAuth'
|
|
||||||
export default {
|
|
||||||
name: 'LazyTree',
|
|
||||||
components: { },
|
|
||||||
props: {
|
|
||||||
filterText: {
|
|
||||||
type: String,
|
|
||||||
required: false,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
authCondition: {
|
|
||||||
type: Object,
|
|
||||||
required: false,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
dataInfo: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
activeName: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
attachActiveName: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
defaultProps: {
|
|
||||||
type: Object,
|
|
||||||
required: false,
|
|
||||||
default: function() {
|
|
||||||
return {
|
|
||||||
children: 'children',
|
|
||||||
label: 'name',
|
|
||||||
id: 'id',
|
|
||||||
parentId: 'pid',
|
|
||||||
isLeaf: 'leaf'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showExtent: Boolean,
|
|
||||||
highlightCurrent: Boolean
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: false,
|
|
||||||
treeData: [],
|
|
||||||
changeIndex: 0,
|
|
||||||
timeMachine: null,
|
|
||||||
expandedKey: [], // 展开节点 搜索时默认展开父级节点
|
|
||||||
defaultCondition: { // pid 是0的时候 查询的是顶级的节点
|
|
||||||
pid: '0'
|
|
||||||
},
|
|
||||||
authDetails: {},
|
|
||||||
defaultAuthDetails: [],
|
|
||||||
searchStatus: false, // 当前是否在搜索状态 (搜索状态 展开不加载子节点)
|
|
||||||
// 当前已经加载的节点ID 备用(当前把当前authTarget的所有授权加载进来)
|
|
||||||
loadedNodeIds: new Set()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
filterText(val) {
|
|
||||||
this.expandedKey = []
|
|
||||||
if (val && val.length > 0) {
|
|
||||||
this.searchStatus = true
|
|
||||||
}
|
|
||||||
// 当组件名和 activeName 相等时 才进行查询
|
|
||||||
if (this.dataInfo.authType === this.activeName) {
|
|
||||||
this.destroyTimeMachine()
|
|
||||||
this.changeIndex++
|
|
||||||
this.filterNode(this.changeIndex)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
authCondition: {
|
|
||||||
handler(newVal, oldVla) {
|
|
||||||
this.loadAuth()
|
|
||||||
},
|
|
||||||
deep: true
|
|
||||||
},
|
|
||||||
attachActiveName: {
|
|
||||||
handler(newVal, oldVla) {
|
|
||||||
this.authDetails = {}
|
|
||||||
},
|
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
// 初始化授权模板
|
|
||||||
if (this.showExtent) {
|
|
||||||
authDetailsModel(this.dataInfo.authType).then(res => {
|
|
||||||
this.defaultAuthDetails = res.data
|
|
||||||
})
|
|
||||||
this.loadAuth()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadAuth() {
|
|
||||||
if (this.authCondition && this.showExtent) {
|
|
||||||
let authQueryCondition = {}
|
|
||||||
if (this.dataInfo.direction === 'source') {
|
|
||||||
// 当前为授权数据 获取当前authTarget 的授权信息 authSource
|
|
||||||
authQueryCondition = {
|
|
||||||
authTarget: this.authCondition.id,
|
|
||||||
authTargetType: this.authCondition.type,
|
|
||||||
authSourceType: this.dataInfo.authType
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
authQueryCondition = {
|
|
||||||
authSource: this.authCondition.id,
|
|
||||||
authSourceType: this.authCondition.type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
authDetails(authQueryCondition).then(res => {
|
|
||||||
this.authDetails = res.data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
loadNodes(node, resolve) {
|
|
||||||
if (!this.searchStatus) {
|
|
||||||
if (node.level === 0) {
|
|
||||||
const queryCondition = {
|
|
||||||
modelType: this.dataInfo.authType,
|
|
||||||
...
|
|
||||||
this.defaultCondition
|
|
||||||
}
|
|
||||||
authModel(queryCondition).then(res => {
|
|
||||||
const data = res.data
|
|
||||||
resolve(data)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
const queryCondition = {
|
|
||||||
modelType: this.dataInfo.authType
|
|
||||||
}
|
|
||||||
queryCondition[this.defaultProps.parentId] = node.data[this.defaultProps.id]
|
|
||||||
authModel(queryCondition).then(res => {
|
|
||||||
const data = res.data
|
|
||||||
resolve(data)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
resolve(node.data.children)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
filterNode(index) {
|
|
||||||
this.timeMachine = setTimeout(() => {
|
|
||||||
if (index === this.changeIndex) {
|
|
||||||
const queryCondition = {
|
|
||||||
withExtend: 'parent',
|
|
||||||
modelType: this.dataInfo.authType
|
|
||||||
}
|
|
||||||
queryCondition[this.defaultProps.label] = this.filterText
|
|
||||||
authModel(queryCondition).then(res => {
|
|
||||||
// 高亮显示
|
|
||||||
this.highlights(res.data)
|
|
||||||
this.treeData = this.buildTree(res.data)
|
|
||||||
// 恢复searchStatus 状态 可以允许继续展开父级
|
|
||||||
this.$nextTick(() => (this.searchStatus = false))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.destroyTimeMachine()
|
|
||||||
}, 1500)
|
|
||||||
},
|
|
||||||
nodeClick(data, node) {
|
|
||||||
this.$emit('nodeClick', { id: data.id, type: this.dataInfo.authType })
|
|
||||||
},
|
|
||||||
destroyTimeMachine() {
|
|
||||||
this.timeMachine && clearTimeout(this.timeMachine)
|
|
||||||
this.timeMachine = null
|
|
||||||
},
|
|
||||||
buildTree(arrs) {
|
|
||||||
const idMapping = arrs.reduce((acc, el, i) => {
|
|
||||||
acc[el[this.defaultProps.id]] = i
|
|
||||||
return acc
|
|
||||||
}, {})
|
|
||||||
const roots = []
|
|
||||||
arrs.forEach(el => {
|
|
||||||
// 判断根节点 ###
|
|
||||||
if (el[this.defaultProps.parentId] === null || el[this.defaultProps.parentId] === 0 || el[this.defaultProps.parentId] === '0') {
|
|
||||||
roots.push(el)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 用映射表找到父元素
|
|
||||||
const parentEl = arrs[idMapping[el[this.defaultProps.parentId]]]
|
|
||||||
// 把当前元素添加到父元素的`children`数组中
|
|
||||||
parentEl.children = [...(parentEl.children || []), el]
|
|
||||||
|
|
||||||
// 设置展开节点 如果没有子节点则不进行展开
|
|
||||||
if (parentEl.children.length > 0) {
|
|
||||||
this.expandedKey.push(parentEl[this.defaultProps.id])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return roots
|
|
||||||
},
|
|
||||||
// 权限修改
|
|
||||||
clickAuth(dataId, auth) {
|
|
||||||
let authChangeCondition = {}
|
|
||||||
if (this.dataInfo.direction === 'source') { // 当前为授权数据
|
|
||||||
authChangeCondition = {
|
|
||||||
authSource: dataId,
|
|
||||||
authSourceType: this.dataInfo.authType,
|
|
||||||
authTarget: this.authCondition.id,
|
|
||||||
authTargetType: this.authCondition.type,
|
|
||||||
authDetail: auth
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
authChangeCondition = {
|
|
||||||
authTarget: dataId,
|
|
||||||
authTargetType: this.dataInfo.authType,
|
|
||||||
authSource: this.authCondition.id,
|
|
||||||
authSourceType: this.authCondition.type,
|
|
||||||
authDetail: auth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.loading = true
|
|
||||||
authChange(authChangeCondition).then(res => {
|
|
||||||
// 重新加载权限
|
|
||||||
this.loadAuth()
|
|
||||||
this.loading = false
|
|
||||||
}).catch((e) => {
|
|
||||||
// this.$warning(e)
|
|
||||||
this.loading = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 高亮显示搜索内容
|
|
||||||
highlights(data) {
|
|
||||||
if (data && this.filterText && this.filterText.length > 0) {
|
|
||||||
const replaceReg = new RegExp(this.filterText, 'g')// 匹配关键字正则
|
|
||||||
const replaceString = '<span style="color: #faaa39">' + this.filterText + '</span>' // 高亮替换v-html值
|
|
||||||
data.forEach(item => {
|
|
||||||
item.name = item.name.replace(replaceReg, replaceString) // 开始替换
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.custom-tree-node {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
font-size: 14px;
|
|
||||||
padding-left: 8px;
|
|
||||||
}
|
|
||||||
.tree-main{
|
|
||||||
overflow-y: auto!important;
|
|
||||||
}
|
|
||||||
/* .tree-head{
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
border-bottom: 1px solid #e6e6e6;
|
|
||||||
background-color: #f7f8fa;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #3d4d66 ;
|
|
||||||
} */
|
|
||||||
.tree-head{
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
border-bottom: 1px solid var(--TableBorderColor, #e6e6e6);
|
|
||||||
background-color: var(--SiderBG, #f7f8fa);
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--TableColor, #3d4d66) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
.auth-span{
|
|
||||||
float: right;
|
|
||||||
width:50px;
|
|
||||||
margin-right: 30px
|
|
||||||
}
|
|
||||||
.highlights-text {
|
|
||||||
color: #faaa39 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
@ -1,46 +0,0 @@
|
|||||||
<template>
|
|
||||||
<de-main-container style="height: calc(100vh - 56px)">
|
|
||||||
<el-tabs
|
|
||||||
v-model="authorityType"
|
|
||||||
@tab-click="handleClick"
|
|
||||||
>
|
|
||||||
<el-tab-pane name="authConfig">
|
|
||||||
<span slot="label">{{ $t('auth.authConfig') }}</span>
|
|
||||||
<auth-config />
|
|
||||||
</el-tab-pane>
|
|
||||||
<!-- <el-tab-pane name="authQuickConfig">-->
|
|
||||||
<!-- <span slot="label">{{$t('auth.authQuickConfig')}}</span>-->
|
|
||||||
<!-- <auth-quick-config />-->
|
|
||||||
<!-- </el-tab-pane>-->
|
|
||||||
</el-tabs>
|
|
||||||
</de-main-container>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import DeMainContainer from '@/components/dataease/DeMainContainer'
|
|
||||||
import DeContainer from '@/components/dataease/DeContainer'
|
|
||||||
import AuthConfig from './authConfig'
|
|
||||||
import AuthQuickConfig from './authQuickConfig'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Authority',
|
|
||||||
// eslint-disable-next-line vue/no-unused-components
|
|
||||||
components: { DeContainer, DeMainContainer, AuthConfig, AuthQuickConfig },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
authorityType: 'authConfig'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleClick() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
276
frontend/src/views/system/log/FilterUser.vue
Normal file
276
frontend/src/views/system/log/FilterUser.vue
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer
|
||||||
|
v-closePress
|
||||||
|
:title="$t('user.filter_method')"
|
||||||
|
:visible.sync="userDrawer"
|
||||||
|
custom-class="de-user-drawer"
|
||||||
|
size="680px"
|
||||||
|
direction="rtl"
|
||||||
|
>
|
||||||
|
<div class="el-drawer__body-cont">
|
||||||
|
<div class="filter">
|
||||||
|
<span>{{ $t("log.optype") }}</span>
|
||||||
|
<div class="filter-item">
|
||||||
|
<span
|
||||||
|
v-for="item in types"
|
||||||
|
:key="item.label"
|
||||||
|
class="item"
|
||||||
|
:class="[activeType.includes(item.value) ? 'active' : '']"
|
||||||
|
@click="statusChange(item.value)"
|
||||||
|
>{{ $t(item.label) }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="filter">
|
||||||
|
<span>{{ $t("log.user") }}</span>
|
||||||
|
<div class="filter-item">
|
||||||
|
<span
|
||||||
|
v-for="ele in usersValueCopy"
|
||||||
|
:key="ele.id"
|
||||||
|
class="item"
|
||||||
|
:class="[activeUser.includes(ele.id) ? 'active' : '']"
|
||||||
|
@click="activeUserChange(ele.id)"
|
||||||
|
>{{ ele.username }}</span>
|
||||||
|
<el-popover
|
||||||
|
placement="bottom"
|
||||||
|
popper-class="user-popper"
|
||||||
|
width="200"
|
||||||
|
trigger="click"
|
||||||
|
>
|
||||||
|
<el-select
|
||||||
|
ref="userSelect"
|
||||||
|
v-model="usersValue"
|
||||||
|
multiple
|
||||||
|
filterable
|
||||||
|
:placeholder="$t('commons.please_select')"
|
||||||
|
value-key="id"
|
||||||
|
@change="changeUser"
|
||||||
|
@remove-tag="changeUser"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in usersComputed"
|
||||||
|
:key="item.username"
|
||||||
|
:label="item.username"
|
||||||
|
:value="item"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
<span
|
||||||
|
slot="reference"
|
||||||
|
class="more"
|
||||||
|
>+ {{ $t("panel.more") }}</span>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="filter">
|
||||||
|
<span>{{ $t("dedaterange.label") }}</span>
|
||||||
|
<div class="filter-item">
|
||||||
|
<DeDatePick v-model="dataRange" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="foot">
|
||||||
|
<el-button
|
||||||
|
class="btn normal"
|
||||||
|
@click="reset"
|
||||||
|
>{{
|
||||||
|
$t("commons.reset")
|
||||||
|
}}</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
class="btn"
|
||||||
|
@click="search"
|
||||||
|
>{{
|
||||||
|
$t("commons.adv_search.search")
|
||||||
|
}}</el-button>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { dateFormat } from '@/views/system/task/options.js'
|
||||||
|
import { opTypes } from '@/api/system/log'
|
||||||
|
import { post } from '@/api/dataset/dataset'
|
||||||
|
import DeDatePick from '@/components/deCustomCm/deDatePick.vue'
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
DeDatePick
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
types: [],
|
||||||
|
treeLoading: false,
|
||||||
|
filterTextMap: [],
|
||||||
|
dataRange: [],
|
||||||
|
usersValue: [],
|
||||||
|
activeUser: [],
|
||||||
|
users: [],
|
||||||
|
userCahe: [],
|
||||||
|
activeType: [],
|
||||||
|
userDrawer: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
usersComputed() {
|
||||||
|
return this.users.filter((ele) => !this.activeUser.includes(ele.id))
|
||||||
|
},
|
||||||
|
usersValueCopy() {
|
||||||
|
return this.userCahe.filter((ele) => this.activeUser.includes(ele.id))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.loadUsers()
|
||||||
|
this.loadType()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadType() {
|
||||||
|
opTypes().then((res) => {
|
||||||
|
this.types = res.data.map((item) => {
|
||||||
|
return { label: item.name, value: item.id }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
loadUsers() {
|
||||||
|
post('/api/user/userLists', {}, false).then((res) => {
|
||||||
|
this.users = res.data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
changeUser() {
|
||||||
|
if (
|
||||||
|
this.userCahe.length >
|
||||||
|
this.usersValue.length + this.activeUser.length
|
||||||
|
) {
|
||||||
|
this.userCahe = this.userCahe.filter((ele) =>
|
||||||
|
this.usersValue
|
||||||
|
.map((ele) => ele.id)
|
||||||
|
.concat(this.activeUser)
|
||||||
|
.includes(ele.id)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const userIdx = this.usersValue.findIndex(
|
||||||
|
(ele) =>
|
||||||
|
!this.userCahe
|
||||||
|
.map((ele) => ele.id)
|
||||||
|
.concat(this.activeUser)
|
||||||
|
.includes(ele.id)
|
||||||
|
)
|
||||||
|
if (userIdx === -1) return
|
||||||
|
this.activeUser.push(this.usersValue[userIdx].id)
|
||||||
|
this.userCahe.push(this.usersValue[userIdx])
|
||||||
|
this.usersValue.splice(userIdx, 1)
|
||||||
|
},
|
||||||
|
activeUserChange(id) {
|
||||||
|
const userIndex = this.activeUser.findIndex((ele) => ele === id)
|
||||||
|
if (userIndex === -1) {
|
||||||
|
this.activeUser.push(id)
|
||||||
|
this.usersValue = this.usersValue.filter((ele) => ele.id !== id)
|
||||||
|
} else {
|
||||||
|
this.activeUser.splice(userIndex, 1)
|
||||||
|
const user = this.userCahe.find((ele) => ele.id === id)
|
||||||
|
this.usersValue.push(user)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clearFilter() {
|
||||||
|
this.dataRange = []
|
||||||
|
this.usersValue = []
|
||||||
|
this.activeUser = []
|
||||||
|
this.activeType = []
|
||||||
|
this.userCahe = []
|
||||||
|
this.$emit('search', [], [])
|
||||||
|
},
|
||||||
|
clearOneFilter(index) {
|
||||||
|
(this.filterTextMap[index] || []).forEach((ele) => {
|
||||||
|
this[ele] = []
|
||||||
|
})
|
||||||
|
},
|
||||||
|
statusChange(value, type) {
|
||||||
|
const statusIndex = this.activeType.findIndex((ele) => ele === value)
|
||||||
|
if (statusIndex === -1) {
|
||||||
|
this.activeType.push(value)
|
||||||
|
} else {
|
||||||
|
this.activeType.splice(statusIndex, 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
search() {
|
||||||
|
this.userDrawer = false
|
||||||
|
this.$emit('search', this.formatCondition(), this.formatText())
|
||||||
|
},
|
||||||
|
formatText() {
|
||||||
|
this.filterTextMap = []
|
||||||
|
const params = []
|
||||||
|
if (this.activeType.length) {
|
||||||
|
params.push(
|
||||||
|
`${this.$t('log.optype')}:${this.activeType
|
||||||
|
.map((item) =>
|
||||||
|
this.types.find((itx) => itx.value === item).label
|
||||||
|
)
|
||||||
|
.join('、')}`
|
||||||
|
)
|
||||||
|
this.filterTextMap.push([`activeType`])
|
||||||
|
}
|
||||||
|
if (this.activeUser.length) {
|
||||||
|
const str = `${this.$t('log.user')}:${this.activeUser.reduce(
|
||||||
|
(pre, next) =>
|
||||||
|
(this.users.find((ele) => ele.id === next) || {}).username +
|
||||||
|
'、' +
|
||||||
|
pre,
|
||||||
|
''
|
||||||
|
)}`
|
||||||
|
params.push(str.slice(0, str.length - 1))
|
||||||
|
this.filterTextMap.push([
|
||||||
|
'usersValue',
|
||||||
|
'activeUser',
|
||||||
|
'userCahe'
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.dataRange.length) {
|
||||||
|
params.push(
|
||||||
|
`${this.$t('dedaterange.label')}:${this.dataRange
|
||||||
|
.map((ele) => {
|
||||||
|
return dateFormat('YYYY-mm-dd', ele)
|
||||||
|
})
|
||||||
|
.join('-')}`
|
||||||
|
)
|
||||||
|
this.filterTextMap.push(['dataRange'])
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
},
|
||||||
|
formatCondition() {
|
||||||
|
const fildMap = {
|
||||||
|
optype: this.activeType,
|
||||||
|
'user_id': this.activeUser
|
||||||
|
}
|
||||||
|
const conditions = []
|
||||||
|
Object.keys(fildMap).forEach((ele) => {
|
||||||
|
if (fildMap[ele].length) {
|
||||||
|
conditions.push({
|
||||||
|
field: ele,
|
||||||
|
operator: 'in',
|
||||||
|
value: fildMap[ele]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// eslint-disable-next-line
|
||||||
|
let [min, max] = this.dataRange
|
||||||
|
if (min && max) {
|
||||||
|
if (+min === +max) {
|
||||||
|
max = +max + 24 * 3600 * 1000
|
||||||
|
}
|
||||||
|
conditions.push({
|
||||||
|
field: 'time',
|
||||||
|
operator: 'between',
|
||||||
|
value: [+min, +max]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return conditions
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
this.userDrawer = true
|
||||||
|
},
|
||||||
|
reset() {
|
||||||
|
this.clearFilter()
|
||||||
|
this.userDrawer = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -137,7 +137,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import DeLayoutContent from '@/components/business/DeLayoutContent'
|
import DeLayoutContent from '@/components/business/DeLayoutContent'
|
||||||
import GridTable from '@/components/gridTable/index.vue'
|
import GridTable from '@/components/gridTable/index.vue'
|
||||||
import filterUser from './filterUser'
|
import filterUser from './FilterUser'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import keyEnter from '@/components/msgCfm/keyEnter.js'
|
import keyEnter from '@/components/msgCfm/keyEnter.js'
|
||||||
import {
|
import {
|
||||||
|
@ -18,9 +18,6 @@ export default {
|
|||||||
defaultPcode: '100000',
|
defaultPcode: '100000',
|
||||||
mapurl: '/api/map/resourceFull/'
|
mapurl: '/api/map/resourceFull/'
|
||||||
}
|
}
|
||||||
},
|
|
||||||
created() {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
const chartDom = document.getElementById('maptest')
|
const chartDom = document.getElementById('maptest')
|
||||||
|
@ -1,242 +0,0 @@
|
|||||||
<template>
|
|
||||||
<layout-content
|
|
||||||
:header="formType=='add' ? $t('menu.create') : $t('menu.modify')"
|
|
||||||
back-name="system-menu"
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="menuForm"
|
|
||||||
:model="form"
|
|
||||||
:rules="rule"
|
|
||||||
size="small"
|
|
||||||
label-width="auto"
|
|
||||||
label-position="right"
|
|
||||||
>
|
|
||||||
<el-form-item
|
|
||||||
:label="$t('menu.menu_type')"
|
|
||||||
prop="type"
|
|
||||||
>
|
|
||||||
<el-radio-group
|
|
||||||
v-model="form.type"
|
|
||||||
size="mini"
|
|
||||||
:disabled="formType!=='add'"
|
|
||||||
>
|
|
||||||
<el-radio-button label="0">{{ $t('commons.catalogue') }}</el-radio-button>
|
|
||||||
<el-radio-button label="1">{{ $t('commons.menu') }}</el-radio-button>
|
|
||||||
<el-radio-button label="2">{{ $t('commons.button') }}</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-if="form.type=== 1 && form.icon"
|
|
||||||
:label="$t('commons.icon')"
|
|
||||||
prop="icon"
|
|
||||||
>
|
|
||||||
<el-popover
|
|
||||||
placement="bottom-start"
|
|
||||||
width="425"
|
|
||||||
trigger="click"
|
|
||||||
@show="$refs['iconSelect'].reset()"
|
|
||||||
>
|
|
||||||
<IconSelect
|
|
||||||
ref="iconSelect"
|
|
||||||
@selected="selected"
|
|
||||||
/>
|
|
||||||
<el-input
|
|
||||||
slot="reference"
|
|
||||||
v-model="form.icon"
|
|
||||||
:placeholder="$t('menu.select_icon')"
|
|
||||||
readonly
|
|
||||||
>
|
|
||||||
<svg-icon
|
|
||||||
v-if="form.icon"
|
|
||||||
slot="prefix"
|
|
||||||
:icon-class="form.icon"
|
|
||||||
class="el-input__icon"
|
|
||||||
style="height: 32px;width: 16px;"
|
|
||||||
/>
|
|
||||||
<i
|
|
||||||
v-else
|
|
||||||
slot="prefix"
|
|
||||||
class="el-icon-search el-input__icon"
|
|
||||||
/>
|
|
||||||
</el-input>
|
|
||||||
</el-popover>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item
|
|
||||||
v-if="form.type !== 2"
|
|
||||||
:label="$t('menu.tile')"
|
|
||||||
prop="title"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
v-model="form.title"
|
|
||||||
:placeholder="$t('menu.tile')"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-if="form.type === 2"
|
|
||||||
:label="$t('menu.button_name')"
|
|
||||||
prop="title"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
v-model="form.title"
|
|
||||||
:placeholder="$t('menu.button_name')"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-if="form.type !== 2"
|
|
||||||
:label="$t('menu.menu_sort')"
|
|
||||||
prop="menuSort"
|
|
||||||
>
|
|
||||||
<el-input-number
|
|
||||||
v-model.number="form.menuSort"
|
|
||||||
:min="0"
|
|
||||||
:max="999"
|
|
||||||
controls-position="right"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
:label="$t('menu.parent_category')"
|
|
||||||
prop="pid"
|
|
||||||
>
|
|
||||||
<treeselect
|
|
||||||
v-model="form.pid"
|
|
||||||
:disabled="formType!=='add'"
|
|
||||||
:options="menus"
|
|
||||||
:load-options="loadMenus"
|
|
||||||
:placeholder="$t('menu.parent_category')"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
@click="save"
|
|
||||||
>{{ $t('commons.reset') }}</el-button>
|
|
||||||
<el-button @click="reset">{{ $t('commons.confirm') }}</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
</layout-content>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import LayoutContent from '@/components/business/LayoutContent'
|
|
||||||
import Treeselect from '@riophae/vue-treeselect'
|
|
||||||
import IconSelect from '@/components/IconSelect'
|
|
||||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
|
||||||
import { LOAD_CHILDREN_OPTIONS, LOAD_ROOT_OPTIONS } from '@riophae/vue-treeselect'
|
|
||||||
import { addMenu, editMenu, getMenusTree, treeByMenuId } from '@/api/system/menu'
|
|
||||||
export default {
|
|
||||||
|
|
||||||
components: { LayoutContent, Treeselect, IconSelect },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
topMunu: { id: 0, label: '顶级目录', children: null },
|
|
||||||
defaultForm: { menuId: null, title: null, menuSort: 999, path: null, component: null, componentName: null, iframe: false, pid: 0, icon: null, cache: false, hidden: false, type: 0, permission: null },
|
|
||||||
form: {},
|
|
||||||
rule: {
|
|
||||||
name: [
|
|
||||||
{ required: true, message: this.$t('organization.input_name'), trigger: 'blur' },
|
|
||||||
{ min: 2, max: 25, message: this.$t('commons.input_limit', [2, 25]), trigger: 'blur' }
|
|
||||||
],
|
|
||||||
description: [
|
|
||||||
{ max: 50, message: this.$t('commons.input_limit', [0, 50]), trigger: 'blur' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
menus: null,
|
|
||||||
maps: new Map(),
|
|
||||||
formType: 'add'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
if (this.$router.currentRoute.params && this.$router.currentRoute.params.menuId) {
|
|
||||||
const row = this.$router.currentRoute.params
|
|
||||||
this.edit(row)
|
|
||||||
} else {
|
|
||||||
this.create()
|
|
||||||
}
|
|
||||||
this.initData()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
create() {
|
|
||||||
this.formType = 'add'
|
|
||||||
this.form = Object.assign({}, this.defaultForm)
|
|
||||||
},
|
|
||||||
edit(row) {
|
|
||||||
this.formType = 'modify'
|
|
||||||
this.form = Object.assign({}, row)
|
|
||||||
this.initMenuTree()
|
|
||||||
},
|
|
||||||
initMenuTree() {
|
|
||||||
treeByMenuId(this.form.pid || 0).then(res => {
|
|
||||||
const results = res.data.map(node => {
|
|
||||||
if (node.hasChildren && !node.children) {
|
|
||||||
node.children = null
|
|
||||||
}
|
|
||||||
return node
|
|
||||||
})
|
|
||||||
this.menus = results
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取弹窗内部门数据
|
|
||||||
loadMenus({ action, parentNode, callback }) {
|
|
||||||
if (action === LOAD_ROOT_OPTIONS) {
|
|
||||||
const _self = this
|
|
||||||
!this.menus && getMenusTree('0').then(res => {
|
|
||||||
_self.menus = res.data.map(node => _self.normalizer(node))
|
|
||||||
callback()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action === LOAD_CHILDREN_OPTIONS) {
|
|
||||||
const _self = this
|
|
||||||
getMenusTree(parentNode.id).then(res => {
|
|
||||||
parentNode.children = res.data.map(function(obj) {
|
|
||||||
return _self.normalizer(obj)
|
|
||||||
})
|
|
||||||
callback()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
initData() {
|
|
||||||
this.menus = []
|
|
||||||
this.menus.push(this.topMunu)
|
|
||||||
},
|
|
||||||
normalizer(node) {
|
|
||||||
if (node.hasChildren) {
|
|
||||||
node.children = null
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
id: node.menuId,
|
|
||||||
label: node.title,
|
|
||||||
children: node.children
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
selected(name) {
|
|
||||||
this.form.icon = name
|
|
||||||
},
|
|
||||||
|
|
||||||
reset() {
|
|
||||||
this.$refs.menuForm.resetFields()
|
|
||||||
},
|
|
||||||
save() {
|
|
||||||
this.$refs.menuForm.validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
const method = this.formType === 'add' ? addMenu : editMenu
|
|
||||||
method(this.form).then(res => {
|
|
||||||
this.$success(this.$t('commons.save_success'))
|
|
||||||
this.backToList()
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
backToList() {
|
|
||||||
this.$router.push({ name: 'system-menu' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
@ -1,604 +0,0 @@
|
|||||||
<template>
|
|
||||||
<layout-content v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
|
|
||||||
<tree-table
|
|
||||||
:columns="columns"
|
|
||||||
:search-config="searchConfig"
|
|
||||||
@search="search"
|
|
||||||
>
|
|
||||||
<template #toolbar>
|
|
||||||
<fu-table-button
|
|
||||||
v-permission="['menu:add']"
|
|
||||||
icon="el-icon-circle-plus-outline"
|
|
||||||
:label="$t('menu.create')"
|
|
||||||
@click="create"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<el-table
|
|
||||||
ref="table"
|
|
||||||
:data="tableData"
|
|
||||||
lazy
|
|
||||||
:load="initTableData"
|
|
||||||
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
|
||||||
row-key="menuId"
|
|
||||||
>
|
|
||||||
|
|
||||||
<!-- <el-table-column type="selection" fix /> -->
|
|
||||||
<el-table-column
|
|
||||||
:show-overflow-tooltip="true"
|
|
||||||
:label="$t('menu.tile')"
|
|
||||||
prop="title"
|
|
||||||
/>
|
|
||||||
<el-table-column
|
|
||||||
prop="icon"
|
|
||||||
:label="$t('commons.icon')"
|
|
||||||
align="center"
|
|
||||||
>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<svg-icon :icon-class="scope.row.icon ? scope.row.icon : ''" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
prop="createTime"
|
|
||||||
:label="$t('menu.create_time')"
|
|
||||||
>
|
|
||||||
<template #default="scope">
|
|
||||||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<fu-table-operations
|
|
||||||
:buttons="buttons"
|
|
||||||
:label="$t('commons.operating')"
|
|
||||||
fix
|
|
||||||
/>
|
|
||||||
</el-table>
|
|
||||||
</tree-table>
|
|
||||||
|
|
||||||
<el-dialog
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
:title="formType=='add' ? $t('menu.create') : $t('menu.modify')"
|
|
||||||
:visible.sync="dialogVisible"
|
|
||||||
width="580px"
|
|
||||||
:destroy-on-close="true"
|
|
||||||
@closed="closeFunc"
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="menuForm"
|
|
||||||
inline
|
|
||||||
:model="form"
|
|
||||||
:rules="rule"
|
|
||||||
size="small"
|
|
||||||
label-width="80px"
|
|
||||||
>
|
|
||||||
|
|
||||||
<el-form-item
|
|
||||||
label="菜单类型"
|
|
||||||
prop="type"
|
|
||||||
>
|
|
||||||
<el-radio-group
|
|
||||||
v-model="form.type"
|
|
||||||
size="mini"
|
|
||||||
:disabled="formType!=='add'"
|
|
||||||
style="width: 179px"
|
|
||||||
>
|
|
||||||
<el-radio-button label="0">{{ $t('commons.catalogue') }} </el-radio-button>
|
|
||||||
<el-radio-button label="1">{{ $t('commons.menu') }} </el-radio-button>
|
|
||||||
<el-radio-button label="2">{{ $t('commons.button') }}</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-show="form.type!== 2"
|
|
||||||
:label="$t('commons.icon')"
|
|
||||||
prop="icon"
|
|
||||||
>
|
|
||||||
<el-popover
|
|
||||||
placement="bottom-start"
|
|
||||||
width="425"
|
|
||||||
trigger="click"
|
|
||||||
@show="$refs['iconSelect'].reset()"
|
|
||||||
>
|
|
||||||
<IconSelect
|
|
||||||
ref="iconSelect"
|
|
||||||
@selected="selected"
|
|
||||||
/>
|
|
||||||
<el-input
|
|
||||||
slot="reference"
|
|
||||||
v-model="form.icon"
|
|
||||||
style="width: 450px;"
|
|
||||||
:placeholder="$t('menu.select_icon')"
|
|
||||||
readonly
|
|
||||||
>
|
|
||||||
<svg-icon
|
|
||||||
v-if="form.icon"
|
|
||||||
slot="prefix"
|
|
||||||
:icon-class="form.icon"
|
|
||||||
class="el-input__icon"
|
|
||||||
style="height: 32px;width: 16px;"
|
|
||||||
/>
|
|
||||||
<i
|
|
||||||
v-else
|
|
||||||
slot="prefix"
|
|
||||||
class="el-icon-search el-input__icon"
|
|
||||||
/>
|
|
||||||
</el-input>
|
|
||||||
</el-popover>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item
|
|
||||||
v-if="form.type !== 2"
|
|
||||||
:label="$t('menu.tile')"
|
|
||||||
prop="title"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
v-model="form.title"
|
|
||||||
:style=" form.type === '0' ? 'width: 450px' : 'width: 179px'"
|
|
||||||
:placeholder="$t('menu.tile')"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-if="form.type === 2"
|
|
||||||
:label="$t('menu.button_name')"
|
|
||||||
prop="title"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
v-model="form.title"
|
|
||||||
:placeholder="$t('menu.button_name')"
|
|
||||||
style="width: 179px;"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-show="form.type !== 0"
|
|
||||||
:label="$t('menu.authority_identification')"
|
|
||||||
prop="permission"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
v-model="form.permission"
|
|
||||||
:disabled="form.iframe || formType!=='add'"
|
|
||||||
:placeholder="$t('menu.authority_identification')"
|
|
||||||
style="width: 179px;"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-if="form.type !== 2"
|
|
||||||
label="$t('menu.route_addr')"
|
|
||||||
prop="path"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
v-model="form.path"
|
|
||||||
:placeholder="$t('menu.route_addr')"
|
|
||||||
:disabled="formType!=='add'"
|
|
||||||
style="width: 179px;"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
:label="$t('menu.menu_sort')"
|
|
||||||
prop="menuSort"
|
|
||||||
>
|
|
||||||
<el-input-number
|
|
||||||
v-model.number="form.menuSort"
|
|
||||||
:min="0"
|
|
||||||
:max="999"
|
|
||||||
controls-position="right"
|
|
||||||
style="width: 179px;"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-show="!form.iframe && form.type === 1"
|
|
||||||
:label="$t('menu.module_name')"
|
|
||||||
prop="componentName"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
v-model="form.componentName"
|
|
||||||
:disabled="formType!=='add'"
|
|
||||||
style="width: 179px;"
|
|
||||||
placeholder="匹配组件内Name字段"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-show="!form.iframe && form.type === 1"
|
|
||||||
label="$t('menu.path')"
|
|
||||||
prop="component"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
v-model="form.component"
|
|
||||||
:disabled="formType!=='add'"
|
|
||||||
style="width: 179px;"
|
|
||||||
:placeholder="$t('menu.path')"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
:label="$t('menu.parent_category')"
|
|
||||||
prop="pid"
|
|
||||||
>
|
|
||||||
<treeselect
|
|
||||||
v-model="form.pid"
|
|
||||||
:disabled="formType!=='add'"
|
|
||||||
:options="menus"
|
|
||||||
:load-options="loadMenus"
|
|
||||||
style="width: 450px;"
|
|
||||||
:placeholder="$t('menu.parent_category')"
|
|
||||||
:no-children-text="$t('commons.treeselect.no_children_text')"
|
|
||||||
:no-options-text="$t('commons.treeselect.no_options_text')"
|
|
||||||
:no-results-text="$t('commons.treeselect.no_results_text')"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<div
|
|
||||||
slot="footer"
|
|
||||||
class="dialog-footer"
|
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="text"
|
|
||||||
@click="dialogVisible = false"
|
|
||||||
>{{ $t('commons.cancel') }}</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
@click="createMenu('menuForm')"
|
|
||||||
>{{ $t('commons.confirm') }}</el-button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
</layout-content>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import LayoutContent from '@/components/business/LayoutContent'
|
|
||||||
import TreeTable from '@/components/business/tree-table'
|
|
||||||
// import { checkPermission } from '@/utils/permission'
|
|
||||||
import IconSelect from '@/components/IconSelect'
|
|
||||||
import Treeselect from '@riophae/vue-treeselect'
|
|
||||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
|
||||||
import { LOAD_CHILDREN_OPTIONS, LOAD_ROOT_OPTIONS } from '@riophae/vue-treeselect'
|
|
||||||
import { checkPermission } from '@/utils/permission'
|
|
||||||
import { addMenu, editMenu, delMenu, getMenusTree, queryCondition } from '@/api/system/menu'
|
|
||||||
import { formatCondition, formatQuickCondition } from '@/utils/index'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
TreeTable,
|
|
||||||
LayoutContent,
|
|
||||||
Treeselect,
|
|
||||||
IconSelect
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
menus: [],
|
|
||||||
topMunu: { id: 0, label: '顶级目录', children: null },
|
|
||||||
formType: 'add',
|
|
||||||
dialogVisible: false,
|
|
||||||
condition: {},
|
|
||||||
tableData: [],
|
|
||||||
maps: new Map(),
|
|
||||||
oldPid: null,
|
|
||||||
defaultForm: { menuId: null, title: null, menuSort: 999, path: null, component: null, componentName: null, iframe: false, pid: 0, icon: null, cache: false, hidden: false, type: 0, permission: null },
|
|
||||||
form: {},
|
|
||||||
rule: {
|
|
||||||
name: [
|
|
||||||
{ required: true, message: this.$t('organization.input_name'), trigger: 'blur' },
|
|
||||||
{ min: 2, max: 25, message: this.$t('commons.input_limit', [2, 25]), trigger: 'blur' }
|
|
||||||
],
|
|
||||||
description: [
|
|
||||||
{ max: 50, message: this.$t('commons.input_limit', [0, 50]), trigger: 'blur' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
permission: {
|
|
||||||
add: ['menu:add'],
|
|
||||||
edit: ['menu:edit'],
|
|
||||||
del: ['menu:del']
|
|
||||||
},
|
|
||||||
|
|
||||||
header: '',
|
|
||||||
columns: [],
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
label: this.$t('commons.edit'), icon: 'el-icon-edit', type: 'primary', click: this.edit,
|
|
||||||
show: checkPermission(['menu:edit'])
|
|
||||||
}, {
|
|
||||||
label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this._handleDelete,
|
|
||||||
show: checkPermission(['menu:del'])
|
|
||||||
}
|
|
||||||
],
|
|
||||||
searchConfig: {
|
|
||||||
useQuickSearch: true,
|
|
||||||
quickPlaceholder: '按标题搜索',
|
|
||||||
components: [
|
|
||||||
|
|
||||||
{ field: 'title', label: this.$t('menu.tile'), component: 'FuComplexInput' }
|
|
||||||
|
|
||||||
// {
|
|
||||||
// field: 'enabled',
|
|
||||||
// label: '状态',
|
|
||||||
// component: 'FuComplexSelect',
|
|
||||||
// options: [
|
|
||||||
// { label: '启用', value: '1' },
|
|
||||||
// { label: '禁用', value: '0' }
|
|
||||||
// ],
|
|
||||||
// multiple: false
|
|
||||||
// }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.form = Object.assign({}, this.defaultForm)
|
|
||||||
this.initTableData()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// create() {
|
|
||||||
// this.form = Object.assign({}, this.defaultForm)
|
|
||||||
// this.dialogVisible = true
|
|
||||||
// this.formType = 'add'
|
|
||||||
// },
|
|
||||||
create() {
|
|
||||||
this.$router.push({ name: 'system-menu-form' })
|
|
||||||
},
|
|
||||||
search(condition) {
|
|
||||||
condition = formatQuickCondition(condition, 'title')
|
|
||||||
const temp = formatCondition(condition)
|
|
||||||
if (!temp || !temp.conditions || temp.conditions.length === 0) {
|
|
||||||
this.initTableData()
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.tableData.forEach(node => {
|
|
||||||
this.$refs.table.toggleRowExpansion(node, false)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const param = temp || {}
|
|
||||||
queryCondition(param).then(res => {
|
|
||||||
let data = res.data
|
|
||||||
data = data.map(obj => {
|
|
||||||
if (obj.subCount > 0) {
|
|
||||||
obj.hasChildren = true
|
|
||||||
}
|
|
||||||
return obj
|
|
||||||
})
|
|
||||||
|
|
||||||
if (condition) {
|
|
||||||
data = data.map(node => {
|
|
||||||
delete (node.hasChildren)
|
|
||||||
return node
|
|
||||||
})
|
|
||||||
this.tableData = this.buildTree(data)
|
|
||||||
this.$nextTick(() => {
|
|
||||||
data.forEach(node => {
|
|
||||||
this.$refs.table.toggleRowExpansion(node, true)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.tableData = data
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
buildTree(arrs) {
|
|
||||||
const idMapping = arrs.reduce((acc, el, i) => {
|
|
||||||
acc[el.menuId] = i
|
|
||||||
return acc
|
|
||||||
}, {})
|
|
||||||
const roots = []
|
|
||||||
arrs.forEach(el => {
|
|
||||||
// 判断根节点
|
|
||||||
if (el.pid === null || el.pid === 0) {
|
|
||||||
roots.push(el)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 用映射表找到父元素
|
|
||||||
const parentEl = arrs[idMapping[el.pid]]
|
|
||||||
// 把当前元素添加到父元素的`children`数组中
|
|
||||||
parentEl.children = [...(parentEl.children || []), el]
|
|
||||||
})
|
|
||||||
return roots
|
|
||||||
},
|
|
||||||
|
|
||||||
// edit(row) {
|
|
||||||
// this.dialogVisible = true
|
|
||||||
// this.formType = 'modify'
|
|
||||||
// this.oldPid = row.pid
|
|
||||||
// this.form = Object.assign({}, row)
|
|
||||||
// this.treeByRow(row)
|
|
||||||
// },
|
|
||||||
edit(row) {
|
|
||||||
this.$router.push({ name: 'system-menu-form', params: row })
|
|
||||||
},
|
|
||||||
|
|
||||||
treeByRow(row) {
|
|
||||||
!this.menus && (this.menus = [])
|
|
||||||
if (!this.menus.some(node => node.id === row.pid) && row.pid !== 0) {
|
|
||||||
const arr = this.mapToArray()
|
|
||||||
const ids = arr.map(item => item.id)
|
|
||||||
const tempTreeNodes = this.treeByArr(arr)
|
|
||||||
const pnodes = this.tableData.filter(node => (node.pid === 0) && (ids.indexOf(node.menuId) === -1)).map(node => this.normalizer(node))
|
|
||||||
const showNodes = tempTreeNodes.concat(pnodes)
|
|
||||||
this.menus = this.menus.concat(showNodes)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
mapToArray() {
|
|
||||||
const result = []
|
|
||||||
|
|
||||||
this.maps.forEach((value, key) => {
|
|
||||||
if (Object.prototype.hasOwnProperty.call(value, 'row')) {
|
|
||||||
result.push(this.editNormalizer(value.row))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return result
|
|
||||||
},
|
|
||||||
treeByArr(arr) {
|
|
||||||
if (!Array.isArray(arr) || !arr.length) return
|
|
||||||
const map = {}
|
|
||||||
|
|
||||||
arr.forEach(item => {
|
|
||||||
map[item.id] = item
|
|
||||||
})
|
|
||||||
|
|
||||||
const roots = []
|
|
||||||
arr.forEach(item => {
|
|
||||||
const parent = map[item.pid]
|
|
||||||
if (parent) {
|
|
||||||
(parent.children || (parent.children = [])).push(item)
|
|
||||||
} else {
|
|
||||||
roots.push(item)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return roots
|
|
||||||
},
|
|
||||||
|
|
||||||
initTableData(row, treeNode, resolve) {
|
|
||||||
const _self = this
|
|
||||||
const pid = (row && row.menuId) ? row.menuId : '0'
|
|
||||||
|
|
||||||
getMenusTree(pid).then(response => {
|
|
||||||
let data = response.data
|
|
||||||
data = data.map(obj => {
|
|
||||||
if (obj.subCount > 0) {
|
|
||||||
obj.hasChildren = true
|
|
||||||
}
|
|
||||||
return obj
|
|
||||||
})
|
|
||||||
if (!row) {
|
|
||||||
// data.some(node => node.children = null)
|
|
||||||
_self.tableData = data
|
|
||||||
_self.menus = []
|
|
||||||
_self.menus.push(_self.topMunu)
|
|
||||||
} else {
|
|
||||||
this.maps.set(row.menuId, { row, treeNode, resolve })
|
|
||||||
resolve && resolve(data)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
closeFunc() {
|
|
||||||
this.initTableData()
|
|
||||||
this.form = this.defaultForm
|
|
||||||
this.oldPid = null
|
|
||||||
this.menus = null
|
|
||||||
this.dialogVisible = false
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取弹窗内部门数据
|
|
||||||
loadMenus({ action, parentNode, callback }) {
|
|
||||||
if (action === LOAD_ROOT_OPTIONS) {
|
|
||||||
const _self = this
|
|
||||||
!this.menus && getMenusTree('0').then(res => {
|
|
||||||
_self.menus = res.data.map(node => _self.normalizer(node))
|
|
||||||
callback()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action === LOAD_CHILDREN_OPTIONS) {
|
|
||||||
const _self = this
|
|
||||||
getMenusTree(parentNode.id).then(res => {
|
|
||||||
parentNode.children = res.data.map(function(obj) {
|
|
||||||
return _self.normalizer(obj)
|
|
||||||
})
|
|
||||||
callback()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
normalizer(node) {
|
|
||||||
if (node.hasChildren) {
|
|
||||||
node.children = null
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
id: node.menuId,
|
|
||||||
label: node.title,
|
|
||||||
children: node.children
|
|
||||||
}
|
|
||||||
},
|
|
||||||
editNormalizer(node) {
|
|
||||||
return {
|
|
||||||
id: node.menuId,
|
|
||||||
pid: node.pid,
|
|
||||||
label: node.title,
|
|
||||||
children: node.children
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
createMenu(menuForm) {
|
|
||||||
this.$refs[menuForm].validate(valid => {
|
|
||||||
if (valid) {
|
|
||||||
let method = addMenu
|
|
||||||
this.formType === 'modify' && this.form['menuId'] && (method = editMenu)
|
|
||||||
method(this.form).then(res => {
|
|
||||||
this.$success(this.$t('commons.save_success'))
|
|
||||||
// this.initTableData()
|
|
||||||
this.oldPid && this.reloadByPid(this.oldPid)
|
|
||||||
this.reloadByPid(this.form['pid'])
|
|
||||||
this.dialogVisible = false
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
_handleDelete(menu) {
|
|
||||||
this.$confirm(this.$t('menu.delete_confirm'), '', {
|
|
||||||
confirmButtonText: this.$t('commons.confirm'),
|
|
||||||
cancelButtonText: this.$t('commons.cancel'),
|
|
||||||
type: 'warning'
|
|
||||||
}).then(() => {
|
|
||||||
const request = { menuId: menu.menuId, pid: menu.pid }
|
|
||||||
delMenu(request).then(res => {
|
|
||||||
this.$success(this.$t('commons.delete_success'))
|
|
||||||
this.initTableData()
|
|
||||||
this.reloadByPid(menu.pid)
|
|
||||||
})
|
|
||||||
}).catch(() => {
|
|
||||||
this.$message({
|
|
||||||
type: 'info',
|
|
||||||
message: this.$t('commons.delete_cancelled')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
reloadByPid(pid) {
|
|
||||||
if (pid !== 0 && this.maps.get(pid)) {
|
|
||||||
const { row, treeNode, resolve } = this.maps.get(pid)
|
|
||||||
const sto = this.$refs.table['store']
|
|
||||||
this.$set(sto.states.lazyTreeNodeMap, pid, [])
|
|
||||||
this.initTableData(row, treeNode, resolve)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 选中图标
|
|
||||||
selected(name) {
|
|
||||||
this.form.icon = name
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.member-size {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.org-member-id {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.org-member-email {
|
|
||||||
float: right;
|
|
||||||
color: #8492a6;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select-width {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-css ::v-deep .el-dialog__header {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
::v-deep .el-input-number .el-input__inner {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
::v-deep .vue-treeselect__control,::v-deep .vue-treeselect__placeholder,::v-deep .vue-treeselect__single-value {
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
@ -8,7 +8,7 @@
|
|||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
v-on="$listeners"
|
v-on="$listeners"
|
||||||
@execute-axios="executeAxios"
|
@execute-axios="executeAxios"
|
||||||
@on-add-languanges="addLanguages"
|
@on-add-languages="addLanguages"
|
||||||
@plugin-call-back="pluginCallBack"
|
@plugin-call-back="pluginCallBack"
|
||||||
/>
|
/>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
v-if="showAsync"
|
v-if="showAsync"
|
||||||
:url="url"
|
:url="url"
|
||||||
@execute-axios="executeAxios"
|
@execute-axios="executeAxios"
|
||||||
@on-add-languanges="addLanguages"
|
@on-add-languages="addLanguages"
|
||||||
@on-plugin-layout="setLayoutInfo"
|
@on-plugin-layout="setLayoutInfo"
|
||||||
@plugin-call-back="pluginCallBack"
|
@plugin-call-back="pluginCallBack"
|
||||||
/>
|
/>
|
||||||
@ -22,7 +22,7 @@
|
|||||||
v-if="showAsync"
|
v-if="showAsync"
|
||||||
:url="url"
|
:url="url"
|
||||||
@execute-axios="executeAxios"
|
@execute-axios="executeAxios"
|
||||||
@on-add-languanges="addLanguages"
|
@on-add-languages="addLanguages"
|
||||||
@on-plugin-layout="setLayoutInfo"
|
@on-plugin-layout="setLayoutInfo"
|
||||||
@plugin-call-back="pluginCallBack"
|
@plugin-call-back="pluginCallBack"
|
||||||
/>
|
/>
|
||||||
@ -35,7 +35,7 @@
|
|||||||
v-if="showAsync"
|
v-if="showAsync"
|
||||||
:url="url"
|
:url="url"
|
||||||
@execute-axios="executeAxios"
|
@execute-axios="executeAxios"
|
||||||
@on-add-languanges="addLanguages"
|
@on-add-languages="addLanguages"
|
||||||
@on-plugin-layout="setLayoutInfo"
|
@on-plugin-layout="setLayoutInfo"
|
||||||
@plugin-call-back="pluginCallBack"
|
@plugin-call-back="pluginCallBack"
|
||||||
/>
|
/>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<!--基础配置表单-->
|
<!--基础配置表单-->
|
||||||
<el-form
|
<el-form
|
||||||
v-if="!status.includes['read-only', 'empty']"
|
v-if="!['read-only', 'empty'].includes(status)"
|
||||||
ref="formInline"
|
ref="formInline"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:model="formInline"
|
:model="formInline"
|
||||||
|
Loading…
Reference in New Issue
Block a user