feat: 新增工作区域内容模块

This commit is contained in:
MTrun 2022-01-20 21:25:35 +08:00
parent cb14424110
commit 20a1866923
27 changed files with 398 additions and 106 deletions

View File

@ -2,8 +2,4 @@
<div>
<Skeleton :repeat="3" :load="true"/>
</div>
</template>
<script setup lang="ts">
import { Skeleton } from '@/components/Skeleton/index'
</script>
</template>

View File

@ -1,5 +1,6 @@
import type { App } from 'vue'
import { Skeleton } from '@/components/Skeleton'
import { LoadingComponent } from '@/components/LoadingComponent'
/**
*
@ -7,4 +8,5 @@ import { Skeleton } from '@/components/Skeleton'
*/
export function setupCustomComponents(app: App) {
app.component('Skeleton', Skeleton)
app.component('LoadingComponent', LoadingComponent)
}

View File

@ -1,3 +1,50 @@
// 编辑区域大小
export enum EditCanvasTypeEnum {
EDITLAYOUTDOM = 'editLayoutDom',
EDITCONTENTDON = 'editContentDom',
WIDTH = 'width',
HEIGHT = 'height',
OFFSET = 'offset',
SCALE = 'scale',
LOCKSCALE = 'lockScale',
BACKGROUND = 'background'
}
export type EditCanvasType = {
// 编辑区域 DOM
[EditCanvasTypeEnum.EDITLAYOUTDOM]?: HTMLElement
[EditCanvasTypeEnum.EDITCONTENTDON]?: HTMLElement
// 大屏宽度
[EditCanvasTypeEnum.WIDTH]: number
// 大屏高度
[EditCanvasTypeEnum.HEIGHT]: number
// 偏移大小
[EditCanvasTypeEnum.OFFSET]: number
// 缩放
[EditCanvasTypeEnum.SCALE]: number
// 锁定缩放
[EditCanvasTypeEnum.LOCKSCALE]: boolean
// 背景色
[EditCanvasTypeEnum.BACKGROUND]?: string
}
// 坐标轴信息
export enum EditCanvasTypeEnum {
X = 'x',
Y = 'y'
}
export type MousePositionType = {
// X 轴
[EditCanvasTypeEnum.X]: number
// y 轴
[EditCanvasTypeEnum.Y]: number
}
// Store 类型
export enum chartEditStoreEnum {
EDITCANVAS = 'editCanvas',
MOUSEPOSITION = 'mousePosition'
}
export interface chartEditStoreType {
}
[chartEditStoreEnum.EDITCANVAS]: EditCanvasType
[chartEditStoreEnum.MOUSEPOSITION]: MousePositionType
}

View File

