2024-06-22 10:54:02 +08:00
|
|
|
<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";
|
2024-07-23 12:51:10 +08:00
|
|
|
import { Atom ,LineChart,Combine} from 'lucide-vue-next';
|
2024-06-22 10:54:02 +08:00
|
|
|
|
|
|
|
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">
|
2024-07-23 12:51:10 +08:00
|
|
|
<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>
|
2024-06-22 10:54:02 +08:00
|
|
|
</template>
|
2024-07-23 12:51:10 +08:00
|
|
|
</n-float-button >
|
|
|
|
<n-modal
|
|
|
|
v-model:show="visible"
|
2024-07-23 17:34:23 +08:00
|
|
|
style="width: auto;"
|
2024-07-23 12:51:10 +08:00
|
|
|
>
|
|
|
|
<SettingCard />
|
|
|
|
</n-modal>
|
|
|
|
<n-modal
|
|
|
|
v-model:show="cardVisible"
|
|
|
|
preset="card"
|
|
|
|
style="width: 500px"
|
|
|
|
>
|
|
|
|
<AddCard/>
|
|
|
|
</n-modal>
|
2024-06-22 10:54:02 +08:00
|
|
|
<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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-07-02 14:28:15 +08:00
|
|
|
|
2024-06-22 10:54:02 +08:00
|
|
|
.vgl-layout {
|
|
|
|
margin: -10px;
|
|
|
|
}
|
2024-07-02 14:28:15 +08:00
|
|
|
:deep(.speed-button){
|
|
|
|
position: fixed;
|
|
|
|
right: 30px;
|
|
|
|
bottom: 40px;
|
|
|
|
z-index: 100;
|
|
|
|
gap: 5px;
|
|
|
|
.p-speeddial-list{
|
|
|
|
gap: 5px;
|
|
|
|
}
|
|
|
|
}
|
2024-06-22 10:54:02 +08:00
|
|
|
</style>
|