feat: 新增获取项目数据功能,新增同步数据功能

This commit is contained in:
奔跑的面条 2022-05-23 23:50:35 +08:00
parent c930efba0c
commit 9a5d71fb5c
16 changed files with 282 additions and 72 deletions

View File

@ -32,6 +32,26 @@ export const fetchProjectApi = async (data: object) => {
}
}
// * 保存项目
export const saveProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)(`${ModuleTypeEnum.PROJECT}/save/data`, data);
return res;
} catch {
httpErrorHandle();
}
}
// * 修改项目
export const updateProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)(`${ModuleTypeEnum.PROJECT}/edit`, data);
return res;
} catch {
httpErrorHandle();
}
}
// * 删除项目
export const deleteProjectApi = async (data: object) => {

View File

@ -35,4 +35,16 @@ export enum MacKeyboard {
CTRL = '⌘',
SHIFT = '⇧',
ALT = '⌥',
}
// 同步状态枚举
export enum SyncEnum {
// 等待
PENDING,
// 开始
START,
// 成功
SUCCESS,
// 失败
FAILURE
}

View File

@ -34,7 +34,7 @@ const global = {
}
const http = {
error_message: '接口异常,请检查',
error_message: '获取数据失败,请稍后重试',
token_overdue_message: '登录过期,请重新登录!'
}

View File

@ -52,7 +52,8 @@ import {
ArrowBack as ArrowBackIcon,
ArrowForward as ArrowForwardIcon,
Planet as PawIcon,
Search as SearchIcon
Search as SearchIcon,
Reload as ReloadIcon
} from '@vicons/ionicons5'
import {
@ -190,7 +191,9 @@ const ionicons5 = {
// 狗爪
PawIcon,
// 搜索(放大镜)
SearchIcon
SearchIcon,
// 加载
ReloadIcon
}
const carbon = {

View File

@ -1,6 +1,7 @@
import { CreateComponentType, FilterEnum} from '@/packages/index.d'
import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
import { RequestHttpEnum, RequestDataTypeEnum } from '@/enums/httpEnum'
import { SyncEnum } from '@/enums/editPageEnum'
import { PreviewScaleEnum } from '@/enums/styleEnum'
import type {
ChartColorsNameType,
@ -17,9 +18,10 @@ export enum EditCanvasTypeEnum {
LOCK_SCALE = 'lockScale',
IS_CREATE = 'isCreate',
IS_DRAG = 'isDrag',
SAVE_STATUS = 'saveStatus'
}
// 编辑区域
// 编辑区域(临时)
export type EditCanvasType = {
// 编辑区域 DOM
[EditCanvasTypeEnum.EDIT_LAYOUT_DOM]: HTMLElement | null
@ -36,6 +38,8 @@ export type EditCanvasType = {
[EditCanvasTypeEnum.IS_CREATE]: boolean
// 拖拽中
[EditCanvasTypeEnum.IS_DRAG]: boolean
// 保存状态
[EditCanvasTypeEnum.SAVE_STATUS]: SyncEnum
}
// 滤镜/背景色/宽高主题等
@ -50,6 +54,7 @@ export enum EditCanvasConfigEnum {
PREVIEW_SCALE_TYPE = 'previewScaleType',
}
// 画布属性(需保存)
export interface EditCanvasConfigType {
// 滤镜-色相
[FilterEnum.HUE_ROTATE]: number
@ -137,6 +142,7 @@ export type RequestGlobalConfigType = {
// 轮询时间
requestInterval: number
}
// 单个图表请求配置
export type RequestConfigType = {
// 获取数据的方式
@ -159,6 +165,7 @@ export interface ChartEditStoreType {
[ChartEditStoreEnum.COMPONENT_LIST]: CreateComponentType[]
}
// 需要存储的数据内容
export interface ChartEditStorage {
[ChartEditStoreEnum.EDIT_CANVAS_CONFIG]: EditCanvasConfigType
[ChartEditStoreEnum.REQUEST_GLOBAL_CONFIG]: RequestGlobalConfigType

View File

@ -9,9 +9,11 @@ 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 } from '@/enums/editPageEnum'
import { PreviewScaleEnum } from '@/enums/styleEnum'
// 画布枚举
import { MenuEnum, SyncEnum } from '@/enums/editPageEnum'
import {
ChartEditStoreEnum,
ChartEditStorage,
@ -47,7 +49,9 @@ export const useChartEditStore = defineStore({
// 初始化
isCreate: false,
// 拖拽中
isDrag: false
isDrag: false,
// 同步中
saveStatus: SyncEnum.PENDING
},
// 右键菜单
rightMenuShow: false,
@ -517,8 +521,8 @@ export const useChartEditStore = defineStore({
attr.x -= distance
break;
}
},
// ----------------
},
// * 页面缩放设置-----------------
// * 设置页面大小
setPageSize(scale: number): void {
this.setPageStyle('height', `${this.editCanvasConfig.height * scale}px`)

View File

@ -1,6 +1,10 @@
<template>
<div class="go-edit-bottom">
<edit-history></edit-history>
<div class="go-flex-items-center">
<edit-history></edit-history>
<n-divider vertical />
<edit-data-sync></edit-data-sync>
</div>
<n-space class="bottom-ri">
<!-- 快捷键提示 -->
@ -55,7 +59,8 @@
import { reactive, ref, toRefs, watchEffect } from 'vue'
import { icon } from '@/plugins'
import { EditHistory } from '../EditHistory/index'
import EditShortcutKey from '../EditShortcutKey/index.vue'
import { EditShortcutKey } from '../EditShortcutKey/index'
import { EditDataSync } from '../EditDataSync/index'
import { useDesignStore } from '@/store/modules/designStore/designStore'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
@ -136,12 +141,13 @@ watchEffect(() => {
<style lang="scss" scoped>
$min-width: 500px;
@include go('edit-bottom') {
width: 100%;
min-width: $min-width;
padding: 0 10px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10px;
width: 100%;
min-width: $min-width;
height: 40px;
.bottom-ri {
position: relative;
top: 15px;

View File

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

View File

@ -0,0 +1,75 @@
<template>
<div class="go-edit-data-sync go-flex-items-center">
<n-text class="status-desc go-ml-2" :type="descType" depth="3">
{{ statusDesc }}
</n-text>
<n-spin
v-show="saveStatus === SyncEnum.START"
class="status-spin go-ml-2"
size="small"
>
<template #icon>
<n-icon size="13">
<reload-icon />
</n-icon>
</template>
</n-spin>
</div>
</template>
<script lang="ts" setup>
import { ref, toRefs, watchEffect } from 'vue'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { SyncEnum } from '@/enums/editPageEnum'
import { icon } from '@/plugins'
const { ReloadIcon } = icon.ionicons5
const chartEditStore = useChartEditStore()
const { saveStatus } = toRefs(chartEditStore.getEditCanvas)
const statusDesc = ref('')
const descType = ref('')
watchEffect(() => {
const statusDescObj = {
[SyncEnum.PENDING]: {
text: '待同步',
type: '',
},
[SyncEnum.START]: {
text: '同步中',
type: 'success',
},
[SyncEnum.SUCCESS]: {
text: '同步成功!',
type: 'success',
},
[SyncEnum.FAILURE]: {
text: '同步失败!',
type: 'error',
},
}
statusDesc.value = statusDescObj[saveStatus.value]['text']
descType.value = statusDescObj[saveStatus.value]['type']
// 3
setTimeout(() => {
statusDesc.value = statusDescObj[SyncEnum.PENDING]['text']
descType.value = statusDescObj[SyncEnum.PENDING]['type']
}, 3000)
})
</script>
<style lang="scss" scoped>
@include go('edit-data-sync') {
@include deep() {
.n-spin {
width: 13px;
height: 13px;
}
}
.status-desc {
font-size: 12px;
line-height: 40px;
opacity: .8;
}
}
</style>

View File

@ -10,7 +10,7 @@
>
<template #trigger>
<n-button
class="mr-10"
class="go-mr-1"
secondary
size="small"
:disabled="options.length === 0"
@ -140,9 +140,6 @@ const handleClick = () => {
</script>
<style lang="scss" scoped>
.mr-10 {
margin-right: 10px;
}
.edit-history-popover {
.btn-text {
font-size: 12px;

View File

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

View File

@ -1,61 +1,12 @@
import { ref, nextTick } from 'vue'
import { UploadCustomRequestOptions } from 'naive-ui'
import { FileTypeEnum } from '@/enums/fileTypeEnum'
import { fetchChartComponent } from '@/packages/index'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { ChartEditStoreEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore'
import { readFile, goDialog } from '@/utils'
import { createComponent } from '@/packages'
// 更新函数
const updateComponent = async (fileData: any, isSplace = false) => {
const chartEditStore = useChartEditStore()
const chartHistoryStore = useChartHistoryStore()
if (isSplace) {
// 清除列表
chartEditStore.componentList = []
// 清除历史记录
chartHistoryStore.clearBackStack()
chartHistoryStore.clearForwardStack()
}
// 列表组件注册
fileData.componentList.forEach(async (e: CreateComponentType) => {
if (!window['$vue'].component(e.chartConfig.chartKey)) {
window['$vue'].component(
e.chartConfig.chartKey,
fetchChartComponent(e.chartConfig)
)
}
})
// 数据赋值
for (const key in fileData) {
// 组件
if (key === ChartEditStoreEnum.COMPONENT_LIST) {
for (const comItem of fileData[key]) {
// 补充 class 上的方法
let newComponent: CreateComponentType = await createComponent(
comItem.chartConfig
)
// 不保存到记录
chartEditStore.addComponentList(
Object.assign(newComponent, comItem),
false,
true
)
}
} else {
// 非组件(顺便排除脏数据)
if(key !== 'editCanvasConfig' && key !== 'requestGlobalConfig') return
Object.assign((chartEditStore as any)[key], fileData[key])
}
}
}
import { useSync } from '@/views/chart/hooks/useSync.hook'
export const useFile = () => {
const importUploadFileListRef = ref()
const { updateComponent } = useSync()
// 上传-前置
//@ts-ignore
const importBeforeUpload = ({ file }) => {

View File

@ -68,7 +68,7 @@
</template>
<script setup lang="ts">
import { ref, computed, h } from 'vue';
import { ref, computed } from 'vue';
import { useSettingStore } from '@/store/modules/settingStore/settingStore'
import { ToolsStatusEnum } from '@/store/modules/settingStore/settingStore.d'
import { exportHandle } from './utils'

View File

@ -9,7 +9,7 @@ export const exportHandle = () => {
// 导出数据
downloadTextFile(
JSON.stringify(chartEditStore.getStorageInfo || [], (k, v) => {
JSON.stringify(chartEditStore.getStorageInfo || {}, (k, v) => {
return v === undefined ? null : v
}),
undefined,

View File

@ -71,6 +71,7 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore
import { useLayout } from './hooks/useLayout.hook'
import { useAddKeyboard } from '../hooks/useKeyboard.hook'
import { useSync } from '../hooks/useSync.hook'
import { dragHandle, dragoverHandle, useMouseHandle } from './hooks/useDrag.hook'
import { useComponentStyle, useSizeStyle } from './hooks/useStyle.hook'
@ -82,6 +83,7 @@ import { EditTools } from './components/EditTools'
const chartEditStore = useChartEditStore()
const { handleContextMenu } = useContextMenu()
const { dataSyncFetch } = useSync()
//
useLayout()
@ -121,9 +123,11 @@ const rangeStyle = computed(() => {
}
})
//
onMounted(() => {
//
useAddKeyboard()
//
dataSyncFetch()
})
</script>

View File

@ -0,0 +1,127 @@
import { onUnmounted } from 'vue';
import { useRoute } from 'vue-router'
import { httpErrorHandle } from '@/utils'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { EditCanvasTypeEnum, ChartEditStoreEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore'
import { fetchChartComponent, createComponent } from '@/packages/index'
import { CreateComponentType } from '@/packages/index.d'
// 接口状态
import { ResultEnum } from '@/enums/httpEnum'
// 接口
import { saveProjectApi, fetchProjectApi } from '@/api/path/project'
// 画布枚举
import { SyncEnum } from '@/enums/editPageEnum'
// 请求处理
export const useSync = () => {
const chartEditStore = useChartEditStore()
const chartHistoryStore = useChartHistoryStore()
const routerParamsInfo = useRoute()
/**
* *
* @param projectData
* @param isSplace
* @returns
*/
const updateComponent = async (projectData: any, isSplace = false) => {
if (isSplace) {
// 清除列表
chartEditStore.componentList = []
// 清除历史记录
chartHistoryStore.clearBackStack()
chartHistoryStore.clearForwardStack()
}
// 列表组件注册
projectData.componentList.forEach(async (e: CreateComponentType) => {
if (!window['$vue'].component(e.chartConfig.chartKey)) {
window['$vue'].component(
e.chartConfig.chartKey,
fetchChartComponent(e.chartConfig)
)
}
})
// 数据赋值
for (const key in projectData) {
// 组件
if (key === ChartEditStoreEnum.COMPONENT_LIST) {
for (const comItem of projectData[key]) {
// 补充 class 上的方法
let newComponent: CreateComponentType = await createComponent(
comItem.chartConfig
)
// 不保存到记录
chartEditStore.addComponentList(
Object.assign(newComponent, comItem),
false,
true
)
}
} else {
// 非组件(顺便排除脏数据)
if (key !== 'editCanvasConfig' && key !== 'requestGlobalConfig') return
Object.assign((chartEditStore as any)[key], projectData[key])
}
}
}
// 数据获取
const dataSyncFetch = async () => {
chartEditStore.setEditCanvas(EditCanvasTypeEnum.SAVE_STATUS, SyncEnum.START)
try {
const { id } = routerParamsInfo.params
const res: any = await fetchProjectApi({ id: id[0] })
if (res.code === ResultEnum.SUCCESS) {
if (res.data) {
const data = JSON.parse(res.data)
await updateComponent(data)
return
}
setTimeout(() => {
chartEditStore.setEditCanvas(EditCanvasTypeEnum.SAVE_STATUS, SyncEnum.SUCCESS)
}, 1000)
return
}
chartEditStore.setEditCanvas(EditCanvasTypeEnum.SAVE_STATUS, SyncEnum.FAILURE)
httpErrorHandle()
} catch (error) {
chartEditStore.setEditCanvas(EditCanvasTypeEnum.SAVE_STATUS, SyncEnum.FAILURE)
httpErrorHandle()
}
}
// 数据保存
const dataSyncUpdate = async () => {
chartEditStore.setEditCanvas(EditCanvasTypeEnum.SAVE_STATUS, SyncEnum.START)
// 获取id
const { id } = routerParamsInfo.params
const res: any = await saveProjectApi({
projectId: id[0],
content: JSON.stringify(chartEditStore.getStorageInfo || {})
})
if (res.code === ResultEnum.SUCCESS) {
// 成功状态
setTimeout(() => {
chartEditStore.setEditCanvas(EditCanvasTypeEnum.SAVE_STATUS, SyncEnum.SUCCESS)
}, 1000)
return
}
// 失败状态
chartEditStore.setEditCanvas(EditCanvasTypeEnum.SAVE_STATUS, SyncEnum.FAILURE)
}
const syncTiming = setInterval(() => {
dataSyncUpdate()
}, 15000)
onUnmounted(() => {
clearInterval(syncTiming)
})
return {
updateComponent,
dataSyncFetch,
dataSyncUpdate
}
}