| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608 |
- import { defineStore } from 'pinia'
- import { getUUID, loadingStart, loadingFinish, loadingError } from '@/utils'
- import { CreateComponentType } from '@/packages/index.d'
- import debounce from 'lodash/debounce'
- import cloneDeep from 'lodash/cloneDeep'
- import { defaultTheme, globalThemeJson } from '@/settings/chartThemes/index'
- import { requestInterval, previewScaleType } from '@/settings/designSetting'
- // 记录记录
- 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, SyncEnum } from '@/enums/editPageEnum'
- import {
- ProjectInfoType,
- ChartEditStoreEnum,
- ChartEditStorage,
- ChartEditStoreType,
- EditCanvasType,
- MousePositionType,
- TargetChartType,
- RecordChartType,
- RequestGlobalConfigType,
- EditCanvasConfigType
- } from './chartEditStore.d'
- const chartHistoryStore = useChartHistoryStore()
- const settingStore = useSettingStore()
- // 编辑区域内容
- export const useChartEditStore = defineStore({
- id: 'useChartEditStore',
- state: (): ChartEditStoreType => ({
- // 项目数据
- projectInfo: {
- projectName: '',
- remarks: '',
- thumbnail: '',
- release: false
- },
- // 画布属性
- editCanvas: {
- // 编辑区域 Dom
- editLayoutDom: null,
- editContentDom: null,
- // 偏移量
- offset: 20,
- // 系统控制缩放
- scale: 1,
- // 用户控制的缩放
- userScale: 1,
- // 锁定缩放
- lockScale: false,
- // 初始化
- isCreate: false,
- // 拖拽中
- isDrag: false,
- // 同步中
- saveStatus: SyncEnum.PENDING
- },
- // 右键菜单
- rightMenuShow: false,
- // 鼠标定位
- mousePosition: {
- startX: 0,
- startY: 0,
- x: 0,
- y: 0
- },
- // 目标图表
- targetChart: {
- hoverId: undefined,
- selectId: undefined
- },
- // 记录临时数据(复制等)
- recordChart: undefined,
- // -----------------------
- // 画布属性(需存储给后端)
- editCanvasConfig: {
- // 默认宽度
- width: 1920,
- // 默认高度
- height: 1080,
- // 色相
- hueRotate: 0,
- // 饱和度
- saturate: 1,
- // 对比度
- contrast: 1,
- // 亮度
- brightness: 1,
- // 透明度
- opacity: 1,
- // 变换(暂不更改)
- rotateZ: 0,
- rotateX: 0,
- rotateY: 0,
- skewX: 0,
- skewY: 0,
- // 默认背景色
- background: undefined,
- backgroundImage: undefined,
- // 是否使用纯颜色
- selectColor: true,
- // chart 主题色
- chartThemeColor: defaultTheme || 'dark',
- // 全局配置
- chartThemeSetting: globalThemeJson,
- // 预览方式
- previewScaleType: previewScaleType
- },
- // 数据请求处理(需存储给后端)
- requestGlobalConfig: {
- requestOriginUrl: '',
- requestInterval: requestInterval
- },
- // 图表数组(需存储给后端)
- componentList: []
- }),
- getters: {
- getProjectInfo(): ProjectInfoType {
- return this.projectInfo
- },
- getMousePosition(): MousePositionType {
- return this.mousePosition
- },
- getRightMenuShow(): boolean {
- return this.rightMenuShow
- },
- getEditCanvas(): EditCanvasType {
- return this.editCanvas
- },
- getEditCanvasConfig(): EditCanvasConfigType {
- return this.editCanvasConfig
- },
- getTargetChart():TargetChartType {
- return this.targetChart
- },
- getRecordChart(): RecordChartType | undefined {
- return this.recordChart
- },
- getRequestGlobalConfig(): RequestGlobalConfigType {
- return this.requestGlobalConfig
- },
- getComponentList(): CreateComponentType[] {
- return this.componentList
- },
- // 获取需要存储的数据项
- getStorageInfo(): ChartEditStorage {
- return {
- [ChartEditStoreEnum.EDIT_CANVAS_CONFIG]: this.getEditCanvasConfig,
- [ChartEditStoreEnum.COMPONENT_LIST]: this.getComponentList,
- [ChartEditStoreEnum.REQUEST_GLOBAL_CONFIG]: this.getRequestGlobalConfig
- }
- }
- },
- actions: {
- // * 设置 peojectInfo 数据项
- setProjectInfo<T extends keyof ProjectInfoType, K extends ProjectInfoType[T]>(key: T, value: K) {
- this.projectInfo[key] = value
- },
- // * 设置 editCanvas 数据项
- setEditCanvas<T extends keyof EditCanvasType, K extends EditCanvasType[T]>(key: T, value: K) {
- this.editCanvas[key] = value
- },
- // * 设置 editCanvasConfig(需保存后端) 数据项
- setEditCanvasConfig<T extends keyof EditCanvasConfigType, K extends EditCanvasConfigType[T]>(key: T, value: K) {
- this.editCanvasConfig[key] = value
- },
- // * 设置右键菜单
- setRightMenuShow(value: boolean) {
- this.rightMenuShow = value
- },
- // * 设置目标数据 hover
- setTargetHoverChart(hoverId?:TargetChartType["hoverId"]) {
- this.targetChart.hoverId = hoverId
- },
- // * 设置目标数据 select
- setTargetSelectChart(selectId?:TargetChartType["selectId"]) {
- this.targetChart.selectId = selectId
- },
- // * 设置记录数据
- setRecordChart(item: RecordChartType | undefined) {
- this.recordChart = cloneDeep(item)
- },
- // * 设置鼠标位置
- setMousePosition(x?: number, y?: number, startX?: number, startY?: number): void {
- if (startX) this.mousePosition.startX = startX
- if (startY) this.mousePosition.startY = startY
- if (x) this.mousePosition.x = x
- if (y) this.mousePosition.y = y
- },
- // * 找到目标 id 数据下标位置(无则返回-1)
- fetchTargetIndex(id?: string): number {
- const targetId = id || this.getTargetChart.selectId
- if(!targetId) {
- loadingFinish()
- return -1
- }
- const index = this.componentList.findIndex(e => e.id === targetId)
- if (index === -1) {
- loadingError()
- }
- return index
- },
- /**
- * * 新增组件列表
- * @param chartConfig 新图表实例
- * @param isHead 是否头部插入
- * @param isHistory 是否进行记录
- * @returns
- */
- addComponentList(chartConfig: CreateComponentType, isHead = false, isHistory = false): void {
- if (isHistory) {
- chartHistoryStore.createAddHistory(chartConfig)
- }
- if (isHead) {
- this.componentList.unshift(chartConfig)
- return
- }
- this.componentList.push(chartConfig)
- },
- // * 删除组件列表
- removeComponentList(isHistory = true): void {
- try {
- loadingStart()
- const index = this.fetchTargetIndex()
- if (index !== -1) {
- isHistory ? chartHistoryStore.createDeleteHistory(this.getComponentList[index]) : undefined
- this.componentList.splice(index, 1)
- loadingFinish()
- return
- }
- } catch(value) {
- loadingError()
- }
- },
- // * 更新组件列表某一项的值
- updateComponentList(index: number, newData: CreateComponentType) {
- if (index < 1 && index > this.getComponentList.length) return
- this.componentList[index] = newData
- },
- // * 设置页面样式属性
- setPageStyle<T extends keyof CSSStyleDeclaration>(
- key: T,
- value: any
- ): void {
- const dom = this.getEditCanvas.editContentDom
- if (dom) {
- dom.style[key] = value
- }
- },
- // * 移动组件列表层级位置到两端
- setBothEnds(isEnd = false, isHistory = true): void {
- try {
- loadingStart()
- const length = this.getComponentList.length
- if (length < 2) {
- loadingFinish()
- return
- }
- const index = this.fetchTargetIndex()
- const targetData = this.getComponentList[index]
- if (index !== -1) {
- // 置底排除最底层, 置顶排除最顶层
- if ((isEnd && index === 0) || (!isEnd && index === length - 1 )) {
- loadingFinish()
- return
- }
- // 记录原有位置
- const setIndex = (t:CreateComponentType, i:number) => {
- const temp = cloneDeep(t)
- temp.attr.zIndex = i
- return temp
- }
- // 历史记录
- if (isHistory) {
- chartHistoryStore.createLaryerHistory(
- setIndex(targetData, index),
- isEnd ? HistoryActionTypeEnum.BOTTOM : HistoryActionTypeEnum.TOP
- )
- }
- // 插入两端
- this.addComponentList(targetData, isEnd)
- this.getComponentList.splice(isEnd ? index + 1: index, 1)
- loadingFinish()
- return
- }
- } catch(value) {
- loadingError()
- }
- },
- // * 置顶
- setTop(isHistory = true): void {
- this.setBothEnds(false, isHistory)
- },
- // * 置底
- setBottom(isHistory = true): void {
- this.setBothEnds(true, isHistory)
- },
- // * 上移/下移互换图表位置
- wrap(isDown = false, isHistory = true) {
- try {
- loadingStart()
- const length = this.getComponentList.length
- if (length < 2) {
- loadingFinish()
- return
- }
- const index:number = this.fetchTargetIndex()
- if (index !== -1) {
- // 下移排除最底层, 上移排除最顶层
- if ((isDown && index === 0) || (!isDown && index === length - 1)) {
- loadingFinish()
- return
- }
- // 互换位置
- const swapIndex = isDown ? index - 1 : index + 1
- const targetItem = this.getComponentList[index]
- const swapItem = this.getComponentList[swapIndex]
- // 历史记录
- if (isHistory) {
- chartHistoryStore.createLaryerHistory(
- targetItem,
- isDown ? HistoryActionTypeEnum.DOWN : HistoryActionTypeEnum.UP
- )
- }
- this.updateComponentList(index, swapItem)
- this.updateComponentList(swapIndex, targetItem)
- loadingFinish()
- return
- }
- } catch(value) {
- loadingError()
- }
- },
- // * 图层上移
- setUp(isHistory = true) {
- this.wrap(false, isHistory)
- },
- // * 图层下移
- setDown(isHistory = true) {
- this.wrap(true, isHistory)
- },
- // * 复制
- setCopy(isCut = false) {
- try {
- loadingStart()
- const index:number = this.fetchTargetIndex()
- if (index !== -1) {
- 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.getRecordChart
- if (recordCharts === undefined) {
- loadingFinish()
- return
- }
- const parseHandle = (e: CreateComponentType) => {
- e = cloneDeep(e)
- // 生成新 id
- e.id = getUUID()
- // 偏移位置
- e.attr.x = this.getMousePosition.x + 30
- e.attr.y = this.getMousePosition.y + 30
- return 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(true)
- }
- })
- if (isCut) this.setRecordChart(undefined)
- loadingFinish()
- return
- }
- // 单项
- 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 (item.targetType === HistoryTargetTypeEnum.CANVAS) {
- this.editCanvas = item.historyData as EditCanvasType
- return
- }
- const historyData = item.historyData as CreateComponentType
- // 处理新增类型
- const isAdd = item.actionType === HistoryActionTypeEnum.ADD
- const isDel = item.actionType === HistoryActionTypeEnum.DELETE
- this.setTargetSelectChart(historyData.id)
- if (isAdd || isDel) {
- if ((isAdd && isForward) || (isDel && !isForward)) {
- this.addComponentList(historyData)
- return
- }
- this.removeComponentList(false)
- return
- }
- // 处理层级
- const isTop = item.actionType === HistoryActionTypeEnum.TOP
- const isBottom = item.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)
- return
- }
- if (isTop) this.setTop(false)
- if (isBottom) this.setBottom(false)
- }
- const isUp = item.actionType === HistoryActionTypeEnum.UP
- const isDown = item.actionType === HistoryActionTypeEnum.DOWN
- if (isUp || isDown) {
- if ((isUp && isForward) || (isDown && !isForward)) {
- this.setUp(false)
- return
- }
- this.setDown(false)
- return
- }
- // 处理内容修改
- this.getComponentList[this.fetchTargetIndex()] = item.historyData as CreateComponentType
- },
- // * 撤回
- setBack() {
- try {
- loadingStart()
- const targetData = chartHistoryStore.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()
- const targetData = chartHistoryStore.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()
- }
- },
- // * 移动位置
- setMove(keyboardValue: MenuEnum) {
- const index = this.fetchTargetIndex()
- if(index === -1) return
- const attr = this.getComponentList[index].attr
- const distance = settingStore.getChartMoveDistance
- switch (keyboardValue) {
- case MenuEnum.ARROW_UP:
- attr.y -= distance
- break;
- case MenuEnum.ARROW_RIGHT:
- attr.x += distance
- break;
- case MenuEnum.ARROW_DOWN:
- attr.y += distance
- break;
- case MenuEnum.ARROW_LEFT:
- attr.x -= distance
- break;
- }
- },
- // * 页面缩放设置-----------------
- // * 设置页面大小
- setPageSize(scale: number): void {
- this.setPageStyle('height', `${this.editCanvasConfig.height * scale}px`)
- this.setPageStyle('width', `${this.editCanvasConfig.width * scale}px`)
- },
- // * 计算缩放
- 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 editCanvasWidth = this.editCanvasConfig.width
- const editCanvasHeight = this.editCanvasConfig.height
- // 需保持的比例
- const baseProportion = parseFloat(
- (editCanvasWidth / editCanvasHeight).toFixed(5)
- )
- const currentRate = parseFloat((width / height).toFixed(5))
- if (currentRate > baseProportion) {
- // 表示更宽
- const scaleWidth = parseFloat(
- ((height * baseProportion) / editCanvasWidth).toFixed(5)
- )
- this.setScale( scaleWidth > 1 ? 1 : scaleWidth)
- } else {
- // 表示更高
- const scaleHeight = parseFloat(
- (width / baseProportion / editCanvasHeight).toFixed(5)
- )
- this.setScale(scaleHeight > 1 ? 1 : scaleHeight)
- }
- } else {
- window['$message'].warning('请先创建画布,再进行缩放')
- }
- },
- // * 监听缩放
- listenerScale(): Function {
- const resize = debounce(this.computedScale, 200)
- // 默认执行一次
- resize()
- // 开始监听
- window.addEventListener('resize', resize)
- // 销毁函数
- const remove = () => {
- window.removeEventListener('resize', resize)
- }
- return remove
- },
- /**
- * * 设置缩放
- * @param scale 0~1 number 缩放比例;
- * @param force boolean 强制缩放
- */
- setScale(scale: number, force = false): void {
- if (!this.getEditCanvas.lockScale || force) {
- this.setPageSize(scale)
- this.getEditCanvas.userScale = scale
- this.getEditCanvas.scale = scale
- }
- }
- }
- })
|