LoongPanel-Asp/web/components/Grid/MainGrid.vue

180 lines
4.9 KiB
Vue

<script lang="ts" setup>
import {GridItem, GridLayout} from 'grid-layout-plus'
import ICard from "~/components/Cards/ICard.vue";
import IChart from "~/components/Cards/IChart.vue";
import {type IGridItem, type Layouts, useMainLayoutStore} from "~/strores/UseMainLayoutStore";
import {UseDraggable} from '@vueuse/components'
import AddCard from "~/components/AddCard.vue";
import {type dataHistoryType, useDataStore} from "~/strores/DataStore";
import _ from "lodash";
import {useLoadStore} from "~/strores/LoadStore";
import type {HttpType} from "~/types/baseType";
import type {UserInfoType} from "~/types/UserType";
import {deepEqual} from "~/utils";
import { Atom ,LineChart,Combine} from 'lucide-vue-next';
const layout = ref<IGridItem[]>([])
const presetLayouts = ref<Layouts>(<Layouts>{})
const {width, height} = useWindowSize()
const el = ref(null)
const {width: gridWidth, height: gridHeight} = useElementSize(el)
const mainLayoutStore = useMainLayoutStore()
const loadStore = useLoadStore()
const dataStore = useDataStore()
onMounted(() => {
layout.value = mainLayoutStore.LayoutsConfig.lg
presetLayouts.value = mainLayoutStore.LayoutsConfig
console.log(layout.value)
console.log(presetLayouts.value)
})
const visible = ref(false)
const cardVisible = ref(false)
const layoutChangedEvent = _.throttle((newLayout: IGridItem[]) => {
let breakPoint = 'lg';
//计算对应的breakPoint
if (gridWidth.value <= 1200) {
breakPoint = 'md';
}
if (gridWidth.value <= 992) {
breakPoint = 'sm';
}
if (gridWidth.value <= 768) {
breakPoint = 'xs';
}
mainLayoutStore.LayoutsConfig[breakPoint] = newLayout;
presetLayouts.value[breakPoint] = newLayout;
}, 500)
onMounted(() => {
$fetch('/Api/User/GetLayoutConfig', {
method: 'POST',
responseType: "json",
body: {
layout: JSON.stringify(mainLayoutStore.LayoutsConfig),
},
headers: {
'Authorization': 'Bearer ' + useCookie('token').value
},
baseURL: useRuntimeConfig().public.baseUrl,
}).then((res) => {
if (res === 'null') return;
const data = JSON.parse(res as string) as Layouts
console.log(data)
mainLayoutStore.LayoutsConfig = data;
presetLayouts.value = data;
if (loadStore.LayoutLoad) return;
loadStore.LayoutLoad = true
window.location.reload()
})
})
watchDebounced(
layout,
() => {
$fetch('/Api/User/PutLayoutConfig', {
method: 'PUT',
body: {
Layout: JSON.stringify(mainLayoutStore.LayoutsConfig),
},
headers: {
'Authorization': 'Bearer ' + useCookie('token').value
},
baseURL: useRuntimeConfig().public.baseUrl,
}).catch((err) => {
console.log(err)
})
},
{debounce: 15000, maxWait: 60000}
)
</script>
<template>
<div class="main-grid-layout">
<n-float-button :right="42" :bottom="90" position="fixed" style="z-index: 200" type="primary" menu-trigger="hover">
<n-icon>
<Atom/>
</n-icon>
<template #menu>
<n-float-button @click=" visible = true" >
<n-icon>
<LineChart/>
</n-icon>
</n-float-button>
<n-float-button @click="cardVisible = true">
<n-icon>
<Combine />
</n-icon>
</n-float-button>
</template>
</n-float-button >
<n-modal
v-model:show="visible"
style="width: auto;"
preset="card"
title="添加图表"
>
<SettingCard />
</n-modal>
<n-modal
v-model:show="cardVisible"
preset="card"
style="width: 500px"
>
<AddCard/>
</n-modal>
<GridLayout
ref="el"
v-model:layout="layout"
:breakpoints="{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }"
:col-num="16"
:cols="{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }"
:responsive-layouts="presetLayouts"
:row-height="30"
is-draggable
is-resizables
responsive
use-css-transforms
vertical-compact
@layoutUpdated="layoutChangedEvent"
>
<GridItem
v-for="item in layout"
:key="item.i"
:h="item.h"
:i="item.i"
:w="item.w"
:x="item.x"
:y="item.y"
drag-allow-from=".vue-draggable-handle"
drag-ignore-from=".no-drag"
>
<IChart v-if="item.type==='chart'&&item.serverValues&&item.selectChart" :id="String(item.i)"
:chart="item.selectChart"
:title="item.cardConfig?.['name'].value??'默认标题'" :values="item.serverValues"/>
<ICard v-if="item.type==='card'&&item.selectCard" :id="String(item.i)" :card-id="item.selectCard"/>
</GridItem>
</GridLayout>
</div>
</template>
<style lang="scss" scoped>
.main-grid-layout {
//min-width: 950px;
}
.vgl-layout {
margin: -10px;
}
:deep(.speed-button){
position: fixed;
right: 30px;
bottom: 40px;
z-index: 100;
gap: 5px;
.p-speeddial-list{
gap: 5px;
}
}
</style>