feat: 新增剪切

This commit is contained in:
MTrun 2022-02-04 12:17:50 +08:00
parent ad8cc8a003
commit 71e13c83e6
11 changed files with 224 additions and 45 deletions

View File

@ -1,17 +1,12 @@
import { getUUID } from '@/utils'
import { echartOptionProfixHandle } from '@/packages/utils/chart'
import { echartOptionProfixHandle, publicConfig } from '@/packages/utils'
import { BarCommonConfig } from './index'
import { ConfigType, CreateComponentType } from '@/packages/index.d'
import omit from 'lodash/omit'
export default class Config implements CreateComponentType {
public id = getUUID()
export default class Config extends publicConfig implements CreateComponentType {
public key = BarCommonConfig.key
public rename = undefined
public chartData: Exclude<ConfigType, ['node']> = omit(BarCommonConfig, ['node'])
public attr = { x: 0, y: 0, w: 500, h: 300 }
// 图表配置项
public option = echartOptionProfixHandle({
tooltip: {
@ -34,10 +29,4 @@ export default class Config implements CreateComponentType {
}
]
})
// 设置坐标
public setPosition(x: number, y: number): void {
this.attr.x = x
this.attr.y = y
}
}

View File

@ -13,14 +13,16 @@ export type ConfigType = {
}
// 组件实例类
export interface CreateComponentType {
export interface PublicConfigType {
id: string
key: string
rename?: string
attr: { x: number; y: number; w: number; h: number }
attr: { x: number; y: number; w: number; h: number; zIndex: number }
setPosition: Function
}
export interface CreateComponentType extends PublicConfigType {
key: string
chartData: ConfigType
option: object
setPosition: Function
}
// 包分类枚举

View File

@ -1 +1,2 @@
export * from '@/packages/utils/chart'
export * from '@/packages/utils/publicConfig'

View File

@ -0,0 +1,15 @@
import { getUUID } from '@/utils'
import { PublicConfigType } from '@/packages/index.d'
export class publicConfig implements PublicConfigType{
public id = getUUID()
// 重命名
public rename = undefined
// 基本信息
public attr = { x: 0, y: 0, w: 500, h: 300, zIndex: 0 }
// 设置坐标
public setPosition(x: number, y: number): void {
this.attr.x = x
this.attr.y = y
}
}

View File

@ -41,7 +41,8 @@ import {
ChevronUp as ChevronUpIcon,
ChevronDown as ChevronDownIcon,
TimeOutline as TimeOutlineIcon,
ClipboardOutline as ClipboardOutlineIcon
ClipboardOutline as ClipboardOutlineIcon,
Cut as CutIcon
} from '@vicons/ionicons5'
import {
@ -143,7 +144,9 @@ const ionicons5 = {
// 时间
TimeOutlineIcon,
// 剪贴板
ClipboardOutlineIcon
ClipboardOutlineIcon,
// 剪贴
CutIcon
}
const carbon = {

View File

@ -1,4 +1,5 @@
import { CreateComponentType } from '@/packages/index.d'
import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
// 编辑画布属性
export enum EditCanvasTypeEnum {
@ -13,6 +14,7 @@ export enum EditCanvasTypeEnum {
BACKGROUND = 'background'
}
// 编辑区域
export type EditCanvasType = {
// 编辑区域 DOM
[EditCanvasTypeEnum.EDIT_LAYOUT_DOM]: HTMLElement | null
@ -53,6 +55,12 @@ export type TargetChartType = {
selectId?: string
}
// 数据记录
export type RecordChartType = {
charts: CreateComponentType | CreateComponentType[]
type: HistoryActionTypeEnum.CUT | HistoryActionTypeEnum.COPY
}
// Store 枚举
export enum ChartEditStoreEnum {
EDIT_RANGE = 'editRange',
@ -60,7 +68,7 @@ export enum ChartEditStoreEnum {
RIGHT_MENU_SHOW = 'rightMenuShow',
MOUSE_POSITION = 'mousePosition',
TARGET_CHART = 'targetChart',
RECORD_CHARTS = 'recordCharts',
RECORD_CHART = 'recordChart',
COMPONENT_LIST = 'componentList'
}
@ -70,6 +78,6 @@ export interface chartEditStoreType {
[ChartEditStoreEnum.RIGHT_MENU_SHOW]: boolean
[ChartEditStoreEnum.MOUSE_POSITION]: MousePositionType
[ChartEditStoreEnum.TARGET_CHART]: TargetChartType
[ChartEditStoreEnum.RECORD_CHARTS]?: CreateComponentType | CreateComponentType[]
[ChartEditStoreEnum.RECORD_CHART]?: RecordChartType
[ChartEditStoreEnum.COMPONENT_LIST]: CreateComponentType[]
}

View File

@ -7,12 +7,13 @@ import {
chartEditStoreType,
EditCanvasType,
MousePositionType,
TargetChartType
TargetChartType,
RecordChartType
} from './chartEditStore.d'
// 记录记录
import { useChartHistoryStoreStore } from '@/store/modules/chartHistoryStore/chartHistoryStore'
import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
import { HistoryActionTypeEnum, HistoryItemType } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
const chartHistoryStoreStore = useChartHistoryStoreStore()
@ -53,7 +54,7 @@ export const useChartEditStoreStore = defineStore({
selectId: undefined
},
// 记录临时数据(复制等)
recordCharts: undefined,
recordChart: undefined,
// 图表数组
componentList: []
}),
@ -70,8 +71,8 @@ export const useChartEditStoreStore = defineStore({
getTargetChart():TargetChartType {
return this.targetChart
},
getRecordCharts(): CreateComponentType | CreateComponentType[] | undefined {
return this.recordCharts
getRecordChart(): RecordChartType | undefined {
return this.recordChart
},
getComponentList(): CreateComponentType[] {
return this.componentList
@ -95,14 +96,13 @@ export const useChartEditStoreStore = defineStore({
this.targetChart.selectId = selectId
},
// * 设置记录数据
setRecordCharts(item: CreateComponentType | CreateComponentType[] | undefined) {
this.recordCharts = cloneDeep(item)
setRecordChart(item: RecordChartType | undefined) {
this.recordChart = cloneDeep(item)
},
// * 找到目标 id 数据下标位置
fetchTargetIndex(): number {
const index = this.componentList.findIndex(e => e.id === this.getTargetChart.selectId)
if (index === -1) {
window['$message'].success(`操作失败,无法找到此元素`)
loadingError()
}
return index
@ -202,7 +202,6 @@ export const useChartEditStoreStore = defineStore({
const index:number = this.fetchTargetIndex()
if (index !== -1) {
// 下移排除最底层, 上移排除最顶层
if ((isDown && index === 0) || (!isDown && index === length - 1)) {
loadingFinish()
@ -233,24 +232,32 @@ export const useChartEditStoreStore = defineStore({
this.wrap(true)
},
// * 复制
setCopy() {
setCopy(isCut = false) {
try {
loadingStart()
const index:number = this.fetchTargetIndex()
if (index !== -1) {
this.setRecordCharts(this.getComponentList[index])
window['$message'].success('复制成功!')
const copyData:RecordChartType = {
charts :this.getComponentList[index],
type: isCut ? HistoryActionTypeEnum.CUT : HistoryActionTypeEnum.COPY
}
this.setRecordChart(copyData)
window['$message'].success(isCut ? '剪切成功' : '复制成功!')
loadingFinish()
}
} catch(value) {
loadingError()
}
},
// * 剪切
setCut() {
this.setCopy(true)
},
// * 粘贴
setParse() {
try {
loadingStart()
const recordCharts = this.getRecordCharts
const recordCharts = this.getRecordChart
if (recordCharts === undefined) {
loadingFinish()
return
@ -264,20 +271,90 @@ export const useChartEditStoreStore = defineStore({
e.attr.y = e.attr.y + 30
return e
}
if (Array.isArray(recordCharts)) {
recordCharts.forEach((e: CreateComponentType) => {
console.log(parseHandle(e));
const isCut = recordCharts.type === HistoryActionTypeEnum.CUT
// 多项
if (Array.isArray(recordCharts.charts)) {
recordCharts.charts.forEach((e: CreateComponentType) => {
this.addComponentList(parseHandle(e), undefined, true)
// 剪切需删除原数据
if (isCut) {
this.setTargetSelectChart(e.id)
this.removeComponentList()
}
})
if (isCut) this.setRecordChart(undefined)
loadingFinish()
return
}
this.addComponentList(parseHandle(recordCharts), undefined, true)
// 单项
this.addComponentList(parseHandle(recordCharts.charts), undefined, true)
if(isCut) {
this.setTargetSelectChart(recordCharts.charts.id)
this.removeComponentList()
this.setRecordChart(undefined)
}
loadingFinish()
} catch(value) {
loadingError()
}
},
// 撤回处理
setBackAndSetForwardHandle(item: HistoryItemType, isForward = false) {
// 前进
if (isForward) {
return
}
console.log(item);
},
// * 撤回
setBack() {
try {
loadingStart()
console.log('撤回');
const targetData = chartHistoryStoreStore.backAction()
if (!targetData) {
loadingFinish()
return
}
if (Array.isArray(targetData)) {
targetData.forEach((e: HistoryItemType) => {
this.setBackAndSetForwardHandle(e)
})
loadingFinish()
return
}
this.setBackAndSetForwardHandle(targetData)
loadingFinish()
} catch(value) {
loadingError()
}
},
// * 前进
setForward() {
try {
loadingStart()
console.log('前进');
const targetData = chartHistoryStoreStore.forwardAction()
if (!targetData) {
loadingFinish()
return
}
if (Array.isArray(targetData)) {
targetData.forEach((e: HistoryItemType) => {
this.setBackAndSetForwardHandle(e, true)
})
loadingFinish()
return
}
this.setBackAndSetForwardHandle(targetData, true)
loadingFinish()
} catch(value) {
loadingError()
}
},
// ----------------
// * 设置鼠标位置
setMousePosition(x: number, y: number): void {
this.mousePosition.x = x

View File

@ -11,6 +11,10 @@ export enum HistoryActionTypeEnum {
UPDATE = 'update',
// 移动
MOVE = 'move',
// 复制
COPY = 'copy',
// 剪切
CUT = 'cut',
// 粘贴
PASTE = 'paste',
// 改变层级

View File

@ -2,6 +2,7 @@ import { defineStore } from 'pinia'
import { CreateComponentType } from '@/packages/index.d'
import { ChartLayoutType } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore'
import { loadingStart, loadingFinish, loadingError } from '@/utils'
import {
HistoryStackEnum,
HistoryStackItemEnum,
@ -47,9 +48,13 @@ export const useChartHistoryStoreStore = defineStore({
this.createStackItem(canvas, HistoryActionTypeEnum.ADD, HistoryTargetTypeEnum.CANVAS)
},
// * 推入记录栈
pushBackStackItem(item: HistoryItemType | Array<HistoryItemType>): void {
pushBackStackItem(item: HistoryItemType | Array<HistoryItemType>, notClear = false): void {
if (item instanceof Array) this.backStack = [...this.backStack, ...item]
else this.backStack.push(item)
// 新动作需清空前进栈
if(notClear) return
this.clearForwardStack()
},
// * 推入前进栈
pushForwardStack(item: HistoryItemType | Array<HistoryItemType>): void {
@ -77,6 +82,51 @@ export const useChartHistoryStoreStore = defineStore({
return this.forwardStack.pop()
}
},
// * 清空前进栈
clearForwardStack() {
this.forwardStack = []
},
// * 撤回
backAction() {
try {
loadingStart()
// 排除画布初始化
if (this.getBackStack.length > 1) {
const targetData = this.popBackStackItem()
if (!targetData) {
loadingFinish()
return
}
// 移除记录到前进堆
this.pushForwardStack(targetData)
loadingFinish()
return targetData
}
loadingFinish()
} catch (error) {
loadingError()
}
},
// * 前进
forwardAction() {
try {
loadingStart()
if (this.getForwardStack.length) {
const targetData = this.popForwardStack()
if (!targetData) {
loadingFinish()
return
}
// 放入后退栈
this.pushBackStackItem(targetData, true)
loadingFinish()
return targetData
}
loadingFinish()
} catch (error) {
loadingError()
}
},
// * 新增组件记录
createAddHistory(item: CreateComponentType) {
this.createStackItem(item, HistoryActionTypeEnum.ADD, HistoryTargetTypeEnum.CHART)

View File

@ -1,26 +1,49 @@
import { isMac, addEventListener, removeEventListener } from '@/utils'
import { getChartEditStore } from './useStore.hook'
import { MenuEnum } from '@/views/chart/hooks/useContextMenu.hook'
const chartEditStore = getChartEditStore()
export const keyboardValue = {
[MenuEnum.COPY]: 'c',
[MenuEnum.CUT]: 'x',
[MenuEnum.PARSE]: 'v',
[MenuEnum.DELETE]: 'delete',
back: 'z',
}
const KeyboardHandle = (e: KeyboardEvent) => {
const ismacRes = isMac()
// 暂不支持mac因为我没有😤👻
if(ismacRes) return
if (ismacRes) return
const key = e.key.toLowerCase()
if (key === 'delete') {
// 删除
if (key === keyboardValue.delete) {
chartEditStore.removeComponentList()
return
}
// 前进
if (e.ctrlKey && e.shiftKey && key == keyboardValue.back) {
chartEditStore.setForward()
return
}
if (e.ctrlKey) {
switch (key) {
// 复制
case 'c': chartEditStore.setCopy()
case keyboardValue.copy: chartEditStore.setCopy()
break;
// 剪切
case keyboardValue.cut: chartEditStore.setCut()
break;
// 粘贴
case 'v': chartEditStore.setParse()
case keyboardValue.parse: chartEditStore.setParse()
break;
// 撤回
case keyboardValue.back: chartEditStore.setBack()
break;
}
e.preventDefault()

View File

@ -4,14 +4,15 @@ import { CreateComponentType } from '@/packages/index.d'
import { renderIcon, loadingError } from '@/utils'
import { icon } from '@/plugins'
const { CopyIcon, ClipboardOutlineIcon, TrashIcon, ChevronDownIcon, ChevronUpIcon } = icon.ionicons5
const { CopyIcon, CutIcon, ClipboardOutlineIcon, TrashIcon, ChevronDownIcon, ChevronUpIcon } = icon.ionicons5
const { UpToTopIcon, DownToBottomIcon } = icon.carbon
const chartEditStore = useChartEditStoreStore()
enum MenuEnum {
export enum MenuEnum {
DELETE = 'delete',
COPY = 'copy',
CUT = 'cut',
PARSE = 'parse',
TOP = 'top',
BOTTOM = 'bottom',
@ -35,6 +36,12 @@ const defaultOptions: MenuOptionsItemType[] = [
icon: renderIcon(CopyIcon),
fnHandle: chartEditStore.setCopy
},
{
label: '剪切',
key: MenuEnum.CUT,
icon: renderIcon(CutIcon),
fnHandle: chartEditStore.setCut
},
{
label: '粘贴',
key: MenuEnum.PARSE,