mirror of
https://gitee.com/dromara/go-view.git
synced 2025-04-06 03:58:04 +08:00
Merge branch 'dev-feat-multi-select' of https://gitee.com/MTrun/go-view into dev
This commit is contained in:
commit
e4e1fee8b4
@ -3,6 +3,7 @@
|
||||
<n-input-number
|
||||
v-model:value="chartAttr.w"
|
||||
:min="50"
|
||||
:disabled="isGroup"
|
||||
size="small"
|
||||
placeholder="px"
|
||||
>
|
||||
@ -13,6 +14,7 @@
|
||||
<n-input-number
|
||||
v-model:value="chartAttr.h"
|
||||
:min="50"
|
||||
:disabled="isGroup"
|
||||
size="small"
|
||||
placeholder="px"
|
||||
>
|
||||
@ -32,6 +34,10 @@ const props = defineProps({
|
||||
chartAttr: {
|
||||
type: Object as PropType<Omit<PickCreateComponentType<'attr'>, 'node' | 'conNode'>>,
|
||||
required: true
|
||||
},
|
||||
isGroup: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
@ -1,4 +1,9 @@
|
||||
<template>
|
||||
<div v-show="isGroup">
|
||||
<n-divider n-divider style="margin: 10px 0"></n-divider>
|
||||
<n-tag type="warning"> 解散分组「 {{ isCanvas ? '滤镜' : '滤镜 / 变换' }} 」也将消失!</n-tag>
|
||||
</div>
|
||||
|
||||
<collapse-item :name="isCanvas ? '滤镜' : '滤镜 / 变换'">
|
||||
<setting-item-box name="色相" :alone="true">
|
||||
<setting-item :name="`值:${chartStyles.hueRotate}deg`">
|
||||
@ -13,9 +18,7 @@
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="饱和度" :alone="true">
|
||||
<setting-item
|
||||
:name="`值:${(parseFloat(String(chartStyles.saturate)) * 100).toFixed(0)}%`"
|
||||
>
|
||||
<setting-item :name="`值:${(parseFloat(String(chartStyles.saturate)) * 100).toFixed(0)}%`">
|
||||
<!-- 透明度 -->
|
||||
<n-slider
|
||||
v-model:value="chartStyles.saturate"
|
||||
@ -27,9 +30,7 @@
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="对比度" :alone="true">
|
||||
<setting-item
|
||||
:name="`值:${(parseFloat(String(chartStyles.contrast)) * 100).toFixed(0)}%`"
|
||||
>
|
||||
<setting-item :name="`值:${(parseFloat(String(chartStyles.contrast)) * 100).toFixed(0)}%`">
|
||||
<!-- 透明度 -->
|
||||
<n-slider
|
||||
v-model:value="chartStyles.contrast"
|
||||
@ -41,9 +42,7 @@
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="亮度" :alone="true">
|
||||
<setting-item
|
||||
:name="`值:${(parseFloat(String(chartStyles.brightness)) * 100).toFixed(0)}%`"
|
||||
>
|
||||
<setting-item :name="`值:${(parseFloat(String(chartStyles.brightness)) * 100).toFixed(0)}%`">
|
||||
<!-- 透明度 -->
|
||||
<n-slider
|
||||
v-model:value="chartStyles.brightness"
|
||||
@ -55,9 +54,7 @@
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="透明度" :alone="true">
|
||||
<setting-item
|
||||
:name="`值:${(parseFloat(String(chartStyles.opacity)) * 100).toFixed(0)}%`"
|
||||
>
|
||||
<setting-item :name="`值:${(parseFloat(String(chartStyles.opacity)) * 100).toFixed(0)}%`">
|
||||
<!-- 透明度 -->
|
||||
<n-slider
|
||||
v-model:value="chartStyles.opacity"
|
||||
@ -130,21 +127,21 @@
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { PickCreateComponentType } from '@/packages/index.d'
|
||||
import {
|
||||
SettingItemBox,
|
||||
SettingItem,
|
||||
CollapseItem,
|
||||
} from '@/components/Pages/ChartItemSetting'
|
||||
import { SettingItemBox, SettingItem, CollapseItem } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
const props = defineProps({
|
||||
isGroup: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
isCanvas: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
chartStyles: {
|
||||
type: Object as PropType<Omit<PickCreateComponentType<'styles'>, 'animations'>>,
|
||||
required: true,
|
||||
},
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
// 百分比格式化persen
|
||||
|
@ -1,24 +1,46 @@
|
||||
// 鼠标点击左右键
|
||||
export enum MouseEventButton {
|
||||
LEFT = 1,
|
||||
RIGHT = 2,
|
||||
}
|
||||
|
||||
// 页面拖拽键名
|
||||
export enum DragKeyEnum {
|
||||
DROG_KEY = 'ChartData'
|
||||
}
|
||||
|
||||
// 右键枚举
|
||||
// 操作枚举
|
||||
export enum MenuEnum {
|
||||
// 移动
|
||||
ARROW_UP = 'up',
|
||||
ARROW_RIGHT = 'right',
|
||||
ARROW_DOWN = 'down',
|
||||
ARROW_LEFT = 'left',
|
||||
// 删除
|
||||
DELETE = 'delete',
|
||||
// 复制
|
||||
COPY = 'copy',
|
||||
// 剪切
|
||||
CUT = 'cut',
|
||||
// 粘贴
|
||||
PARSE = 'parse',
|
||||
// 置顶
|
||||
TOP = 'top',
|
||||
// 置底
|
||||
BOTTOM = 'bottom',
|
||||
// 上移
|
||||
UP = 'up',
|
||||
// 下移
|
||||
DOWN = 'down',
|
||||
// 清空剪贴板
|
||||
CLEAR = 'clear',
|
||||
// 成组
|
||||
GROUP = 'group',
|
||||
// 解组
|
||||
UN_GROUP = 'unGroup',
|
||||
// 后退
|
||||
BACK = 'back',
|
||||
// 前进
|
||||
FORWORD = 'forward'
|
||||
}
|
||||
|
||||
@ -27,6 +49,9 @@ export enum WinKeyboard {
|
||||
CTRL = 'ctrl',
|
||||
SHIFT = 'shift',
|
||||
ALT = ' alt',
|
||||
CTRL_SOURCE_KEY = "control",
|
||||
SHIFT_SOURCE_KEY = "shift",
|
||||
ALT_SOURCE_KEY = "alt"
|
||||
}
|
||||
|
||||
// Mac 键盘枚举
|
||||
@ -35,4 +60,7 @@ export enum MacKeyboard {
|
||||
CTRL = '⌘',
|
||||
SHIFT = '⇧',
|
||||
ALT = '⌥',
|
||||
CTRL_SOURCE_KEY = "⌘",
|
||||
SHIFT_SOURCE_KEY = "⇧",
|
||||
ALT_SOURCE_KEY = "⌥"
|
||||
}
|
37
src/packages/index.d.ts
vendored
37
src/packages/index.d.ts
vendored
@ -27,12 +27,12 @@ export type ConfigType = {
|
||||
|
||||
// 数据请求
|
||||
interface requestConfig {
|
||||
request: RequestConfigType,
|
||||
request: RequestConfigType
|
||||
}
|
||||
|
||||
// Echarts 数据类型
|
||||
interface EchartsDataType {
|
||||
dimensions: string[],
|
||||
dimensions: string[]
|
||||
source: any[]
|
||||
}
|
||||
|
||||
@ -56,27 +56,27 @@ export enum FilterEnum {
|
||||
|
||||
// 倾斜
|
||||
SKEW_X = 'skewX',
|
||||
SKEW_Y = 'skewY',
|
||||
SKEW_Y = 'skewY'
|
||||
}
|
||||
|
||||
// 组件实例类
|
||||
export interface PublicConfigType extends requestConfig {
|
||||
export interface PublicConfigType {
|
||||
id: string
|
||||
rename?: string
|
||||
isGroup: boolean
|
||||
attr: { x: number; y: number; w: number; h: number; zIndex: number }
|
||||
styles: {
|
||||
[FilterEnum.OPACITY]: number;
|
||||
[FilterEnum.SATURATE]: number;
|
||||
[FilterEnum.CONTRAST]: number;
|
||||
[FilterEnum.HUE_ROTATE]: number;
|
||||
[FilterEnum.BRIGHTNESS]: number;
|
||||
[FilterEnum.OPACITY]: number
|
||||
[FilterEnum.SATURATE]: number
|
||||
[FilterEnum.CONTRAST]: number
|
||||
[FilterEnum.HUE_ROTATE]: number
|
||||
[FilterEnum.BRIGHTNESS]: number
|
||||
|
||||
[FilterEnum.ROTATE_Z]: number;
|
||||
[FilterEnum.ROTATE_X]: number;
|
||||
[FilterEnum.ROTATE_Y]: number;
|
||||
[FilterEnum.ROTATE_Z]: number
|
||||
[FilterEnum.ROTATE_X]: number
|
||||
[FilterEnum.ROTATE_Y]: number
|
||||
|
||||
[FilterEnum.SKEW_X]: number;
|
||||
[FilterEnum.SKEW_Y]: number;
|
||||
[FilterEnum.SKEW_X]: number
|
||||
[FilterEnum.SKEW_Y]: number
|
||||
// 动画
|
||||
animations: string[]
|
||||
}
|
||||
@ -84,12 +84,17 @@ export interface PublicConfigType extends requestConfig {
|
||||
setPosition: Function
|
||||
}
|
||||
|
||||
export interface CreateComponentType extends PublicConfigType {
|
||||
export interface CreateComponentType extends PublicConfigType, requestConfig {
|
||||
key: string
|
||||
chartConfig: ConfigType
|
||||
option: GlobalThemeJsonType
|
||||
}
|
||||
|
||||
// 组件成组实例类
|
||||
export interface CreateComponentGroupType extends CreateComponentType {
|
||||
groupList: Array<CreateComponentType>
|
||||
}
|
||||
|
||||
// 获取组件实例类中某个key对应value类型的方法
|
||||
export type PickCreateComponentType<T extends keyof CreateComponentType> = Pick<CreateComponentType, T>[T]
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { getUUID } from '@/utils'
|
||||
import { PublicConfigType } from '@/packages/index.d'
|
||||
import { ChartFrameEnum, PublicConfigType, CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
|
||||
import { groupTitle } from '@/settings/designSetting'
|
||||
import {
|
||||
RequestHttpEnum,
|
||||
RequestDataTypeEnum,
|
||||
@ -10,6 +11,7 @@ import {
|
||||
} from '@/enums/httpEnum'
|
||||
import { chartInitConfig } from '@/settings/designSetting'
|
||||
|
||||
// 请求基础属性
|
||||
const requestConfig: RequestConfigType = {
|
||||
requestDataType: RequestDataTypeEnum.STATIC,
|
||||
requestHttpType: RequestHttpEnum.GET,
|
||||
@ -33,10 +35,10 @@ const requestConfig: RequestConfigType = {
|
||||
}
|
||||
}
|
||||
|
||||
// 单实例类
|
||||
export class publicConfig implements PublicConfigType {
|
||||
public id = getUUID()
|
||||
// 重命名
|
||||
public rename = undefined
|
||||
public isGroup = false
|
||||
// 基本信息
|
||||
public attr = { ...chartInitConfig, zIndex: -1 }
|
||||
// 基本样式
|
||||
@ -75,3 +77,32 @@ export class publicConfig implements PublicConfigType {
|
||||
this.attr.y = y
|
||||
}
|
||||
}
|
||||
|
||||
// 成组类 (部分属性不需要, 不继承 publicConfig)
|
||||
export class PublicGroupConfigClass extends publicConfig implements CreateComponentGroupType {
|
||||
// 成组
|
||||
public isGroup = true
|
||||
// 名称
|
||||
public chartConfig = {
|
||||
key: 'group',
|
||||
chartKey: 'group',
|
||||
conKey: 'group',
|
||||
category: 'group',
|
||||
categoryName: 'group',
|
||||
package: 'group',
|
||||
chartFrame: ChartFrameEnum.COMMON,
|
||||
title: groupTitle,
|
||||
image: ''
|
||||
}
|
||||
// 组成员列表
|
||||
public groupList: Array<CreateComponentType> = []
|
||||
// ---- 原有 ---
|
||||
// key
|
||||
public key = 'group'
|
||||
// 配置
|
||||
public option = {}
|
||||
// 标识
|
||||
public id = getUUID()
|
||||
// 基本信息
|
||||
public attr = { w: 0, h: 0, x: 0, y: 0, zIndex: -1 }
|
||||
}
|
||||
|
@ -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 {
|
||||
@ -84,6 +86,8 @@ import {
|
||||
FitToScreen as FitToScreenIcon,
|
||||
FitToHeight as FitToHeightIcon,
|
||||
FitToWidth as FitToWidthIcon,
|
||||
Carbon3DCursor as Carbon3DCursorIcon,
|
||||
Carbon3DSoftware as Carbon3DSoftwareIcon,
|
||||
Filter as FilterIcon,
|
||||
FilterEdit as FilterEditIcon
|
||||
} from '@vicons/carbon'
|
||||
@ -203,7 +207,11 @@ const ionicons5 = {
|
||||
// 向下
|
||||
ChevronDownOutlineIcon,
|
||||
// 脉搏
|
||||
PulseIcon
|
||||
PulseIcon,
|
||||
// 文件夹
|
||||
FolderIcon,
|
||||
// 文件夹打开
|
||||
FolderOpenIcon
|
||||
}
|
||||
|
||||
const carbon = {
|
||||
@ -248,6 +256,10 @@ const carbon = {
|
||||
FitToScreenIcon,
|
||||
FitToHeightIcon,
|
||||
FitToWidthIcon,
|
||||
// 成组
|
||||
Carbon3DCursorIcon,
|
||||
// 解组
|
||||
Carbon3DSoftwareIcon,
|
||||
// 过滤器
|
||||
FilterIcon,
|
||||
FilterEditIcon
|
||||
|
@ -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'
|
||||
|
||||
// 轮播间隔
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { CreateComponentType, FilterEnum } from '@/packages/index.d'
|
||||
import { CreateComponentType, CreateComponentGroupType, FilterEnum } from '@/packages/index.d'
|
||||
import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
|
||||
import {
|
||||
RequestHttpEnum,
|
||||
@ -117,7 +117,7 @@ export type TargetChartType = {
|
||||
|
||||
// 数据记录
|
||||
export type RecordChartType = {
|
||||
charts: CreateComponentType | CreateComponentType[]
|
||||
charts: CreateComponentType | CreateComponentGroupType | Array<CreateComponentType | CreateComponentGroupType>
|
||||
type: HistoryActionTypeEnum.CUT | HistoryActionTypeEnum.COPY
|
||||
}
|
||||
|
||||
@ -180,11 +180,12 @@ export interface ChartEditStoreType {
|
||||
[ChartEditStoreEnum.TARGET_CHART]: TargetChartType
|
||||
[ChartEditStoreEnum.RECORD_CHART]?: RecordChartType
|
||||
[ChartEditStoreEnum.REQUEST_GLOBAL_CONFIG]: RequestGlobalConfigType
|
||||
[ChartEditStoreEnum.COMPONENT_LIST]: CreateComponentType[]
|
||||
[ChartEditStoreEnum.COMPONENT_LIST]: Array<CreateComponentType | CreateComponentGroupType>
|
||||
}
|
||||
|
||||
// 存储数据类型
|
||||
export interface ChartEditStorage {
|
||||
[ChartEditStoreEnum.EDIT_CANVAS_CONFIG]: EditCanvasConfigType
|
||||
[ChartEditStoreEnum.REQUEST_GLOBAL_CONFIG]: RequestGlobalConfigType
|
||||
[ChartEditStoreEnum.COMPONENT_LIST]: CreateComponentType[]
|
||||
[ChartEditStoreEnum.COMPONENT_LIST]: Array<CreateComponentType | CreateComponentGroupType>
|
||||
}
|
||||
|
@ -1,24 +1,22 @@
|
||||
import { toRaw } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { PublicGroupConfigClass } from '@/packages/public/publicConfig'
|
||||
import debounce from 'lodash/debounce'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { defaultTheme, globalThemeJson } from '@/settings/chartThemes/index'
|
||||
import { requestInterval, previewScaleType, requestIntervalUnit } from '@/settings/designSetting'
|
||||
import { RequestBodyEnum } from '@/enums/httpEnum'
|
||||
// 记录记录
|
||||
import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore'
|
||||
// 全局设置
|
||||
import { useSettingStore } from '@/store/modules/settingStore/settingStore'
|
||||
import { HistoryActionTypeEnum, HistoryItemType, HistoryTargetTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
|
||||
import { MenuEnum } from '@/enums/editPageEnum'
|
||||
import {
|
||||
getUUID,
|
||||
loadingStart,
|
||||
loadingFinish,
|
||||
loadingError,
|
||||
isString,
|
||||
isArray
|
||||
} from '@/utils'
|
||||
HistoryActionTypeEnum,
|
||||
HistoryItemType,
|
||||
HistoryTargetTypeEnum
|
||||
} from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
|
||||
import { MenuEnum } from '@/enums/editPageEnum'
|
||||
import { getUUID, loadingStart, loadingFinish, loadingError, isString, isArray } from '@/utils'
|
||||
import {
|
||||
ChartEditStoreEnum,
|
||||
ChartEditStorage,
|
||||
@ -114,8 +112,8 @@ export const useChartEditStore = defineStore({
|
||||
requestIntervalUnit: requestIntervalUnit,
|
||||
requestParams: {
|
||||
Body: {
|
||||
"form-data": {},
|
||||
"x-www-form-urlencoded": {},
|
||||
'form-data': {},
|
||||
'x-www-form-urlencoded': {},
|
||||
json: '',
|
||||
xml: ''
|
||||
},
|
||||
@ -148,7 +146,7 @@ export const useChartEditStore = defineStore({
|
||||
getRequestGlobalConfig(): RequestGlobalConfigType {
|
||||
return this.requestGlobalConfig
|
||||
},
|
||||
getComponentList(): CreateComponentType[] {
|
||||
getComponentList(): Array<CreateComponentType | CreateComponentGroupType> {
|
||||
return this.componentList
|
||||
},
|
||||
// 获取需要存储的数据项
|
||||
@ -174,7 +172,7 @@ export const useChartEditStore = defineStore({
|
||||
this.rightMenuShow = value
|
||||
},
|
||||
// * 设置目标数据 hover
|
||||
setTargetHoverChart(hoverId?:TargetChartType["hoverId"]) {
|
||||
setTargetHoverChart(hoverId?: TargetChartType['hoverId']) {
|
||||
this.targetChart.hoverId = hoverId
|
||||
},
|
||||
// * 设置目标数据 select
|
||||
@ -187,7 +185,7 @@ export const useChartEditStore = defineStore({
|
||||
this.targetChart.selectId = []
|
||||
return
|
||||
}
|
||||
// 新增
|
||||
// 多选
|
||||
if (push) {
|
||||
// 字符串
|
||||
if (isString(selectId)) {
|
||||
@ -223,61 +221,103 @@ export const useChartEditStore = defineStore({
|
||||
if (x) this.mousePosition.x = x
|
||||
if (y) this.mousePosition.y = y
|
||||
},
|
||||
// * 找到目标 id 数据下标位置(无则返回-1)
|
||||
// * 找到目标 id 数据的下标位置,id可为父级或子集数组(无则返回-1)
|
||||
fetchTargetIndex(id?: string): number {
|
||||
const targetId = id || this.getTargetChart.selectId.length && this.getTargetChart.selectId[0] || undefined
|
||||
const targetId = id || (this.getTargetChart.selectId.length && this.getTargetChart.selectId[0]) || undefined
|
||||
if (!targetId) {
|
||||
loadingFinish()
|
||||
return -1
|
||||
}
|
||||
const index = this.componentList.findIndex(e => e.id === targetId)
|
||||
if (index === -1) {
|
||||
loadingError()
|
||||
const targetIndex = this.componentList.findIndex(e => e.id === 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 index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1
|
||||
},
|
||||
// * 统一格式化处理入参 id
|
||||
idPreFormat(id?: string | string[]) {
|
||||
const idArr = []
|
||||
if (!id) {
|
||||
idArr.push(...this.getTargetChart.selectId)
|
||||
return idArr
|
||||
}
|
||||
if (isString(id)) idArr.push(id)
|
||||
if (isArray(id)) idArr.push(...id)
|
||||
return idArr
|
||||
},
|
||||
/**
|
||||
* * 新增组件列表
|
||||
* @param chartConfig 新图表实例
|
||||
* @param componentInstance 新图表实例
|
||||
* @param isHead 是否头部插入
|
||||
* @param isHistory 是否进行记录
|
||||
* @returns
|
||||
*/
|
||||
addComponentList(chartConfig: CreateComponentType, isHead = false, isHistory = false): void {
|
||||
addComponentList(
|
||||
componentInstance:
|
||||
| CreateComponentType
|
||||
| CreateComponentGroupType
|
||||
| Array<CreateComponentType | CreateComponentGroupType>,
|
||||
isHead = false,
|
||||
isHistory = false
|
||||
): void {
|
||||
if (componentInstance instanceof Array) {
|
||||
componentInstance.forEach(item => {
|
||||
this.addComponentList(item, isHead, isHistory)
|
||||
})
|
||||
return
|
||||
}
|
||||
if (isHistory) {
|
||||
chartHistoryStore.createAddHistory(chartConfig)
|
||||
chartHistoryStore.createAddHistory([componentInstance])
|
||||
}
|
||||
if (isHead) {
|
||||
this.componentList.unshift(chartConfig)
|
||||
this.componentList.unshift(componentInstance)
|
||||
return
|
||||
}
|
||||
this.componentList.push(chartConfig)
|
||||
this.componentList.push(componentInstance)
|
||||
},
|
||||
// * 删除组件列表
|
||||
removeComponentList(isHistory = true): void {
|
||||
// * 删除组件
|
||||
removeComponentList(id?: string | string[], isHistory = true): void {
|
||||
try {
|
||||
const idArr = this.idPreFormat(id)
|
||||
const history: Array<CreateComponentType | CreateComponentGroupType> = []
|
||||
// 遍历所有对象
|
||||
if (!idArr.length) return
|
||||
|
||||
loadingStart()
|
||||
const index = this.fetchTargetIndex()
|
||||
idArr.forEach(ids => {
|
||||
const index = this.fetchTargetIndex(ids)
|
||||
if (index !== -1) {
|
||||
isHistory ? chartHistoryStore.createDeleteHistory(this.getComponentList[index]) : undefined
|
||||
history.push(this.getComponentList[index])
|
||||
this.componentList.splice(index, 1)
|
||||
}
|
||||
})
|
||||
isHistory && chartHistoryStore.createDeleteHistory(history)
|
||||
loadingFinish()
|
||||
return
|
||||
}
|
||||
} catch (value) {
|
||||
loadingError()
|
||||
}
|
||||
},
|
||||
// * 更新组件列表某一项的值
|
||||
updateComponentList(index: number, newData: CreateComponentType) {
|
||||
updateComponentList(index: number, newData: CreateComponentType | CreateComponentGroupType) {
|
||||
if (index < 1 && index > this.getComponentList.length) return
|
||||
this.componentList[index] = newData
|
||||
},
|
||||
// * 设置页面样式属性
|
||||
setPageStyle<T extends keyof CSSStyleDeclaration>(
|
||||
key: T,
|
||||
value: any
|
||||
): void {
|
||||
setPageStyle<T extends keyof CSSStyleDeclaration>(key: T, value: any): void {
|
||||
const dom = this.getEditCanvas.editContentDom
|
||||
if (dom) {
|
||||
dom.style[key] = value
|
||||
@ -286,6 +326,9 @@ export const useChartEditStore = defineStore({
|
||||
// * 移动组件列表层级位置到两端
|
||||
setBothEnds(isEnd = false, isHistory = true): void {
|
||||
try {
|
||||
// 暂不支持多选
|
||||
if (this.getTargetChart.selectId.length > 1) return
|
||||
|
||||
loadingStart()
|
||||
const length = this.getComponentList.length
|
||||
if (length < 2) {
|
||||
@ -303,8 +346,8 @@ export const useChartEditStore = defineStore({
|
||||
}
|
||||
|
||||
// 记录原有位置
|
||||
const setIndex = (t:CreateComponentType, i:number) => {
|
||||
const temp = cloneDeep(t)
|
||||
const setIndex = (componentInstance: CreateComponentType | CreateComponentGroupType, i: number) => {
|
||||
const temp = cloneDeep(componentInstance)
|
||||
temp.attr.zIndex = i
|
||||
return temp
|
||||
}
|
||||
@ -312,7 +355,7 @@ export const useChartEditStore = defineStore({
|
||||
// 历史记录
|
||||
if (isHistory) {
|
||||
chartHistoryStore.createLayerHistory(
|
||||
setIndex(targetData, index),
|
||||
[setIndex(targetData, index)],
|
||||
isEnd ? HistoryActionTypeEnum.BOTTOM : HistoryActionTypeEnum.TOP
|
||||
)
|
||||
}
|
||||
@ -338,6 +381,9 @@ export const useChartEditStore = defineStore({
|
||||
// * 上移/下移互换图表位置
|
||||
wrap(isDown = false, isHistory = true) {
|
||||
try {
|
||||
// 暂不支持多选
|
||||
if (this.getTargetChart.selectId.length > 1) return
|
||||
|
||||
loadingStart()
|
||||
const length = this.getComponentList.length
|
||||
if (length < 2) {
|
||||
@ -360,7 +406,7 @@ export const useChartEditStore = defineStore({
|
||||
// 历史记录
|
||||
if (isHistory) {
|
||||
chartHistoryStore.createLayerHistory(
|
||||
targetItem,
|
||||
[targetItem],
|
||||
isDown ? HistoryActionTypeEnum.DOWN : HistoryActionTypeEnum.UP
|
||||
)
|
||||
}
|
||||
@ -384,6 +430,9 @@ export const useChartEditStore = defineStore({
|
||||
// * 复制
|
||||
setCopy(isCut = false) {
|
||||
try {
|
||||
// 暂不支持多选
|
||||
if (this.getTargetChart.selectId.length > 1) return
|
||||
|
||||
loadingStart()
|
||||
const index: number = this.fetchTargetIndex()
|
||||
if (index !== -1) {
|
||||
@ -412,7 +461,7 @@ export const useChartEditStore = defineStore({
|
||||
loadingFinish()
|
||||
return
|
||||
}
|
||||
const parseHandle = (e: CreateComponentType) => {
|
||||
const parseHandle = (e: CreateComponentType | CreateComponentGroupType) => {
|
||||
e = cloneDeep(e)
|
||||
// 生成新 id
|
||||
e.id = getUUID()
|
||||
@ -428,7 +477,7 @@ export const useChartEditStore = defineStore({
|
||||
// 剪切需删除原数据
|
||||
if (isCut) {
|
||||
this.setTargetSelectChart(e.id)
|
||||
this.removeComponentList(true)
|
||||
this.removeComponentList(undefined, true)
|
||||
}
|
||||
})
|
||||
if (isCut) this.setRecordChart(undefined)
|
||||
@ -448,45 +497,54 @@ export const useChartEditStore = defineStore({
|
||||
}
|
||||
},
|
||||
// * 撤回/前进 目标处理
|
||||
setBackAndSetForwardHandle(item: HistoryItemType, isForward = false) {
|
||||
setBackAndSetForwardHandle(HistoryItem: HistoryItemType, isForward = false) {
|
||||
// 处理画布
|
||||
if (item.targetType === HistoryTargetTypeEnum.CANVAS) {
|
||||
this.editCanvas = item.historyData as EditCanvasType
|
||||
if (HistoryItem.targetType === HistoryTargetTypeEnum.CANVAS) {
|
||||
this.editCanvas = HistoryItem.historyData[0] as EditCanvasType
|
||||
return
|
||||
}
|
||||
|
||||
const historyData = item.historyData as CreateComponentType
|
||||
let historyData = HistoryItem.historyData as Array<CreateComponentType | CreateComponentGroupType>
|
||||
if (isArray(historyData)) {
|
||||
// 选中目标元素,支持多个
|
||||
historyData.forEach((item: CreateComponentType | CreateComponentGroupType) => {
|
||||
this.setTargetSelectChart(item.id, true)
|
||||
})
|
||||
}
|
||||
|
||||
// 处理新增类型
|
||||
const isAdd = item.actionType === HistoryActionTypeEnum.ADD
|
||||
const isDel = item.actionType === HistoryActionTypeEnum.DELETE
|
||||
this.setTargetSelectChart(historyData.id)
|
||||
const isAdd = HistoryItem.actionType === HistoryActionTypeEnum.ADD
|
||||
const isDel = HistoryItem.actionType === HistoryActionTypeEnum.DELETE
|
||||
if (isAdd || isDel) {
|
||||
if ((isAdd && isForward) || (isDel && !isForward)) {
|
||||
this.addComponentList(historyData)
|
||||
historyData.forEach(item => {
|
||||
this.addComponentList(item)
|
||||
})
|
||||
return
|
||||
}
|
||||
this.removeComponentList(false)
|
||||
historyData.forEach(item => {
|
||||
this.removeComponentList(item.id, false)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 处理层级
|
||||
const isTop = item.actionType === HistoryActionTypeEnum.TOP
|
||||
const isBottom = item.actionType === HistoryActionTypeEnum.BOTTOM
|
||||
const isTop = HistoryItem.actionType === HistoryActionTypeEnum.TOP
|
||||
const isBottom = HistoryItem.actionType === HistoryActionTypeEnum.BOTTOM
|
||||
if (isTop || isBottom) {
|
||||
if (!isForward) {
|
||||
// 插入到原有位置
|
||||
if (isTop) this.getComponentList.pop()
|
||||
if (isBottom) this.getComponentList.shift()
|
||||
this.getComponentList.splice(historyData.attr.zIndex, 0, historyData)
|
||||
this.getComponentList.splice(historyData[0].attr.zIndex, 0, historyData[0])
|
||||
return
|
||||
}
|
||||
if (isTop) this.setTop(false)
|
||||
if (isBottom) this.setBottom(false)
|
||||
}
|
||||
|
||||
const isUp = item.actionType === HistoryActionTypeEnum.UP
|
||||
const isDown = item.actionType === HistoryActionTypeEnum.DOWN
|
||||
const isUp = HistoryItem.actionType === HistoryActionTypeEnum.UP
|
||||
const isDown = HistoryItem.actionType === HistoryActionTypeEnum.DOWN
|
||||
if (isUp || isDown) {
|
||||
if ((isUp && isForward) || (isDown && !isForward)) {
|
||||
this.setUp(false)
|
||||
@ -496,8 +554,32 @@ export const useChartEditStore = defineStore({
|
||||
return
|
||||
}
|
||||
|
||||
// 处理内容修改
|
||||
this.getComponentList[this.fetchTargetIndex()] = item.historyData as CreateComponentType
|
||||
// 处理分组
|
||||
const isGroup = HistoryItem.actionType === HistoryActionTypeEnum.GROUP
|
||||
const isUnGroup = HistoryItem.actionType === HistoryActionTypeEnum.UN_GROUP
|
||||
if (isGroup || isUnGroup) {
|
||||
if ((isGroup && isForward) || (isUnGroup && !isForward)) {
|
||||
const ids: string[] = []
|
||||
if(historyData.length > 1) {
|
||||
historyData.forEach(item => {
|
||||
ids.push(item.id)
|
||||
})
|
||||
} else {
|
||||
(historyData[0] as CreateComponentGroupType).groupList.forEach(item => {
|
||||
ids.push(item.id)
|
||||
})
|
||||
}
|
||||
this.setGroup(ids, false)
|
||||
return
|
||||
}
|
||||
// 都需使用子组件的id去解组
|
||||
if(historyData.length > 1) {
|
||||
this.setUnGroup([(historyData[0] as CreateComponentType).id], undefined, false)
|
||||
} else {
|
||||
this.setUnGroup([(historyData[0] as CreateComponentGroupType).groupList[0].id], undefined, false)
|
||||
}
|
||||
return
|
||||
}
|
||||
},
|
||||
// * 撤回
|
||||
setBack() {
|
||||
@ -508,16 +590,8 @@ export const useChartEditStore = defineStore({
|
||||
loadingFinish()
|
||||
return
|
||||
}
|
||||
if (Array.isArray(targetData)) {
|
||||
targetData.forEach((e: HistoryItemType) => {
|
||||
this.setBackAndSetForwardHandle(e)
|
||||
})
|
||||
loadingFinish()
|
||||
return
|
||||
}
|
||||
this.setBackAndSetForwardHandle(targetData)
|
||||
loadingFinish()
|
||||
|
||||
} catch (value) {
|
||||
loadingError()
|
||||
}
|
||||
@ -531,16 +605,8 @@ export const useChartEditStore = defineStore({
|
||||
loadingFinish()
|
||||
return
|
||||
}
|
||||
if (Array.isArray(targetData)) {
|
||||
targetData.forEach((e: HistoryItemType) => {
|
||||
this.setBackAndSetForwardHandle(e, true)
|
||||
})
|
||||
loadingFinish()
|
||||
return
|
||||
}
|
||||
this.setBackAndSetForwardHandle(targetData, true)
|
||||
loadingFinish()
|
||||
|
||||
} catch (value) {
|
||||
loadingError()
|
||||
}
|
||||
@ -554,16 +620,142 @@ export const useChartEditStore = defineStore({
|
||||
switch (keyboardValue) {
|
||||
case MenuEnum.ARROW_UP:
|
||||
attr.y -= distance
|
||||
break;
|
||||
break
|
||||
case MenuEnum.ARROW_RIGHT:
|
||||
attr.x += distance
|
||||
break;
|
||||
break
|
||||
case MenuEnum.ARROW_DOWN:
|
||||
attr.y += distance
|
||||
break;
|
||||
break
|
||||
case MenuEnum.ARROW_LEFT:
|
||||
attr.x -= distance
|
||||
break;
|
||||
break
|
||||
}
|
||||
},
|
||||
// * 创建分组
|
||||
setGroup(id?: string | string[], isHistory = true) {
|
||||
try {
|
||||
const selectIds = this.idPreFormat(id) || this.getTargetChart.selectId
|
||||
if (selectIds.length < 2) return
|
||||
|
||||
loadingStart()
|
||||
const groupClass = new PublicGroupConfigClass()
|
||||
// 记录整体坐标
|
||||
const groupAttr = {
|
||||
l: this.getEditCanvasConfig.width,
|
||||
t: this.getEditCanvasConfig.height,
|
||||
r: 0,
|
||||
b: 0
|
||||
}
|
||||
const targetList: CreateComponentType[] = []
|
||||
const historyList: CreateComponentType[] = []
|
||||
|
||||
// 若目标中有数组则先解组
|
||||
const newSelectIds: string[] = []
|
||||
selectIds.forEach((id: string) => {
|
||||
const targetIndex = this.fetchTargetIndex(id)
|
||||
if (targetIndex !== -1 && this.getComponentList[targetIndex].isGroup) {
|
||||
this.setUnGroup(
|
||||
[id],
|
||||
(e: CreateComponentType[]) => {
|
||||
e.forEach(e => {
|
||||
this.addComponentList(e)
|
||||
newSelectIds.push(e.id)
|
||||
})
|
||||
},
|
||||
false
|
||||
)
|
||||
} else if (targetIndex !== -1) {
|
||||
newSelectIds.push(id)
|
||||
}
|
||||
})
|
||||
newSelectIds.forEach((id: string) => {
|
||||
// 获取目标数据并从 list 中移除 (成组后不可再次成组, 断言处理)
|
||||
const item = this.componentList.splice(this.fetchTargetIndex(id), 1)[0] as CreateComponentType
|
||||
const { x, y, w, h } = item.attr
|
||||
const { l, t, r, b } = groupAttr
|
||||
// 左
|
||||
groupAttr.l = l > x ? x : l
|
||||
// 上
|
||||
groupAttr.t = t > y ? y : t
|
||||
// 宽
|
||||
groupAttr.r = r < x + w ? x + w : r
|
||||
// 高
|
||||
groupAttr.b = b < y + h ? y + h : b
|
||||
|
||||
targetList.push(item)
|
||||
historyList.push(toRaw(item))
|
||||
})
|
||||
|
||||
// 修改原数据之前,先记录
|
||||
if (isHistory) chartHistoryStore.createGroupHistory(historyList)
|
||||
|
||||
// 设置子组件的位置
|
||||
targetList.forEach((item: CreateComponentType) => {
|
||||
item.attr.x = item.attr.x - groupAttr.l
|
||||
item.attr.y = item.attr.y - groupAttr.t
|
||||
groupClass.groupList.push(item)
|
||||
})
|
||||
|
||||
// 设置 group 属性
|
||||
groupClass.attr.x = groupAttr.l
|
||||
groupClass.attr.y = groupAttr.t
|
||||
groupClass.attr.w = groupAttr.r - groupAttr.l
|
||||
groupClass.attr.h = groupAttr.b - groupAttr.t
|
||||
|
||||
this.addComponentList(groupClass)
|
||||
this.setTargetSelectChart(groupClass.id)
|
||||
|
||||
loadingFinish()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
window['$message'].error('创建分组失败,请联系管理员!')
|
||||
loadingFinish()
|
||||
}
|
||||
},
|
||||
// * 解除分组
|
||||
setUnGroup(ids?: string[], callBack?: (e: CreateComponentType[]) => void, isHistory = true) {
|
||||
try {
|
||||
const selectGroupIdArr = ids || this.getTargetChart.selectId
|
||||
if (selectGroupIdArr.length !== 1) return
|
||||
loadingStart()
|
||||
|
||||
// 解组
|
||||
const unGroup = (targetIndex: number) => {
|
||||
const targetGroup = this.getComponentList[targetIndex] as CreateComponentGroupType
|
||||
if (!targetGroup.isGroup) return
|
||||
|
||||
// 记录数据
|
||||
if (isHistory) chartHistoryStore.createUnGroupHistory(cloneDeep([targetGroup]))
|
||||
|
||||
// 分离组件并还原位置属性
|
||||
targetGroup.groupList.forEach(item => {
|
||||
item.attr.x = item.attr.x + targetGroup.attr.x
|
||||
item.attr.y = item.attr.y + targetGroup.attr.y
|
||||
if (!callBack) {
|
||||
this.addComponentList(item)
|
||||
}
|
||||
})
|
||||
this.setTargetSelectChart(targetGroup.id)
|
||||
// 删除分组
|
||||
this.removeComponentList(targetGroup.id, false)
|
||||
|
||||
if (callBack) {
|
||||
callBack(targetGroup.groupList)
|
||||
}
|
||||
}
|
||||
|
||||
const targetIndex = this.fetchTargetIndex(selectGroupIdArr[0])
|
||||
// 判断目标是否为分组父级
|
||||
if (targetIndex !== -1) {
|
||||
unGroup(targetIndex)
|
||||
}
|
||||
|
||||
loadingFinish()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
window['$message'].error('解除分组失败,请联系管理员!')
|
||||
loadingFinish()
|
||||
}
|
||||
},
|
||||
// ----------------
|
||||
@ -576,32 +768,24 @@ export const useChartEditStore = defineStore({
|
||||
computedScale() {
|
||||
if (this.getEditCanvas.editLayoutDom) {
|
||||
// 现有展示区域
|
||||
const width =
|
||||
this.getEditCanvas.editLayoutDom.clientWidth - this.getEditCanvas.offset * 2 - 5
|
||||
const height =
|
||||
this.getEditCanvas.editLayoutDom.clientHeight - this.getEditCanvas.offset * 4
|
||||
const width = this.getEditCanvas.editLayoutDom.clientWidth - this.getEditCanvas.offset * 2 - 5
|
||||
const height = this.getEditCanvas.editLayoutDom.clientHeight - this.getEditCanvas.offset * 4
|
||||
|
||||
// 用户设定大小
|
||||
const editCanvasWidth = this.editCanvasConfig.width
|
||||
const editCanvasHeight = this.editCanvasConfig.height
|
||||
|
||||
// 需保持的比例
|
||||
const baseProportion = parseFloat(
|
||||
(editCanvasWidth / editCanvasHeight).toFixed(5)
|
||||
)
|
||||
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)
|
||||
)
|
||||
const scaleWidth = parseFloat(((height * baseProportion) / editCanvasWidth).toFixed(5))
|
||||
this.setScale(scaleWidth > 1 ? 1 : scaleWidth)
|
||||
} else {
|
||||
// 表示更高
|
||||
const scaleHeight = parseFloat(
|
||||
(width / baseProportion / editCanvasHeight).toFixed(5)
|
||||
)
|
||||
const scaleHeight = parseFloat((width / baseProportion / editCanvasHeight).toFixed(5))
|
||||
this.setScale(scaleHeight > 1 ? 1 : scaleHeight)
|
||||
}
|
||||
} else {
|
||||
|
@ -15,6 +15,8 @@ export const historyActionTypeName = {
|
||||
[HistoryActionTypeEnum.BOTTOM]: '层级置底',
|
||||
[HistoryActionTypeEnum.UP]: '层级上移',
|
||||
[HistoryActionTypeEnum.DOWN]: '层级下移',
|
||||
[HistoryActionTypeEnum.GROUP]: '创建分组',
|
||||
[HistoryActionTypeEnum.UN_GROUP]: '解除分组',
|
||||
[HistoryActionTypeEnum.SELECT_HISTORY]: '选择记录',
|
||||
|
||||
[HistoryTargetTypeEnum.CANVAS]: '画布初始化'
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { EditCanvasType } from '@/store/modules/chartEditStore/chartEditStore.d'
|
||||
|
||||
// 操作类型枚举
|
||||
@ -25,6 +25,10 @@ export enum HistoryActionTypeEnum {
|
||||
UP = 'up',
|
||||
// 下移
|
||||
DOWN = 'down',
|
||||
// 成组
|
||||
GROUP = 'group',
|
||||
// 解组
|
||||
UN_GROUP = 'unGroup',
|
||||
// 选择历史记录
|
||||
SELECT_HISTORY = 'selectHistory'
|
||||
}
|
||||
@ -51,10 +55,11 @@ export enum HistoryStackItemEnum {
|
||||
|
||||
// 历史记录项类型
|
||||
export interface HistoryItemType {
|
||||
// 会有同时操作多个组件场景
|
||||
[HistoryStackItemEnum.ID]: string
|
||||
[HistoryStackItemEnum.TARGET_TYPE]: HistoryTargetTypeEnum
|
||||
[HistoryStackItemEnum.ACTION_TYPE]: HistoryActionTypeEnum
|
||||
[HistoryStackItemEnum.HISTORY_DATA]: CreateComponentType | EditCanvasType
|
||||
[HistoryStackItemEnum.HISTORY_DATA]: CreateComponentType[] | CreateComponentGroupType[] | EditCanvasType[]
|
||||
}
|
||||
|
||||
// 历史 Store 类型
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { EditCanvasType } from '@/store/modules/chartEditStore/chartEditStore.d'
|
||||
import { loadingStart, loadingFinish, loadingError } from '@/utils'
|
||||
import { editHistoryMax } from '@/settings/designSetting'
|
||||
@ -35,31 +35,26 @@ export const useChartHistoryStore = defineStore({
|
||||
* @param targetType 对象类型(默认图表)
|
||||
*/
|
||||
createStackItem(
|
||||
item: CreateComponentType | EditCanvasType,
|
||||
item: CreateComponentType[] | CreateComponentGroupType[] | EditCanvasType[],
|
||||
actionType: HistoryActionTypeEnum,
|
||||
targetType: HistoryTargetTypeEnum = HistoryTargetTypeEnum.CHART
|
||||
) {
|
||||
// 优化性能转为 freeze
|
||||
this.pushBackStackItem(Object.freeze({
|
||||
this.pushBackStackItem(
|
||||
Object.freeze({
|
||||
[HistoryStackItemEnum.ID]: new Date().getTime().toString(),
|
||||
[HistoryStackItemEnum.HISTORY_DATA]: item,
|
||||
[HistoryStackItemEnum.ACTION_TYPE]: actionType,
|
||||
[HistoryStackItemEnum.TARGET_TYPE]: targetType
|
||||
} as const))
|
||||
} as const)
|
||||
)
|
||||
},
|
||||
// * 画布初始化
|
||||
canvasInit(canvas: EditCanvasType) {
|
||||
this.createStackItem(
|
||||
canvas,
|
||||
HistoryActionTypeEnum.ADD,
|
||||
HistoryTargetTypeEnum.CANVAS
|
||||
)
|
||||
this.createStackItem([canvas], HistoryActionTypeEnum.ADD, HistoryTargetTypeEnum.CANVAS)
|
||||
},
|
||||
// * 推入后退栈
|
||||
pushBackStackItem(
|
||||
item: HistoryItemType | Array<HistoryItemType>,
|
||||
notClear = false
|
||||
): void {
|
||||
pushBackStackItem(item: HistoryItemType | Array<HistoryItemType>, notClear = false): void {
|
||||
if (item instanceof Array) this.backStack = [...this.backStack, ...item]
|
||||
else this.backStack.push(item)
|
||||
this.backStack.splice(0, this.backStack.length - editHistoryMax)
|
||||
@ -69,30 +64,17 @@ export const useChartHistoryStore = defineStore({
|
||||
},
|
||||
// * 推入前进栈
|
||||
pushForwardStack(item: HistoryItemType | Array<HistoryItemType>): void {
|
||||
if (item instanceof Array)
|
||||
this.forwardStack = [...this.forwardStack, ...item]
|
||||
if (item instanceof Array) this.forwardStack = [...this.forwardStack, ...item]
|
||||
else this.forwardStack.push(item)
|
||||
},
|
||||
// * 移出后退栈
|
||||
popBackStackItem(
|
||||
index?: number
|
||||
): HistoryItemType[] | HistoryItemType | undefined {
|
||||
const length = this.backStack.length
|
||||
if (index && length >= index) {
|
||||
return this.backStack.splice(-index)
|
||||
}
|
||||
popBackStackItem(): HistoryItemType | undefined {
|
||||
if (this.backStack.length > 0) {
|
||||
return this.backStack.pop()
|
||||
}
|
||||
},
|
||||
// * 移出前进栈
|
||||
popForwardStack(
|
||||
index?: number
|
||||
): HistoryItemType[] | HistoryItemType | undefined {
|
||||
const length = this.forwardStack.length
|
||||
if (index && length >= index) {
|
||||
return this.forwardStack.splice(-index)
|
||||
}
|
||||
popForwardStack(): HistoryItemType | undefined {
|
||||
if (this.forwardStack.length > 0) {
|
||||
return this.forwardStack.pop()
|
||||
}
|
||||
@ -148,59 +130,43 @@ export const useChartHistoryStore = defineStore({
|
||||
}
|
||||
},
|
||||
// * 新增组件记录
|
||||
createAddHistory(item: CreateComponentType) {
|
||||
this.createStackItem(
|
||||
item,
|
||||
HistoryActionTypeEnum.ADD,
|
||||
HistoryTargetTypeEnum.CHART
|
||||
)
|
||||
createAddHistory(item: Array<CreateComponentType | CreateComponentGroupType>) {
|
||||
this.createStackItem(item, HistoryActionTypeEnum.ADD, HistoryTargetTypeEnum.CHART)
|
||||
},
|
||||
// * 更新属性记录(大小、图表属性)
|
||||
createUpdateHistory(item: CreateComponentType) {
|
||||
this.createStackItem(
|
||||
item,
|
||||
HistoryActionTypeEnum.UPDATE,
|
||||
HistoryTargetTypeEnum.CHART
|
||||
)
|
||||
createUpdateHistory(item: Array<CreateComponentType | CreateComponentGroupType>) {
|
||||
this.createStackItem(item, HistoryActionTypeEnum.UPDATE, HistoryTargetTypeEnum.CHART)
|
||||
},
|
||||
// * 删除组件记录
|
||||
createDeleteHistory(item: CreateComponentType) {
|
||||
this.createStackItem(
|
||||
item,
|
||||
HistoryActionTypeEnum.DELETE,
|
||||
HistoryTargetTypeEnum.CHART
|
||||
)
|
||||
createDeleteHistory(item: Array<CreateComponentType | CreateComponentGroupType>) {
|
||||
this.createStackItem(item, HistoryActionTypeEnum.DELETE, HistoryTargetTypeEnum.CHART)
|
||||
},
|
||||
// * 移动组件记录
|
||||
createMoveHistory(item: CreateComponentType) {
|
||||
this.createStackItem(
|
||||
item,
|
||||
HistoryActionTypeEnum.MOVE,
|
||||
HistoryTargetTypeEnum.CHART
|
||||
)
|
||||
createMoveHistory(item: Array<CreateComponentType | CreateComponentGroupType>) {
|
||||
this.createStackItem(item, HistoryActionTypeEnum.MOVE, HistoryTargetTypeEnum.CHART)
|
||||
},
|
||||
// * 改变层级组件记录
|
||||
createLayerHistory(
|
||||
item: CreateComponentType,
|
||||
item: Array<CreateComponentType | CreateComponentGroupType>,
|
||||
type:
|
||||
| HistoryActionTypeEnum.TOP
|
||||
| HistoryActionTypeEnum.DOWN
|
||||
| HistoryActionTypeEnum.UP
|
||||
| HistoryActionTypeEnum.BOTTOM
|
||||
) {
|
||||
this.createStackItem(
|
||||
item,
|
||||
type,
|
||||
HistoryTargetTypeEnum.CHART
|
||||
)
|
||||
this.createStackItem(item, type, HistoryTargetTypeEnum.CHART)
|
||||
},
|
||||
// * 剪切组件记录
|
||||
createPasteHistory(item: CreateComponentType) {
|
||||
this.createStackItem(
|
||||
item,
|
||||
HistoryActionTypeEnum.CUT,
|
||||
HistoryTargetTypeEnum.CHART
|
||||
)
|
||||
createPasteHistory(item: Array<CreateComponentType | CreateComponentGroupType>) {
|
||||
this.createStackItem(item, HistoryActionTypeEnum.CUT, HistoryTargetTypeEnum.CHART)
|
||||
},
|
||||
// * 创建分组
|
||||
createGroupHistory(item: Array<CreateComponentType | CreateComponentGroupType>) {
|
||||
this.createStackItem(item, HistoryActionTypeEnum.GROUP, HistoryTargetTypeEnum.CHART)
|
||||
},
|
||||
// * 解除分组
|
||||
createUnGroupHistory(item: Array<CreateComponentType | CreateComponentGroupType>) {
|
||||
this.createStackItem(item, HistoryActionTypeEnum.UN_GROUP, HistoryTargetTypeEnum.CHART)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -96,7 +96,7 @@
|
||||
</n-space>
|
||||
|
||||
<!-- 滤镜 -->
|
||||
<styles-setting :is-canvas="true" :chartStyles="canvasConfig"></styles-setting>
|
||||
<styles-setting :isCanvas="true" :chartStyles="canvasConfig"></styles-setting>
|
||||
<n-divider style="margin: 10px 0;"></n-divider>
|
||||
|
||||
<!-- 主题选择和全局配置 -->
|
||||
|
@ -15,7 +15,7 @@
|
||||
<template #action>
|
||||
<n-space justify="space-between">
|
||||
<div>
|
||||
<n-text>「 {{ chartConfig.categoryName || rename }} 」</n-text>
|
||||
<n-text>「 {{ chartConfig.categoryName }} 」</n-text>
|
||||
<n-text>—— </n-text>
|
||||
<n-tag type="primary" :bordered="false" style="border-radius: 5px"> {{ requestContentTypeObj[requestContentType] }} </n-tag>
|
||||
</div>
|
||||
@ -37,9 +37,8 @@ const emit = defineEmits(['update:modelShow'])
|
||||
|
||||
const { targetData } = useTargetData()
|
||||
// 解构基础配置
|
||||
const { chartConfig, rename } = toRefs(targetData.value)
|
||||
const { chartConfig } = toRefs(targetData.value)
|
||||
const { requestContentType } = toRefs(targetData.value.request)
|
||||
|
||||
const requestContentTypeObj = {
|
||||
[RequestContentTypeEnum.DEFAULT]: '普通请求',
|
||||
[RequestContentTypeEnum.SQL]: 'SQL 请求'
|
||||
|
@ -3,11 +3,11 @@
|
||||
<!-- 名称 -->
|
||||
<name-setting :chartConfig="targetData.chartConfig"></name-setting>
|
||||
<!-- 尺寸 -->
|
||||
<size-setting :chartAttr="targetData.attr"></size-setting>
|
||||
<size-setting :isGroup="targetData.isGroup" :chartAttr="targetData.attr"></size-setting>
|
||||
<!-- 位置 -->
|
||||
<position-setting :chartAttr="targetData.attr" :canvasConfig="chartEditStore.getEditCanvasConfig"/>
|
||||
<!-- 滤镜 -->
|
||||
<styles-setting :chartStyles="targetData.styles"></styles-setting>
|
||||
<styles-setting :isGroup="targetData.isGroup" :chartStyles="targetData.styles"></styles-setting>
|
||||
<!-- 自定义配置项 -->
|
||||
<component :is="targetData.chartConfig.conKey" :optionData="targetData.option"></component>
|
||||
</div>
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { computed, Ref } from 'vue'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
|
||||
// 获取当前对象数据
|
||||
export const useTargetData = () => {
|
||||
const chartEditStore = useChartEditStore()
|
||||
const targetData: Ref<CreateComponentType> = computed(() => {
|
||||
const targetData: Ref<CreateComponentType | CreateComponentGroupType> = computed(() => {
|
||||
const list = chartEditStore.getComponentList
|
||||
const targetIndex = chartEditStore.fetchTargetIndex()
|
||||
return list[targetIndex]
|
||||
|
6
src/views/chart/ContentConfigurations/index.d.ts
vendored
Normal file
6
src/views/chart/ContentConfigurations/index.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
export enum TabsEnum {
|
||||
PAGE_SETTING = 'pageSetting',
|
||||
CHART_SETTING = 'chartSetting',
|
||||
CHART_ANIMATION = 'chartAnimation',
|
||||
CHART_DATA = 'chartData',
|
||||
}
|
@ -11,21 +11,12 @@
|
||||
:collapsed="collapsed"
|
||||
:native-scrollbar="false"
|
||||
show-trigger="bar"
|
||||
@collapse="collapsedHindle"
|
||||
@expand="expandHindle"
|
||||
>
|
||||
<content-box
|
||||
class="go-content-layers go-boderbox"
|
||||
:show-top="false"
|
||||
:depth="2"
|
||||
@collapse="collapsedHandle"
|
||||
@expand="expandHandle"
|
||||
>
|
||||
<content-box class="go-content-layers go-boderbox" :show-top="false" :depth="2">
|
||||
<!-- 页面配置 -->
|
||||
<n-tabs
|
||||
v-show="!selectTarget"
|
||||
class="tabs-box"
|
||||
size="small"
|
||||
type="segment"
|
||||
>
|
||||
<n-tabs v-if="!selectTarget" class="tabs-box" size="small" type="segment">
|
||||
<n-tab-pane
|
||||
v-for="item in globalTabList"
|
||||
:key="item.key"
|
||||
@ -46,14 +37,9 @@
|
||||
</n-tabs>
|
||||
|
||||
<!-- 编辑 -->
|
||||
<n-tabs
|
||||
v-show="selectTarget"
|
||||
class="tabs-box"
|
||||
size="small"
|
||||
type="segment"
|
||||
>
|
||||
<n-tabs v-if="selectTarget" v-model:value="tabsSelect" class="tabs-box" size="small" type="segment">
|
||||
<n-tab-pane
|
||||
v-for="(item) in canvasTabList"
|
||||
v-for="item in selectTarget.isGroup ? chartsDefaultTabList : chartsTabList"
|
||||
:key="item.key"
|
||||
:name="item.key"
|
||||
size="small"
|
||||
@ -80,6 +66,7 @@ import { ref, toRefs, watch, computed } from 'vue'
|
||||
import { icon } from '@/plugins'
|
||||
import { loadAsyncComponent } from '@/utils'
|
||||
import { ContentBox } from '../ContentBox/index'
|
||||
import { TabsEnum } from './index.d'
|
||||
import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore'
|
||||
import { ChartLayoutStoreEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
@ -88,35 +75,23 @@ const { getDetails } = toRefs(useChartLayoutStore())
|
||||
const { setItem } = useChartLayoutStore()
|
||||
const chartEditStore = useChartEditStore()
|
||||
|
||||
const {
|
||||
ConstructIcon,
|
||||
FlashIcon,
|
||||
DesktopOutlineIcon,
|
||||
LeafIcon
|
||||
} = icon.ionicons5
|
||||
const { ConstructIcon, FlashIcon, DesktopOutlineIcon, LeafIcon } = icon.ionicons5
|
||||
|
||||
const ContentEdit = loadAsyncComponent(() => import('../ContentEdit/index.vue'))
|
||||
const CanvasPage = loadAsyncComponent(() =>
|
||||
import('./components/CanvasPage/index.vue')
|
||||
)
|
||||
const ChartSetting = loadAsyncComponent(() =>
|
||||
import('./components/ChartSetting/index.vue')
|
||||
)
|
||||
const ChartData = loadAsyncComponent(() =>
|
||||
import('./components/ChartData/index.vue')
|
||||
)
|
||||
const ChartAnimation = loadAsyncComponent(() =>
|
||||
import('./components/ChartAnimation/index.vue')
|
||||
)
|
||||
const CanvasPage = loadAsyncComponent(() => import('./components/CanvasPage/index.vue'))
|
||||
const ChartSetting = loadAsyncComponent(() => import('./components/ChartSetting/index.vue'))
|
||||
const ChartData = loadAsyncComponent(() => import('./components/ChartData/index.vue'))
|
||||
const ChartAnimation = loadAsyncComponent(() => import('./components/ChartAnimation/index.vue'))
|
||||
|
||||
const collapsed = ref<boolean>(getDetails.value)
|
||||
const tabsSelect = ref<TabsEnum>(TabsEnum.CHART_SETTING)
|
||||
|
||||
const collapsedHindle = () => {
|
||||
const collapsedHandle = () => {
|
||||
collapsed.value = true
|
||||
setItem(ChartLayoutStoreEnum.DETAILS, true)
|
||||
}
|
||||
|
||||
const expandHindle = () => {
|
||||
const expandHandle = () => {
|
||||
collapsed.value = false
|
||||
setItem(ChartLayoutStoreEnum.DETAILS, false)
|
||||
}
|
||||
@ -125,42 +100,50 @@ const selectTarget = computed(() => {
|
||||
const selectId = chartEditStore.getTargetChart.selectId
|
||||
// 排除多个
|
||||
if (selectId.length !== 1) return undefined
|
||||
return chartEditStore.componentList[chartEditStore.fetchTargetIndex()]
|
||||
const target = chartEditStore.componentList[chartEditStore.fetchTargetIndex()]
|
||||
if (target?.isGroup) {
|
||||
tabsSelect.value = TabsEnum.CHART_SETTING
|
||||
}
|
||||
return target
|
||||
})
|
||||
|
||||
watch(getDetails, newData => {
|
||||
if (newData) {
|
||||
collapsedHindle()
|
||||
collapsedHandle()
|
||||
} else {
|
||||
expandHindle()
|
||||
expandHandle()
|
||||
}
|
||||
})
|
||||
|
||||
// 页面设置
|
||||
const globalTabList = [
|
||||
{
|
||||
key: 'pageSetting',
|
||||
key: TabsEnum.PAGE_SETTING,
|
||||
title: '页面配置',
|
||||
icon: DesktopOutlineIcon,
|
||||
render: CanvasPage
|
||||
}
|
||||
]
|
||||
|
||||
const canvasTabList = [
|
||||
const chartsDefaultTabList = [
|
||||
{
|
||||
key: 'ChartSetting',
|
||||
key: TabsEnum.CHART_SETTING,
|
||||
title: '定制',
|
||||
icon: ConstructIcon,
|
||||
render: ChartSetting
|
||||
},
|
||||
{
|
||||
key: 'ChartAnimation',
|
||||
key: TabsEnum.CHART_ANIMATION,
|
||||
title: '动画',
|
||||
icon: LeafIcon,
|
||||
render: ChartAnimation
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
const chartsTabList = [
|
||||
...chartsDefaultTabList,
|
||||
{
|
||||
key: 'ChartData',
|
||||
key: TabsEnum.CHART_DATA,
|
||||
title: '数据',
|
||||
icon: FlashIcon,
|
||||
render: ChartData
|
||||
|
@ -16,7 +16,7 @@ import { useDesignStore } from '@/store/modules/designStore/designStore'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
|
||||
import { useSettingStore } from '@/store/modules/settingStore/settingStore'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import throttle from 'lodash/throttle'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
// 全局颜色
|
||||
@ -111,7 +111,7 @@ watch(
|
||||
line.select.clear()
|
||||
line.sorptioned.y = false
|
||||
// 循环查询所有组件数据
|
||||
const componentList = chartEditStore.getComponentList.map((e: CreateComponentType) => {
|
||||
const componentList = chartEditStore.getComponentList.map((e: CreateComponentType | CreateComponentGroupType) => {
|
||||
return {
|
||||
id: e.id,
|
||||
attr: e.attr
|
||||
@ -228,30 +228,6 @@ watch(
|
||||
selectTarget.value.setPosition(componentRightX - selectW, selectTopY)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 我也不知道为什么这个不行,还没时间调
|
||||
if(lineItem.includes('row')) {
|
||||
selectY.forEach(sY => {
|
||||
componentY.forEach(cY => {
|
||||
if (isSorption(sY, cY)) {
|
||||
line.select.set(lineItem, { y: cY })
|
||||
}
|
||||
})
|
||||
})
|
||||
return
|
||||
}
|
||||
if(lineItem.includes('col')) {
|
||||
seletX.forEach(sX => {
|
||||
componentX.forEach(cX => {
|
||||
if (isSorption(sX, cX)) {
|
||||
line.select.set(lineItem, { x: sX })
|
||||
}
|
||||
})
|
||||
})
|
||||
return
|
||||
}
|
||||
*/
|
||||
})
|
||||
})
|
||||
}, 200),
|
||||
@ -267,7 +243,6 @@ watch(
|
||||
if (!val) {
|
||||
line.select.clear()
|
||||
line.sorptioned.y = false
|
||||
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_DRAG, true)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -0,0 +1,3 @@
|
||||
import EditGroup from './index.vue'
|
||||
|
||||
export { EditGroup }
|
126
src/views/chart/ContentEdit/components/EditGroup/index.vue
Normal file
126
src/views/chart/ContentEdit/components/EditGroup/index.vue
Normal file
@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<div class="go-edit-group-box">
|
||||
<edit-shape-box
|
||||
:key="groupData.id"
|
||||
:data-id="groupData.id"
|
||||
:index="groupIndex"
|
||||
:item="groupData"
|
||||
:hiddenPoint="true"
|
||||
:class="animationsClass(groupData.styles.animations)"
|
||||
:style="{
|
||||
...useComponentStyle(groupData.attr, groupIndex),
|
||||
...useSizeStyle(groupData.attr),
|
||||
...getFilterStyle(groupData.styles),
|
||||
...getTransformStyle(groupData.styles)
|
||||
}"
|
||||
@click="mouseClickHandle($event, groupData)"
|
||||
@mousedown="mousedownHandle($event, groupData)"
|
||||
@mouseenter="mouseenterHandle($event, groupData)"
|
||||
@mouseleave="mouseleaveHandle($event, groupData)"
|
||||
@contextmenu="handleContextMenu($event, groupData, optionsHandle)"
|
||||
>
|
||||
<!-- 组合组件 -->
|
||||
<edit-shape-box
|
||||
v-for="item in groupData.groupList"
|
||||
:key="item.id"
|
||||
:data-id="item.id"
|
||||
:index="groupIndex"
|
||||
:item="item"
|
||||
:hiddenPoint="true"
|
||||
:style="{
|
||||
...useComponentStyle(item.attr, groupIndex)
|
||||
}"
|
||||
>
|
||||
<component
|
||||
class="edit-content-chart"
|
||||
:class="animationsClass(item.styles.animations)"
|
||||
:is="item.chartConfig.chartKey"
|
||||
:chartConfig="item"
|
||||
:themeSetting="themeSetting"
|
||||
:themeColor="themeColor"
|
||||
:style="{
|
||||
...useSizeStyle(item.attr),
|
||||
...getFilterStyle(item.styles),
|
||||
...getTransformStyle(item.styles)
|
||||
}"
|
||||
></component>
|
||||
</edit-shape-box>
|
||||
</edit-shape-box>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, PropType } from 'vue'
|
||||
import { MenuEnum } from '@/enums/editPageEnum'
|
||||
import { chartColors } from '@/settings/chartThemes/index'
|
||||
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { MenuOptionsItemType } from '@/views/chart/hooks/useContextMenu.hook.d'
|
||||
import { animationsClass, getFilterStyle, getTransformStyle } from '@/utils'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { useContextMenu, divider } from '@/views/chart/hooks/useContextMenu.hook'
|
||||
import { useMouseHandle } from '../../hooks/useDrag.hook'
|
||||
import { useComponentStyle, useSizeStyle } from '../../hooks/useStyle.hook'
|
||||
import { EditShapeBox } from '../../components/EditShapeBox'
|
||||
|
||||
const props = defineProps({
|
||||
groupData: {
|
||||
type: Object as PropType<CreateComponentGroupType>,
|
||||
required: true
|
||||
},
|
||||
groupIndex: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const chartEditStore = useChartEditStore()
|
||||
const { handleContextMenu } = useContextMenu()
|
||||
|
||||
// 去除创建分组按钮
|
||||
const hideOptionsList = [MenuEnum.GROUP]
|
||||
|
||||
// 点击事件
|
||||
const { mouseenterHandle, mouseleaveHandle, mousedownHandle, mouseClickHandle } = useMouseHandle()
|
||||
|
||||
// 右键
|
||||
const optionsHandle = (
|
||||
targetList: MenuOptionsItemType[],
|
||||
allList: MenuOptionsItemType[],
|
||||
targetInstance: CreateComponentType
|
||||
) => {
|
||||
|
||||
// 多选
|
||||
const moreMenuEnums = [MenuEnum.GROUP, MenuEnum.DELETE]
|
||||
// 单选
|
||||
const singleMenuEnums = [MenuEnum.UN_GROUP]
|
||||
|
||||
const filter = (menulist: MenuEnum[]) => {
|
||||
const list: MenuOptionsItemType[] = []
|
||||
allList.forEach(item => {
|
||||
if (menulist.includes(item.key as MenuEnum)) {
|
||||
list.push(item)
|
||||
}
|
||||
})
|
||||
return list
|
||||
}
|
||||
|
||||
// 多选处理
|
||||
if (chartEditStore.getTargetChart.selectId.length > 1) {
|
||||
return filter(moreMenuEnums)
|
||||
} else {
|
||||
return [...filter(singleMenuEnums), divider(), ...targetList]
|
||||
}
|
||||
}
|
||||
|
||||
// 配置项
|
||||
const themeColor = computed(() => {
|
||||
const chartThemeColor = chartEditStore.getEditCanvasConfig.chartThemeColor
|
||||
return chartColors[chartThemeColor]
|
||||
})
|
||||
|
||||
// 主题色
|
||||
const themeSetting = computed(() => {
|
||||
const chartThemeSetting = chartEditStore.getEditCanvasConfig.chartThemeSetting
|
||||
return chartThemeSetting
|
||||
})
|
||||
</script>
|
@ -1,21 +1,8 @@
|
||||
<template>
|
||||
<div class="go-flex-items-center">
|
||||
<n-popover
|
||||
class="edit-history-popover"
|
||||
:show="showDropdownRef"
|
||||
:show-arrow="false"
|
||||
size="small"
|
||||
trigger="click"
|
||||
placement="top-start"
|
||||
>
|
||||
<n-popover class="edit-history-popover" :show-arrow="false" size="small" trigger="click" placement="top-start">
|
||||
<template #trigger>
|
||||
<n-button
|
||||
class="mr-10"
|
||||
secondary
|
||||
size="small"
|
||||
:disabled="options.length === 0"
|
||||
@click="handleClick"
|
||||
>
|
||||
<n-button class="mr-10" secondary size="small" :disabled="options.length === 0">
|
||||
<span class="btn-text">历史记录</span>
|
||||
</n-button>
|
||||
</template>
|
||||
@ -24,16 +11,11 @@
|
||||
<n-scrollbar style="max-height: 500px">
|
||||
<div
|
||||
class="list-item go-flex-items-center go-ellipsis-1"
|
||||
v-for="item in options"
|
||||
:key="item.key"
|
||||
v-for="(item, index) in options"
|
||||
:key="index"
|
||||
:title="item.label"
|
||||
>
|
||||
<n-icon
|
||||
class="item-icon"
|
||||
size="16"
|
||||
:depth="2"
|
||||
:component="item.icon"
|
||||
/>
|
||||
<n-icon class="item-icon" size="16" :depth="2" :component="item.icon" />
|
||||
<n-text depth="2">{{ item.label }}</n-text>
|
||||
</div>
|
||||
</n-scrollbar>
|
||||
@ -55,7 +37,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { icon } from '@/plugins'
|
||||
import { renderIcon } from '@/utils'
|
||||
import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore'
|
||||
import { historyActionTypeName } from '@/store/modules/chartHistoryStore/chartHistoryDefine'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
@ -64,20 +45,12 @@ import reverse from 'lodash/reverse'
|
||||
import {
|
||||
HistoryItemType,
|
||||
HistoryTargetTypeEnum,
|
||||
HistoryActionTypeEnum,
|
||||
HistoryActionTypeEnum
|
||||
} from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
|
||||
|
||||
const {
|
||||
DesktopOutlineIcon,
|
||||
PencilIcon,
|
||||
TrashIcon,
|
||||
CopyIcon,
|
||||
LayersIcon,
|
||||
DuplicateIcon,
|
||||
HelpOutlineIcon,
|
||||
} = icon.ionicons5
|
||||
const { StackedMoveIcon } = icon.carbon
|
||||
const showDropdownRef = ref(false)
|
||||
const { DesktopOutlineIcon, PencilIcon, TrashIcon, CopyIcon, LayersIcon, DuplicateIcon, HelpOutlineIcon } =
|
||||
icon.ionicons5
|
||||
const { StackedMoveIcon, Carbon3DCursorIcon, Carbon3DSoftwareIcon } = icon.carbon
|
||||
|
||||
const chartHistoryStoreStore = useChartHistoryStore()
|
||||
|
||||
@ -106,6 +79,10 @@ const iconHandle = (e: HistoryItemType) => {
|
||||
return StackedMoveIcon
|
||||
case HistoryActionTypeEnum.ADD:
|
||||
return DuplicateIcon
|
||||
case HistoryActionTypeEnum.GROUP:
|
||||
return Carbon3DCursorIcon
|
||||
case HistoryActionTypeEnum.UN_GROUP:
|
||||
return Carbon3DSoftwareIcon
|
||||
default:
|
||||
return PencilIcon
|
||||
}
|
||||
@ -116,10 +93,11 @@ const labelHandle = (e: HistoryItemType) => {
|
||||
// 画布编辑
|
||||
if (e.targetType === HistoryTargetTypeEnum.CANVAS) {
|
||||
return historyActionTypeName[HistoryTargetTypeEnum.CANVAS]
|
||||
} else if (e.actionType === HistoryActionTypeEnum.GROUP || e.actionType === HistoryActionTypeEnum.UN_GROUP) {
|
||||
return `${historyActionTypeName[e.actionType]}`
|
||||
} else if (e.historyData.length) {
|
||||
return `${historyActionTypeName[e.actionType]} - ${(e.historyData[0] as CreateComponentType).chartConfig.title}`
|
||||
}
|
||||
return `${historyActionTypeName[e.actionType]} - ${
|
||||
(e.historyData as CreateComponentType).chartConfig.title
|
||||
}`
|
||||
}
|
||||
|
||||
const options = computed(() => {
|
||||
@ -127,16 +105,14 @@ const options = computed(() => {
|
||||
const options = backStack.map((e: HistoryItemType) => {
|
||||
return {
|
||||
label: labelHandle(e),
|
||||
key: e.id,
|
||||
icon: iconHandle(e),
|
||||
icon: iconHandle(e)
|
||||
}
|
||||
})
|
||||
return reverse(options)
|
||||
})
|
||||
|
||||
const handleClick = () => {
|
||||
showDropdownRef.value = !showDropdownRef.value
|
||||
}
|
||||
return reverse(options.filter(item => {
|
||||
return item.label
|
||||
}))
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -2,6 +2,7 @@
|
||||
<div class="go-shape-box">
|
||||
<slot></slot>
|
||||
<!-- 锚点 -->
|
||||
<template v-if="!hiddenPoint">
|
||||
<div
|
||||
:class="`shape-point ${point}`"
|
||||
v-for="(point, index) in select ? pointList : []"
|
||||
@ -9,6 +10,7 @@
|
||||
:style="usePointStyle(point, index, item.attr, cursorResize)"
|
||||
@mousedown="useMousePointHandle($event, point, item.attr)"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
<!-- 选中 -->
|
||||
<div class="shape-modal" :style="useSizeStyle(item.attr)">
|
||||
@ -22,14 +24,18 @@
|
||||
import { ref, computed, PropType, toRefs } from 'vue'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { useDesignStore } from '@/store/modules/designStore/designStore'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { useSizeStyle, usePointStyle } from '../../hooks/useStyle.hook'
|
||||
import { useMousePointHandle } from '../../hooks/useDrag.hook'
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
type: Object as PropType<CreateComponentType | CreateComponentGroupType>,
|
||||
required: true
|
||||
},
|
||||
hiddenPoint: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -99,6 +99,21 @@ const shortcutKeyOptions = [
|
||||
win: `${WinKeyboard.CTRL.toUpperCase()} + ${WinKeyboard.SHIFT.toUpperCase()} + Z `,
|
||||
mac: `${MacKeyboard.CTRL.toUpperCase()} + ${MacKeyboard.SHIFT.toUpperCase()} + Z `,
|
||||
},
|
||||
{
|
||||
label: '多选',
|
||||
win: `${WinKeyboard.CTRL.toUpperCase()} + 🖱️ `,
|
||||
mac: `${MacKeyboard.CTRL_SOURCE_KEY.toUpperCase()} + 🖱️ `,
|
||||
},
|
||||
{
|
||||
label: '创建分组',
|
||||
win: `${WinKeyboard.CTRL.toUpperCase()} + G `,
|
||||
mac: `${MacKeyboard.CTRL_SOURCE_KEY.toUpperCase()} + G `,
|
||||
},
|
||||
{
|
||||
label: '解除分组',
|
||||
win: `${WinKeyboard.CTRL.toUpperCase()} + ${WinKeyboard.SHIFT.toUpperCase()} + G `,
|
||||
mac: `${MacKeyboard.CTRL_SOURCE_KEY.toUpperCase()} + ${WinKeyboard.SHIFT.toUpperCase()} + G `,
|
||||
},
|
||||
]
|
||||
const closeHandle = () => {
|
||||
emit('update:modelShow', false)
|
||||
|
@ -32,15 +32,15 @@ export const useFile = () => {
|
||||
negativeText: '覆盖(不可撤回)',
|
||||
negativeButtonProps: { type: 'info', ghost: false },
|
||||
// 新增
|
||||
onNegativeCallback: async () => {
|
||||
onPositiveCallback: async () => {
|
||||
fileData = JSON.parse(fileData)
|
||||
await updateComponent(fileData, true)
|
||||
await updateComponent(fileData, false, true)
|
||||
window['$message'].success('导入成功!')
|
||||
},
|
||||
// 覆盖
|
||||
onPositiveCallback: async () => {
|
||||
onNegativeCallback: async () => {
|
||||
fileData = JSON.parse(fileData)
|
||||
await updateComponent(fileData)
|
||||
await updateComponent(fileData, true, true)
|
||||
window['$message'].success('导入成功!')
|
||||
}
|
||||
})
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { DragKeyEnum } from '@/enums/editPageEnum'
|
||||
import { toRaw } from 'vue'
|
||||
import { DragKeyEnum, MouseEventButton, WinKeyboard, MacKeyboard } from '@/enums/editPageEnum'
|
||||
import { createComponent } from '@/packages'
|
||||
import { ConfigType } from '@/packages/index.d'
|
||||
import {
|
||||
CreateComponentType,
|
||||
PickCreateComponentType,
|
||||
} from '@/packages/index.d'
|
||||
import { CreateComponentType, CreateComponentGroupType, PickCreateComponentType } from '@/packages/index.d'
|
||||
import { useContextMenu } from '@/views/chart/hooks/useContextMenu.hook'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
|
||||
@ -35,10 +33,7 @@ export const dragHandle = async (e: DragEvent) => {
|
||||
// 创建新图表组件
|
||||
let newComponent: CreateComponentType = await createComponent(dropData)
|
||||
|
||||
newComponent.setPosition(
|
||||
e.offsetX - newComponent.attr.w / 2,
|
||||
e.offsetY - newComponent.attr.h / 2
|
||||
)
|
||||
newComponent.setPosition(e.offsetX - newComponent.attr.w / 2, e.offsetY - newComponent.attr.h / 2)
|
||||
chartEditStore.addComponentList(newComponent, false, true)
|
||||
chartEditStore.setTargetSelectChart(newComponent.id)
|
||||
loadingFinish()
|
||||
@ -57,10 +52,7 @@ export const dragoverHandle = (e: DragEvent) => {
|
||||
}
|
||||
|
||||
// * 不拦截默认行为点击
|
||||
export const mousedownHandleUnStop = (
|
||||
e: MouseEvent,
|
||||
item?: CreateComponentType
|
||||
) => {
|
||||
export const mousedownHandleUnStop = (e: MouseEvent, item?: CreateComponentType | CreateComponentGroupType) => {
|
||||
if (item) {
|
||||
chartEditStore.setTargetSelectChart(item.id)
|
||||
return
|
||||
@ -68,51 +60,109 @@ export const mousedownHandleUnStop = (
|
||||
chartEditStore.setTargetSelectChart(undefined)
|
||||
}
|
||||
|
||||
// * 移动图表
|
||||
// * 鼠标事件
|
||||
export const useMouseHandle = () => {
|
||||
// 点击事件(包含移动事件)
|
||||
const mousedownHandle = (e: MouseEvent, item: CreateComponentType) => {
|
||||
// * Click 事件, 松开鼠标触发
|
||||
const mouseClickHandle = (e: MouseEvent, item: CreateComponentType | CreateComponentGroupType) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
// 若此时按下了 CTRL, 表示多选
|
||||
if (
|
||||
window.$KeyboardActive?.has(WinKeyboard.CTRL_SOURCE_KEY) ||
|
||||
window.$KeyboardActive?.has(MacKeyboard.CTRL_SOURCE_KEY)
|
||||
) {
|
||||
// 若已选中,则去除
|
||||
if (chartEditStore.targetChart.selectId.includes(item.id)) {
|
||||
const exList = chartEditStore.targetChart.selectId.filter(e => e !== item.id)
|
||||
chartEditStore.setTargetSelectChart(exList)
|
||||
} else {
|
||||
chartEditStore.setTargetSelectChart(item.id, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// * 按下事件(包含移动事件)
|
||||
const mousedownHandle = (e: MouseEvent, item: CreateComponentType | CreateComponentGroupType) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
onClickOutSide()
|
||||
|
||||
// 按下左键 + CTRL
|
||||
if (
|
||||
e.buttons === MouseEventButton.LEFT &&
|
||||
(window.$KeyboardActive?.has(WinKeyboard.CTRL_SOURCE_KEY) ||
|
||||
window.$KeyboardActive?.has(MacKeyboard.CTRL_SOURCE_KEY))
|
||||
)
|
||||
return
|
||||
|
||||
// 按下右键 + 选中多个 + 目标元素是多选子元素
|
||||
const selectId = chartEditStore.getTargetChart.selectId
|
||||
if (e.buttons === MouseEventButton.RIGHT && selectId.length > 1 && selectId.includes(item.id)) return
|
||||
|
||||
// 选中当前目标组件
|
||||
chartEditStore.setTargetSelectChart(item.id)
|
||||
|
||||
// 按下右键
|
||||
if (e.buttons === MouseEventButton.RIGHT) return
|
||||
|
||||
const scale = chartEditStore.getEditCanvas.scale
|
||||
const width = chartEditStore.getEditCanvasConfig.width
|
||||
const height = chartEditStore.getEditCanvasConfig.height
|
||||
const canvasWidth = chartEditStore.getEditCanvasConfig.width
|
||||
const canvasHeight = chartEditStore.getEditCanvasConfig.height
|
||||
|
||||
// 记录图表初始位置和大小
|
||||
const itemAttrX = item.attr.x
|
||||
const itemAttrY = item.attr.y
|
||||
const itemAttrW = item.attr.w
|
||||
const itemAttrH = item.attr.h
|
||||
const targetMap = new Map()
|
||||
chartEditStore.getTargetChart.selectId.forEach(id => {
|
||||
const index = chartEditStore.fetchTargetIndex(id)
|
||||
if (index !== -1) {
|
||||
const { x, y, w, h } = toRaw(chartEditStore.getComponentList[index]).attr
|
||||
targetMap.set(id, { x, y, w, h })
|
||||
}
|
||||
})
|
||||
|
||||
// 记录点击初始位置
|
||||
const startX = e.screenX
|
||||
const startY = e.screenY
|
||||
|
||||
// 记录初始位置
|
||||
chartEditStore.setMousePosition(startX, startY)
|
||||
|
||||
// 计算偏移量(处理 scale 比例问题)
|
||||
// 移动-计算偏移量
|
||||
const mousemove = throttle((moveEvent: MouseEvent) => {
|
||||
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_DRAG, true)
|
||||
chartEditStore.setMousePosition(moveEvent.screenX, moveEvent.screenY)
|
||||
|
||||
let currX = Math.round(itemAttrX + (moveEvent.screenX - startX) / scale)
|
||||
let currY = Math.round(itemAttrY + (moveEvent.screenY - startY) / scale)
|
||||
// 当前偏移量,处理 scale 比例问题
|
||||
let offsetX = (moveEvent.screenX - startX) / scale
|
||||
let offsetY = (moveEvent.screenY - startY) / scale
|
||||
|
||||
chartEditStore.getTargetChart.selectId.forEach(id => {
|
||||
if(!targetMap.has(id)) return
|
||||
|
||||
const index = chartEditStore.fetchTargetIndex(id)
|
||||
// 拿到初始位置数据
|
||||
const { x, y, w, h } = targetMap.get(id)
|
||||
const componentInstance = chartEditStore.getComponentList[index]
|
||||
|
||||
let currX = Math.round(x + offsetX)
|
||||
let currY = Math.round(y + offsetY)
|
||||
|
||||
// 要预留的距离
|
||||
const distance = 50
|
||||
|
||||
// 基于左上角位置检测
|
||||
currX = currX < -itemAttrW + distance ? -itemAttrW + distance : currX
|
||||
currY = currY < -itemAttrH + distance ? -itemAttrH + distance : currY
|
||||
currX = currX < -w + distance ? -w + distance : currX
|
||||
currY = currY < -h + distance ? -h + distance : currY
|
||||
|
||||
// 基于右下角位置检测
|
||||
currX = currX > width - distance ? width - distance : currX
|
||||
currY = currY > height - distance ? height - distance : currY
|
||||
currX = currX > canvasWidth - distance ? canvasWidth - distance : currX
|
||||
currY = currY > canvasHeight - distance ? canvasHeight - distance : currY
|
||||
|
||||
item.attr.x = currX
|
||||
item.attr.y = currY
|
||||
componentInstance.attr = Object.assign(componentInstance.attr, {
|
||||
x: currX,
|
||||
y: currY
|
||||
})
|
||||
})
|
||||
return
|
||||
}, 30)
|
||||
|
||||
const mouseup = () => {
|
||||
@ -127,29 +177,25 @@ export const useMouseHandle = () => {
|
||||
}
|
||||
|
||||
// * 进入事件
|
||||
const mouseenterHandle = (e: MouseEvent, item: CreateComponentType) => {
|
||||
const mouseenterHandle = (e: MouseEvent, item: CreateComponentType | CreateComponentGroupType) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
chartEditStore.setTargetHoverChart(item.id)
|
||||
}
|
||||
|
||||
// * 移出事件
|
||||
const mouseleaveHandle = (e: MouseEvent, item: CreateComponentType) => {
|
||||
const mouseleaveHandle = (e: MouseEvent, item: CreateComponentType | CreateComponentGroupType) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_DRAG, false)
|
||||
chartEditStore.setTargetHoverChart(undefined)
|
||||
}
|
||||
|
||||
return { mousedownHandle, mouseenterHandle, mouseleaveHandle }
|
||||
return { mouseClickHandle, mousedownHandle, mouseenterHandle, mouseleaveHandle }
|
||||
}
|
||||
|
||||
// * 移动锚点
|
||||
export const useMousePointHandle = (
|
||||
e: MouseEvent,
|
||||
point: string,
|
||||
attr: PickCreateComponentType<'attr'>
|
||||
) => {
|
||||
export const useMousePointHandle = (e: MouseEvent, point: string, attr: PickCreateComponentType<'attr'>) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
|
||||
|
@ -15,22 +15,29 @@
|
||||
<!-- 展示 -->
|
||||
<edit-range>
|
||||
<!-- 滤镜预览 -->
|
||||
<div :style="{
|
||||
<div
|
||||
:style="{
|
||||
...getFilterStyle(chartEditStore.getEditCanvasConfig),
|
||||
...rangeStyle
|
||||
}">
|
||||
}"
|
||||
>
|
||||
<!-- 图表 -->
|
||||
<div v-for="(item, index) in chartEditStore.getComponentList" :key="item.id">
|
||||
<!-- 分组 -->
|
||||
<edit-group v-if="item.isGroup" :groupData="(item as CreateComponentGroupType)" :groupIndex="index"></edit-group>
|
||||
|
||||
<!-- 单组件 -->
|
||||
<edit-shape-box
|
||||
v-for="(item, index) in chartEditStore.getComponentList"
|
||||
:key="item.id"
|
||||
v-else
|
||||
:data-id="item.id"
|
||||
:index="index"
|
||||
:style="useComponentStyle(item.attr, index)"
|
||||
:item="item"
|
||||
@click="mouseClickHandle($event, item)"
|
||||
@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"
|
||||
@ -42,11 +49,12 @@
|
||||
:style="{
|
||||
...useSizeStyle(item.attr),
|
||||
...getFilterStyle(item.styles),
|
||||
...getTransformStyle(item.styles),
|
||||
...getTransformStyle(item.styles)
|
||||
}"
|
||||
></component>
|
||||
</edit-shape-box>
|
||||
</div>
|
||||
</div>
|
||||
</edit-range>
|
||||
</div>
|
||||
|
||||
@ -65,8 +73,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'
|
||||
@ -75,6 +86,7 @@ import { dragHandle, dragoverHandle, useMouseHandle } from './hooks/useDrag.hook
|
||||
import { useComponentStyle, useSizeStyle } from './hooks/useStyle.hook'
|
||||
|
||||
import { ContentBox } from '../ContentBox/index'
|
||||
import { EditGroup } from './components/EditGroup'
|
||||
import { EditRange } from './components/EditRange'
|
||||
import { EditBottom } from './components/EditBottom'
|
||||
import { EditShapeBox } from './components/EditShapeBox'
|
||||
@ -87,7 +99,33 @@ const { handleContextMenu } = useContextMenu()
|
||||
useLayout()
|
||||
|
||||
// 点击事件
|
||||
const { mouseenterHandle, mouseleaveHandle, mousedownHandle } = useMouseHandle()
|
||||
const { mouseenterHandle, mouseleaveHandle, mousedownHandle, mouseClickHandle } = useMouseHandle()
|
||||
|
||||
// 右键事件
|
||||
const optionsHandle = (
|
||||
targetList: MenuOptionsItemType[],
|
||||
allList: MenuOptionsItemType[],
|
||||
targetInstance: CreateComponentType
|
||||
) => {
|
||||
// 多选
|
||||
const moreMenuEnums = [MenuEnum.GROUP, MenuEnum.DELETE]
|
||||
// 单选
|
||||
const singleMenuEnums = targetList
|
||||
|
||||
// 多选处理
|
||||
if (chartEditStore.getTargetChart.selectId.length > 1) {
|
||||
const list: MenuOptionsItemType[] = []
|
||||
|
||||
allList.forEach(item => {
|
||||
// 成组
|
||||
if (moreMenuEnums.includes(item.key as MenuEnum)) {
|
||||
list.push(item)
|
||||
}
|
||||
})
|
||||
return list
|
||||
}
|
||||
return singleMenuEnums
|
||||
}
|
||||
|
||||
// 主题色
|
||||
const themeSetting = computed(() => {
|
||||
|
@ -0,0 +1,3 @@
|
||||
import LayersGroupListItem from './index.vue'
|
||||
|
||||
export { LayersGroupListItem }
|
@ -0,0 +1,220 @@
|
||||
<template>
|
||||
<div class="go-content-layers-group-list-item">
|
||||
<div
|
||||
class="root-item-content"
|
||||
:class="{ hover: hover, select: select }"
|
||||
@click="clickHandle($event)"
|
||||
@mousedown="groupMousedownHandle($event)"
|
||||
@mouseenter="mouseenterHandle(componentGroupData)"
|
||||
@mouseleave="mouseleaveHandle(componentGroupData)"
|
||||
@contextmenu="handleContextMenu($event, componentGroupData, optionsHandle)"
|
||||
>
|
||||
<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($event, element, componentGroupData.id)"
|
||||
@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, WinKeyboard, MacKeyboard } from '@/enums/editPageEnum'
|
||||
import { MenuEnum } from '@/enums/editPageEnum'
|
||||
import { useDesignStore } from '@/store/modules/designStore/designStore'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { useContextMenu, divider } from '@/views/chart/hooks/useContextMenu.hook'
|
||||
import { MenuOptionsItemType } from '@/views/chart/hooks/useContextMenu.hook.d'
|
||||
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 optionsHandle = (
|
||||
targetList: MenuOptionsItemType[],
|
||||
allList: MenuOptionsItemType[],
|
||||
targetInstance: CreateComponentType
|
||||
) => {
|
||||
const filter = (menulist: MenuEnum[]) => {
|
||||
const list: MenuOptionsItemType[] = []
|
||||
allList.forEach(item => {
|
||||
if (menulist.includes(item.key as MenuEnum)) {
|
||||
list.push(item)
|
||||
}
|
||||
})
|
||||
return list
|
||||
}
|
||||
|
||||
// 多选处理
|
||||
if (chartEditStore.getTargetChart.selectId.length > 1) {
|
||||
return filter([MenuEnum.GROUP])
|
||||
} else {
|
||||
return [...filter([MenuEnum.UN_GROUP]), divider(), ...targetList]
|
||||
}
|
||||
}
|
||||
|
||||
// 点击
|
||||
const clickHandle = (e: MouseEvent) => {
|
||||
// 按下左键 + CTRL
|
||||
if (
|
||||
window.$KeyboardActive?.has(WinKeyboard.CTRL_SOURCE_KEY) ||
|
||||
window.$KeyboardActive?.has(MacKeyboard.CTRL_SOURCE_KEY)
|
||||
)
|
||||
return
|
||||
// 判断左右键
|
||||
expend.value = !expend.value
|
||||
mousedownHandle(e, 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 = (e: MouseEvent) => {
|
||||
onClickOutSide()
|
||||
// 若此时按下了 CTRL, 表示多选
|
||||
const id = props.componentGroupData.id
|
||||
if (
|
||||
e.buttons === MouseEventButton.LEFT &&
|
||||
(window.$KeyboardActive?.has(WinKeyboard.CTRL_SOURCE_KEY) ||
|
||||
window.$KeyboardActive?.has(MacKeyboard.CTRL_SOURCE_KEY))
|
||||
) {
|
||||
// 若已选中,则去除
|
||||
if (chartEditStore.targetChart.selectId.includes(id)) {
|
||||
const exList = chartEditStore.targetChart.selectId.filter(e => e !== id)
|
||||
chartEditStore.setTargetSelectChart(exList)
|
||||
} else {
|
||||
chartEditStore.setTargetSelectChart(id, true)
|
||||
}
|
||||
return
|
||||
}
|
||||
chartEditStore.setTargetSelectChart(id)
|
||||
}
|
||||
|
||||
// 公共点击事件
|
||||
const mousedownHandle = (e: MouseEvent, item: CreateComponentType | CreateComponentGroupType, id?: string) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
onClickOutSide()
|
||||
chartEditStore.setTargetSelectChart(id || 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>
|
@ -60,7 +60,7 @@ $textSize: 10px;
|
||||
position: relative;
|
||||
height: $centerHeight;
|
||||
width: 90%;
|
||||
margin: 10px 5%;
|
||||
margin: 5px 5%;
|
||||
margin-bottom: 5px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
|
@ -5,6 +5,7 @@
|
||||
title="图层"
|
||||
:depth="2"
|
||||
@back="backHandle"
|
||||
@mousedown="boxMousedownHandle($event)"
|
||||
>
|
||||
<template #icon>
|
||||
<n-icon size="16" :depth="2">
|
||||
@ -16,20 +17,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 }">
|
||||
<div class="go-content-layer-box">
|
||||
<!-- 组合 -->
|
||||
<layers-group-list-item v-if="element.isGroup" :componentGroupData="element"></layers-group-list-item>
|
||||
<!-- 单组件 -->
|
||||
<layers-list-item
|
||||
v-else
|
||||
:componentData="element"
|
||||
@mousedown="mousedownHandle(element)"
|
||||
@mousedown="mousedownHandle($event, element)"
|
||||
@mouseenter="mouseenterHandle(element)"
|
||||
@mouseleave="mouseleaveHandle(element)"
|
||||
@contextmenu="handleContextMenu($event, element)"
|
||||
@contextmenu="handleContextMenu($event, element, optionsHandle)"
|
||||
></layers-list-item>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</content-box>
|
||||
@ -39,27 +41,49 @@
|
||||
import { computed, toRaw } from 'vue'
|
||||
import Draggable from 'vuedraggable'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
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 { MenuOptionsItemType } from '@/views/chart/hooks/useContextMenu.hook.d'
|
||||
import { useContextMenu } from '@/views/chart/hooks/useContextMenu.hook'
|
||||
import { MenuEnum } from '@/enums/editPageEnum'
|
||||
import { MenuEnum, MouseEventButton, WinKeyboard, MacKeyboard } 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 optionsHandle = (
|
||||
targetList: MenuOptionsItemType[],
|
||||
allList: MenuOptionsItemType[],
|
||||
targetInstance: CreateComponentType
|
||||
) => {
|
||||
// 多选处理
|
||||
if (chartEditStore.getTargetChart.selectId.length > 1) {
|
||||
const list: MenuOptionsItemType[] = []
|
||||
targetList.forEach(item => {
|
||||
// 成组
|
||||
if (item.key === MenuEnum.GROUP) {
|
||||
list.push(item)
|
||||
}
|
||||
})
|
||||
return list
|
||||
}
|
||||
return targetList
|
||||
}
|
||||
|
||||
// 逆序展示
|
||||
const reverseList = computed(() => {
|
||||
const list: CreateComponentType[] = cloneDeep(chartEditStore.getComponentList)
|
||||
const list: Array<CreateComponentType | CreateComponentGroupType> = cloneDeep(chartEditStore.getComponentList)
|
||||
return list.reverse()
|
||||
})
|
||||
|
||||
@ -87,9 +111,33 @@ const onMoveCallback = (val: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
const boxMousedownHandle = (e: MouseEvent) => {
|
||||
const box = document.querySelector('.go-content-layer-box')
|
||||
if ((e.target as any).contains(box)) {
|
||||
chartEditStore.setTargetSelectChart()
|
||||
}
|
||||
}
|
||||
|
||||
// 点击事件
|
||||
const mousedownHandle = (item: CreateComponentType) => {
|
||||
chartEditStore.setTargetSelectChart(item.id)
|
||||
const mousedownHandle = (e: MouseEvent, item: CreateComponentType) => {
|
||||
onClickOutSide()
|
||||
// 若此时按下了 CTRL, 表示多选
|
||||
const id = item.id
|
||||
if (
|
||||
e.buttons === MouseEventButton.LEFT &&
|
||||
(window.$KeyboardActive?.has(WinKeyboard.CTRL_SOURCE_KEY) ||
|
||||
window.$KeyboardActive?.has(MacKeyboard.CTRL_SOURCE_KEY))
|
||||
) {
|
||||
// 若已选中,则去除
|
||||
if (chartEditStore.targetChart.selectId.includes(id)) {
|
||||
const exList = chartEditStore.targetChart.selectId.filter(e => e !== id)
|
||||
chartEditStore.setTargetSelectChart(exList)
|
||||
} else {
|
||||
chartEditStore.setTargetSelectChart(id, true)
|
||||
}
|
||||
return
|
||||
}
|
||||
chartEditStore.setTargetSelectChart(id)
|
||||
}
|
||||
|
||||
// 进入事件
|
||||
|
13
src/views/chart/hooks/useContextMenu.hook.d.ts
vendored
13
src/views/chart/hooks/useContextMenu.hook.d.ts
vendored
@ -1,15 +1,4 @@
|
||||
// 右键枚举
|
||||
export enum MenuEnum {
|
||||
DELETE = 'delete',
|
||||
COPY = 'copy',
|
||||
CUT = 'cut',
|
||||
PARSE = 'parse',
|
||||
TOP = 'top',
|
||||
BOTTOM = 'bottom',
|
||||
UP = 'up',
|
||||
DOWN = 'down',
|
||||
CLEAR = 'clear',
|
||||
}
|
||||
import { MenuEnum } from '@/enums/editPageEnum'
|
||||
|
||||
export interface MenuOptionsItemType {
|
||||
type?: string
|
||||
|
@ -1,87 +1,109 @@
|
||||
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 } = icon.carbon
|
||||
const { CopyIcon, CutIcon, ClipboardOutlineIcon, TrashIcon, ChevronDownIcon, ChevronUpIcon } = icon.ionicons5
|
||||
const { UpToTopIcon, DownToBottomIcon, PaintBrushIcon, Carbon3DSoftwareIcon, Carbon3DCursorIcon } = icon.carbon
|
||||
|
||||
const chartEditStore = useChartEditStore()
|
||||
|
||||
// * 默认选项
|
||||
const defaultOptions: MenuOptionsItemType[] = [
|
||||
/**
|
||||
* 分割线
|
||||
* @param {number} n > 2
|
||||
* @returns
|
||||
*/
|
||||
export const divider = (n:number = 3) => {
|
||||
return {
|
||||
type: 'divider',
|
||||
key: `d${n}`
|
||||
}
|
||||
}
|
||||
|
||||
// * 默认单组件选项
|
||||
export const defaultOptions: MenuOptionsItemType[] = [
|
||||
{
|
||||
label: '复制',
|
||||
key: MenuEnum.COPY,
|
||||
icon: renderIcon(CopyIcon),
|
||||
fnHandle: chartEditStore.setCopy,
|
||||
fnHandle: chartEditStore.setCopy
|
||||
},
|
||||
{
|
||||
label: '剪切',
|
||||
key: MenuEnum.CUT,
|
||||
icon: renderIcon(CutIcon),
|
||||
fnHandle: chartEditStore.setCut,
|
||||
fnHandle: chartEditStore.setCut
|
||||
},
|
||||
{
|
||||
label: '粘贴',
|
||||
key: MenuEnum.PARSE,
|
||||
icon: renderIcon(ClipboardOutlineIcon),
|
||||
fnHandle: chartEditStore.setParse,
|
||||
fnHandle: chartEditStore.setParse
|
||||
},
|
||||
{
|
||||
type: 'divider',
|
||||
key: 'd1',
|
||||
key: 'd1'
|
||||
},
|
||||
{
|
||||
label: '置顶',
|
||||
key: MenuEnum.TOP,
|
||||
icon: renderIcon(UpToTopIcon),
|
||||
fnHandle: chartEditStore.setTop,
|
||||
fnHandle: chartEditStore.setTop
|
||||
},
|
||||
{
|
||||
label: '置底',
|
||||
key: MenuEnum.BOTTOM,
|
||||
icon: renderIcon(DownToBottomIcon),
|
||||
fnHandle: chartEditStore.setBottom,
|
||||
fnHandle: chartEditStore.setBottom
|
||||
},
|
||||
{
|
||||
label: '上移一层',
|
||||
key: MenuEnum.UP,
|
||||
icon: renderIcon(ChevronUpIcon),
|
||||
fnHandle: chartEditStore.setUp,
|
||||
fnHandle: chartEditStore.setUp
|
||||
},
|
||||
{
|
||||
label: '下移一层',
|
||||
key: MenuEnum.DOWN,
|
||||
icon: renderIcon(ChevronDownIcon),
|
||||
fnHandle: chartEditStore.setDown,
|
||||
fnHandle: chartEditStore.setDown
|
||||
},
|
||||
{
|
||||
type: 'divider',
|
||||
key: 'd2',
|
||||
key: 'd2'
|
||||
},
|
||||
{
|
||||
label: '清空剪贴板',
|
||||
key: MenuEnum.CLEAR,
|
||||
icon: renderIcon(PaintBrushIcon),
|
||||
fnHandle: chartEditStore.setRecordChart,
|
||||
fnHandle: chartEditStore.setRecordChart
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
key: MenuEnum.DELETE,
|
||||
icon: renderIcon(TrashIcon),
|
||||
fnHandle: chartEditStore.removeComponentList,
|
||||
fnHandle: chartEditStore.removeComponentList
|
||||
}
|
||||
]
|
||||
|
||||
// * 默认多选组件选项
|
||||
export const defaultMultiSelectOptions: MenuOptionsItemType[] = [
|
||||
{
|
||||
label: '创建分组',
|
||||
key: MenuEnum.GROUP,
|
||||
icon: renderIcon(Carbon3DSoftwareIcon),
|
||||
fnHandle: chartEditStore.setGroup
|
||||
},
|
||||
{
|
||||
label: '解除分组',
|
||||
key: MenuEnum.UN_GROUP,
|
||||
icon: renderIcon(Carbon3DCursorIcon),
|
||||
fnHandle: chartEditStore.setUnGroup
|
||||
}
|
||||
]
|
||||
|
||||
// * 无数据传递拥有的选项
|
||||
@ -95,9 +117,11 @@ const defaultNoItemKeys = [MenuEnum.PARSE, MenuEnum.CLEAR]
|
||||
*/
|
||||
const pickOption = (options: MenuOptionsItemType[], pickList?: MenuEnum[]) => {
|
||||
if (!pickList) return options
|
||||
return options.filter((op: MenuOptionsItemType) => {
|
||||
return pickList.findIndex((e: MenuEnum) => e === op.key) !== -1
|
||||
const list: MenuOptionsItemType[] = []
|
||||
pickList.forEach(e => {
|
||||
list.push(...options.filter(op => op.key === e))
|
||||
})
|
||||
return list
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,36 +144,49 @@ const menuOptions = ref<MenuOptionsItemType[]>([])
|
||||
const handleContextMenu = (
|
||||
e: MouseEvent,
|
||||
// 右键对象
|
||||
item?: CreateComponentType,
|
||||
targetInstance?: CreateComponentType | CreateComponentGroupType,
|
||||
// 判断函数
|
||||
optionsHandle?: Function,
|
||||
// 隐藏选项列表
|
||||
hideOptionsList?: MenuEnum[],
|
||||
// 挑选选项列表
|
||||
pickOptionsList?: MenuEnum[],
|
||||
pickOptionsList?: MenuEnum[]
|
||||
) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
|
||||
let target = e.target
|
||||
while (target instanceof SVGElement) {
|
||||
target = target.parentNode
|
||||
}
|
||||
|
||||
// 展示列表
|
||||
chartEditStore.setRightMenuShow(false)
|
||||
|
||||
// * 设置默认选项
|
||||
// * 多选默认选项
|
||||
if (chartEditStore.getTargetChart.selectId.length > 1) {
|
||||
menuOptions.value = defaultMultiSelectOptions
|
||||
} else {
|
||||
// * 单选默认选项
|
||||
menuOptions.value = defaultOptions
|
||||
}
|
||||
|
||||
if (!item) {
|
||||
menuOptions.value = pickOption(menuOptions.value, defaultNoItemKeys)
|
||||
if (!targetInstance) {
|
||||
menuOptions.value = pickOption(toRaw(menuOptions.value), defaultNoItemKeys)
|
||||
}
|
||||
if (hideOptionsList) {
|
||||
menuOptions.value = hideOption(menuOptions.value, hideOptionsList)
|
||||
menuOptions.value = hideOption([...defaultMultiSelectOptions, divider(), ...defaultOptions], hideOptionsList)
|
||||
}
|
||||
if (pickOptionsList) {
|
||||
menuOptions.value = hideOption(menuOptions.value, pickOptionsList)
|
||||
menuOptions.value = pickOption([...defaultMultiSelectOptions, divider(), ...defaultOptions], pickOptionsList)
|
||||
}
|
||||
if (optionsHandle) {
|
||||
menuOptions.value = optionsHandle(menuOptions.value)
|
||||
// 自定义函数能够拿到当前选项和所有选项
|
||||
menuOptions.value = optionsHandle(
|
||||
cloneDeep(toRaw(menuOptions.value)),
|
||||
[...defaultMultiSelectOptions, ...defaultOptions],
|
||||
targetInstance
|
||||
)
|
||||
}
|
||||
nextTick().then(() => {
|
||||
chartEditStore.setMousePosition(e.clientX, e.clientY)
|
||||
@ -163,7 +200,6 @@ const handleContextMenu = (
|
||||
* @returns
|
||||
*/
|
||||
export const useContextMenu = () => {
|
||||
|
||||
// 设置默认项
|
||||
menuOptions.value = defaultOptions
|
||||
|
||||
@ -175,9 +211,7 @@ export const useContextMenu = () => {
|
||||
// * 事件处理
|
||||
const handleMenuSelect = (key: string) => {
|
||||
chartEditStore.setRightMenuShow(false)
|
||||
const targetItem: MenuOptionsItemType[] = menuOptions.value.filter(
|
||||
(e: MenuOptionsItemType) => e.key === key
|
||||
)
|
||||
const targetItem: MenuOptionsItemType[] = menuOptions.value.filter((e: MenuOptionsItemType) => e.key === key)
|
||||
|
||||
menuOptions.value.forEach((e: MenuOptionsItemType) => {
|
||||
if (e.key === key) {
|
||||
@ -192,9 +226,11 @@ export const useContextMenu = () => {
|
||||
|
||||
return {
|
||||
menuOptions,
|
||||
defaultOptions,
|
||||
defaultMultiSelectOptions,
|
||||
handleContextMenu,
|
||||
onClickOutSide,
|
||||
handleMenuSelect,
|
||||
mousePosition: chartEditStore.getMousePosition,
|
||||
mousePosition: chartEditStore.getMousePosition
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ export const winKeyboardValue = {
|
||||
[MenuEnum.DELETE]: 'delete',
|
||||
[MenuEnum.BACK]: winCtrlMerge('z'),
|
||||
[MenuEnum.FORWORD]: winCtrlMerge(winShiftMerge('z')),
|
||||
[MenuEnum.GROUP]: winCtrlMerge('g'),
|
||||
[MenuEnum.UN_GROUP]: winCtrlMerge(winShiftMerge('g')),
|
||||
}
|
||||
|
||||
// 这个 Ctrl 后面还是换成了 ⌘
|
||||
@ -41,6 +43,8 @@ export const macKeyboardValue = {
|
||||
[MenuEnum.DELETE]: macCtrlMerge('backspace'),
|
||||
[MenuEnum.BACK]: macCtrlMerge('z'),
|
||||
[MenuEnum.FORWORD]: macCtrlMerge(macShiftMerge('z')),
|
||||
[MenuEnum.GROUP]: macCtrlMerge('g'),
|
||||
[MenuEnum.UN_GROUP]: macCtrlMerge(macShiftMerge('g')),
|
||||
}
|
||||
|
||||
// Win 快捷键列表
|
||||
@ -57,6 +61,9 @@ const winKeyList: Array<string> = [
|
||||
|
||||
winKeyboardValue.back,
|
||||
winKeyboardValue.forward,
|
||||
|
||||
winKeyboardValue.group,
|
||||
winKeyboardValue.unGroup,
|
||||
]
|
||||
|
||||
// Mac 快捷键列表
|
||||
@ -73,65 +80,81 @@ const macKeyList: Array<string> = [
|
||||
|
||||
macKeyboardValue.back,
|
||||
macKeyboardValue.forward,
|
||||
|
||||
macKeyboardValue.group,
|
||||
macKeyboardValue.unGroup,
|
||||
]
|
||||
|
||||
// 处理键盘记录
|
||||
const keyRecordHandle = () => {
|
||||
document.onkeydown = throttle((e: KeyboardEvent) => {
|
||||
if(window.$KeyboardActive) window.$KeyboardActive.add(e.key.toLocaleLowerCase())
|
||||
else window.$KeyboardActive = new Set([e.key])
|
||||
}, 200)
|
||||
// 初始化清空
|
||||
if(window.$KeyboardActive) window.$KeyboardActive = new Set([])
|
||||
|
||||
document.onkeyup = throttle((e: KeyboardEvent) => {
|
||||
document.onkeydown = (e: KeyboardEvent) => {
|
||||
if(window.$KeyboardActive) window.$KeyboardActive.add(e.key.toLocaleLowerCase())
|
||||
else window.$KeyboardActive = new Set([e.key.toLocaleLowerCase()])
|
||||
}
|
||||
|
||||
document.onkeyup = (e: KeyboardEvent) => {
|
||||
if(window.$KeyboardActive) window.$KeyboardActive.delete(e.key.toLocaleLowerCase())
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化监听事件
|
||||
export const useAddKeyboard = () => {
|
||||
const throttleTime = 50
|
||||
const switchHandle = (keyboardValue: typeof winKeyboardValue, e: string) => {
|
||||
switch (e) {
|
||||
// ct+↑
|
||||
case keyboardValue.up:
|
||||
keymaster(e, throttle(() => { chartEditStore.setMove(MenuEnum.ARROW_UP); return false }, 200))
|
||||
keymaster(e, throttle(() => { chartEditStore.setMove(MenuEnum.ARROW_UP); return false }, throttleTime))
|
||||
break;
|
||||
// ct+→
|
||||
case keyboardValue.right:
|
||||
keymaster(e, throttle(() => { chartEditStore.setMove(MenuEnum.ARROW_RIGHT); return false }, 200))
|
||||
keymaster(e, throttle(() => { chartEditStore.setMove(MenuEnum.ARROW_RIGHT); return false }, throttleTime))
|
||||
break;
|
||||
// ct+↓
|
||||
case keyboardValue.down:
|
||||
keymaster(e, throttle(() => { chartEditStore.setMove(MenuEnum.ARROW_DOWN); return false }, 200))
|
||||
keymaster(e, throttle(() => { chartEditStore.setMove(MenuEnum.ARROW_DOWN); return false }, throttleTime))
|
||||
break;
|
||||
// ct+←
|
||||
case keyboardValue.left:
|
||||
keymaster(e, throttle(() => { chartEditStore.setMove(MenuEnum.ARROW_LEFT); return false }, 200))
|
||||
keymaster(e, throttle(() => { chartEditStore.setMove(MenuEnum.ARROW_LEFT); return false }, throttleTime))
|
||||
break;
|
||||
|
||||
// 删除 delete
|
||||
case keyboardValue.delete:
|
||||
keymaster(e, debounce(() => { chartEditStore.removeComponentList(); return false }, 200))
|
||||
keymaster(e, debounce(() => { chartEditStore.removeComponentList(); return false }, throttleTime))
|
||||
break;
|
||||
// 复制 ct+v
|
||||
case keyboardValue.copy:
|
||||
keymaster(e, debounce(() => { chartEditStore.setCopy(); return false }, 200))
|
||||
keymaster(e, debounce(() => { chartEditStore.setCopy(); return false }, throttleTime))
|
||||
break;
|
||||
// 剪切 ct+x
|
||||
case keyboardValue.cut:
|
||||
keymaster(e, debounce(() => { chartEditStore.setCut(); return false }, 200))
|
||||
keymaster(e, debounce(() => { chartEditStore.setCut(); return false }, throttleTime))
|
||||
break;
|
||||
// 粘贴 ct+v
|
||||
case keyboardValue.parse:
|
||||
keymaster(e, throttle(() => { chartEditStore.setParse(); return false }, 200))
|
||||
keymaster(e, throttle(() => { chartEditStore.setParse(); return false }, throttleTime))
|
||||
break;
|
||||
|
||||
// 撤回 ct+z
|
||||
case keyboardValue.back:
|
||||
keymaster(e, throttle(() => { chartEditStore.setBack(); return false }, 200))
|
||||
keymaster(e, throttle(() => { chartEditStore.setBack(); return false }, throttleTime))
|
||||
break;
|
||||
// 前进 ct+sh+z
|
||||
case keyboardValue.forward:
|
||||
keymaster(e, throttle(() => { chartEditStore.setForward(); return false }, 200))
|
||||
keymaster(e, throttle(() => { chartEditStore.setForward(); return false }, throttleTime))
|
||||
break;
|
||||
|
||||
// 创建分组 ct+g
|
||||
case keyboardValue.group:
|
||||
keymaster(e, throttle(() => { chartEditStore.setGroup(); return false }, throttleTime))
|
||||
break;
|
||||
// 解除分组 ct+sh+g
|
||||
case keyboardValue.unGroup:
|
||||
keymaster(e, throttle(() => { chartEditStore.setUnGroup(); return false }, throttleTime))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,8 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore
|
||||
import { ChartEditStoreEnum, ChartEditStorage } from '@/store/modules/chartEditStore/chartEditStore.d'
|
||||
import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore'
|
||||
import { fetchChartComponent, fetchConfigComponent, createComponent } from '@/packages/index'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { CreateComponentType, CreateComponentGroupType, ConfigType } from '@/packages/index.d'
|
||||
import { PublicGroupConfigClass } from '@/packages/public/publicConfig'
|
||||
|
||||
// 请求处理
|
||||
export const useSync = () => {
|
||||
@ -13,11 +14,11 @@ export const useSync = () => {
|
||||
/**
|
||||
* * 组件动态注册
|
||||
* @param projectData 项目数据
|
||||
* @param isSplace 是否替换数据
|
||||
* @param isReplace 是否替换数据
|
||||
* @returns
|
||||
*/
|
||||
const updateComponent = async (projectData: ChartEditStorage, isSplace = false) => {
|
||||
if (isSplace) {
|
||||
const updateComponent = async (projectData: ChartEditStorage, isReplace = false, changeId = false) => {
|
||||
if (isReplace) {
|
||||
// 清除列表
|
||||
chartEditStore.componentList = []
|
||||
// 清除历史记录
|
||||
@ -25,16 +26,20 @@ export const useSync = () => {
|
||||
chartHistoryStore.clearForwardStack()
|
||||
}
|
||||
// 列表组件注册
|
||||
projectData.componentList.forEach(async (e: CreateComponentType) => {
|
||||
if (!window['$vue'].component(e.chartConfig.chartKey)) {
|
||||
window['$vue'].component(
|
||||
e.chartConfig.chartKey,
|
||||
fetchChartComponent(e.chartConfig)
|
||||
)
|
||||
window['$vue'].component(
|
||||
e.chartConfig.conKey,
|
||||
fetchConfigComponent(e.chartConfig)
|
||||
)
|
||||
projectData.componentList.forEach(async (e: CreateComponentType | CreateComponentGroupType) => {
|
||||
const intComponent = (target: CreateComponentType) => {
|
||||
if (!window['$vue'].component(target.chartConfig.chartKey)) {
|
||||
window['$vue'].component(target.chartConfig.chartKey, fetchChartComponent(target.chartConfig))
|
||||
window['$vue'].component(target.chartConfig.conKey, fetchConfigComponent(target.chartConfig))
|
||||
}
|
||||
}
|
||||
|
||||
if (e.isGroup) {
|
||||
;(e as CreateComponentGroupType).groupList.forEach(groupItem => {
|
||||
intComponent(groupItem)
|
||||
})
|
||||
} else {
|
||||
intComponent(e as CreateComponentType)
|
||||
}
|
||||
})
|
||||
// 数据赋值
|
||||
@ -42,20 +47,60 @@ export const useSync = () => {
|
||||
// 组件
|
||||
if (key === ChartEditStoreEnum.COMPONENT_LIST) {
|
||||
for (const comItem of projectData[key]) {
|
||||
// 重新创建是为了处理类种方法消失的问题
|
||||
const create = async (
|
||||
_componentInstance: CreateComponentType,
|
||||
callBack?: (componentInstance: CreateComponentType) => void
|
||||
) => {
|
||||
// 补充 class 上的方法
|
||||
let newComponent: CreateComponentType = await createComponent(
|
||||
comItem.chartConfig
|
||||
)
|
||||
let newComponent: CreateComponentType = await createComponent(_componentInstance.chartConfig)
|
||||
if (callBack) {
|
||||
if (changeId) {
|
||||
callBack(Object.assign(newComponent, { ..._componentInstance, id: getUUID() }))
|
||||
} else {
|
||||
callBack(Object.assign(newComponent))
|
||||
}
|
||||
} else {
|
||||
if (changeId) {
|
||||
chartEditStore.addComponentList(
|
||||
Object.assign(newComponent, {...comItem, id: getUUID()}),
|
||||
Object.assign(newComponent, { ..._componentInstance, id: getUUID() }),
|
||||
false,
|
||||
true
|
||||
)
|
||||
} else {
|
||||
chartEditStore.addComponentList(Object.assign(newComponent), false, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (comItem.isGroup) {
|
||||
// 创建分组
|
||||
let groupClass = new PublicGroupConfigClass()
|
||||
if (changeId) {
|
||||
groupClass = Object.assign(groupClass, { ...comItem, id: getUUID() })
|
||||
} else {
|
||||
groupClass = Object.assign(groupClass, { ...comItem })
|
||||
}
|
||||
|
||||
// 注册子应用
|
||||
const targetList: CreateComponentType[] = []
|
||||
;(comItem as CreateComponentGroupType).groupList.forEach(groupItem => {
|
||||
create(groupItem, e => {
|
||||
targetList.push(e)
|
||||
})
|
||||
})
|
||||
groupClass.groupList = targetList
|
||||
|
||||
// 分组插入到列表
|
||||
chartEditStore.addComponentList(groupClass, false, true)
|
||||
} else {
|
||||
create(comItem as CreateComponentType)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 非组件(顺便排除脏数据)
|
||||
if (key !== 'editCanvasConfig' && key !== 'requestGlobalConfig') return
|
||||
Object.assign((chartEditStore as any)[key], projectData[key])
|
||||
Object.assign(chartEditStore[key], projectData[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
3
src/views/preview/components/PreviewRenderGroup/index.ts
Normal file
3
src/views/preview/components/PreviewRenderGroup/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import PreviewRenderGroup from './index.vue'
|
||||
|
||||
export { PreviewRenderGroup }
|
53
src/views/preview/components/PreviewRenderGroup/index.vue
Normal file
53
src/views/preview/components/PreviewRenderGroup/index.vue
Normal file
@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<div
|
||||
class="chart-item"
|
||||
v-for="item in groupData.groupList"
|
||||
:class="animationsClass(item.styles.animations)"
|
||||
:key="item.id"
|
||||
:style="{
|
||||
...getComponentAttrStyle(item.attr, groupIndex),
|
||||
...getFilterStyle(item.styles),
|
||||
...getTransformStyle(item.styles)
|
||||
}"
|
||||
>
|
||||
<component
|
||||
:is="item.chartConfig.chartKey"
|
||||
:chartConfig="item"
|
||||
:themeSetting="themeSetting"
|
||||
:themeColor="themeColor"
|
||||
:style="{...getSizeStyle(item.attr)}"
|
||||
></component>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { animationsClass, getFilterStyle, getTransformStyle } from '@/utils'
|
||||
import { getSizeStyle, getComponentAttrStyle } from '../../utils'
|
||||
|
||||
const props = defineProps({
|
||||
groupData: {
|
||||
type: Object as PropType<CreateComponentGroupType>,
|
||||
required: true
|
||||
},
|
||||
themeSetting: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
themeColor: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
groupIndex: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chart-item {
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div
|
||||
class="chart-item"
|
||||
:class="animationsClass(item.styles.animations)"
|
||||
v-for="(item, index) in localStorageInfo.componentList"
|
||||
:class="animationsClass(item.styles.animations)"
|
||||
:key="item.id"
|
||||
:style="{
|
||||
...getComponentAttrStyle(item.attr, index),
|
||||
@ -10,7 +10,18 @@
|
||||
...getTransformStyle(item.styles)
|
||||
}"
|
||||
>
|
||||
<!-- 分组 -->
|
||||
<preview-render-group
|
||||
v-if="item.isGroup"
|
||||
:groupData="(item as CreateComponentGroupType)"
|
||||
:groupIndex="index"
|
||||
:themeSetting="themeSetting"
|
||||
:themeColor="themeColor"
|
||||
></preview-render-group>
|
||||
|
||||
<!-- 单组件 -->
|
||||
<component
|
||||
v-else
|
||||
:is="item.chartConfig.chartKey"
|
||||
:chartConfig="item"
|
||||
:themeSetting="themeSetting"
|
||||
@ -23,6 +34,8 @@
|
||||
<script setup lang="ts">
|
||||
import { PropType, computed } from 'vue'
|
||||
import { ChartEditStorageType } from '../../index.d'
|
||||
import { PreviewRenderGroup } from '../PreviewRenderGroup/index'
|
||||
import { CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { chartColors } from '@/settings/chartThemes/index'
|
||||
import { animationsClass, getFilterStyle, getTransformStyle } from '@/utils'
|
||||
import { getSizeStyle, getComponentAttrStyle } from '../../utils'
|
||||
@ -45,7 +58,6 @@ const themeColor = computed(() => {
|
||||
const chartThemeColor = props.localStorageInfo.editCanvasConfig.chartThemeColor
|
||||
return chartColors[chartThemeColor]
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ref } from 'vue'
|
||||
import { ChartEditStorageType } from '../index.d'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
|
||||
import { fetchChartComponent } from '@/packages/index'
|
||||
|
||||
export const useComInstall = (localStorageInfo: ChartEditStorageType) => {
|
||||
@ -10,12 +10,20 @@ export const useComInstall = (localStorageInfo: ChartEditStorageType) => {
|
||||
const intervalTiming = setInterval(() => {
|
||||
if (window['$vue'].component) {
|
||||
clearInterval(intervalTiming)
|
||||
localStorageInfo.componentList.forEach(async (e: CreateComponentType) => {
|
||||
if (!window['$vue'].component(e.chartConfig.chartKey)) {
|
||||
window['$vue'].component(
|
||||
e.chartConfig.chartKey,
|
||||
fetchChartComponent(e.chartConfig)
|
||||
)
|
||||
|
||||
const intComponent = (target: CreateComponentType) => {
|
||||
if (!window['$vue'].component(target.chartConfig.chartKey)) {
|
||||
window['$vue'].component(target.chartConfig.chartKey, fetchChartComponent(target.chartConfig))
|
||||
}
|
||||
}
|
||||
|
||||
localStorageInfo.componentList.forEach(async (e: CreateComponentType | CreateComponentGroupType) => {
|
||||
if (e.isGroup) {
|
||||
(e as CreateComponentGroupType).groupList.forEach(groupItem => {
|
||||
intComponent(groupItem)
|
||||
})
|
||||
} else {
|
||||
intComponent(e as CreateComponentType)
|
||||
}
|
||||
})
|
||||
show.value = true
|
||||
|
Loading…
x
Reference in New Issue
Block a user