添加系统绑的功能
This commit is contained in:
@@ -2,7 +2,14 @@
|
|||||||
<div>
|
<div>
|
||||||
<!--指标越限时间分布
|
<!--指标越限时间分布
|
||||||
-->
|
-->
|
||||||
<TableHeader :showReset="false" :timeKeyList="prop.timeKey" ref="TableHeaderRef" @selectChange="selectChange" datePicker v-if="fullscreen">
|
<TableHeader
|
||||||
|
:showReset="false"
|
||||||
|
:timeKeyList="prop.timeKey"
|
||||||
|
ref="TableHeaderRef"
|
||||||
|
@selectChange="selectChange"
|
||||||
|
datePicker
|
||||||
|
v-if="fullscreen"
|
||||||
|
>
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="监测点">
|
<el-form-item label="监测点">
|
||||||
<el-select size="small" filterable v-model="tableStore.table.params.lineId">
|
<el-select size="small" filterable v-model="tableStore.table.params.lineId">
|
||||||
@@ -22,7 +29,7 @@
|
|||||||
:options="echartList1"
|
:options="echartList1"
|
||||||
:style="{
|
:style="{
|
||||||
width: prop.width,
|
width: prop.width,
|
||||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
<!-- <my-echart
|
<!-- <my-echart
|
||||||
@@ -49,7 +56,7 @@ const prop = defineProps({
|
|||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: Array as () => string[] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object },
|
timeValue: { type: Object },
|
||||||
interval: { type: Number }
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
@@ -146,6 +153,9 @@ const initProbabilityData = () => {
|
|||||||
const yAxisData = sortedData.map(item => item.indexName)
|
const yAxisData = sortedData.map(item => item.indexName)
|
||||||
|
|
||||||
echartList.value = {
|
echartList.value = {
|
||||||
|
title: {
|
||||||
|
text: '指标越限概率分布'
|
||||||
|
},
|
||||||
options: {
|
options: {
|
||||||
backgroundColor: '#fff',
|
backgroundColor: '#fff',
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@@ -166,14 +176,7 @@ const initProbabilityData = () => {
|
|||||||
return tips
|
return tips
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
title: {
|
|
||||||
text: '指标越限概率分布',
|
|
||||||
x: 'center',
|
|
||||||
textStyle: {
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: 'normal'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 移除或隐藏 visualMap 组件
|
// 移除或隐藏 visualMap 组件
|
||||||
visualMap: {
|
visualMap: {
|
||||||
show: false, // 设置为 false 隐藏右侧颜色条
|
show: false, // 设置为 false 隐藏右侧颜色条
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--指标越限概率分布 -->
|
<!--指标越限概率分布 -->
|
||||||
<TableHeader :showReset="false" :timeKeyList="prop.timeKey" ref="TableHeaderRef" @selectChange="selectChange" datePicker v-if="fullscreen">
|
<TableHeader
|
||||||
|
:showReset="false"
|
||||||
|
:timeKeyList="prop.timeKey"
|
||||||
|
ref="TableHeaderRef"
|
||||||
|
@selectChange="selectChange"
|
||||||
|
datePicker
|
||||||
|
v-if="fullscreen"
|
||||||
|
>
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="监测点">
|
<el-form-item label="监测点">
|
||||||
<el-select size="small" filterable v-model="tableStore.table.params.lineId">
|
<el-select size="small" filterable v-model="tableStore.table.params.lineId">
|
||||||
@@ -21,7 +28,7 @@
|
|||||||
:options="echartList"
|
:options="echartList"
|
||||||
:style="{
|
:style="{
|
||||||
width: prop.width,
|
width: prop.width,
|
||||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
<!-- <my-echart
|
<!-- <my-echart
|
||||||
@@ -48,7 +55,7 @@ const prop = defineProps({
|
|||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: Array as () => string[] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object },
|
timeValue: { type: Object },
|
||||||
interval: { type: Number }
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
@@ -145,6 +152,9 @@ const initProbabilityData = () => {
|
|||||||
const yAxisData = sortedData.map(item => item.indexName)
|
const yAxisData = sortedData.map(item => item.indexName)
|
||||||
|
|
||||||
echartList.value = {
|
echartList.value = {
|
||||||
|
title: {
|
||||||
|
text: '指标越限概率分布'
|
||||||
|
},
|
||||||
options: {
|
options: {
|
||||||
backgroundColor: '#fff',
|
backgroundColor: '#fff',
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@@ -165,14 +175,7 @@ const initProbabilityData = () => {
|
|||||||
return tips
|
return tips
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
title: {
|
|
||||||
text: '指标越限概率分布',
|
|
||||||
x: 'center',
|
|
||||||
textStyle: {
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: 'normal'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 移除或隐藏 visualMap 组件
|
// 移除或隐藏 visualMap 组件
|
||||||
visualMap: {
|
visualMap: {
|
||||||
show: false, // 设置为 false 隐藏右侧颜色条
|
show: false, // 设置为 false 隐藏右侧颜色条
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
datePicker
|
datePicker
|
||||||
@selectChange="selectChange"
|
@selectChange="selectChange"
|
||||||
v-if="fullscreen"
|
v-if="fullscreen"
|
||||||
ref="TableHeaderRef"
|
ref="TableHeaderRef"
|
||||||
:timeKeyList="prop.timeKey"
|
:timeKeyList="prop.timeKey"
|
||||||
>
|
>
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
@@ -100,7 +100,7 @@ const prop = defineProps({
|
|||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: Array as () => string[] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object },
|
timeValue: { type: Object },
|
||||||
interval: { type: Number }
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
@@ -432,10 +432,9 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
initLineList().then(() => {
|
await initLineList()
|
||||||
initCode()
|
await initCode()
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :style="{ width: menuCollapse ? '40px' : props.width }" style="transition: all 0.3s; overflow: hidden">
|
<div :style="{ width: menuCollapse ? '40px' : props.width }" style="transition: all 0.3s; overflow: hidden">
|
||||||
<div class="mt15 mr10" style="display: flex; justify-content: end">
|
<div class="mt10 mr10" style="display: flex; justify-content: end">
|
||||||
<el-button type="primary" icon="el-icon-Select" @click="save" :loading="loading">保存</el-button>
|
<el-button type="primary" icon="el-icon-Select" @click="save" :loading="loading">保存</el-button>
|
||||||
</div>
|
</div>
|
||||||
<Icon
|
<Icon
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-tree
|
<el-tree
|
||||||
:style="{ height: 'calc(100vh - 235px)' }"
|
:style="{ height: 'calc(100vh - 267px)' }"
|
||||||
style="overflow: auto"
|
style="overflow: auto"
|
||||||
ref="treeRef"
|
ref="treeRef"
|
||||||
:props="defaultProps"
|
:props="defaultProps"
|
||||||
@@ -183,5 +183,7 @@ defineExpose({ treeRef, loading })
|
|||||||
.custom-tree-node {
|
.custom-tree-node {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,81 +1,81 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-scrollbar ref="verticalMenusRef" class="vertical-menus-scrollbar">
|
<el-scrollbar ref="verticalMenusRef" class="vertical-menus-scrollbar">
|
||||||
<el-menu
|
<el-menu
|
||||||
class="layouts-menu-vertical"
|
class="layouts-menu-vertical"
|
||||||
:collapse-transition="false"
|
:collapse-transition="false"
|
||||||
:unique-opened="config.layout.menuUniqueOpened"
|
:unique-opened="config.layout.menuUniqueOpened"
|
||||||
:default-active="state.defaultActive"
|
:default-active="state.defaultActive"
|
||||||
:collapse="config.layout.menuCollapse"
|
:collapse="config.layout.menuCollapse"
|
||||||
>
|
>
|
||||||
<MenuTree :menus="navTabs.state.tabsViewRoutes" />
|
<MenuTree :menus="navTabs.state.tabsViewRoutes" />
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, nextTick, onMounted, reactive, ref } from 'vue'
|
import { computed, nextTick, onMounted, reactive, ref } from 'vue'
|
||||||
import MenuTree from '@/layouts/admin/components/menus/menuTree.vue'
|
import MenuTree from '@/layouts/admin/components/menus/menuTree.vue'
|
||||||
import { useRoute, onBeforeRouteUpdate, type RouteLocationNormalizedLoaded } from 'vue-router'
|
import { useRoute, onBeforeRouteUpdate, type RouteLocationNormalizedLoaded } from 'vue-router'
|
||||||
import type { ScrollbarInstance } from 'element-plus'
|
import type { ScrollbarInstance } from 'element-plus'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
import { useNavTabs } from '@/stores/navTabs'
|
import { useNavTabs } from '@/stores/navTabs'
|
||||||
|
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
const navTabs = useNavTabs()
|
const navTabs = useNavTabs()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const verticalMenusRef = ref<ScrollbarInstance>()
|
const verticalMenusRef = ref<ScrollbarInstance>()
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
defaultActive: '',
|
defaultActive: '',
|
||||||
})
|
})
|
||||||
|
|
||||||
const verticalMenusScrollbarHeight = computed(() => {
|
const verticalMenusScrollbarHeight = computed(() => {
|
||||||
let menuTopBarHeight = 0
|
let menuTopBarHeight = 0
|
||||||
if (config.layout.menuShowTopBar) {
|
if (config.layout.menuShowTopBar) {
|
||||||
menuTopBarHeight = 50
|
menuTopBarHeight = 50
|
||||||
}
|
}
|
||||||
if (config.layout.layoutMode == 'Default') {
|
if (config.layout.layoutMode == 'Default') {
|
||||||
return 'calc(100vh - ' + (32 + menuTopBarHeight) + 'px)'
|
return 'calc(100vh - ' + (32 + menuTopBarHeight) + 'px)'
|
||||||
} else {
|
} else {
|
||||||
return 'calc(100vh - ' + menuTopBarHeight + 'px)'
|
return 'calc(100vh - ' + menuTopBarHeight + 'px)'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 激活当前路由的菜单
|
// 激活当前路由的菜单
|
||||||
const currentRouteActive = (currentRoute: RouteLocationNormalizedLoaded) => {
|
const currentRouteActive = (currentRoute: RouteLocationNormalizedLoaded) => {
|
||||||
state.defaultActive = currentRoute.path
|
state.defaultActive = currentRoute.path
|
||||||
}
|
}
|
||||||
|
|
||||||
// 滚动条滚动到激活菜单所在位置
|
// 滚动条滚动到激活菜单所在位置
|
||||||
const verticalMenusScroll = () => {
|
const verticalMenusScroll = () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
let activeMenu: HTMLElement | null = document.querySelector('.el-menu.layouts-menu-vertical li.is-active')
|
let activeMenu: HTMLElement | null = document.querySelector('.el-menu.layouts-menu-vertical li.is-active')
|
||||||
if (!activeMenu) return false
|
if (!activeMenu) return false
|
||||||
verticalMenusRef.value?.setScrollTop(activeMenu.offsetTop)
|
verticalMenusRef.value?.setScrollTop(activeMenu.offsetTop)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
currentRouteActive(route)
|
currentRouteActive(route)
|
||||||
verticalMenusScroll()
|
verticalMenusScroll()
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeRouteUpdate((to) => {
|
onBeforeRouteUpdate((to) => {
|
||||||
currentRouteActive(to)
|
currentRouteActive(to)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.vertical-menus-scrollbar {
|
.vertical-menus-scrollbar {
|
||||||
height: v-bind(verticalMenusScrollbarHeight);
|
height: v-bind(verticalMenusScrollbarHeight);
|
||||||
background-color: v-bind('config.getColorVal("menuBackground")');
|
background-color: v-bind('config.getColorVal("menuBackground")');
|
||||||
}
|
}
|
||||||
.layouts-menu-vertical {
|
.layouts-menu-vertical {
|
||||||
border: 0;
|
border: 0;
|
||||||
padding-bottom: 30px;
|
padding-bottom: 30px;
|
||||||
--el-menu-bg-color: v-bind('config.getColorVal("menuBackground")');
|
--el-menu-bg-color: v-bind('config.getColorVal("menuBackground")');
|
||||||
--el-menu-text-color: v-bind('config.getColorVal("menuColor")');
|
--el-menu-text-color: v-bind('config.getColorVal("menuColor")');
|
||||||
--el-menu-active-color: v-bind('config.getColorVal("menuActiveColor")');
|
--el-menu-active-color: v-bind('config.getColorVal("menuActiveColor")');
|
||||||
--el-menu-hover-color: v-bind('config.getColorVal("menuActiveBackground")');
|
--el-menu-hover-color: v-bind('config.getColorVal("menuActiveBackground")');
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
size="18"
|
size="18"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-dropdown style="height: 100%" @command="handleCommand">
|
<el-dropdown style="height: 100%" @command="handleCommand">
|
||||||
<div class="admin-info" :class="state.currentNavMenu == 'adminInfo' ? 'hover' : ''">
|
<div class="admin-info" :class="state.currentNavMenu == 'adminInfo' ? 'hover' : ''">
|
||||||
<el-avatar :size="25" fit="fill">
|
<el-avatar :size="25" fit="fill">
|
||||||
@@ -47,8 +47,9 @@
|
|||||||
name="fa fa-cogs"
|
name="fa fa-cogs"
|
||||||
size="18"
|
size="18"
|
||||||
/>
|
/>
|
||||||
</div> -->"
|
</div> -->
|
||||||
|
"
|
||||||
|
|
||||||
<Config />
|
<Config />
|
||||||
<PopupPwd ref="popupPwd" />
|
<PopupPwd ref="popupPwd" />
|
||||||
<AdminInfo ref="popupAdminInfo" />
|
<AdminInfo ref="popupAdminInfo" />
|
||||||
@@ -71,7 +72,6 @@ import PopupPwd from './popup/password.vue'
|
|||||||
import AdminInfo from './popup/adminInfo.vue'
|
import AdminInfo from './popup/adminInfo.vue'
|
||||||
import { useNavTabs } from '@/stores/navTabs'
|
import { useNavTabs } from '@/stores/navTabs'
|
||||||
|
|
||||||
|
|
||||||
const adminInfo = useAdminInfo()
|
const adminInfo = useAdminInfo()
|
||||||
const navTabs = useNavTabs()
|
const navTabs = useNavTabs()
|
||||||
const configStore = useConfig()
|
const configStore = useConfig()
|
||||||
@@ -106,7 +106,7 @@ const onFullScreen = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCommand = (key: string) => {
|
const handleCommand = async (key: string) => {
|
||||||
// console.log(key)
|
// console.log(key)
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'adminInfo':
|
case 'adminInfo':
|
||||||
@@ -116,10 +116,13 @@ const handleCommand = (key: string) => {
|
|||||||
popupPwd.value.open()
|
popupPwd.value.open()
|
||||||
break
|
break
|
||||||
case 'layout':
|
case 'layout':
|
||||||
navTabs.closeTabs()
|
await window.location.reload()
|
||||||
window.localStorage.clear()
|
setTimeout(() => {
|
||||||
adminInfo.reset()
|
navTabs.closeTabs()
|
||||||
router.push({ name: 'login' })
|
window.localStorage.clear()
|
||||||
|
adminInfo.reset()
|
||||||
|
router.push({ name: 'login' })
|
||||||
|
}, 0)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ export const useNavTabs = defineStore(
|
|||||||
})
|
})
|
||||||
|
|
||||||
function addTab(route: RouteLocationNormalized) {
|
function addTab(route: RouteLocationNormalized) {
|
||||||
console.log('🚀 ~ addTab ~ route:', route)
|
|
||||||
if (!route.meta.addtab) return
|
if (!route.meta.addtab) return
|
||||||
for (const key in state.tabsView) {
|
for (const key in state.tabsView) {
|
||||||
if (state.tabsView[key].path === route.path) {
|
if (state.tabsView[key].path === route.path) {
|
||||||
@@ -69,7 +68,7 @@ export const useNavTabs = defineStore(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const setTabsViewRoutes = (data: RouteRecordRaw[]): void => {
|
const setTabsViewRoutes = (data: RouteRecordRaw[]): void => {
|
||||||
state.tabsViewRoutes = encodeRoutesURI(data)
|
state.tabsViewRoutes = encodeRoutesURI(JSON.parse(JSON.stringify(data)))
|
||||||
}
|
}
|
||||||
|
|
||||||
const setAuthNode = (key: string, data: string[]) => {
|
const setAuthNode = (key: string, data: string[]) => {
|
||||||
@@ -87,9 +86,9 @@ export const useNavTabs = defineStore(
|
|||||||
const refresh = () => {
|
const refresh = () => {
|
||||||
// setTimeout(() => {
|
// setTimeout(() => {
|
||||||
// console.log(123, state.tabsViewRoutes)
|
// console.log(123, state.tabsViewRoutes)
|
||||||
|
|
||||||
let list = matchAndReturnRouteData(state.tabsViewRoutes, state.tabsView)
|
let list = matchAndReturnRouteData(state.tabsViewRoutes, state.tabsView)
|
||||||
state.tabsView = []
|
state.tabsView = []
|
||||||
list.forEach(item => {
|
list.forEach(item => {
|
||||||
addTab(item)
|
addTab(item)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,16 +7,34 @@
|
|||||||
</div>
|
</div>
|
||||||
<Table ref="tableRef" :row-config="{ isCurrent: true, isHover: true }" @currentChange="currentChange" />
|
<Table ref="tableRef" :row-config="{ isCurrent: true, isHover: true }" @currentChange="currentChange" />
|
||||||
</div>
|
</div>
|
||||||
<Tree
|
<div>
|
||||||
v-if="menuListId"
|
<el-tabs type="border-card">
|
||||||
ref="treeRef"
|
<el-tab-pane label="菜单">
|
||||||
show-checkbox
|
<Tree
|
||||||
width="350px"
|
v-if="menuListId"
|
||||||
:data="menuTree"
|
ref="treeRef"
|
||||||
:checkStrictly="false"
|
show-checkbox
|
||||||
@checkChange="checkChange"
|
width="350px"
|
||||||
></Tree>
|
:data="menuTree"
|
||||||
<el-empty style="width: 350px; padding-top: 300px; box-sizing: border-box" description="请选择角色" v-else />
|
:checkStrictly="false"
|
||||||
|
@checkChange="checkChange"
|
||||||
|
></Tree>
|
||||||
|
<el-empty
|
||||||
|
style="width: 350px; padding-top: 300px; box-sizing: border-box"
|
||||||
|
description="请选择角色"
|
||||||
|
v-else
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="系统">
|
||||||
|
<div class="mt10 mr10" style="display: flex; justify-content: end">
|
||||||
|
<el-button type="primary" icon="el-icon-Select" @click="saveSystem">保存</el-button>
|
||||||
|
</div>
|
||||||
|
<el-checkbox-group v-model="systemIds" class="md10 system" >
|
||||||
|
<el-checkbox v-for="item in systemList" :label="item.name" :value="item.id" :key="item.id" />
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
<PopupForm ref="popupRef"></PopupForm>
|
<PopupForm ref="popupRef"></PopupForm>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -34,11 +52,14 @@ import { del } from '@/api/user-boot/role'
|
|||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import PopupForm from './popupForm.vue'
|
import PopupForm from './popupForm.vue'
|
||||||
import { useAdminInfo } from '@/stores/adminInfo'
|
import { useAdminInfo } from '@/stores/adminInfo'
|
||||||
|
import { useDictData } from '@/stores/dictData'
|
||||||
|
const dictData = useDictData()
|
||||||
|
const systemList = dictData.getBasicData('System_Type')
|
||||||
const adminInfo = useAdminInfo()
|
const adminInfo = useAdminInfo()
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'auth/role'
|
name: 'auth/role'
|
||||||
})
|
})
|
||||||
|
const systemIds = ref([])
|
||||||
const height = mainHeight(20).height
|
const height = mainHeight(20).height
|
||||||
const treeRef = ref()
|
const treeRef = ref()
|
||||||
const menuTree = ref<treeData[]>([])
|
const menuTree = ref<treeData[]>([])
|
||||||
@@ -163,6 +184,19 @@ const checkChange = (data: any) => {
|
|||||||
treeRef.value.loading = false
|
treeRef.value.loading = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const saveSystem = () => {
|
||||||
|
// updateRoleMenu({
|
||||||
|
// id: menuListId.value,
|
||||||
|
// idList: systemIds.value
|
||||||
|
// })
|
||||||
|
// .then(() => {
|
||||||
|
// ElMessage.success('操作成功!')
|
||||||
|
// treeRef.value.loading = false
|
||||||
|
// })
|
||||||
|
// .catch(() => {
|
||||||
|
// treeRef.value.loading = false
|
||||||
|
// })
|
||||||
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
})
|
})
|
||||||
@@ -170,3 +204,17 @@ const addRole = () => {
|
|||||||
popupRef.value.open('新增角色')
|
popupRef.value.open('新增角色')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.el-tabs--border-card > .el-tabs__content) {
|
||||||
|
padding: 0px !important;
|
||||||
|
}
|
||||||
|
.system{
|
||||||
|
width: 330px;
|
||||||
|
height: calc(100vh - 225px);
|
||||||
|
border: 1px solid var(--el-border-color);
|
||||||
|
padding: 5px 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ const tableStore = new TableStore({
|
|||||||
},
|
},
|
||||||
click: row => {
|
click: row => {
|
||||||
popupEditRef.value.open('编辑用户', row)
|
popupEditRef.value.open('编辑用户', row)
|
||||||
|
console.log("🚀 ~ row:", row)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,245 +1,271 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog class="cn-operate-dialog" v-model.trim="dialogVisible" :title="title">
|
<el-dialog class="cn-operate-dialog" v-model.trim="dialogVisible" :title="title">
|
||||||
|
<el-form :model="form" label-width="auto" class="form-two" :rules="rules">
|
||||||
<el-form :model="form" label-width="auto" class="form-two" :rules="rules">
|
<el-form-item label="用户名" prop="name">
|
||||||
<el-form-item label="用户名" prop="name">
|
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入昵称" />
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入昵称" />
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item label="登录名" prop="loginName">
|
||||||
<el-form-item label="登录名" prop="loginName">
|
<el-input maxlength="32" show-word-limit v-model.trim="form.loginName" placeholder="请输入登录名" />
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.loginName" placeholder="请输入登录名" />
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item label="默认密码" prop="password" v-if="title === '新增用户'">
|
||||||
<el-form-item label="默认密码" prop="password" v-if="title === '新增用户'">
|
<el-input
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.password" placeholder="请输入密码" disabled />
|
maxlength="32"
|
||||||
</el-form-item>
|
show-word-limit
|
||||||
<el-form-item label="权限类型" prop="type">
|
v-model.trim="form.password"
|
||||||
<el-select v-model.trim="form.type" @change="changeValue" disabled placeholder="请选择权限类型">
|
placeholder="请输入密码"
|
||||||
<el-option v-for="(item, index) in UserTypeOption" :label="item.label" :value="item.value"
|
disabled
|
||||||
:key="index"></el-option>
|
/>
|
||||||
</el-select>
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item label="权限类型" prop="type">
|
||||||
<el-form-item label="用户类型" prop="casualUser">
|
<el-select v-model.trim="form.type" @change="changeValue" disabled placeholder="请选择权限类型">
|
||||||
<el-select v-model.trim="form.casualUser" placeholder="请选择权限类型">
|
<el-option
|
||||||
<el-option v-for="(item, index) in TypeOptions" :label="item.label" :value="item.value"
|
v-for="(item, index) in UserTypeOption"
|
||||||
:key="index"></el-option>
|
:label="item.label"
|
||||||
</el-select>
|
:value="item.value"
|
||||||
</el-form-item>
|
:key="index"
|
||||||
<!-- <el-form-item label="所属部门" prop="deptId">
|
></el-option>
|
||||||
<Area v-model.trim="form.deptId" />
|
</el-select>
|
||||||
</el-form-item> -->
|
</el-form-item>
|
||||||
<el-form-item label="角色" prop="role">
|
<el-form-item label="用户类型" prop="casualUser">
|
||||||
<el-select v-model.trim="form.role" placeholder="请选择角色" multiple collapse-tags>
|
<el-select v-model.trim="form.casualUser" placeholder="请选择权限类型">
|
||||||
<el-option v-for="(item, index) in roleOptions" :label="item.label" :value="item.value"
|
<el-option
|
||||||
:key="index"></el-option>
|
v-for="(item, index) in TypeOptions"
|
||||||
</el-select>
|
:label="item.label"
|
||||||
</el-form-item>
|
:value="item.value"
|
||||||
|
:key="index"
|
||||||
<el-form-item label="手机号" prop="phone">
|
></el-option>
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.phone" placeholder="请输入手机号" />
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="邮箱" prop="email">
|
<!-- <el-form-item label="所属部门" prop="deptId">
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.email" placeholder="请输入描述" />
|
<Area v-model.trim="form.deptId" />
|
||||||
</el-form-item>
|
</el-form-item> -->
|
||||||
<el-form-item label="时间段" prop="limitTime">
|
<el-form-item label="角色" prop="role">
|
||||||
<el-slider v-model.trim="form.limitTime" style="width: 95%" range show-stops :max="24" />
|
<el-select v-model.trim="form.role" placeholder="请选择角色" multiple collapse-tags>
|
||||||
</el-form-item>
|
<el-option
|
||||||
<el-form-item label="起始IP" prop="limitIpStart">
|
v-for="(item, index) in roleOptions"
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.limitIpStart" placeholder="请输入描述" />
|
:label="item.label"
|
||||||
</el-form-item>
|
:value="item.value"
|
||||||
<el-form-item label="结束IP" prop="limitIpEnd">
|
:key="index"
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.limitIpEnd" placeholder="请输入描述" />
|
></el-option>
|
||||||
</el-form-item>
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="短信通知" prop="smsNotice">
|
|
||||||
<el-radio-group v-model.trim="form.smsNotice" style="width: 200px">
|
<el-form-item label="手机号" prop="phone">
|
||||||
<el-radio-button :label="0">是</el-radio-button>
|
<el-input maxlength="32" show-word-limit v-model.trim="form.phone" placeholder="请输入手机号" />
|
||||||
<el-radio-button :label="1">否</el-radio-button>
|
</el-form-item>
|
||||||
</el-radio-group>
|
<el-form-item label="邮箱" prop="email">
|
||||||
</el-form-item>
|
<el-input maxlength="32" show-word-limit v-model.trim="form.email" placeholder="请输入描述" />
|
||||||
<el-form-item label="邮件通知" prop="emailNotice">
|
</el-form-item>
|
||||||
<el-radio-group v-model.trim="form.emailNotice" style="width: 200px">
|
<el-form-item label="时间段" prop="limitTime">
|
||||||
<el-radio-button :label="0">是</el-radio-button>
|
<el-slider v-model.trim="form.limitTime" style="width: 95%" range show-stops :max="24" />
|
||||||
<el-radio-button :label="1">否</el-radio-button>
|
</el-form-item>
|
||||||
</el-radio-group>
|
<el-form-item label="起始IP" prop="limitIpStart">
|
||||||
</el-form-item>
|
<el-input maxlength="32" show-word-limit v-model.trim="form.limitIpStart" placeholder="请输入描述" />
|
||||||
<el-form-item label="用户ID">
|
</el-form-item>
|
||||||
<div style="display: flex; width: 100%">
|
<el-form-item label="结束IP" prop="limitIpEnd">
|
||||||
<el-radio-group v-model.trim="useId">
|
<el-input maxlength="32" show-word-limit v-model.trim="form.limitIpEnd" placeholder="请输入描述" />
|
||||||
<el-radio-button :label="1">是</el-radio-button>
|
</el-form-item>
|
||||||
<el-radio-button :label="0">否</el-radio-button>
|
|
||||||
</el-radio-group>
|
<el-form-item label="短信通知" prop="smsNotice">
|
||||||
<el-input maxlength="32" show-word-limit :disabled="title !== '新增用户'" v-model.trim="form.id"
|
<el-radio-group v-model.trim="form.smsNotice" style="width: 200px">
|
||||||
placeholder="请输入用户id" v-if="useId" style="flex: 1;" class="ml10"></el-input>
|
<el-radio-button :label="0">是</el-radio-button>
|
||||||
</div>
|
<el-radio-button :label="1">否</el-radio-button>
|
||||||
</el-form-item>
|
</el-radio-group>
|
||||||
</el-form>
|
</el-form-item>
|
||||||
|
<el-form-item label="邮件通知" prop="emailNotice">
|
||||||
<template #footer>
|
<el-radio-group v-model.trim="form.emailNotice" style="width: 200px">
|
||||||
<span class="dialog-footer">
|
<el-radio-button :label="0">是</el-radio-button>
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-radio-button :label="1">否</el-radio-button>
|
||||||
<el-button type="primary" @click="submit">确认</el-button>
|
</el-radio-group>
|
||||||
</span>
|
</el-form-item>
|
||||||
</template>
|
<el-form-item label="用户ID">
|
||||||
</el-dialog>
|
<div style="display: flex; width: 100%">
|
||||||
</template>
|
<el-radio-group v-model.trim="useId">
|
||||||
<script lang="ts" setup>
|
<el-radio-button :label="1">是</el-radio-button>
|
||||||
import { ref, inject } from 'vue'
|
<el-radio-button :label="0">否</el-radio-button>
|
||||||
import { reactive } from 'vue'
|
</el-radio-group>
|
||||||
import TableStore from '@/utils/tableStore'
|
<el-input
|
||||||
import { ElMessage, FormItemRule } from 'element-plus'
|
maxlength="32"
|
||||||
import { roleList } from '@/api/user-boot/role'
|
show-word-limit
|
||||||
import { add, edit } from '@/api/user-boot/user'
|
:disabled="title !== '新增用户'"
|
||||||
import { useAdminInfo } from '@/stores/adminInfo'
|
v-model.trim="form.id"
|
||||||
import Area from '@/components/form/area/index.vue'
|
placeholder="请输入用户id"
|
||||||
import { Arrayable } from 'element-plus/es/utils'
|
v-if="useId"
|
||||||
|
style="flex: 1"
|
||||||
const adminInfo = useAdminInfo()
|
class="ml10"
|
||||||
const tableStore = inject('tableStore') as TableStore
|
></el-input>
|
||||||
// do not use same name with ref
|
</div>
|
||||||
const form = reactive({
|
</el-form-item>
|
||||||
id: '',
|
</el-form>
|
||||||
name: '',
|
|
||||||
password: '123456',
|
<template #footer>
|
||||||
email: '',
|
<span class="dialog-footer">
|
||||||
limitIpStart: '',
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
deptId: '',
|
<el-button type="primary" @click="submit">确认</el-button>
|
||||||
deptName: '',
|
</span>
|
||||||
casualUser: 1,
|
</template>
|
||||||
loginName: '',
|
</el-dialog>
|
||||||
phone: '',
|
</template>
|
||||||
limitIpEnd: '',
|
<script lang="ts" setup>
|
||||||
limitTime: [1, 2],
|
import { ref, inject } from 'vue'
|
||||||
role: [],
|
import { reactive } from 'vue'
|
||||||
smsNotice: 0,
|
import TableStore from '@/utils/tableStore'
|
||||||
emailNotice: 0,
|
import { ElMessage, FormItemRule } from 'element-plus'
|
||||||
type: 0
|
import { roleList } from '@/api/user-boot/role'
|
||||||
})
|
import { add, edit } from '@/api/user-boot/user'
|
||||||
const rules: Partial<Record<string, Arrayable<FormItemRule>>> = {
|
import { useAdminInfo } from '@/stores/adminInfo'
|
||||||
name: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
|
import Area from '@/components/form/area/index.vue'
|
||||||
role: [{ required: true, message: '角色不能为空', trigger: 'blur' }],
|
import { Arrayable } from 'element-plus/es/utils'
|
||||||
password: [{ required: true, message: '用户密码不能为空', trigger: 'blur' }],
|
|
||||||
loginName: [{ required: true, message: '登录名不能为空', trigger: 'blur' }],
|
const adminInfo = useAdminInfo()
|
||||||
casualUser: [{ required: true, message: '用户类型不能为空', trigger: 'blur' }],
|
const tableStore = inject('tableStore') as TableStore
|
||||||
smsNotice: [{ required: true, message: '短信通知不能为空', trigger: 'blur' }],
|
// do not use same name with ref
|
||||||
emailNotice: [{ required: true, message: '邮件通知不能为空', trigger: 'blur' }],
|
const form = reactive({
|
||||||
email: [
|
id: '',
|
||||||
{ required: false, message: '邮箱不能为空', trigger: 'blur' },
|
name: '',
|
||||||
{
|
password: '123456',
|
||||||
type: 'email',
|
email: '',
|
||||||
message: "'请输入正确的邮箱地址",
|
limitIpStart: '',
|
||||||
trigger: ['blur', 'change']
|
deptId: '',
|
||||||
}
|
deptName: '',
|
||||||
],
|
casualUser: 1,
|
||||||
phone: [
|
loginName: '',
|
||||||
{ required: false, message: '手机号不能为空', trigger: 'blur' },
|
phone: '',
|
||||||
{
|
limitIpEnd: '',
|
||||||
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
limitTime: [1, 2],
|
||||||
message: '请输入正确的手机号码',
|
role: [],
|
||||||
trigger: 'blur'
|
smsNotice: 0,
|
||||||
}
|
emailNotice: 0,
|
||||||
],
|
type: 0
|
||||||
limitTime: [{ required: true, message: '时间段不能为空', trigger: 'blur' }],
|
})
|
||||||
limitIpStart: [
|
const rules: Partial<Record<string, Arrayable<FormItemRule>>> = {
|
||||||
{ required: true, message: '起始IP不能为空', trigger: 'blur' },
|
name: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
|
||||||
{
|
role: [{ required: true, message: '角色不能为空', trigger: 'blur' }],
|
||||||
required: true,
|
password: [{ required: true, message: '用户密码不能为空', trigger: 'blur' }],
|
||||||
validator: (rule: any, value: string, callback: any) => {
|
loginName: [{ required: true, message: '登录名不能为空', trigger: 'blur' }],
|
||||||
let regexp = /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/
|
casualUser: [{ required: true, message: '用户类型不能为空', trigger: 'blur' }],
|
||||||
let isCorrect = regexp.test(value)
|
smsNotice: [{ required: true, message: '短信通知不能为空', trigger: 'blur' }],
|
||||||
if (value == '') {
|
emailNotice: [{ required: true, message: '邮件通知不能为空', trigger: 'blur' }],
|
||||||
return callback(new Error('请输入IP地址'))
|
email: [
|
||||||
} else if (!isCorrect) {
|
{ required: false, message: '邮箱不能为空', trigger: 'blur' },
|
||||||
callback(new Error('请输入正确的IP地址'))
|
{
|
||||||
} else {
|
type: 'email',
|
||||||
callback()
|
message: "'请输入正确的邮箱地址",
|
||||||
}
|
trigger: ['blur', 'change']
|
||||||
},
|
}
|
||||||
trigger: 'blur'
|
],
|
||||||
}
|
phone: [
|
||||||
],
|
{ required: false, message: '手机号不能为空', trigger: 'blur' },
|
||||||
limitIpEnd: [
|
{
|
||||||
{ required: true, message: '结束IP不能为空', trigger: 'blur' },
|
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
||||||
{
|
message: '请输入正确的手机号码',
|
||||||
required: true,
|
trigger: 'blur'
|
||||||
validator: (rule: any, value: string, callback: any) => {
|
}
|
||||||
let regexp = /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/
|
],
|
||||||
let isCorrect = regexp.test(value)
|
limitTime: [{ required: true, message: '时间段不能为空', trigger: 'blur' }],
|
||||||
if (value == '') {
|
limitIpStart: [
|
||||||
return callback(new Error('请输入IP地址'))
|
{ required: true, message: '起始IP不能为空', trigger: 'blur' },
|
||||||
} else if (!isCorrect) {
|
{
|
||||||
callback(new Error('请输入正确的IP地址'))
|
required: true,
|
||||||
} else {
|
validator: (rule: any, value: string, callback: any) => {
|
||||||
callback()
|
let regexp = /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/
|
||||||
}
|
let isCorrect = regexp.test(value)
|
||||||
},
|
if (value == '') {
|
||||||
trigger: 'blur'
|
return callback(new Error('请输入IP地址'))
|
||||||
}
|
} else if (!isCorrect) {
|
||||||
]
|
callback(new Error('请输入正确的IP地址'))
|
||||||
}
|
} else {
|
||||||
const UserTypeOption = [
|
callback()
|
||||||
{ label: '管理员', value: 1 },
|
}
|
||||||
{ label: '普通用户', value: 2 }
|
},
|
||||||
]
|
trigger: 'blur'
|
||||||
const TypeOptions = [
|
}
|
||||||
{ label: '临时用户', value: 0 },
|
],
|
||||||
{ label: '长期用户', value: 1 }
|
limitIpEnd: [
|
||||||
]
|
{ required: true, message: '结束IP不能为空', trigger: 'blur' },
|
||||||
const useId = ref(1)
|
{
|
||||||
const roleOptions = ref<treeData>()
|
required: true,
|
||||||
const queryRole = () => {
|
validator: (rule: any, value: string, callback: any) => {
|
||||||
roleList(adminInfo.$state.userType).then((res: any) => {
|
let regexp = /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/
|
||||||
roleOptions.value = res.data.map((item: any) => {
|
let isCorrect = regexp.test(value)
|
||||||
return {
|
if (value == '') {
|
||||||
label: item.name,
|
return callback(new Error('请输入IP地址'))
|
||||||
value: item.id
|
} else if (!isCorrect) {
|
||||||
}
|
callback(new Error('请输入正确的IP地址'))
|
||||||
})
|
} else {
|
||||||
})
|
callback()
|
||||||
}
|
}
|
||||||
queryRole()
|
},
|
||||||
const dialogVisible = ref(false)
|
trigger: 'blur'
|
||||||
const title = ref('新增菜单')
|
}
|
||||||
const open = (text: string, data?: anyObj) => {
|
]
|
||||||
title.value = text
|
}
|
||||||
dialogVisible.value = true
|
const UserTypeOption = [
|
||||||
if (data) {
|
{ label: '管理员', value: 1 },
|
||||||
for (let key in form) {
|
{ label: '普通用户', value: 2 }
|
||||||
form[key] = data[key]
|
]
|
||||||
}
|
const TypeOptions = [
|
||||||
form.limitTime = data.limitTime.split('-')
|
{ label: '临时用户', value: 0 },
|
||||||
form.role = data.roleList
|
{ label: '长期用户', value: 1 }
|
||||||
} else {
|
]
|
||||||
for (let key in form) {
|
const useId = ref(1)
|
||||||
form[key] = ''
|
const roleOptions = ref<treeData>()
|
||||||
}
|
const queryRole = () => {
|
||||||
form.casualUser = 1
|
roleList(adminInfo.$state.userType).then((res: any) => {
|
||||||
form.limitTime = [0, 24]
|
roleOptions.value = res.data.map((item: any) => {
|
||||||
form.role = []
|
return {
|
||||||
form.smsNotice = 0
|
label: item.name,
|
||||||
form.emailNotice = 0
|
value: item.id
|
||||||
useId.value = 1
|
}
|
||||||
form.id = ''
|
})
|
||||||
form.limitIpStart = '0.0.0.0'
|
})
|
||||||
form.limitIpEnd = '255.255.255.255'
|
}
|
||||||
form.password = '123456'
|
queryRole()
|
||||||
}
|
const dialogVisible = ref(false)
|
||||||
form.type = adminInfo.$state.userType + 1
|
const title = ref('新增菜单')
|
||||||
}
|
const open = (text: string, data?: anyObj) => {
|
||||||
const submit = async () => {
|
title.value = text
|
||||||
let obj = JSON.parse(JSON.stringify(form))
|
dialogVisible.value = true
|
||||||
obj.limitTime = obj.limitTime.join('-')
|
console.log("🚀 ~ open ~ data:", data)
|
||||||
delete obj.password
|
if (data) {
|
||||||
if (form.id) {
|
for (let key in form) {
|
||||||
await edit(obj)
|
form[key] = data[key]
|
||||||
ElMessage.success('修改成功')
|
}
|
||||||
} else {
|
form.limitTime = data.limitTime.split('-')
|
||||||
form.type = adminInfo.$state.userType + 1
|
form.role = data.roleList
|
||||||
await add(obj)
|
} else {
|
||||||
ElMessage.success('新增成功')
|
for (let key in form) {
|
||||||
}
|
form[key] = ''
|
||||||
tableStore.index()
|
}
|
||||||
dialogVisible.value = false
|
form.casualUser = 1
|
||||||
}
|
form.limitTime = [0, 24]
|
||||||
|
form.role = []
|
||||||
const changeValue = () => { }
|
form.smsNotice = 0
|
||||||
defineExpose({ open })
|
form.emailNotice = 0
|
||||||
</script>
|
useId.value = 1
|
||||||
|
form.id = ''
|
||||||
|
form.limitIpStart = '0.0.0.0'
|
||||||
|
form.limitIpEnd = '255.255.255.255'
|
||||||
|
form.password = '123456'
|
||||||
|
form.type = adminInfo.$state.userType + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const submit = async () => {
|
||||||
|
let obj = JSON.parse(JSON.stringify(form))
|
||||||
|
obj.limitTime = obj.limitTime.join('-')
|
||||||
|
delete obj.password
|
||||||
|
if (form.id) {
|
||||||
|
await edit(obj)
|
||||||
|
ElMessage.success('修改成功')
|
||||||
|
} else {
|
||||||
|
form.type = adminInfo.$state.userType + 1
|
||||||
|
await add(obj)
|
||||||
|
ElMessage.success('新增成功')
|
||||||
|
}
|
||||||
|
tableStore.index()
|
||||||
|
dialogVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeValue = () => {}
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -380,10 +380,11 @@ const drag = throttle(row => {
|
|||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
Object.assign(item.state, {
|
Object.assign(item.state, {
|
||||||
top: mouseAt.y - parentRect.top,
|
top: mouseAt.y - parentRect.top - 300,
|
||||||
left: mouseAt.x - parentRect.left
|
left: mouseAt.x - parentRect.left - 180
|
||||||
})
|
})
|
||||||
const newPos = item.calcXY(mouseAt.y - parentRect.top, mouseAt.x - parentRect.left)
|
|
||||||
|
const newPos = item.calcXY(mouseAt.y - parentRect.top - 300, mouseAt.x - parentRect.left - 180)
|
||||||
|
|
||||||
if (mouseInGrid) {
|
if (mouseInGrid) {
|
||||||
gridLayout.value.dragEvent('dragstart', dropId, newPos.x, newPos.y, dragItem.h, dragItem.w)
|
gridLayout.value.dragEvent('dragstart', dropId, newPos.x, newPos.y, dragItem.h, dragItem.w)
|
||||||
@@ -441,7 +442,7 @@ const onSubmit = () => {
|
|||||||
console.log(123, findDuplicateNames(layout.value))
|
console.log(123, findDuplicateNames(layout.value))
|
||||||
let repeat = findDuplicateNames(layout.value) || []
|
let repeat = findDuplicateNames(layout.value) || []
|
||||||
if (repeat.length > 0) {
|
if (repeat.length > 0) {
|
||||||
return ElMessage.warning(repeat.join('、')+' 组件重复,请删除重复组件!')
|
return ElMessage.warning(repeat.join('、') + ' 组件重复,请删除重复组件!')
|
||||||
}
|
}
|
||||||
|
|
||||||
// const maxValue = Math.max(...layout.value.map(item => item.y + item.h))
|
// const maxValue = Math.max(...layout.value.map(item => item.y + item.h))
|
||||||
|
|||||||
@@ -31,13 +31,6 @@
|
|||||||
<el-input v-model="form.path" placeholder="请输入组件路径"></el-input>
|
<el-input v-model="form.path" placeholder="请输入组件路径"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item class="top" label="组件查询时间" prop="timeKeys">
|
<el-form-item class="top" label="组件查询时间" prop="timeKeys">
|
||||||
<!-- <el-radio-group v-model="form.timeKeys" style="width: 100%">
|
|
||||||
<el-radio-button label="年" value="1" />
|
|
||||||
<el-radio-button label="季" value="2" />
|
|
||||||
<el-radio-button label="月" value="3" />
|
|
||||||
<el-radio-button label="周" value="4" />
|
|
||||||
<el-radio-button label="日" value="5" />
|
|
||||||
</el-radio-group> -->
|
|
||||||
<el-checkbox-group v-model="form.timeKeys">
|
<el-checkbox-group v-model="form.timeKeys">
|
||||||
<el-checkbox-button value="1">年</el-checkbox-button>
|
<el-checkbox-button value="1">年</el-checkbox-button>
|
||||||
<el-checkbox-button value="2">季</el-checkbox-button>
|
<el-checkbox-button value="2">季</el-checkbox-button>
|
||||||
@@ -46,6 +39,17 @@
|
|||||||
<el-checkbox-button value="5">日</el-checkbox-button>
|
<el-checkbox-button value="5">日</el-checkbox-button>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item class="top" label="组件绑定系统" prop="systemIds">
|
||||||
|
<el-select
|
||||||
|
v-model="form.systemIds"
|
||||||
|
multiple
|
||||||
|
collapse-tags
|
||||||
|
collapse-tags-tooltip
|
||||||
|
placeholder="请选择组件绑定系统"
|
||||||
|
>
|
||||||
|
<el-option v-for="item in systemList" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item class="top" label="组件排序" prop="sort">
|
<el-form-item class="top" label="组件排序" prop="sort">
|
||||||
<el-input v-model.number="form.sort" placeholder="请输入组件排序"></el-input>
|
<el-input v-model.number="form.sort" placeholder="请输入组件排序"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -70,7 +74,7 @@
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="cancel">取消</el-button>
|
<el-button @click="cancel">取消</el-button>
|
||||||
<el-button type="primary" @click="submit">保存</el-button>
|
<el-button type="primary" @click="submit" :loading="loading">保存</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -88,6 +92,7 @@ const dictData = useDictData()
|
|||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const title = ref('')
|
const title = ref('')
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
|
const loading = ref(false)
|
||||||
// 注意不要和表单ref的命名冲突
|
// 注意不要和表单ref的命名冲突
|
||||||
const form = ref<anyObj>({
|
const form = ref<anyObj>({
|
||||||
name: '',
|
name: '',
|
||||||
@@ -95,6 +100,7 @@ const form = ref<anyObj>({
|
|||||||
system: [],
|
system: [],
|
||||||
timeKeys: ['1', '2', '3', '4', '5'],
|
timeKeys: ['1', '2', '3', '4', '5'],
|
||||||
code: '',
|
code: '',
|
||||||
|
systemIds: [],
|
||||||
path: ''
|
path: ''
|
||||||
})
|
})
|
||||||
const props = { label: 'name', value: 'id' }
|
const props = { label: 'name', value: 'id' }
|
||||||
@@ -105,11 +111,14 @@ const rules = {
|
|||||||
icon: [{ required: true, message: '请先择组件图标', trigger: 'change' }],
|
icon: [{ required: true, message: '请先择组件图标', trigger: 'change' }],
|
||||||
path: [{ required: true, message: '请输入组件路径', trigger: 'blur' }],
|
path: [{ required: true, message: '请输入组件路径', trigger: 'blur' }],
|
||||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||||
timeKeys: [{ required: true, message: '请选择组件查询时间', trigger: 'change' }]
|
timeKeys: [{ required: true, message: '请选择组件查询时间', trigger: 'change' }],
|
||||||
|
systemIds: [{ required: true, message: '请选择组件绑定系统', trigger: 'change' }]
|
||||||
}
|
}
|
||||||
const customDeptOption: any = ref([])
|
const customDeptOption: any = ref([])
|
||||||
|
const systemList = dictData.getBasicData('System_Type')
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
customDeptOption.value = dictData.getBasicData('System_Type')
|
customDeptOption.value = dictData.getBasicData('Component_Type')
|
||||||
|
|
||||||
customDeptOption.value.forEach((item: any) => {
|
customDeptOption.value.forEach((item: any) => {
|
||||||
getFatherComponent({ systemType: item.id }).then(res => {
|
getFatherComponent({ systemType: item.id }).then(res => {
|
||||||
item.children = res.data.filter(item => item.name != '无')
|
item.children = res.data.filter(item => item.name != '无')
|
||||||
@@ -134,6 +143,7 @@ const submit = () => {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
let url = ''
|
let url = ''
|
||||||
ElMessage.info('正在保存请稍等!')
|
ElMessage.info('正在保存请稍等!')
|
||||||
|
loading.value = true
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await html2canvas(document.querySelector('.GridLayout'), {
|
await html2canvas(document.querySelector('.GridLayout'), {
|
||||||
// scale: 2
|
// scale: 2
|
||||||
@@ -173,6 +183,7 @@ const submit = () => {
|
|||||||
cancel()
|
cancel()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
loading.value = false
|
||||||
}, 500)
|
}, 500)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,11 +13,11 @@
|
|||||||
/> -->
|
/> -->
|
||||||
<el-tabs v-model="tableName" type="border-card" @tab-change="changeTab">
|
<el-tabs v-model="tableName" type="border-card" @tab-change="changeTab">
|
||||||
<el-tab-pane v-for="item in tableStore.table.data" :key="item.name" :label="item.name" :name="item.name">
|
<el-tab-pane v-for="item in tableStore.table.data" :key="item.name" :label="item.name" :name="item.name">
|
||||||
<el-tabs v-model="tableName1" tab-position="left">
|
<el-tabs v-model="tableName1" tab-position="left" class="componentList">
|
||||||
<el-tab-pane v-for="k in item?.children" :key="k.name" :label="k.name" :name="k.name">
|
<el-tab-pane v-for="k in item?.children" :key="k.name" :label="k.name" :name="k.name">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span class="custom-tabs-label">
|
<span class="custom-tabs-label">
|
||||||
<span>{{ k.name }}</span>
|
<p>{{ k.name }}</p>
|
||||||
|
|
||||||
<!-- <el-icon><Edit /></el-icon> -->
|
<!-- <el-icon><Edit /></el-icon> -->
|
||||||
<el-button
|
<el-button
|
||||||
@@ -25,21 +25,21 @@
|
|||||||
icon="el-icon-Edit"
|
icon="el-icon-Edit"
|
||||||
link
|
link
|
||||||
class="ml10"
|
class="ml10"
|
||||||
@click="editTree(k, 0)"
|
@click.stop="editTree(k, 0)"
|
||||||
></el-button>
|
></el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="danger"
|
type="danger"
|
||||||
icon="el-icon-Delete"
|
icon="el-icon-Delete"
|
||||||
link
|
link
|
||||||
class="ml0"
|
class="ml0"
|
||||||
@click="del(k)"
|
@click.stop="del(k)"
|
||||||
></el-button>
|
></el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<div :style="height" style="overflow-y: auto; overflow-x: hidden">
|
<div :style="height" style="overflow-y: auto; overflow-x: hidden">
|
||||||
<el-row :gutter="10" class="pl5 pr5 pt5">
|
<el-row :gutter="10" class="pl5 pr5 pt5">
|
||||||
<el-col :span="6" v-for="component in k.children" :key="component.id" class="mb10">
|
<el-col :span="6" v-for="component in k.children" :key="component.id" class="mb10">
|
||||||
<el-card class="box-card" shadow="hover">
|
<el-card class="box-card" shadow="hover">
|
||||||
<div slot="header" class="clearfix">
|
<div slot="header" class="clearfix">
|
||||||
<span style="display: flex; align-items: center">
|
<span style="display: flex; align-items: center">
|
||||||
{{ component.name }}
|
{{ component.name }}
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
icon="el-icon-Edit"
|
icon="el-icon-Edit"
|
||||||
style="padding: 3px 0; color: blue"
|
style="padding: 3px 0; color: blue"
|
||||||
type="text"
|
type="text"
|
||||||
@click="editTree(component, 1)"
|
@click.stop="editTree(component, 1)"
|
||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
icon="el-icon-Delete"
|
icon="el-icon-Delete"
|
||||||
style="padding: 3px 0; color: red"
|
style="padding: 3px 0; color: red"
|
||||||
type="text"
|
type="text"
|
||||||
@click="del(component)"
|
@click.stop="del(component)"
|
||||||
>
|
>
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -356,4 +356,9 @@ span {
|
|||||||
min-width: 128px;
|
min-width: 128px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
:deep(.componentList){
|
||||||
|
.el-tabs__header{
|
||||||
|
height: calc(100vh - 250px)!important;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user