@ -1,11 +1,118 @@
import { defineStore } from 'pinia'
import { chartEditStoreType } from './chartEditStore.d'
import { setLocalStorage, getLocalStorage } from '@/utils'
import { StorageEnum } from '@/enums/storageEnum'
import debounce from 'lodash/debounce'
import {
chartEditStoreType,
EditCanvasType,
MousePositionType
} from './chartEditStore.d'
// 编辑区域内容
export const useChartEditStoreStore = defineStore({
id: 'useChartEditStoreStore',
state: (): chartEditStoreType => ({}),
getters: {},
actions: {}
})
state: (): chartEditStoreType => ({
editCanvas: {
// 编辑区域 Dom
editLayoutDom: undefined,
editContentDom: undefined,
// 默认宽度
width: 1920,
// 默认高度
height: 1080,
// 偏移量
offset: 20,
// 默认缩放
scale: 1,
// 锁定缩放
lockScale: false,
// 默认背景色
background: undefined
},
mousePosition: {
x: 0,
y: 0
}
}),
getters: {
getMousePosition(): MousePositionType {
return this.mousePosition
},
getEditCanvas(): EditCanvasType {
return this.editCanvas
}
},
actions: {
// * 设置数据项
setEditCanvasItem<T extends keyof EditCanvasType>(key: T, value: any) {
this.editCanvas[key] = value
},
// * 设置页面属性
setPageAttribute<T extends keyof CSSStyleDeclaration>(
key: T,
value: any
): void {
const dom = this.editCanvas.editContentDom
if (dom) {
// @ts-ignore
dom.style[key] = value
}
},
// * 设置页面大小
setPageSize(): void {
this.setPageAttribute('height', `${this.editCanvas.height}px`)
this.setPageAttribute('width', `${this.editCanvas.width}px`)
},
// * 设置鼠标位置
setMousePosition(x: number, y: number): void {
this.mousePosition.x = x
this.mousePosition.y = y
},
// * 计算缩放
computedScale() {
if (this.editCanvas.editLayoutDom) {
// 现有展示区域
const width = this.editCanvas.editLayoutDom.clientWidth - this.editCanvas.offset * 2
const height = this.editCanvas.editLayoutDom.clientHeight - this.editCanvas.offset * 4
// 用户设定大小
const editCanvasWidth = this.editCanvas.width
const editCanvasHeight = this.editCanvas.height
// 需保持的比例
const baseProportion = parseFloat((editCanvasWidth / editCanvasHeight).toFixed(5))
const currentRate = parseFloat((width / height).toFixed(5))
if (currentRate > baseProportion) {
// 表示更宽
const scaleWidth = parseFloat(((height * baseProportion) / editCanvasWidth).toFixed(5))
this.setScale(parseFloat((scaleWidth).toFixed(5)))
} else {
// 表示更高
const scaleHeight = parseFloat(((width / baseProportion) / editCanvasHeight).toFixed(5))
this.setScale(parseFloat((scaleHeight).toFixed(5)))
}
} else {
window['$message'].warning('找不到元素')
}
},
// * 监听缩放
listenerScale(): Function {
const resize = debounce(this.computedScale, 200)
// 默认执行一次
resize()
// 开始监听
window.addEventListener('resize', resize)
// 销毁函数
const remove = () => {
window.removeEventListener('resize', resize)
}
return remove
},
// * 设置缩放
setScale(scale: number): void {
this.getEditCanvas.scale = scale
// 设置页面元素
this.setPageAttribute('transform', `scale(${scale})`)
}
}
})

View File

@ -1,35 +1,43 @@
import { ThemeEnum } from '@/enums/styleEnum'
export enum ChartLayoutFilterEnum {
HUEROTATE = 'hueRotate',
SATURATE = 'saturate',
BRIGHTNESS = 'brightness',
CONTRAST = 'contrast',
UNOPACITY = 'unOpacity',
}
export interface ChartLayoutFilterType {
// 色相
hueRotate: number
[ChartLayoutFilterEnum.HUEROTATE]: number
// 饱和度
saturate: number
[ChartLayoutFilterEnum.SATURATE]: number
// 亮度
brightness: number
[ChartLayoutFilterEnum.BRIGHTNESS]: number
// 对比度
contrast: number
[ChartLayoutFilterEnum.CONTRAST]: number
// 不透明度
unOpacity: number
[ChartLayoutFilterEnum.UNOPACITY]: number
}
export interface ChartLayoutType {
// 图层控制
layers: boolean
// 图表组件
charts: boolean
// 详情设置
details: boolean
// 对齐线
alignLine: boolean
// 滤镜
filter: ChartLayoutFilterType
}
export enum ChartLayoutStoreEnums {
export enum ChartLayoutStoreEnum {
LAYERS = 'layers',
CHARTS = 'charts',
DETAILS = 'details',
ALIGNLINE = 'alignLine',
FILTER = 'filter',
}
}
export interface ChartLayoutType {
// 图层控制
[ChartLayoutStoreEnum.LAYERS]: boolean
// 图表组件
[ChartLayoutStoreEnum.CHARTS]: boolean
// 详情设置
[ChartLayoutStoreEnum.DETAILS]: boolean
// 对齐线
[ChartLayoutStoreEnum.ALIGNLINE]: boolean
// 滤镜
[ChartLayoutStoreEnum.FILTER]: ChartLayoutFilterType
}

