mirror of
https://gitee.com/dromara/go-view.git
synced 2025-02-24 08:12:49 +08:00
feat: 新增成组,解组,图层处理
This commit is contained in:
parent
6d4cfe29ba
commit
32488a03cd
@ -1,7 +1,7 @@
|
||||
// 鼠标点击左右键
|
||||
export enum MouseEventButton {
|
||||
LEFT = 1,
|
||||
RIGHT = 2
|
||||
RIGHT = 2,
|
||||
}
|
||||
|
||||
// 页面拖拽键名
|
||||
@ -24,6 +24,9 @@ export enum MenuEnum {
|
||||
UP = 'up',
|
||||
DOWN = 'down',
|
||||
CLEAR = 'clear',
|
||||
GROUP = 'group',
|
||||
UN_GROUP = 'unGroup',
|
||||
|
||||
BACK = 'back',
|
||||
FORWORD = 'forward'
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { getUUID } from '@/utils'
|
||||
import { PublicConfigType, CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
|
||||
import { groupTitle } from '@/settings/designSetting'
|
||||
import {
|
||||
RequestHttpEnum,
|
||||
RequestDataTypeEnum,
|
||||
@ -83,7 +84,7 @@ export class PublicGroupConfigClass implements CreateComponentGroupType {
|
||||
public isGroup = true
|
||||
// 名称
|
||||
public chartConfig = {
|
||||
title: '分组'
|
||||
title: groupTitle
|
||||
}
|
||||
// 组成员列表
|
||||
public groupList: Array<CreateComponentType> = []
|
||||
|
@ -55,7 +55,9 @@ import {
|
||||
Search as SearchIcon,
|
||||
ChevronUpOutline as ChevronUpOutlineIcon,
|
||||
ChevronDownOutline as ChevronDownOutlineIcon,
|
||||
Pulse as PulseIcon
|
||||
Pulse as PulseIcon,
|
||||
Folder as FolderIcon,
|
||||
FolderOpen as FolderOpenIcon
|
||||
} from '@vicons/ionicons5'
|
||||
|
||||
import {
|
||||
@ -205,7 +207,11 @@ const ionicons5 = {
|
||||
// 向下
|
||||
ChevronDownOutlineIcon,
|
||||
// 脉搏
|
||||
PulseIcon
|
||||
PulseIcon,
|
||||
// 文件夹
|
||||
FolderIcon,
|
||||
// 文件夹打开
|
||||
FolderOpenIcon
|
||||
}
|
||||
|
||||
const carbon = {
|
||||
|
@ -8,6 +8,9 @@ export const lang = LangEnum.ZH
|
||||
// 水印文字
|
||||
export const watermarkText = "GoView 低代码平台"
|
||||
|
||||
// 分组名称
|
||||
export const groupTitle = "分组"
|
||||
|
||||
// 主题配置
|
||||
export const theme = {
|
||||
// 默认是否开启深色主题
|
||||
@ -37,7 +40,7 @@ export const asideCollapsedWidth = 60
|
||||
// 弹窗是否可以通过点击遮罩关闭
|
||||
export const maskClosable = false
|
||||
|
||||
// 修改边框圆角
|
||||
// 全局边框圆角
|
||||
export const borderRadius = '6px'
|
||||
|
||||
// 轮播间隔
|
||||
|
@ -236,6 +236,32 @@ export const useChartEditStore = defineStore({
|
||||
}
|
||||
return index
|
||||
},
|
||||
// * 找到组数据的下标位置,id可为父级或子集数组(无则返回-1)
|
||||
fetchTargetGroupIndex(id?: string): number {
|
||||
const targetId = id || this.getTargetChart.selectId.length && this.getTargetChart.selectId[0] || undefined
|
||||
if(!targetId) {
|
||||
loadingFinish()
|
||||
return -1
|
||||
}
|
||||
const targetIndex = this.fetchTargetIndex(targetId)
|
||||
|
||||
// 当前
|
||||
if(targetIndex !== -1) {
|
||||
return targetIndex
|
||||
} else {
|
||||
const length = this.getComponentList.length
|
||||
for(let i = 0; i < length; i++) {
|
||||
if(this.getComponentList[i].isGroup) {
|
||||
for(const cItem of (this.getComponentList[i] as CreateComponentGroupType).groupList) {
|
||||
if(cItem.id === targetId) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1
|
||||
},
|
||||
/**
|
||||
* * 新增组件列表
|
||||
* @param chartConfig 新图表实例
|
||||
@ -575,12 +601,33 @@ export const useChartEditStore = defineStore({
|
||||
groupClass.groupList.push(item)
|
||||
})
|
||||
this.addComponentList(groupClass)
|
||||
// todo 输出
|
||||
console.log(this.getComponentList)
|
||||
},
|
||||
// * 解除分组
|
||||
setUnGroup() {
|
||||
const selectGroupIdArr = this.getTargetChart.selectId
|
||||
if(selectGroupIdArr.length > 1) {
|
||||
window['$message'].error('解除分组失败,请联系管理员!')
|
||||
return
|
||||
}
|
||||
|
||||
// 解组
|
||||
const unGroup = (targetIndex: number) => {
|
||||
const targetGroup = this.getComponentList[targetIndex] as CreateComponentGroupType
|
||||
targetGroup.groupList.forEach(item => {
|
||||
this.addComponentList(item)
|
||||
})
|
||||
this.setTargetSelectChart(targetGroup.id)
|
||||
// 删除分组
|
||||
this.removeComponentList(false)
|
||||
}
|
||||
|
||||
const targetIndex = this.fetchTargetGroupIndex(selectGroupIdArr[0])
|
||||
// 判断目标是否为分组父级
|
||||
if(targetIndex !== -1) {
|
||||
unGroup(targetIndex)
|
||||
} else {
|
||||
window['$message'].error('解除分组失败,请联系管理员!')
|
||||
}
|
||||
},
|
||||
// ----------------
|
||||
// * 设置页面大小
|
||||
|
@ -31,7 +31,7 @@
|
||||
@mousedown="mousedownHandle($event, item)"
|
||||
@mouseenter="mouseenterHandle($event, item)"
|
||||
@mouseleave="mouseleaveHandle($event, item)"
|
||||
@contextmenu="handleContextMenu($event, item)"
|
||||
@contextmenu="handleContextMenu($event, item, optionsHandle)"
|
||||
>
|
||||
<component
|
||||
class="edit-content-chart"
|
||||
@ -66,8 +66,11 @@
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, computed } from 'vue'
|
||||
import { chartColors } from '@/settings/chartThemes/index'
|
||||
import { MenuEnum } from '@/enums/editPageEnum'
|
||||
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { animationsClass, getFilterStyle, getTransformStyle } from '@/utils'
|
||||
import { useContextMenu } from '@/views/chart/hooks/useContextMenu.hook'
|
||||
import { MenuOptionsItemType } from '@/views/chart/hooks/useContextMenu.hook.d'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
|
||||
import { useLayout } from './hooks/useLayout.hook'
|
||||
@ -90,6 +93,20 @@ useLayout()
|
||||
// 点击事件
|
||||
const { mouseenterHandle, mouseleaveHandle, mousedownHandle, mouseClickHandle } = useMouseHandle()
|
||||
|
||||
// 右键事件
|
||||
const optionsHandle = (targetList: MenuOptionsItemType[], allList: MenuOptionsItemType[], item: CreateComponentType | CreateComponentGroupType) => {
|
||||
// 多选处理
|
||||
if(chartEditStore.getTargetChart.selectId.length > 1) {
|
||||
targetList.forEach(item => {
|
||||
if(item.key !== MenuEnum.GROUP) {
|
||||
item.disabled = true
|
||||
}
|
||||
})
|
||||
return targetList
|
||||
}
|
||||
return targetList
|
||||
}
|
||||
|
||||
// 主题色
|
||||
const themeSetting = computed(() => {
|
||||
const chartThemeSetting = chartEditStore.getEditCanvasConfig.chartThemeSetting
|
||||
|
@ -0,0 +1,3 @@
|
||||
import LayersGroupListItem from './index.vue'
|
||||
|
||||
export { LayersGroupListItem }
|
@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<div class="go-content-layers-group-list-item">
|
||||
<div
|
||||
class="root-item-content"
|
||||
:class="{ hover: hover, select: select }"
|
||||
@click="clickHandle($event)"
|
||||
@mousedown="groupMousedownHandle()"
|
||||
@mouseenter="mouseenterHandle(componentGroupData)"
|
||||
@mouseleave="mouseleaveHandle(componentGroupData)"
|
||||
@contextmenu="handleContextMenu($event, componentGroupData, undefined, undefined, pickOptionsList)"
|
||||
>
|
||||
<div class="go-flex-items-center item-content">
|
||||
<n-icon size="20" class="go-ml-1">
|
||||
<template v-if="expend">
|
||||
<folder-open-icon></folder-open-icon>
|
||||
</template>
|
||||
<template v-else>
|
||||
<folder-icon></folder-icon>
|
||||
</template>
|
||||
</n-icon>
|
||||
<n-ellipsis>
|
||||
<n-text class="go-ml-2 list-text" :depth="2">
|
||||
{{ componentGroupData.chartConfig.title }}
|
||||
</n-text>
|
||||
</n-ellipsis>
|
||||
</div>
|
||||
<div :class="{ 'select-modal': select }"></div>
|
||||
</div>
|
||||
<n-collapse-transition :show="expend">
|
||||
<LayersListItem
|
||||
v-for="element in componentGroupData.groupList"
|
||||
:key="element.id"
|
||||
:componentData="element"
|
||||
@mousedown="mousedownHandle(element)"
|
||||
@mouseenter="mouseenterHandle(element)"
|
||||
@mouseleave="mouseleaveHandle(element)"
|
||||
@contextmenu="handleContextMenu($event, componentGroupData, undefined, undefined, pickOptionsList)"
|
||||
></LayersListItem>
|
||||
</n-collapse-transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, PropType } from 'vue'
|
||||
import { MouseEventButton } from '@/enums/editPageEnum'
|
||||
import { MenuEnum } from '@/enums/editPageEnum'
|
||||
import { useDesignStore } from '@/store/modules/designStore/designStore'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { useContextMenu } from '@/views/chart/hooks/useContextMenu.hook'
|
||||
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { LayersListItem } from '../LayersListItem'
|
||||
import throttle from 'lodash/throttle'
|
||||
import { icon } from '@/plugins'
|
||||
|
||||
const props = defineProps({
|
||||
componentGroupData: {
|
||||
type: Object as PropType<CreateComponentGroupType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
// 右键
|
||||
const pickOptionsList = [MenuEnum.UN_GROUP]
|
||||
|
||||
// 全局颜色
|
||||
const designStore = useDesignStore()
|
||||
const { FolderIcon, FolderOpenIcon } = icon.ionicons5
|
||||
|
||||
const chartEditStore = useChartEditStore()
|
||||
const { handleContextMenu, onClickOutSide } = useContextMenu()
|
||||
|
||||
const themeColor = ref(designStore.getAppTheme)
|
||||
const expend = ref(false)
|
||||
|
||||
// 点击
|
||||
const clickHandle = (e: MouseEvent) => {
|
||||
// 判断左右键
|
||||
expend.value = !expend.value
|
||||
mousedownHandle(props.componentGroupData)
|
||||
}
|
||||
|
||||
// 计算当前选中目标
|
||||
const select = computed(() => {
|
||||
const id = props.componentGroupData.id
|
||||
return chartEditStore.getTargetChart.selectId.find((e: string) => e === id)
|
||||
})
|
||||
|
||||
// 悬浮
|
||||
const hover = computed(() => {
|
||||
return props.componentGroupData.id === chartEditStore.getTargetChart.hoverId
|
||||
})
|
||||
|
||||
// 组点击事件
|
||||
const groupMousedownHandle = () => {
|
||||
onClickOutSide()
|
||||
chartEditStore.setTargetSelectChart(props.componentGroupData.id)
|
||||
}
|
||||
|
||||
// 公共点击事件
|
||||
const mousedownHandle = (item: CreateComponentType | CreateComponentGroupType) => {
|
||||
onClickOutSide()
|
||||
chartEditStore.setTargetSelectChart(item.id)
|
||||
}
|
||||
|
||||
// 公共进入事件
|
||||
const mouseenterHandle = (item: CreateComponentType | CreateComponentGroupType) => {
|
||||
chartEditStore.setTargetHoverChart(item.id)
|
||||
}
|
||||
|
||||
// 公共移出事件
|
||||
const mouseleaveHandle = (item: CreateComponentType | CreateComponentGroupType) => {
|
||||
chartEditStore.setTargetHoverChart(undefined)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$centerHeight: 52px;
|
||||
$textSize: 10px;
|
||||
|
||||
@include go(content-layers-group-list-item) {
|
||||
position: relative;
|
||||
width: 90%;
|
||||
margin: 10px 5%;
|
||||
margin-bottom: 5px;
|
||||
@extend .go-transition-quick;
|
||||
|
||||
.root-item-content {
|
||||
height: $centerHeight;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
border: 1px solid rgba(0, 0, 0, 0);
|
||||
&.hover,
|
||||
&:hover {
|
||||
@include fetch-bg-color('background-color4');
|
||||
}
|
||||
/* 选中 */
|
||||
&.select {
|
||||
border: 1px solid v-bind('themeColor');
|
||||
/* 需要设置最高级,覆盖 hover 的颜色 */
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
.list-img {
|
||||
border: 1px solid v-bind('themeColor') !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.select-modal,
|
||||
.item-content {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.item-content {
|
||||
z-index: 1;
|
||||
padding: 6px 5px;
|
||||
justify-content: start !important;
|
||||
width: calc(100% - 10px);
|
||||
height: calc(#{$centerHeight} - 10px);
|
||||
}
|
||||
.select-modal {
|
||||
width: 100%;
|
||||
height: calc(#{$centerHeight} + 2px);
|
||||
opacity: 0.3;
|
||||
background-color: v-bind('themeColor');
|
||||
}
|
||||
.list-text {
|
||||
padding-left: 6px;
|
||||
font-size: $textSize;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -16,20 +16,21 @@
|
||||
<n-text class="not-layer-text">暂无图层~</n-text>
|
||||
</n-space>
|
||||
<!-- https://github.com/SortableJS/vue.draggable.next -->
|
||||
<draggable
|
||||
item-key="id"
|
||||
v-model="reverseList"
|
||||
ghostClass="ghost"
|
||||
@change="onMoveCallback"
|
||||
>
|
||||
<draggable item-key="id" v-model="reverseList" ghostClass="ghost" @change="onMoveCallback">
|
||||
<template #item="{ element }">
|
||||
<layers-list-item
|
||||
:componentData="element"
|
||||
@mousedown="mousedownHandle(element)"
|
||||
@mouseenter="mouseenterHandle(element)"
|
||||
@mouseleave="mouseleaveHandle(element)"
|
||||
@contextmenu="handleContextMenu($event, element)"
|
||||
></layers-list-item>
|
||||
<div>
|
||||
<!-- 组合 -->
|
||||
<LayersGroupListItem v-if="element.isGroup" :componentGroupData="element"></LayersGroupListItem>
|
||||
<!-- 单组件 -->
|
||||
<LayersListItem
|
||||
v-else
|
||||
:componentData="element"
|
||||
@mousedown="mousedownHandle(element)"
|
||||
@mouseenter="mouseenterHandle(element)"
|
||||
@mouseleave="mouseleaveHandle(element)"
|
||||
@contextmenu="handleContextMenu($event, element)"
|
||||
></LayersListItem>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</content-box>
|
||||
@ -44,22 +45,24 @@ import { ContentBox } from '../ContentBox/index'
|
||||
import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore'
|
||||
import { ChartLayoutStoreEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { useContextMenu } from '@/views/chart/hooks/useContextMenu.hook'
|
||||
import { MenuEnum } from '@/enums/editPageEnum'
|
||||
|
||||
import { LayersListItem } from './components/LayersListItem/index'
|
||||
import { LayersGroupListItem } from './components/LayersGroupListItem/index'
|
||||
|
||||
import { icon } from '@/plugins'
|
||||
|
||||
const { LayersIcon } = icon.ionicons5
|
||||
const chartLayoutStore = useChartLayoutStore()
|
||||
const chartEditStore = useChartEditStore()
|
||||
|
||||
const { handleContextMenu } = useContextMenu()
|
||||
const { handleContextMenu, onClickOutSide } = useContextMenu()
|
||||
|
||||
// 逆序展示
|
||||
const reverseList = computed(() => {
|
||||
const list: CreateComponentType[] = cloneDeep(chartEditStore.getComponentList)
|
||||
const list: Array<CreateComponentType | CreateComponentGroupType> = cloneDeep(chartEditStore.getComponentList)
|
||||
return list.reverse()
|
||||
})
|
||||
|
||||
@ -89,6 +92,7 @@ const onMoveCallback = (val: any) => {
|
||||
|
||||
// 点击事件
|
||||
const mousedownHandle = (item: CreateComponentType) => {
|
||||
onClickOutSide()
|
||||
chartEditStore.setTargetSelectChart(item.id)
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { ref, nextTick } from 'vue'
|
||||
import { ref, nextTick, toRaw } from 'vue';
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { renderIcon, loadingError } from '@/utils'
|
||||
import { icon } from '@/plugins'
|
||||
import { MenuOptionsItemType } from './useContextMenu.hook.d'
|
||||
import { MenuEnum } from '@/enums/editPageEnum'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
const { CopyIcon, CutIcon, ClipboardOutlineIcon, TrashIcon, ChevronDownIcon, ChevronUpIcon } = icon.ionicons5
|
||||
const { UpToTopIcon, DownToBottomIcon, PaintBrushIcon, Carbon3DSoftwareIcon, Carbon3DCursorIcon } = icon.carbon
|
||||
@ -81,10 +82,16 @@ const defaultOptions: MenuOptionsItemType[] = [
|
||||
const defaultMultiSelectOptions: MenuOptionsItemType[] = [
|
||||
{
|
||||
label: '创建分组',
|
||||
key: MenuEnum.COPY,
|
||||
key: MenuEnum.GROUP,
|
||||
icon: renderIcon(Carbon3DSoftwareIcon),
|
||||
fnHandle: chartEditStore.setGroup
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '解除分组',
|
||||
key: MenuEnum.UN_GROUP,
|
||||
icon: renderIcon(Carbon3DCursorIcon),
|
||||
fnHandle: chartEditStore.setUnGroup
|
||||
},
|
||||
]
|
||||
|
||||
// * 无数据传递拥有的选项
|
||||
@ -123,7 +130,7 @@ const menuOptions = ref<MenuOptionsItemType[]>([])
|
||||
const handleContextMenu = (
|
||||
e: MouseEvent,
|
||||
// 右键对象
|
||||
item?: CreateComponentType,
|
||||
item?: CreateComponentType | CreateComponentGroupType,
|
||||
// 判断函数
|
||||
optionsHandle?: Function,
|
||||
// 隐藏选项列表
|
||||
@ -133,10 +140,13 @@ const handleContextMenu = (
|
||||
) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
|
||||
let target = e.target
|
||||
while (target instanceof SVGElement) {
|
||||
target = target.parentNode
|
||||
}
|
||||
|
||||
// 展示列表
|
||||
chartEditStore.setRightMenuShow(false)
|
||||
|
||||
// * 多选默认选项
|
||||
@ -148,16 +158,17 @@ const handleContextMenu = (
|
||||
}
|
||||
|
||||
if (!item) {
|
||||
menuOptions.value = pickOption(menuOptions.value, defaultNoItemKeys)
|
||||
menuOptions.value = pickOption(toRaw(menuOptions.value), defaultNoItemKeys)
|
||||
}
|
||||
if (hideOptionsList) {
|
||||
menuOptions.value = hideOption(menuOptions.value, hideOptionsList)
|
||||
menuOptions.value = hideOption([...defaultMultiSelectOptions, ...defaultOptions], hideOptionsList)
|
||||
}
|
||||
if (pickOptionsList) {
|
||||
menuOptions.value = hideOption(menuOptions.value, pickOptionsList)
|
||||
menuOptions.value = pickOption([...defaultMultiSelectOptions, ...defaultOptions], pickOptionsList)
|
||||
}
|
||||
if (optionsHandle) {
|
||||
menuOptions.value = optionsHandle(menuOptions.value)
|
||||
// 自定义函数能够拿到当前选项和所有选项
|
||||
menuOptions.value = optionsHandle(cloneDeep(toRaw(menuOptions.value)), [...defaultMultiSelectOptions, ...defaultOptions], item)
|
||||
}
|
||||
nextTick().then(() => {
|
||||
chartEditStore.setMousePosition(e.clientX, e.clientY)
|
||||
@ -197,6 +208,8 @@ export const useContextMenu = () => {
|
||||
|
||||
return {
|
||||
menuOptions,
|
||||
defaultOptions,
|
||||
defaultMultiSelectOptions,
|
||||
handleContextMenu,
|
||||
onClickOutSide,
|
||||
handleMenuSelect,
|
||||
|
Loading…
Reference in New Issue
Block a user