Merge branch 'main' of http://192.168.1.22:3000/Web/admin-govern
This commit is contained in:
@@ -77,3 +77,11 @@ export const queryByPagePath = (params: any) => {
|
|||||||
params
|
params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 根据用户id查询用户驾驶舱
|
||||||
|
export const getDashboardPageByUserId = (params: any) => {
|
||||||
|
return createAxios({
|
||||||
|
url: '/system-boot/dashboard/getDashboardPageByUserId',
|
||||||
|
method: 'post',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--治理效果报表 -->
|
<!--治理效果报表 -->
|
||||||
<TableHeader :showReset="false">
|
<TableHeader :showReset="false" v-if="fullscreen">
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="治理对象">
|
<el-form-item label="治理对象">
|
||||||
<el-select
|
<el-select
|
||||||
@@ -26,13 +26,16 @@
|
|||||||
<div style="display: flex">
|
<div style="display: flex">
|
||||||
<div
|
<div
|
||||||
id="luckysheet"
|
id="luckysheet"
|
||||||
:style="{ width: `calc(${prop.width} )`, height: `calc(${prop.height} - 57px )` }"
|
:style="{
|
||||||
|
width: `calc(${prop.width} )`,
|
||||||
|
height: `calc(${prop.height} - 57px + ${fullscreen ? 0 : 56}px)`
|
||||||
|
}"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch, h, computed } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import { exportExcel } from '@/views/govern/reportForms/export.js'
|
import { exportExcel } from '@/views/govern/reportForms/export.js'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
@@ -44,6 +47,8 @@ import { useConfig } from '@/stores/config'
|
|||||||
import Json from './index.json'
|
import Json from './index.json'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
|
w: { type: String },
|
||||||
|
h: { type: String },
|
||||||
width: { type: String },
|
width: { type: String },
|
||||||
height: { type: String },
|
height: { type: String },
|
||||||
timeKey: { type: String },
|
timeKey: { type: String },
|
||||||
@@ -98,6 +103,17 @@ onMounted(() => {
|
|||||||
|
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
})
|
})
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeKey,
|
() => prop.timeKey,
|
||||||
val => {
|
val => {
|
||||||
@@ -120,5 +136,4 @@ const addMenu = () => {}
|
|||||||
:deep(.el-select) {
|
:deep(.el-select) {
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--指标拟合图 -->
|
<!--指标拟合图 -->
|
||||||
<TableHeader :showReset="false" @selectChange="selectChange">
|
<TableHeader :showReset="false" datePicker @selectChange="selectChange" v-if="fullscreen">
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="用户功率">
|
<el-form-item label="用户功率">
|
||||||
<el-select
|
<el-select
|
||||||
@@ -53,12 +53,15 @@
|
|||||||
<my-echart
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
:style="{ width: prop.width, height: `calc(${prop.height} - ${headerHeight}px )` }"
|
:style="{
|
||||||
|
width: prop.width,
|
||||||
|
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px )`
|
||||||
|
}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch, h, computed } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
@@ -68,6 +71,8 @@ import { getTimeOfTheMonth } from '@/utils/formatTime'
|
|||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
|
w: { type: String },
|
||||||
|
h: { type: String },
|
||||||
width: { type: String },
|
width: { type: String },
|
||||||
height: { type: String },
|
height: { type: String },
|
||||||
timeKey: { type: String },
|
timeKey: { type: String },
|
||||||
@@ -84,6 +89,17 @@ const powerList: any = ref([
|
|||||||
value: '2'
|
value: '2'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
const exceedingTheLimitList: any = ref([
|
const exceedingTheLimitList: any = ref([
|
||||||
{
|
{
|
||||||
label: '越限',
|
label: '越限',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--趋势对比 -->
|
<!--趋势对比 -->
|
||||||
<TableHeader :showReset="false" @selectChange="selectChange">
|
<TableHeader :showReset="false" @selectChange="selectChange" v-if="fullscreen">
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="监测点名称">
|
<el-form-item label="监测点名称">
|
||||||
<el-select
|
<el-select
|
||||||
@@ -53,12 +53,12 @@
|
|||||||
<my-echart
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
:style="{ width: prop.width, height: `calc(${prop.height} - ${headerHeight}px )` }"
|
:style="{ width: prop.width, height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)` }"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch, h, computed } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
@@ -68,6 +68,8 @@ import { getTimeOfTheMonth } from '@/utils/formatTime'
|
|||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
|
w: { type: String },
|
||||||
|
h: { type: String },
|
||||||
width: { type: String },
|
width: { type: String },
|
||||||
height: { type: String },
|
height: { type: String },
|
||||||
timeKey: { type: String },
|
timeKey: { type: String },
|
||||||
@@ -84,6 +86,17 @@ const powerList: any = ref([
|
|||||||
value: '2'
|
value: '2'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
const exceedingTheLimitList: any = ref([
|
const exceedingTheLimitList: any = ref([
|
||||||
{
|
{
|
||||||
label: '2次',
|
label: '2次',
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ const info = () => {
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (arr3.length) {
|
if (arr3.length) {
|
||||||
//初始化选中
|
//初始化选中
|
||||||
treRef.value.treeRef1.setCurrentKey(arr3[0].id)
|
treRef.value.treeRef.setCurrentKey(arr3[0].id)
|
||||||
// 注册父组件事件
|
// 注册父组件事件
|
||||||
emit('init', {
|
emit('init', {
|
||||||
level: 2,
|
level: 2,
|
||||||
|
|||||||
@@ -24,8 +24,6 @@
|
|||||||
@node-click="handleNodeClick"
|
@node-click="handleNodeClick"
|
||||||
:default-checked-keys="defaultCheckedKeys"
|
:default-checked-keys="defaultCheckedKeys"
|
||||||
v-bind='$attrs'
|
v-bind='$attrs'
|
||||||
|
|
||||||
|
|
||||||
>
|
>
|
||||||
<template #default='{ node, data }'>
|
<template #default='{ node, data }'>
|
||||||
<span class='custom-tree-node'>
|
<span class='custom-tree-node'>
|
||||||
|
|||||||
@@ -1,104 +1,104 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-main class="layout-main" :style="mainHeight()">
|
<el-main class="layout-main" :style="mainHeight()">
|
||||||
<router-view v-slot="{ Component }">
|
<router-view v-slot="{ Component }">
|
||||||
<transition :name="config.layout.mainAnimation" mode="out-in">
|
<transition :name="config.layout.mainAnimation" mode="out-in">
|
||||||
<keep-alive :include="state.keepAliveComponentNameList">
|
<keep-alive :include="state.keepAliveComponentNameList">
|
||||||
<component :is="Component" :key="state.componentKey" />
|
<component :is="Component" :key="state.componentKey" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</transition>
|
</transition>
|
||||||
</router-view>
|
</router-view>
|
||||||
</el-main>
|
</el-main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted, watch, onBeforeMount, onUnmounted, nextTick, provide } from 'vue'
|
import { ref, reactive, onMounted, watch, onBeforeMount, onUnmounted, nextTick, provide } from 'vue'
|
||||||
import { useRoute, type RouteLocationNormalized } from 'vue-router'
|
import { useRoute, type RouteLocationNormalized } from 'vue-router'
|
||||||
import { mainHeight } from '@/utils/layout'
|
import { mainHeight } from '@/utils/layout'
|
||||||
import useCurrentInstance from '@/utils/useCurrentInstance'
|
import useCurrentInstance from '@/utils/useCurrentInstance'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
import { useNavTabs } from '@/stores/navTabs'
|
import { useNavTabs } from '@/stores/navTabs'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'layout/main'
|
name: 'layout/main'
|
||||||
})
|
})
|
||||||
|
|
||||||
const { proxy } = useCurrentInstance()
|
const { proxy } = useCurrentInstance()
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
const navTabs = useNavTabs()
|
const navTabs = useNavTabs()
|
||||||
|
|
||||||
const state: {
|
const state: {
|
||||||
componentKey: string
|
componentKey: string
|
||||||
keepAliveComponentNameList: string[]
|
keepAliveComponentNameList: string[]
|
||||||
} = reactive({
|
} = reactive({
|
||||||
componentKey: route.path,
|
componentKey: route.path,
|
||||||
keepAliveComponentNameList: []
|
keepAliveComponentNameList: []
|
||||||
})
|
})
|
||||||
|
|
||||||
const addKeepAliveComponentName = function (keepAliveName: string | undefined) {
|
const addKeepAliveComponentName = function (keepAliveName: string | undefined) {
|
||||||
if (keepAliveName) {
|
if (keepAliveName) {
|
||||||
let exist = state.keepAliveComponentNameList.find((name: string) => {
|
let exist = state.keepAliveComponentNameList.find((name: string) => {
|
||||||
return name === keepAliveName
|
return name === keepAliveName
|
||||||
})
|
})
|
||||||
if (exist) return
|
if (exist) return
|
||||||
state.keepAliveComponentNameList.push(keepAliveName)
|
state.keepAliveComponentNameList.push(keepAliveName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
proxy.eventBus.on('onTabViewRefresh', (menu: RouteLocationNormalized) => {
|
proxy.eventBus.on('onTabViewRefresh', (menu: RouteLocationNormalized) => {
|
||||||
state.keepAliveComponentNameList = state.keepAliveComponentNameList.filter(
|
state.keepAliveComponentNameList = state.keepAliveComponentNameList.filter(
|
||||||
(name: string) => menu.meta.keepalive !== name
|
(name: string) => menu.meta.keepalive !== name
|
||||||
)
|
)
|
||||||
state.componentKey = ''
|
state.componentKey = ''
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
state.componentKey = menu.path
|
state.componentKey = menu.path
|
||||||
addKeepAliveComponentName(menu.meta.keepalive as string)
|
addKeepAliveComponentName(menu.meta.keepalive as string)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
proxy.eventBus.on('onTabViewClose', (menu: RouteLocationNormalized) => {
|
proxy.eventBus.on('onTabViewClose', (menu: RouteLocationNormalized) => {
|
||||||
state.keepAliveComponentNameList = state.keepAliveComponentNameList.filter(
|
state.keepAliveComponentNameList = state.keepAliveComponentNameList.filter(
|
||||||
(name: string) => menu.meta.keepalive !== name
|
(name: string) => menu.meta.keepalive !== name
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
proxy.eventBus.off('onTabViewRefresh')
|
proxy.eventBus.off('onTabViewRefresh')
|
||||||
proxy.eventBus.off('onTabViewClose')
|
proxy.eventBus.off('onTabViewClose')
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 确保刷新页面时也能正确取得当前路由 keepalive 参数
|
// 确保刷新页面时也能正确取得当前路由 keepalive 参数
|
||||||
if (typeof navTabs.state.activeRoute?.meta.keepalive == 'string') {
|
if (typeof navTabs.state.activeRoute?.meta.keepalive == 'string') {
|
||||||
addKeepAliveComponentName(navTabs.state.activeRoute?.meta.keepalive)
|
addKeepAliveComponentName(navTabs.state.activeRoute?.meta.keepalive)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => route.path,
|
() => route.path,
|
||||||
() => {
|
() => {
|
||||||
state.componentKey = route.path
|
state.componentKey = route.path
|
||||||
if (typeof navTabs.state.activeRoute?.meta.keepalive == 'string') {
|
if (typeof navTabs.state.activeRoute?.meta.keepalive == 'string') {
|
||||||
addKeepAliveComponentName(navTabs.state.activeRoute?.meta.keepalive)
|
addKeepAliveComponentName(navTabs.state.activeRoute?.meta.keepalive)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.layout-container .layout-main {
|
.layout-container .layout-main {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-main-scrollbar {
|
.layout-main-scrollbar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
//overflow: hidden;
|
//overflow: hidden;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import router from '@/router/index'
|
import router from '@/router/index'
|
||||||
import { isNavigationFailure, NavigationFailureType } from 'vue-router'
|
import { isNavigationFailure, NavigationFailureType ,useRouter} from 'vue-router'
|
||||||
import type { RouteRecordRaw, RouteLocationRaw } from 'vue-router'
|
import type { RouteRecordRaw, RouteLocationRaw } from 'vue-router'
|
||||||
import { ElNotification } from 'element-plus'
|
import { ElNotification } from 'element-plus'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
@@ -8,8 +8,9 @@ import { closeShade } from '@/utils/pageShade'
|
|||||||
import { adminBaseRoute } from '@/router/static'
|
import { adminBaseRoute } from '@/router/static'
|
||||||
import { compact, isEmpty, reverse } from 'lodash-es'
|
import { compact, isEmpty, reverse } from 'lodash-es'
|
||||||
import { isAdminApp } from '@/utils/common'
|
import { isAdminApp } from '@/utils/common'
|
||||||
import { log } from 'console'
|
import { getRouteMenu, dictDataCache } from '@/api/auth'
|
||||||
|
import { adminBaseRoutePath } from '@/router/static'
|
||||||
|
const route = useRouter()
|
||||||
/**
|
/**
|
||||||
* 导航失败有错误消息的路由push
|
* 导航失败有错误消息的路由push
|
||||||
* @param to — 导航位置,同 router.push
|
* @param to — 导航位置,同 router.push
|
||||||
@@ -17,7 +18,7 @@ import { log } from 'console'
|
|||||||
export const routePush = async (to: RouteLocationRaw) => {
|
export const routePush = async (to: RouteLocationRaw) => {
|
||||||
try {
|
try {
|
||||||
const failure = await router.push(to)
|
const failure = await router.push(to)
|
||||||
|
|
||||||
if (isNavigationFailure(failure, NavigationFailureType.aborted)) {
|
if (isNavigationFailure(failure, NavigationFailureType.aborted)) {
|
||||||
ElNotification({
|
ElNotification({
|
||||||
message: 'utils.Navigation failed, navigation guard intercepted!',
|
message: 'utils.Navigation failed, navigation guard intercepted!',
|
||||||
@@ -279,6 +280,41 @@ export const addRouteItem = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 刷新菜单
|
||||||
|
export const getMenu = () => {
|
||||||
|
getRouteMenu().then((res: any) => {
|
||||||
|
const handlerMenu = (data: any) => {
|
||||||
|
data.forEach((item: any) => {
|
||||||
|
item.routePath =
|
||||||
|
item.routePath[0] == '/' ? item.routePath.substring(1, item.routePath.length) : item.routePath
|
||||||
|
item.path = item.routePath
|
||||||
|
item.name = item.routePath
|
||||||
|
item.keepalive = item.routePath
|
||||||
|
item.component = item.routeName
|
||||||
|
? item.routeName.indexOf('/src/views/') > -1
|
||||||
|
? item.routeName
|
||||||
|
: `/src/views/${item.routeName}/index.vue`
|
||||||
|
: ''
|
||||||
|
item.type = item.children && item.children.length > 0 ? 'menu_dir' : 'menu'
|
||||||
|
item.menu_type = item.children && item.children.length > 0 ? null : 'tab'
|
||||||
|
if (item.children) {
|
||||||
|
handlerMenu(item.children)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
handlerMenu(res.data)
|
||||||
|
handleAdminRoute(res.data)
|
||||||
|
if (route.params.to) {
|
||||||
|
const lastRoute = JSON.parse(route.params.to as string)
|
||||||
|
if (lastRoute.path != adminBaseRoutePath) {
|
||||||
|
let query = !isEmpty(lastRoute.query) ? lastRoute.query : {}
|
||||||
|
routePush({ path: lastRoute.path, query: query })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据name字符串,获取父级name组合的数组
|
* 根据name字符串,获取父级name组合的数组
|
||||||
* @param name
|
* @param name
|
||||||
|
|||||||
@@ -10,6 +10,15 @@
|
|||||||
<div class="device-control-right" v-if="deviceData">
|
<div class="device-control-right" v-if="deviceData">
|
||||||
<el-descriptions title="监测点信息" class="mb10" width="180" :column="3" border>
|
<el-descriptions title="监测点信息" class="mb10" width="180" :column="3" border>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
|
<!-- <el-button v-if="deviceType == '1'" type="primary" @click="handleDownLoadTemplate">
|
||||||
|
模版下载
|
||||||
|
</el-button> -->
|
||||||
|
<!-- <el-button v-if="deviceType == '1'" type="primary" icon="el-icon-Connection" @click="handleImport">
|
||||||
|
离线补召
|
||||||
|
</el-button>
|
||||||
|
<el-button v-if="deviceType == '1'" type="primary" icon="el-icon-Monitor" @click="handleaddDevice">
|
||||||
|
在线补召
|
||||||
|
</el-button> -->
|
||||||
<el-button
|
<el-button
|
||||||
v-if="deviceType == '1'"
|
v-if="deviceType == '1'"
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -36,6 +45,9 @@
|
|||||||
}}
|
}}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
<!-- <el-descriptions-item label="安装位置" width="160">
|
||||||
|
{{ devData.position || '/' }}
|
||||||
|
</el-descriptions-item> -->
|
||||||
|
|
||||||
<el-descriptions-item label="PT变比" width="160">
|
<el-descriptions-item label="PT变比" width="160">
|
||||||
{{ devData.ptRatio || '/' }}
|
{{ devData.ptRatio || '/' }}
|
||||||
@@ -44,9 +56,28 @@
|
|||||||
{{ devData.ctRatio || '/' }}
|
{{ devData.ctRatio || '/' }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
<!-- <el-descriptions-item label="名称">
|
||||||
|
{{ devData.name ? devData.name : '/' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="类型">
|
||||||
|
{{ echoName(devData.devType, devTypeOptions) }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
<el-descriptions-item label="接入方式">
|
||||||
|
{{ devData.devAccessMethod ? devData.devAccessMethod : '/' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="网络设备ID">
|
||||||
|
{{ devData.ndid ? devData.ndid : '/' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="型号">
|
||||||
|
{{ echoName(devData.devModel, devModelOptions) }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="接入日期">
|
||||||
|
{{ devData.time ? devData.time : '/' }}
|
||||||
|
</el-descriptions-item> -->
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
<el-tabs v-model.trim="dataSet" type="border-card" class="mb10" @tab-click="handleClick">
|
<el-tabs v-model.trim="dataSet" type="border-card" class="device-control-box-card" @tab-click="handleClick">
|
||||||
|
|
||||||
<el-tab-pane
|
<el-tab-pane
|
||||||
lazy
|
lazy
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
@@ -468,7 +499,7 @@
|
|||||||
v-if="dataSet.indexOf('_event') != -1"
|
v-if="dataSet.indexOf('_event') != -1"
|
||||||
v-loading="tableLoading"
|
v-loading="tableLoading"
|
||||||
>
|
>
|
||||||
<Event ref="eventRef" :device-type="deviceType"></Event>
|
<Event ref="eventRef"></Event>
|
||||||
</div>
|
</div>
|
||||||
<!-- 测试项记录 -->
|
<!-- 测试项记录 -->
|
||||||
<div
|
<div
|
||||||
@@ -898,7 +929,6 @@ const nodeClick = async (e: anyObj) => {
|
|||||||
const deviceType = ref('0')
|
const deviceType = ref('0')
|
||||||
const pointTypeChange = (val: any, obj: any) => {
|
const pointTypeChange = (val: any, obj: any) => {
|
||||||
deviceType.value = val
|
deviceType.value = val
|
||||||
console.log('pointTypeChange', val)
|
|
||||||
nodeClick(obj)
|
nodeClick(obj)
|
||||||
}
|
}
|
||||||
const realTimeRef: any = ref()
|
const realTimeRef: any = ref()
|
||||||
@@ -1390,7 +1420,9 @@ const echoName = (value: any, arr: any[]) => {
|
|||||||
return value ? arr.find(item => item.value == value)?.label : '/'
|
return value ? arr.find(item => item.value == value)?.label : '/'
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {})
|
onMounted(() => {
|
||||||
|
|
||||||
|
})
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
clearInterval(realDataTimer.value)
|
clearInterval(realDataTimer.value)
|
||||||
clearInterval(trendTimer.value)
|
clearInterval(trendTimer.value)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import TableStore from '@/utils/tableStore'
|
|||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import waveFormAnalysis from './components/waveFormAnalysis.vue'
|
import waveFormAnalysis from './components/waveFormAnalysis.vue'
|
||||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
import { ArrowLeft, Message } from '@element-plus/icons-vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { analyseWave,getFileByEventId } from '@/api/common'
|
import { analyseWave,getFileByEventId } from '@/api/common'
|
||||||
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
|
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
|
||||||
@@ -173,6 +173,7 @@ const tableStore: any = new TableStore({
|
|||||||
},
|
},
|
||||||
click: row => {
|
click: row => {
|
||||||
getFileByEventId(row.id).then(res => {
|
getFileByEventId(row.id).then(res => {
|
||||||
|
ElMessage.success(res.message)
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ const tableStore: any = new TableStore({
|
|||||||
{
|
{
|
||||||
field: 'engineeringName',
|
field: 'engineeringName',
|
||||||
title: '项目名称',
|
title: '项目名称',
|
||||||
minWidth: 170,
|
|
||||||
formatter: row => {
|
formatter: row => {
|
||||||
return row.cellValue ? row.cellValue : '/'
|
return row.cellValue ? row.cellValue : '/'
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ const tableStore: any = new TableStore({
|
|||||||
{
|
{
|
||||||
field: 'projectName',
|
field: 'projectName',
|
||||||
title: '工程名称',
|
title: '工程名称',
|
||||||
minWidth: 170,
|
|
||||||
formatter: row => {
|
formatter: row => {
|
||||||
return row.cellValue ? row.cellValue : '/'
|
return row.cellValue ? row.cellValue : '/'
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ const tableStore: any = new TableStore({
|
|||||||
{
|
{
|
||||||
field: 'deviceName',
|
field: 'deviceName',
|
||||||
title: '设备名称',
|
title: '设备名称',
|
||||||
minWidth: 170,
|
|
||||||
formatter: row => {
|
formatter: row => {
|
||||||
return row.cellValue ? row.cellValue : '/'
|
return row.cellValue ? row.cellValue : '/'
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ const tableStore: any = new TableStore({
|
|||||||
{
|
{
|
||||||
field: 'lineName',
|
field: 'lineName',
|
||||||
title: '监测点名称',
|
title: '监测点名称',
|
||||||
minWidth: 170,
|
|
||||||
formatter: row => {
|
formatter: row => {
|
||||||
return row.cellValue ? row.cellValue : '/'
|
return row.cellValue ? row.cellValue : '/'
|
||||||
}
|
}
|
||||||
@@ -73,15 +73,15 @@ const tableStore: any = new TableStore({
|
|||||||
{
|
{
|
||||||
field: 'logTime',
|
field: 'logTime',
|
||||||
title: '补召时间',
|
title: '补召时间',
|
||||||
minWidth: 170,
|
|
||||||
formatter: row => {
|
formatter: row => {
|
||||||
return row.cellValue ? row.cellValue : '/'
|
return row.cellValue ? row.cellValue : '/'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'log',
|
field: 'log',
|
||||||
title: '日志',
|
title: '类型',
|
||||||
minWidth: 170,
|
|
||||||
formatter: row => {
|
formatter: row => {
|
||||||
return row.cellValue ? row.cellValue : '/'
|
return row.cellValue ? row.cellValue : '/'
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,15 @@ const tableStore: any = new TableStore({
|
|||||||
{
|
{
|
||||||
field: 'status',
|
field: 'status',
|
||||||
title: '状态',
|
title: '状态',
|
||||||
minWidth: 170,
|
|
||||||
|
formatter: row => {
|
||||||
|
return row.cellValue ? row.cellValue : '/'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'result',
|
||||||
|
title: '结果',
|
||||||
|
|
||||||
formatter: row => {
|
formatter: row => {
|
||||||
return row.cellValue ? row.cellValue : '/'
|
return row.cellValue ? row.cellValue : '/'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
style="position: relative"
|
style="position: relative"
|
||||||
>
|
>
|
||||||
<!-- @init="nodeClick" -->
|
<!-- @init="nodeClick" -->
|
||||||
<PointTree @node-click="nodeClick" @checkChange="handleCheckedNodesChange"></PointTree>
|
<PointTree @node-click="nodeClick" @init="nodeClick" @checkChange="handleCheckedNodesChange"></PointTree>
|
||||||
<div class="device-control-right" >
|
<div class="device-control-right" >
|
||||||
<el-tabs type="border-card" class="mb10" @tab-click="handleClick" v-model="activeTab">
|
<el-tabs type="border-card" class="mb10" @tab-click="handleClick" v-model="activeTab">
|
||||||
<el-tab-pane label="稳态补召" name="deviceInfo1">
|
<el-tab-pane label="稳态补召" name="deviceInfo1">
|
||||||
@@ -42,7 +42,7 @@ const checkedNodes = ref<any[]>([]) // 存储左侧树勾选的节点
|
|||||||
const currentNode = ref<any>(null) // 存储当前点击的树节点
|
const currentNode = ref<any>(null) // 存储当前点击的树节点
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'govern/monitorRecall/index'
|
name: '/cs-device-boot/monitorRecall'
|
||||||
})
|
})
|
||||||
|
|
||||||
// 处理子组件传递的勾选节点变化
|
// 处理子组件传递的勾选节点变化
|
||||||
@@ -78,6 +78,7 @@ const triggerEventRecallQuery = () => {
|
|||||||
if (activeTab.value === 'deviceInfo2' && eventRef.value) {
|
if (activeTab.value === 'deviceInfo2' && eventRef.value) {
|
||||||
// 将当前点击的节点传递给暂态补召组件
|
// 将当前点击的节点传递给暂态补召组件
|
||||||
if (eventRef.value.handleTreeNodeClick) {
|
if (eventRef.value.handleTreeNodeClick) {
|
||||||
|
|
||||||
eventRef.value.handleTreeNodeClick(currentNode.value)
|
eventRef.value.handleTreeNodeClick(currentNode.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,7 +86,7 @@ const triggerEventRecallQuery = () => {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
.device-control {
|
.device-control {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
161
src/views/pqs/cockpit/homePage/components/routingConfig.vue
Normal file
161
src/views/pqs/cockpit/homePage/components/routingConfig.vue
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-dialog v-model="dialogVisible" title="设置" width="600">
|
||||||
|
<div style="display: flex; justify-content: end" class="mb10">
|
||||||
|
<el-button icon="el-icon-Plus" type="primary" @click="add">新增</el-button>
|
||||||
|
</div>
|
||||||
|
<div style="height: calc(100vh / 2); max-height: 400px">
|
||||||
|
<vxe-table
|
||||||
|
border
|
||||||
|
ref="tableRef"
|
||||||
|
:data="pageList.filter((item: any) => item.pagePath != 'dashboard/index')"
|
||||||
|
align="center"
|
||||||
|
height="auto"
|
||||||
|
v-bind="defaultAttribute"
|
||||||
|
>
|
||||||
|
<vxe-column field="pageName" title="菜单名称"></vxe-column>
|
||||||
|
|
||||||
|
<vxe-column field="icon" title="图标" width="80">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<Icon class="ba-icon-dark" :name="row.icon || ''" />
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
<vxe-column field="startTime" title="是否激活">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-switch
|
||||||
|
v-model="row.state"
|
||||||
|
inline-prompt
|
||||||
|
:active-value="1"
|
||||||
|
:inactive-value="0"
|
||||||
|
active-text="已激活"
|
||||||
|
inactive-text="未激活"
|
||||||
|
:before-change="() => beforeChange(row)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
<vxe-column field="startTime" title="操作">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button type="primary" link @click="edit(row)">编辑</el-button>
|
||||||
|
|
||||||
|
<el-button type="danger" link @click="deletes(row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
</vxe-table>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||||
|
import { getDashboardPageByUserId, deleteDashboard, activatePage } from '@/api/system-boot/csstatisticalset'
|
||||||
|
import { useAdminInfo } from '@/stores/adminInfo'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
|
||||||
|
import { getMenu } from '@/utils/router'
|
||||||
|
|
||||||
|
const { push } = useRouter()
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const route = useRouter()
|
||||||
|
const adminInfo = useAdminInfo()
|
||||||
|
const pageList: any = ref([])
|
||||||
|
|
||||||
|
const open = () => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
const init = () => {
|
||||||
|
getDashboardPageByUserId({ id: adminInfo.id, state: false }).then(res => {
|
||||||
|
pageList.value = res.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 新增
|
||||||
|
const add = () => {
|
||||||
|
push(`/admin/cockpit/popup?path=${String(getNextPagePath(pageList.value))}`)
|
||||||
|
}
|
||||||
|
// 修改
|
||||||
|
const edit = (row: any) => {
|
||||||
|
push(`/admin/cockpit/popup?id=${row?.id}&&path=${row.pagePath}`)
|
||||||
|
}
|
||||||
|
// 激活
|
||||||
|
const beforeChange = (row: any): Promise<boolean> => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
// setTimeout(() => {
|
||||||
|
// loading1.value = false
|
||||||
|
// ElMessage.success('Switch success')
|
||||||
|
// return resolve(true)
|
||||||
|
// }, 1000)
|
||||||
|
ElMessageBox.confirm('此操作将激活该页面, 是否继续?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
activatePage({ id: row.id, state: row.state == 0 ? 1 : 0 }).then((res: any) => {
|
||||||
|
if (res.code == 'A0000') {
|
||||||
|
ElMessage({
|
||||||
|
type: 'success',
|
||||||
|
message: '操作成功!'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
init()
|
||||||
|
resolve(true)
|
||||||
|
getMenu()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
ElMessage({
|
||||||
|
type: 'info',
|
||||||
|
message: '已取消删除'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 删除
|
||||||
|
const deletes = (row: any) => {
|
||||||
|
ElMessageBox.confirm('此操作将永久删除该菜单, 是否继续?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
deleteDashboard({ id: row.id }).then((res: any) => {
|
||||||
|
if (res.code == 'A0000') {
|
||||||
|
ElMessage({
|
||||||
|
type: 'success',
|
||||||
|
message: '删除页面成功!'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
init()
|
||||||
|
getMenu()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
ElMessage({
|
||||||
|
type: 'info',
|
||||||
|
message: '已取消删除'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function getNextPagePath(pages: any) {
|
||||||
|
// 提取所有pagePath中的数字部分
|
||||||
|
const numbers = pages.map((page: any) => {
|
||||||
|
const match = page.pagePath.match(/dashboard\/index(\d*)$/)
|
||||||
|
if (match && match[1]) {
|
||||||
|
return parseInt(match[1], 10)
|
||||||
|
}
|
||||||
|
return 0 // 没有数字时视为0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 找到最大数字并加1
|
||||||
|
const maxNum = Math.max(...numbers)
|
||||||
|
const nextNum = maxNum + 1
|
||||||
|
|
||||||
|
// 生成下一个pagePath
|
||||||
|
return `dashboard/index${nextNum}`
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@@ -1,12 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main">
|
<div class="default-main">
|
||||||
<TableHeader :showSearch="false">
|
<TableHeader :showSearch="false" v-if="flag">
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="日期">
|
<el-form-item label="日期">
|
||||||
<DatePicker ref="datePickerRef" :nextFlag="false" :theCurrentTime="true"></DatePicker>
|
<DatePicker ref="datePickerRef" :nextFlag="false" :theCurrentTime="true"></DatePicker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-slot:operation>
|
||||||
|
<el-button type="primary" icon="el-icon-Edit" @click="editd">编辑</el-button>
|
||||||
|
<el-button type="primary" icon="el-icon-Tools" @click="settings">设置</el-button>
|
||||||
|
</template>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
|
|
||||||
<GridLayout
|
<GridLayout
|
||||||
v-model:layout="layout"
|
v-model:layout="layout"
|
||||||
:row-height="rowHeight"
|
:row-height="rowHeight"
|
||||||
@@ -21,66 +26,74 @@
|
|||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<div style="display: flex; align-items: center">
|
<div style="display: flex; align-items: center">
|
||||||
<Icon class="HelpFilled" :name="item.icon" />
|
<Icon class="HelpFilled" :name="(item as LayoutItem).icon" />
|
||||||
{{ item.name }}
|
{{ (item as LayoutItem).name }}
|
||||||
</div>
|
</div>
|
||||||
<!-- <FullScreen class="HelpFilled" style="cursor: pointer" @click="zoom(item)" /> -->
|
<!-- <FullScreen class="HelpFilled" style="cursor: pointer" @click="zoom(item)" /> -->
|
||||||
<img :src="flag ? img : img1" style="cursor: pointer; height: 16px" @click="zoom(item)" />
|
<img :src="flag ? img : img1" style="cursor: pointer; height: 16px" @click="zoom(item)" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<component
|
<component
|
||||||
:is="item.component"
|
:is="(item as LayoutItem).component"
|
||||||
v-if="item.component"
|
v-if="(item as LayoutItem).component"
|
||||||
class="pd10"
|
class="pd10"
|
||||||
:key="key"
|
:key="key"
|
||||||
:timeValue="datePickerRef.timeValue"
|
:timeValue="datePickerRef?.timeValue || 3"
|
||||||
:height="rowHeight * item.h - seRowHeight(item.h) + 'px'"
|
:height="rowHeight * item.h - seRowHeight(item.h) + 'px'"
|
||||||
:width="rowWidth * item.w - 30 + 'px'"
|
:width="rowWidth * item.w - 30 + 'px'"
|
||||||
:timeKey="item.timeKey"
|
:timeKey="(item as LayoutItem).timeKey"
|
||||||
|
:w="item.w"
|
||||||
|
:h="item.h"
|
||||||
/>
|
/>
|
||||||
<div v-else class="pd10">组件加载失败...</div>
|
<div v-else class="pd10">组件加载失败...</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
|
<!-- 设置 -->
|
||||||
|
<RoutingConfig ref="RoutingConfigRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted, markRaw, onUnmounted, defineAsyncComponent, type Component } from 'vue'
|
import { ref, reactive, onMounted, markRaw, onUnmounted, computed, defineAsyncComponent, type Component } from 'vue'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import { GridLayout } from 'grid-layout-plus'
|
import { GridLayout } from 'grid-layout-plus'
|
||||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||||
import { useDebounceFn } from '@vueuse/core'
|
import { useDebounceFn } from '@vueuse/core'
|
||||||
import { queryActivatePage, queryByPagePath } from '@/api/system-boot/csstatisticalset'
|
import { queryActivatePage, queryByPagePath } from '@/api/system-boot/csstatisticalset'
|
||||||
import { HelpFilled, FullScreen } from '@element-plus/icons-vue'
|
import RoutingConfig from '@/views/pqs/cockpit/homePage/components/routingConfig.vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
const { push } = useRouter()
|
||||||
const datePickerRef = ref()
|
const datePickerRef = ref()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
// defineOptions({
|
defineOptions({
|
||||||
// name: 'cockpit/homePage'
|
// name: 'dashboard/index'
|
||||||
// })
|
})
|
||||||
// 定义类型
|
// 定义类型
|
||||||
interface LayoutItem {
|
interface LayoutItem {
|
||||||
x: number
|
x: number
|
||||||
y: number
|
y: number
|
||||||
w: number
|
w: number
|
||||||
h: number
|
h: number
|
||||||
|
timeKey: number | string
|
||||||
i: string | number
|
i: string | number
|
||||||
name: string
|
name: string
|
||||||
path: string
|
path: string
|
||||||
|
icon?: string // 新增 icon 可选字段
|
||||||
component?: Component | string
|
component?: Component | string
|
||||||
loading?: boolean
|
loading?: boolean
|
||||||
error?: any
|
error?: any
|
||||||
}
|
}
|
||||||
|
const RoutingConfigRef = ref()
|
||||||
const key = ref(0)
|
const key = ref(0)
|
||||||
const img = new URL(`@/assets/img/amplify.png`, import.meta.url)
|
const img = new URL(`@/assets/img/amplify.png`, import.meta.url).href
|
||||||
const img1 = new URL(`@/assets/img/reduce.png`, import.meta.url)
|
const img1 = new URL(`@/assets/img/reduce.png`, import.meta.url).href
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
const rowHeight = ref(0)
|
const rowHeight = ref(0)
|
||||||
const rowWidth = ref(0)
|
const rowWidth = ref(0)
|
||||||
const layout = ref<LayoutItem[]>([
|
const layout: any = ref([
|
||||||
// {
|
// {
|
||||||
// x: 4,
|
// x: 4,
|
||||||
// y: 0,
|
// y: 0,
|
||||||
@@ -91,11 +104,11 @@ const layout = ref<LayoutItem[]>([
|
|||||||
// path: '/src/views/pqs/runManage/assessment/components/uese/index.vue'
|
// path: '/src/views/pqs/runManage/assessment/components/uese/index.vue'
|
||||||
// },
|
// },
|
||||||
])
|
])
|
||||||
const layoutCopy = ref<LayoutItem[]>([])
|
const layoutCopy: any = ref([])
|
||||||
const flag = ref(true)
|
const flag = ref(true)
|
||||||
// 组件映射
|
// 组件映射
|
||||||
const componentMap = reactive(new Map<string, Component | string>())
|
const componentMap = reactive(new Map<string, Component | string>())
|
||||||
|
const dataList: any = ref({})
|
||||||
// 获取主内容区域高度
|
// 获取主内容区域高度
|
||||||
const getMainHeight = () => {
|
const getMainHeight = () => {
|
||||||
const elMain = document.querySelector('.el-main')
|
const elMain = document.querySelector('.el-main')
|
||||||
@@ -109,7 +122,7 @@ const getMainWidth = () => {
|
|||||||
|
|
||||||
// 初始化行高
|
// 初始化行高
|
||||||
const initRowHeight = () => {
|
const initRowHeight = () => {
|
||||||
rowHeight.value = Math.max(0, (getMainHeight() - 72) / 6)
|
rowHeight.value = Math.max(0, (getMainHeight() - 77 + (flag.value ? 0 : 56)) / 6)
|
||||||
rowWidth.value = Math.max(0, getMainWidth() / 12)
|
rowWidth.value = Math.max(0, getMainWidth() / 12)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,13 +166,14 @@ const zoom = (value: any) => {
|
|||||||
if (flag.value) {
|
if (flag.value) {
|
||||||
layout.value = [{ ...value, x: 0, y: 0, w: 12, h: 6 }]
|
layout.value = [{ ...value, x: 0, y: 0, w: 12, h: 6 }]
|
||||||
} else {
|
} else {
|
||||||
layout.value = layoutCopy.value.map((item, index) => ({
|
layout.value = layoutCopy.value.map((item:any, index: number) => ({
|
||||||
...item,
|
...item,
|
||||||
i: item.i || index, // 确保有唯一标识
|
i: item.i || index, // 确保有唯一标识
|
||||||
component: registerComponent(item.path)
|
component: registerComponent(item.path)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
flag.value = !flag.value
|
flag.value = !flag.value
|
||||||
|
initRowHeight()
|
||||||
key.value += 1
|
key.value += 1
|
||||||
}
|
}
|
||||||
// 计算组件高度
|
// 计算组件高度
|
||||||
@@ -177,6 +191,7 @@ const seRowHeight = (value: any) => {
|
|||||||
const fetchLayoutData = async () => {
|
const fetchLayoutData = async () => {
|
||||||
try {
|
try {
|
||||||
const { data } = await queryByPagePath({ pagePath: router.currentRoute.value.name })
|
const { data } = await queryByPagePath({ pagePath: router.currentRoute.value.name })
|
||||||
|
dataList.value = data
|
||||||
const parsedLayout = JSON.parse(data.containerConfig || '[]') as LayoutItem[]
|
const parsedLayout = JSON.parse(data.containerConfig || '[]') as LayoutItem[]
|
||||||
// 处理布局数据
|
// 处理布局数据
|
||||||
layout.value = parsedLayout.map((item, index) => ({
|
layout.value = parsedLayout.map((item, index) => ({
|
||||||
@@ -185,6 +200,7 @@ const fetchLayoutData = async () => {
|
|||||||
component: registerComponent(item.path)
|
component: registerComponent(item.path)
|
||||||
}))
|
}))
|
||||||
layoutCopy.value = JSON.parse(JSON.stringify(layout.value))
|
layoutCopy.value = JSON.parse(JSON.stringify(layout.value))
|
||||||
|
initRowHeight()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取布局数据失败:', error)
|
console.error('获取布局数据失败:', error)
|
||||||
// 可以添加错误提示逻辑
|
// 可以添加错误提示逻辑
|
||||||
@@ -197,9 +213,21 @@ const handleResize = useDebounceFn(() => {
|
|||||||
key.value += 1
|
key.value += 1
|
||||||
}, 200)
|
}, 200)
|
||||||
|
|
||||||
|
// 修改
|
||||||
|
const editd = (e: any) => {
|
||||||
|
if (dataList.value?.id) {
|
||||||
|
push(`/admin/cockpit/popup?id=${dataList.value?.id}&&path=${String(router.currentRoute.value.name)}`)
|
||||||
|
} else {
|
||||||
|
push(`/admin/cockpit/popup?path=${String(router.currentRoute.value.name)}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 设置
|
||||||
|
const settings = () => {
|
||||||
|
RoutingConfigRef.value.open()
|
||||||
|
}
|
||||||
// 生命周期钩子
|
// 生命周期钩子
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initRowHeight()
|
// initRowHeight()
|
||||||
fetchLayoutData()
|
fetchLayoutData()
|
||||||
|
|
||||||
// 添加窗口大小变化监听器
|
// 添加窗口大小变化监听器
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-card class="bottom-container " style="flex: 1;min-height: 165px;">
|
<el-card class="bottom-container " style="min-height: 230px;">
|
||||||
<div class="buttonBox">
|
<div class="buttonBox">
|
||||||
<el-button type="primary" icon="el-icon-Aim">复位</el-button>
|
<el-button type="primary" icon="el-icon-Aim">复位</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,31 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="pd10">
|
<div class="pd10">
|
||||||
<el-card>
|
<el-card>
|
||||||
<el-form ref="formRef" inline :rules="rules" :model="form" label-width="120px" class="form-four">
|
<el-form ref="formRef" inline :rules="rules" :model="form" label-width="auto" class="form-four">
|
||||||
<el-form-item label="页面名称" prop="pageName">
|
<el-form-item label="页面名称" prop="pageName">
|
||||||
<el-input
|
<el-input
|
||||||
|
style="width: 100%"
|
||||||
maxlength="32"
|
maxlength="32"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
v-model.trim="form.pageName"
|
v-model.trim="form.pageName"
|
||||||
placeholder="请输入页面名称"
|
placeholder="请输入页面名称"
|
||||||
></el-input>
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="图标">
|
||||||
<el-form-item label="页面排序" prop="sort">
|
<IconSelector v-model.trim="form.icon" style="width: 80%" placeholder="请选择图标" />
|
||||||
<el-input
|
|
||||||
maxlength="32"
|
|
||||||
show-word-limit-number
|
|
||||||
v-model.trim.number="form.sort"
|
|
||||||
:min="0"
|
|
||||||
:step="1"
|
|
||||||
step-strictly
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="绑定页面">
|
<el-form-item label="页面排序" prop="sort">
|
||||||
|
<el-input-number style="width: 100%" v-model.trim="form.sort" :min="0" :max="10000" :step="1" />
|
||||||
|
</el-form-item>
|
||||||
|
<!-- <el-form-item label="绑定页面">
|
||||||
<el-select v-model="form.pagePath" filterable placeholder="请选择绑定页面" style="width: 100%" clearable>
|
<el-select v-model="form.pagePath" filterable placeholder="请选择绑定页面" style="width: 100%" clearable>
|
||||||
<el-option v-for="item in pageList" :key="item.path" :label="item.name" :value="item.path" />
|
<el-option v-for="item in pageList" :key="item.path" :label="item.name" :value="item.path" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item> -->
|
||||||
|
|
||||||
<el-form-item label="备注" class="top">
|
<el-form-item label="备注" class="top">
|
||||||
<el-input
|
<el-input
|
||||||
@@ -91,6 +87,7 @@
|
|||||||
<template #item="{ item }">
|
<template #item="{ item }">
|
||||||
<div class="imgBox">
|
<div class="imgBox">
|
||||||
<div class="textName">{{ item.name }}</div>
|
<div class="textName">{{ item.name }}</div>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
:src="getImg(item.path)"
|
:src="getImg(item.path)"
|
||||||
:style="{
|
:style="{
|
||||||
@@ -110,6 +107,7 @@
|
|||||||
'px'
|
'px'
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<CloseBold class="remove" @click="removeItem(item.i)" />
|
<CloseBold class="remove" @click="removeItem(item.i)" />
|
||||||
</div>
|
</div>
|
||||||
<!-- <span class="text">{{ `${item?.name}` }}</span>
|
<!-- <span class="text">{{ `${item?.name}` }}</span>
|
||||||
@@ -127,6 +125,7 @@ import { useRouter } from 'vue-router'
|
|||||||
import BackComponent from '@/components/icon/back/index.vue'
|
import BackComponent from '@/components/icon/back/index.vue'
|
||||||
import { mainHeight } from '@/utils/layout'
|
import { mainHeight } from '@/utils/layout'
|
||||||
import type { CollapseIconPositionType } from 'element-plus'
|
import type { CollapseIconPositionType } from 'element-plus'
|
||||||
|
import IconSelector from '@/components/baInput/components/iconSelector.vue'
|
||||||
import { componentTree } from '@/api/user-boot/user'
|
import { componentTree } from '@/api/user-boot/user'
|
||||||
import { GridLayout, GridItem } from 'grid-layout-plus'
|
import { GridLayout, GridItem } from 'grid-layout-plus'
|
||||||
import { throttle } from 'lodash-es'
|
import { throttle } from 'lodash-es'
|
||||||
@@ -135,7 +134,7 @@ import { Tools, CloseBold } from '@element-plus/icons-vue'
|
|||||||
import { addDashboard, updateDashboard, queryById } from '@/api/system-boot/csstatisticalset'
|
import { addDashboard, updateDashboard, queryById } from '@/api/system-boot/csstatisticalset'
|
||||||
import html2canvas from 'html2canvas'
|
import html2canvas from 'html2canvas'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
import { getMenu } from '@/utils/router'
|
||||||
// defineOptions({
|
// defineOptions({
|
||||||
// name: 'cockpit/popup'
|
// name: 'cockpit/popup'
|
||||||
// })
|
// })
|
||||||
@@ -154,9 +153,11 @@ const form: any = reactive({
|
|||||||
containerConfig: [],
|
containerConfig: [],
|
||||||
sort: '100',
|
sort: '100',
|
||||||
id: '',
|
id: '',
|
||||||
|
|
||||||
|
icon: '',
|
||||||
pagePath: '',
|
pagePath: '',
|
||||||
pathName: '',
|
remark: '',
|
||||||
remark: ''
|
routeName: '/src/views/pqs/cockpit/homePage/index.vue'
|
||||||
})
|
})
|
||||||
const activeNames = ref([])
|
const activeNames = ref([])
|
||||||
const activeNames1 = ref([])
|
const activeNames1 = ref([])
|
||||||
@@ -204,12 +205,14 @@ const info = () => {
|
|||||||
queryById({ id: query.id }).then(res => {
|
queryById({ id: query.id }).then(res => {
|
||||||
layout.value = JSON.parse(res.data.containerConfig)
|
layout.value = JSON.parse(res.data.containerConfig)
|
||||||
form.pageName = res.data.pageName
|
form.pageName = res.data.pageName
|
||||||
form.pagePath = res.data.pagePath
|
form.pagePath = query.path || res.data.pagePath
|
||||||
form.pathName = res.data.pathName
|
|
||||||
form.sort = res.data.sort
|
form.sort = res.data.sort
|
||||||
form.remark = res.data.remark
|
form.remark = res.data.remark
|
||||||
form.id = res.data.id
|
form.id = res.data.id
|
||||||
|
form.icon = res.data.icon
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
form.pagePath = query.path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,7 +311,6 @@ const drag = throttle(row => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function dragEnd(row: any) {
|
function dragEnd(row: any) {
|
||||||
console.log('🚀 ~ drag ~ row:', row)
|
|
||||||
const parentRect = wrapper.value?.getBoundingClientRect()
|
const parentRect = wrapper.value?.getBoundingClientRect()
|
||||||
|
|
||||||
if (!parentRect || !gridLayout.value) return
|
if (!parentRect || !gridLayout.value) return
|
||||||
@@ -331,7 +333,7 @@ function dragEnd(row: any) {
|
|||||||
y: dragItem.y,
|
y: dragItem.y,
|
||||||
w: dragItem.w,
|
w: dragItem.w,
|
||||||
h: dragItem.h,
|
h: dragItem.h,
|
||||||
i: dragItem.i,
|
i: Math.random(), //dragItem.i,
|
||||||
name: row.name,
|
name: row.name,
|
||||||
path: row.path,
|
path: row.path,
|
||||||
icon: row.icon,
|
icon: row.icon,
|
||||||
@@ -349,10 +351,10 @@ const onSubmit = () => {
|
|||||||
if (layout.value.length == 0) {
|
if (layout.value.length == 0) {
|
||||||
return ElMessage.warning('页面设计不能为空!')
|
return ElMessage.warning('页面设计不能为空!')
|
||||||
}
|
}
|
||||||
const maxValue = Math.max(...layout.value.map(item => item.y + item.h))
|
// const maxValue = Math.max(...layout.value.map(item => item.y + item.h))
|
||||||
if (maxValue > 6) {
|
// if (maxValue > 6) {
|
||||||
return ElMessage.warning('组件不能超出当前容器!')
|
// return ElMessage.warning('组件不能超出当前容器!')
|
||||||
}
|
// }
|
||||||
|
|
||||||
formRef.value.validate(async (valid: boolean) => {
|
formRef.value.validate(async (valid: boolean) => {
|
||||||
let url = ''
|
let url = ''
|
||||||
@@ -362,7 +364,6 @@ const onSubmit = () => {
|
|||||||
url = canvas.toDataURL('image/png')
|
url = canvas.toDataURL('image/png')
|
||||||
})
|
})
|
||||||
form.pagePath = form.pagePath || ''
|
form.pagePath = form.pagePath || ''
|
||||||
form.pathName = pageList.value.filter((item: any) => item.path == form.pagePath)?.[0]?.name || ''
|
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (form.id == '') {
|
if (form.id == '') {
|
||||||
@@ -370,6 +371,7 @@ const onSubmit = () => {
|
|||||||
(res: any) => {
|
(res: any) => {
|
||||||
ElMessage.success('新增页面成功!')
|
ElMessage.success('新增页面成功!')
|
||||||
go(-1)
|
go(-1)
|
||||||
|
getMenu()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@@ -377,6 +379,7 @@ const onSubmit = () => {
|
|||||||
(res: any) => {
|
(res: any) => {
|
||||||
ElMessage.success('修改页面成功!')
|
ElMessage.success('修改页面成功!')
|
||||||
go(-1)
|
go(-1)
|
||||||
|
getMenu()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -386,6 +389,7 @@ const onSubmit = () => {
|
|||||||
const getImg = throttle((path: string) => {
|
const getImg = throttle((path: string) => {
|
||||||
if (path != undefined) return treeComponentsCopy.value.filter(item => item.path == path)[0]?.image
|
if (path != undefined) return treeComponentsCopy.value.filter(item => item.path == path)[0]?.image
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
info()
|
info()
|
||||||
|
|
||||||
@@ -460,7 +464,9 @@ onBeforeUnmount(() => {
|
|||||||
.vgl-layout {
|
.vgl-layout {
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
}
|
}
|
||||||
|
:deep(.el-input-group) {
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
.remove {
|
.remove {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
@@ -486,4 +492,7 @@ onBeforeUnmount(() => {
|
|||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
}
|
}
|
||||||
|
:deep(.el-form--inline .el-form-item) {
|
||||||
|
margin-right: 0px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -31,12 +31,7 @@
|
|||||||
>
|
>
|
||||||
{{ item.pageName }}
|
{{ item.pageName }}
|
||||||
</span>
|
</span>
|
||||||
<div style="display: flex; align-items: center; font-weight: 550">
|
|
||||||
<div v-if="item.pathName" :style="{ color: `var(--el-color-primary)` }">
|
|
||||||
绑定页面:{{ item.pathName }}
|
|
||||||
</div>
|
|
||||||
<div v-else>暂未绑定</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="display: flex; justify-content: end">
|
<div style="display: flex; justify-content: end">
|
||||||
<!-- <el-button
|
<!-- <el-button
|
||||||
|
|||||||
@@ -32,11 +32,11 @@
|
|||||||
<el-input v-model="form.sort" placeholder="请输入组件排序"></el-input>
|
<el-input v-model="form.sort" placeholder="请输入组件排序"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div style="width: 600px; height: 360px; overflow: hidden">
|
<div style="width: 600px; height: 390px; overflow: hidden">
|
||||||
<div class="ml10" style="font-weight: 600">组件展示</div>
|
<div class="ml10" style="font-weight: 600">组件展示</div>
|
||||||
<component :is="registerComponent(form.path)" v-if="registerComponent(form.path)"
|
<component :is="registerComponent(form.path)" v-if="registerComponent(form.path)"
|
||||||
class="pd10 GridLayout" :key="form.path" :height="'350px'" :width="'580px'"
|
class="pd10 GridLayout" :key="form.path" :height="'350px'" :width="'580px'"
|
||||||
:timeKey="form.timeKey" />
|
:timeKey="form.timeKey" :w="12" :h="6"/>
|
||||||
<!-- <div class="pd10">组件加载失败...</div> -->
|
<!-- <div class="pd10">组件加载失败...</div> -->
|
||||||
<el-empty v-else description="未查询到组件" style="height: 350px; width: 533px" />
|
<el-empty v-else description="未查询到组件" style="height: 350px; width: 533px" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user