View File

@ -2,6 +2,9 @@ import { defineStore } from 'pinia'
import { ChartLayoutType, ChartLayoutFilterType } from './chartLayoutStore.d'
import { setLocalStorage, getLocalStorage } from '@/utils'
import { StorageEnum } from '@/enums/storageEnum'
import { useChartEditStoreStore } from '@/store/modules/chartEditStore/chartEditStore'
const chartEditStore = useChartEditStoreStore()
const { GO_CHART_LAYOUT_STORE } = StorageEnum
@ -9,6 +12,7 @@ const storageChartLayout: ChartLayoutType = getLocalStorage(
GO_CHART_LAYOUT_STORE
)
// 编辑区域布局和静态设置
export const useChartLayoutStore = defineStore({
id: 'useChartLayoutStore',
state: (): ChartLayoutType =>
@ -32,8 +36,8 @@ export const useChartLayoutStore = defineStore({
// 对比度
contrast: 100,
// 不透明度
unOpacity: 100,
},
unOpacity: 100
}
},
getters: {
getLayers(): boolean {
@ -50,16 +54,23 @@ export const useChartLayoutStore = defineStore({
},
getFilter(): ChartLayoutFilterType {
return this.filter
},
}
},
actions: {
setItem(key: string, value: boolean): void {
;(this as any)[key] = value
setLocalStorage(GO_CHART_LAYOUT_STORE, this.$state)
// 重新计算拖拽区域缩放比例
setTimeout(() => {
chartEditStore.computedScale()
}, 500)
},
setFilter<T extends keyof ChartLayoutFilterType>(key: T, value: boolean): void {
setFilter<T extends keyof ChartLayoutFilterType>(
key: T,
value: boolean
): void {
;(this.filter as any)[key] = value
setLocalStorage(GO_CHART_LAYOUT_STORE, this.$state)
},
},
}
}
})

View File

@ -25,4 +25,7 @@ $dark: (
),
// hover 边框颜色
hover-border-color: #55606e,
// 阴影
box-shadow: 0 8px 20px #5252521f
);

View File

@ -26,5 +26,7 @@ $light: (
linear-gradient(90deg, transparent 14px, $--color-dark-bg-5 0)
),
// hover 边框颜色
hover-border-color: $--color-light-bg-1
hover-border-color: $--color-light-bg-1,
// 阴影
box-shadow: 0 8px 20px #0000001a
);

View File

