fix: 无效代码删除 文件大小写 地图bug修复

This commit is contained in:
dataeaseShu 2022-10-21 15:23:12 +08:00
parent a55959f4f7
commit 16dcda863a
12 changed files with 282 additions and 1720 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View 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>

View File

@ -137,7 +137,7 @@
<script>
import DeLayoutContent from '@/components/business/DeLayoutContent'
import GridTable from '@/components/gridTable/index.vue'
import filterUser from './filterUser'
import filterUser from './FilterUser'
import _ from 'lodash'
import keyEnter from '@/components/msgCfm/keyEnter.js'
import {

View File

@ -18,9 +18,6 @@ export default {
defaultPcode: '100000',
mapurl: '/api/map/resourceFull/'
}
},
created() {
},
mounted() {
const chartDom = document.getElementById('maptest')

View File

@ -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>

View File

@ -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>

View File

@ -8,7 +8,7 @@
v-bind="$attrs"
v-on="$listeners"
@execute-axios="executeAxios"
@on-add-languanges="addLanguages"
@on-add-languages="addLanguages"
@plugin-call-back="pluginCallBack"
/>
<div v-else>

View File

@ -9,7 +9,7 @@
v-if="showAsync"
:url="url"
@execute-axios="executeAxios"
@on-add-languanges="addLanguages"
@on-add-languages="addLanguages"
@on-plugin-layout="setLayoutInfo"
@plugin-call-back="pluginCallBack"
/>
@ -22,7 +22,7 @@
v-if="showAsync"
:url="url"
@execute-axios="executeAxios"
@on-add-languanges="addLanguages"
@on-add-languages="addLanguages"
@on-plugin-layout="setLayoutInfo"
@plugin-call-back="pluginCallBack"
/>
@ -35,7 +35,7 @@
v-if="showAsync"
:url="url"
@execute-axios="executeAxios"
@on-add-languanges="addLanguages"
@on-add-languages="addLanguages"
@on-plugin-layout="setLayoutInfo"
@plugin-call-back="pluginCallBack"
/>

View File

@ -2,7 +2,7 @@
<div>
<!--基础配置表单-->
<el-form
v-if="!status.includes['read-only', 'empty']"
v-if="!['read-only', 'empty'].includes(status)"
ref="formInline"
v-loading="loading"
:model="formInline"