@ -9,6 +9,13 @@
}
}
@mixin goId($block) {
$B: $namespace + '-' + $block;
##{$B} {
@content;
}
}
@mixin deep() {
:deep {
@content;

View File

@ -2,7 +2,6 @@
@import './animation.scss';
@import './mixins/mixins.scss';
// extends
// 过度
.go-transition {
transition: all 0.4s;
@ -16,7 +15,7 @@
}
.go-flex-no-wrap {
flex-wrap: nowrap!important;
flex-wrap: nowrap !important;
}
.go-absolute-center {

View File

@ -2,4 +2,5 @@ export * from '@/utils/utils'
export * from '@/utils/page'
export * from '@/utils/storage'
export * from '@/utils/style'
export * from '@/utils/plugin'
export * from '@/utils/plugin'
export * from '@/utils/componets'

View File

@ -56,10 +56,10 @@ export const requireFallbackImg = (path?: string, name?: string) => {
}
/**
*
* @param isFullscreen
* @param isEnabled
* @returns
* *
* @param isFullscreen
* @param isEnabled
* @returns
*/
export const screenfullFn = (isFullscreen?: boolean, isEnabled?: boolean) => {
// 是否是全屏
@ -76,6 +76,23 @@ export const screenfullFn = (isFullscreen?: boolean, isEnabled?: boolean) => {
window['$message'].warning('您的浏览器不支持全屏功能!')
}
/**
* *
* @param HTMLElement
* @param key
* @param value
*/
export const setDomAttribute = <T extends keyof CSSStyleDeclaration>(
HTMLElement: HTMLElement,
key: T,
value: any
) => {
if (HTMLElement) {
// @ts-ignore
HTMLElement.style[key] = value
}
}
/**
* *
*/

View File

@ -23,8 +23,10 @@
</n-space>
</div>
<aside class="content">
<n-scrollbar>
<slot></slot>
<n-scrollbar x-scrollable>
<n-scrollbar>
<slot></slot>
</n-scrollbar>
</n-scrollbar>
</aside>
<div v-if="showBottom" class="bottom go-mt-0">

View File

@ -5,7 +5,7 @@ import { themeColor, setItem, getCharts } from './layoutHook'
import { PackagesCategoryEnum, PackagesCategoryName } from '@/packages/index.d'
// 图表
import { usePackagesStore } from '@/store/modules/packagesStore/packagesStore'
import { ChartLayoutStoreEnums } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
import { ChartLayoutStoreEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
// 图标
const { BarChartIcon } = icon.ionicons5
const {
@ -68,9 +68,9 @@ const clickItemHandle = (key: string, item: any) => {
selectOptions.value = item
// 处理折叠
if (beforeSelect === key) {
setItem(ChartLayoutStoreEnums.CHARTS, !getCharts.value)
setItem(ChartLayoutStoreEnum.CHARTS, !getCharts.value)
} else {
setItem(ChartLayoutStoreEnums.CHARTS, true)
setItem(ChartLayoutStoreEnum.CHARTS, true)
}
beforeSelect = key
}

View File

@ -1,8 +1,8 @@
<template>
<n-layout has-sider sider-placement="right">
<n-layout-content>
<!-- 为了展示折叠的按钮放在了这里 呜呜呜 -->
<ContentDrag />
<!-- 图表拖拽区域 -->
<ContentEdit />
</n-layout-content>
<n-layout-sider
collapse-mode="transform"
@ -43,11 +43,11 @@ import { shallowRef, ref, toRefs, watch, reactive } from 'vue'
import { icon } from '@/plugins'
import { ContentBox } from '../ContentBox/index'
import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore'
import { ChartLayoutStoreEnums } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
import { ChartLayoutStoreEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
import { Setting } from './components/Setting/index'
import { Behind } from './components/Behind/index'
import { Page } from './components/Page/index'
import { ContentDrag } from '../ContentDrag/index'
import { ContentEdit } from '../ContentEdit/index'
const { getDetails } = toRefs(useChartLayoutStore())
const { setItem } = useChartLayoutStore()
@ -58,12 +58,12 @@ const collapsed = ref<boolean>(getDetails.value)
const collapsedHindle = () => {
collapsed.value = true
setItem(ChartLayoutStoreEnums.DETAILS, true)
setItem(ChartLayoutStoreEnum.DETAILS, true)
}
const expandHindle = () => {
collapsed.value = false
setItem(ChartLayoutStoreEnums.DETAILS, false)
setItem(ChartLayoutStoreEnum.DETAILS, false)
}
watch(getDetails, (newData) => {

View File

@ -1,3 +0,0 @@
import ContentDrag from './index.vue'
export { ContentDrag }

View File

@ -1,25 +0,0 @@
<template>
<ContentBox
class="go-content-draw"
:flex="true"
:showTop="false"
:showBottom="true"
:depth="1"
>
<template #bottom>
</template>
</ContentBox>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
import { ContentBox } from '../ContentBox/index'
</script>
<style lang="scss" scoped>
@include go(content-draw) {
overflow: hidden;
@include background-image('background-point');
@extend .go-point-bg;
}
</style>

View File

@ -0,0 +1,3 @@
import EditRange from './index.vue'
export { EditRange }

View File

@ -0,0 +1,22 @@
<template>
<div class="go-edit-range">
<slot></slot>
</div>
</template>
<script setup lang="ts"></script>
<style lang="scss" scoped>
@include go(edit-range) {
position: relative;
height: 1080px;
width: 1920px;
border: 1px solid;
border-radius: 15px;
background-color: #333;
@include filter-bg-color('background-color2');
@include fetch-theme('box-shadow');
@include filter-border-color('hover-border-color');
@include fetch-theme-custom('border-color', 'background-color4');
}
</style>

View File

@ -0,0 +1,6 @@
import { useChartEditStoreStore } from '@/store/modules/chartEditStore/chartEditStore'
const chartEditStore = useChartEditStoreStore()
export const getChartEditStore = () => {
return chartEditStore
}

View File

@ -0,0 +1,3 @@
import ContentEdit from './index.vue'
export { ContentEdit }

View File

@ -0,0 +1,68 @@
<template>
<ContentBox
id="go-chart-edit-layout"
ref="editDomRef"
:flex="true"
:showTop="false"
:showBottom="true"
:depth="1"
>
<div id="go-chart-edit-content">
<!-- 中间区域 -->
<EditRange>
</EditRange>
</div>
<!-- 底部控制 -->
<template #bottom> </template>
</ContentBox>
</template>
<script lang="ts" setup>
import { ref, onUnmounted, onMounted, computed } from 'vue'
import { ContentBox } from '../ContentBox/index'
import { EditRange } from './components/EditRange'
import { getChartEditStore } from './hooks/useStore'
import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
const chartEditStore = getChartEditStore()
onMounted(() => {
// Dom (ref document)
chartEditStore.setEditCanvasItem(
EditCanvasTypeEnum.EDITLAYOUTDOM,
document.getElementById('go-chart-edit-layout')
)
chartEditStore.setEditCanvasItem(
EditCanvasTypeEnum.EDITCONTENTDON,
document.getElementById('go-chart-edit-content')
)
//
chartEditStore.setPageSize()
//
const removeScale = chartEditStore.listenerScale()
onUnmounted(() => {
removeScale()
})
})
computed(() => {})
</script>
<style lang="scss" scoped>
@include goId(chart-edit-layout) {
position: relative;
width: 100%;
@include background-image('background-point');
@extend .go-point-bg;
@include goId(chart-edit-content) {
position: relative;
top: 20px;
left: 20px;
transform-origin: left top;
@extend .go-transition;
}
}
</style>

View File

@ -18,13 +18,13 @@
<script setup lang="ts">
import { ContentBox } from '../ContentBox/index'
import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore'
import { ChartLayoutStoreEnums } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
import { ChartLayoutStoreEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
import { icon } from '@/plugins'
const { LayersIcon } = icon.ionicons5
const chartLayoutStore = useChartLayoutStore()
const backHandle = () => {
chartLayoutStore.setItem(ChartLayoutStoreEnums.LAYERS, false)
chartLayoutStore.setItem(ChartLayoutStoreEnum.LAYERS, false)
}
</script>

View File

@ -26,7 +26,7 @@ import { renderIcon, goDialog, goHome } from '@/utils'
import { icon } from '@/plugins'
const { LayersIcon, BarChartIcon, PrismIcon, HomeIcon } = icon.ionicons5
import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore'
import { ChartLayoutStoreEnums } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
import { ChartLayoutStoreEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
const { setItem } = useChartLayoutStore()
const { getLayers, getCharts, getDetails } = toRefs(useChartLayoutStore())
@ -40,19 +40,19 @@ type ItemType = {
const btnList = reactive<ItemType[]>([
{
key: ChartLayoutStoreEnums.CHARTS,
key: ChartLayoutStoreEnum.CHARTS,
select: getCharts,
title: '图表组件',
icon: renderIcon(BarChartIcon)
},
{
key: ChartLayoutStoreEnums.LAYERS,
key: ChartLayoutStoreEnum.LAYERS,
select: getLayers,
title: '图层控制',
icon: renderIcon(LayersIcon)
},
{
key: ChartLayoutStoreEnums.DETAILS,
key: ChartLayoutStoreEnum.DETAILS,
select: getDetails,
title: '详情设置',
icon: renderIcon(PrismIcon)
@ -62,7 +62,7 @@ const btnList = reactive<ItemType[]>([
// store ContentDetails collapsed
const styleHandle = (item: ItemType) => {
if (item.key === ChartLayoutStoreEnums.DETAILS) {
if (item.key === ChartLayoutStoreEnum.DETAILS) {
return item.select ? '' : 'success'
}
return item.select ? 'success' : ''

View File

@ -22,17 +22,31 @@
</template>
<script setup lang="ts">
import { loadAsyncComponent } from '@/utils'
import { HeaderPro } from '@/layout/components/HeaderPro'
import { HeaderLeftBtn } from './components/HeaderLeftBtn/index'
import { HeaderRightBtn } from './components/HeaderRightBtn/index'
import { HeaderTitle } from './components/HeaderTitle/index'
import { ContentLayers } from './components/ContentLayers/index'
import { ContentCharts } from './components/ContentCharts/index'
import { ContentDetails } from './components/ContentDetails/index'
const HeaderLeftBtn = loadAsyncComponent(() =>
import('./components/HeaderLeftBtn/index.vue')
)
const HeaderRightBtn = loadAsyncComponent(() =>
import('./components/HeaderRightBtn/index.vue')
)
const HeaderTitle = loadAsyncComponent(() =>
import('./components/HeaderTitle/index.vue')
)
const ContentLayers = loadAsyncComponent(() =>
import('./components/ContentLayers/index.vue')
)
const ContentCharts = loadAsyncComponent(() =>
import('./components/ContentCharts/index.vue')
)
const ContentDetails = loadAsyncComponent(() =>
import('./components/ContentDetails/index.vue')
)
</script>
<style lang="scss" scoped>
@include go("chart") {
@include go('chart') {
height: 100vh;
width: 100vw;
overflow: hidden;

View File

@ -104,7 +104,6 @@
<script lang="ts" setup>
import { reactive, ref, onMounted } from 'vue'
import { useMessage } from 'naive-ui'
import { requireUrl } from '@/utils'
import { routerTurnByName } from '@/utils'
import shuffle from 'lodash/shuffle'
@ -125,7 +124,6 @@ interface FormState {
}
const formRef = ref()
const message = useMessage()
const loading = ref(false)
const autoLogin = ref(true)
const show = ref(false)
@ -199,10 +197,10 @@ const handleSubmit = (e: Event) => {
if (!errors) {
const { username, password } = formInline
loading.value = true
message.success(`${t('login.login_success')}!`)
window['$message'].success(`${t('login.login_success')}!`)
routerTurnByName(PageEnum.BASE_HOME_NAME, true)
} else {
message.error(`${t('login.login_message')}!`)
window['$message'].error(`${t('login.login_message')}!`)
}
})
}

View File

@ -33,7 +33,7 @@
</template>
<script setup lang="ts">
import { ref, computed, onMounted, toRefs } from 'vue'
import { ref, computed, onMounted, onUnmounted, toRefs } from 'vue'
import { Create } from '../Create/index'
import { AsideFooter } from '../AsideFooter/index'
import { asideWidth, asideCollapsedWidth } from '@/settings/designSetting'
@ -62,6 +62,10 @@ const watchWidth = () => {
onMounted(() => {
window.addEventListener('resize', watchWidth)
})
onUnmounted(()=> {
window.removeEventListener('resize', watchWidth)
})
</script>
<style lang="scss" scoped>