refactor: canvas save

This commit is contained in:
wangjiahao
2025-06-09 15:06:08 +08:00
parent c8346414ad
commit e5ae9b5ceb
11 changed files with 161 additions and 54 deletions
+6 -6
View File
@@ -3,7 +3,7 @@ from fastapi import APIRouter, File, UploadFile, HTTPException
from apps.dashboard.crud.dashboard_service import get_dashboard_list, preview_with_id, \
create_resource, create_canvas
from apps.dashboard.models.dashboard_model import CreateDashboard
from apps.dashboard.models.dashboard_model import CreateDashboard,BaseDashboard
from common.core.deps import SessionDep, CurrentUser
router = APIRouter(tags=["dashboard"], prefix="/dashboard")
@@ -16,18 +16,18 @@ async def datasource_list(session: SessionDep):
async def preview_dashboard(session: SessionDep,id:str):
return preview_with_id(session=session,dashboard_id=id)
@router.post("/add", response_model=CreateDashboard)
@router.post("/add", response_model=BaseDashboard)
async def add(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
return create_resource(session, user, dashboard)
@router.post("/update", response_model=CreateDashboard)
@router.post("/update", response_model=BaseDashboard)
async def update(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
return create_resource(session, user, dashboard)
@router.post("/add_dashboard", response_model=CreateDashboard)
async def add_dashboard(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
@router.post("/add_canvas", response_model=BaseDashboard)
async def add_canvas(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
return create_canvas(session, user, dashboard)
@router.post("/update_dashboard", response_model=CreateDashboard)
@router.post("/update_canvas", response_model=BaseDashboard)
async def update(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
return
@@ -27,8 +27,6 @@ def create_resource(session: SessionDep, user: CurrentUser, dashboard: CreateDas
session.commit()
return record
def update_resource(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
record = session.query(CoreDashboard).filter(CoreDashboard.id == dashboard.id).first()
record.name = dashboard.name
@@ -44,6 +42,7 @@ def create_canvas(session: SessionDep, user: CurrentUser, dashboard: CreateDashb
record.canvas_style_data = dashboard.canvas_style_data
session.add(record)
session.flush()
return record
def update_canvas(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
record = session.query(CoreDashboard).filter(CoreDashboard.id == dashboard.id).first()
@@ -131,17 +131,19 @@ class DashboardBaseResponse(BaseModel):
create_time: Optional[int] = None
update_time: Optional[int] = None
# dashboard create obj
class CreateDashboard(BaseModel):
class BaseDashboard(BaseModel):
id: str = ''
name: str = ''
pid: str = ''
workspace_id: str = ''
org_id: str = ''
description: str = ''
type: str = ''
node_type: str = ''
create_by: int = 0
# dashboard create obj
class CreateDashboard(BaseDashboard):
canvas_style_data: str =''
component_data: str = ''
configuration: str = ''
create_by: int = 0
description: str = ''
+2 -2
View File
@@ -7,6 +7,6 @@ export const dashboardApi = {
moveResource: (data: any) => request.post('/dashboard/move',data),
addResource: (data: any) => request.post('/dashboard/add',data),
updateResource: (data: any) => request.post('/dashboard/update',data),
saveCanvas: (data: any) => request.post('/dashboard/save_canvas',data),
updateCanvas: (data: any) => request.post('/dashboard/update_canvas',data)
saveCanvas: (data: any) => request.post('/dashboard/add_canvas',data),
updateCanvas: (data: any) => request.post('/dashboard/update_',data)
}
+8 -1
View File
@@ -17,6 +17,7 @@ export const dashboardStore = defineStore('dashboard', {
pid: null,
workspaceId: null,
status: null,
dataState: null,
type: null,
creatorName: null,
updateName: null,
@@ -51,7 +52,13 @@ export const dashboardStore = defineStore('dashboard', {
setTabMoveInActiveId(tabId: any) {
this.tabMoveInActiveId = tabId
},
canvasDataInit(){
updateDashboardInfo(params: any) {
Object.keys(params).forEach((key: string) => {
// @ts-ignore
this.dashboardInfo[key] = params[key]
})
},
canvasDataInit() {
}
@@ -23,6 +23,14 @@ const props = defineProps({
type: Object as PropType<CanvasItem>,
required: false
},
dashboardInfo: {
type: Object,
required: false
},
canvasStyleData: {
type: Object,
required: false
},
canvasComponentData: {
type: Array as PropType<CanvasItem[]>,
required: true
@@ -2,11 +2,13 @@
import folder from '@/assets/svg/folder.svg'
import {type SQTreeNode} from '@/views/dashboard/utils/treeNode'
import {ref, reactive, computed} from 'vue'
import {dashboardApi} from "@/api/dashboard.ts";
import {saveDashboardResource} from "@/views/dashboard/utils/canvasUtils.ts";
const emits = defineEmits(['finish'])
const state = reactive({
placeholder:'',
showParentSelected: false,
opt: null,
placeholder: '',
nodeType: 'folder',
parentSelect: false,
resourceFormNameLabel: 'Name',
dialogTitle: '',
tData: [],
@@ -17,8 +19,8 @@ const state = reactive({
let tData: any = []
const getTitle = (cmd: string) => {
switch (cmd) {
const getTitle = (opt: string) => {
switch (opt) {
case 'newLeaf':
return 'New Dashboard'
case 'newFolder':
@@ -28,8 +30,8 @@ const getTitle = (cmd: string) => {
}
}
const getResourceNewName = (cmd: string) => {
switch (cmd) {
const getResourceNewName = (opt: string) => {
switch (opt) {
case 'newLeaf':
return 'New Dashboard'
case 'newFolder':
@@ -41,19 +43,21 @@ const getResourceNewName = (cmd: string) => {
const optInit = (params: any) => {
// @ts-ignore
state.dialogTitle = getTitle(params.cmd)
state.showParentSelected = params.parentSelect
state.dialogTitle = getTitle(params.opt)
state.opt = params.opt
state.parentSelect = params.parentSelect
state.targetInfo = params.data
state.nodeType = params.nodeType || 'folder'
resourceDialogShow.value = true
// @ts-ignore
resourceForm.name = getResourceNewName(params.cmd)
// @ts-ignore
resourceForm.name = params.name || getResourceNewName(params.opt)
}
const resourceDialogShow = ref(false)
const loading = ref(false)
const pid = ref()
const id = ref()
const cmd = ref('')
const opt = ref('')
const resourceForm = reactive({
pid: '',
pName: '',
@@ -105,29 +109,31 @@ const editeInit = (param: SQTreeNode) => {
const propsTree = {
label: 'name',
children: 'children',
// @ts-ignore
// @ts-ignore
isLeaf: node => !node.children?.length
}
const showPid = computed(() => {
return ['newLeaf', 'copy', 'newLeafAfter'].includes(cmd.value) && state.showParentSelected
return ['newLeaf'].includes(opt.value) && state.parentSelect
})
const saveResource = () => {
const params = {
nodeType: 'folder',
name: resourceForm.name,
type: 'dashboard'
}
// @ts-ignore
dashboardApi.addResource(params).then(res => {
ElMessage({
type: 'success',
message: 'Save Success',
})
resetForm()
const params = {
nodeType: state.nodeType,
name: resourceForm.name,
opt: state.opt,
type: 'dashboard'
}
saveDashboardResource(params, function (rsp:any) {
ElMessage({
type: 'success',
message: 'Save Success',
})
if (state.opt === 'newLeaf') {
emits('finish', {opt: state.opt, resourceId: rsp.id})
}
resetForm()
})
}
const nodeClick = (data: SQTreeNode) => {
@@ -135,8 +141,8 @@ const nodeClick = (data: SQTreeNode) => {
resourceForm.pName = data.name as string
}
const filterMethod = (value:any) => {
// @ts-ignore
const filterMethod = (value: any) => {
// @ts-ignore
state.tData = [...tData].filter(item => item.name.includes(value))
}
@@ -145,7 +151,6 @@ defineExpose({
editeInit
})
const emits = defineEmits(['finish'])
</script>
<template>
@@ -20,6 +20,14 @@ const props = defineProps({
type: Object as PropType<CanvasItem>,
required: false
},
dashboardInfo: {
type: Object,
required: false
},
canvasStyleData: {
type: Object,
required: false
},
canvasComponentData: {
type: Array as PropType<CanvasItem[]>,
required: true
@@ -98,6 +106,8 @@ const emits = defineEmits(["parentAddItemBox"]);
:base-margin-left="baseMarginLeft"
:base-margin-top="baseMarginTop"
:canvas-component-data="canvasComponentData"
:canvas-style-data="canvasStyleData"
:dashboard-info="dashboardInfo"
:parent-config-item="parentConfigItem"
:canvas-id="canvasId"
@parentAddItemBox=" item => emits('parentAddItemBox',item)"
@@ -8,6 +8,7 @@ import dvText from '@/assets/svg/dv-text.svg'
import dvView from '@/assets/svg/dv-view.svg'
import ResourceGroupOpt from "@/views/dashboard/common/ResourceGroupOpt.vue";
import {ref} from 'vue'
const dashboardStore = dashboardStoreWithOut()
const {dashboardInfo} = storeToRefs(dashboardStore)
const emits = defineEmits(['addComponent'])
@@ -16,8 +17,31 @@ const openViewDialog = () => {
// do addComponent
}
const saveCanvasWithCheck = () =>{
const saveCanvasWithCheck = () => {
if (dashboardInfo.value.dataState === 'prepare') {
const createParams = {
name: dashboardInfo.value.name,
pid: props.baseParams?.pid,
opt: 'newLeaf',
nodeType: 'leaf',
parentSelect: true
}
// @ts-ignore
resourceGroupOptRef.value?.optInit(createParams)
}
}
const props = defineProps({
baseParams: {
type: Object,
required: false,
}
})
const groupOptFinish = (result: any) => {
let url = window.location.href
url = url.replace(/(#\/[^?]*)(?:\?[^#]*)?/, `$1?dvId=${result.id}`)
window.history.replaceState( { path: url }, '', url )
}
</script>
@@ -52,14 +76,14 @@ const saveCanvasWithCheck = () =>{
</component-button-label>
</div>
<div class="right-toolbar">
<el-button @click="saveCanvasWithCheck()"
style="float: right; margin-right: 12px"
type="primary"
<el-button @click="saveCanvasWithCheck()"
style="float: right; margin-right: 12px"
type="primary"
>
Save
</el-button>
</div>
<ResourceGroupOpt ref="resourceGroupOptRef"></ResourceGroupOpt>
<ResourceGroupOpt @finish="groupOptFinish " ref="resourceGroupOptRef"></ResourceGroupOpt>
</div>
</template>
@@ -78,6 +102,7 @@ const saveCanvasWithCheck = () =>{
left: 50%;
transform: translateX(-50%);
}
.right-toolbar {
display: flex;
position: absolute;
+30 -2
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import {ref} from 'vue'
import {onMounted, ref, computed, reactive} from 'vue'
import Toolbar from "@/views/dashboard/editor/Toolbar.vue";
import DashboardEditor from "@/views/dashboard/editor/DashboardEditor.vue";
import {findNewComponentFromList} from "@/views/dashboard/components/component-list.ts";
@@ -7,11 +7,18 @@ import {guid} from "@/utils/canvas.ts";
import cloneDeep from 'lodash/cloneDeep';
import {storeToRefs} from "pinia";
import {dashboardStoreWithOut} from "@/stores/dashboard/dashboard.ts";
import router from '@/router'
const dashboardStore = dashboardStoreWithOut()
const {componentData} = storeToRefs(dashboardStore)
const state = reactive({
routerPid: null,
resourceId: null,
opt: null
})
const dashboardEditorRef = ref(null);
const addComponent = (componentType: string) => {
const component = cloneDeep(findNewComponentFromList(componentType))
@@ -29,11 +36,32 @@ const addComponent = (componentType: string) => {
}
}
onMounted(() => {
//@ts-ignore
state.opt = router.currentRoute.value.query.opt
//@ts-ignore
state.resourceId = router.currentRoute.value.query.resourceId
//@ts-ignore
state.routerPid = router.currentRoute.value.query.pid
if (state.opt === 'create') {
dashboardStore.updateDashboardInfo({dataState: 'prepare', name: 'New Dashboard', pid: state.routerPid})
}
})
const baseParams = computed(() => {
return {
opt: state.opt,
resourceId: state.resourceId,
routerPid: state.routerPid
}
})
</script>
<template>
<div class="editor-main">
<Toolbar @add-component="addComponent"></Toolbar>
<Toolbar :base-params="baseParams" @add-component="addComponent"></Toolbar>
<DashboardEditor
ref="dashboardEditorRef"
:canvas-component-data="componentData">
@@ -1,4 +1,8 @@
import {dashboardApi} from "@/api/dashboard.ts";
import {dashboardStoreWithOut} from "@/stores/dashboard/dashboard.ts";
import {storeToRefs} from "pinia";
const dashboardStore = dashboardStoreWithOut()
const {componentData,canvasStyle} = storeToRefs(dashboardStore)
export const initCanvasData = (params: any, callBack: Function) => {
dashboardApi.getDashboardInfo(params).then((res: any) => {
@@ -21,4 +25,23 @@ export const initCanvasData = (params: any, callBack: Function) => {
const canvasViewInfoPreview = canvasInfo.canvasViewInfo
callBack({dashboardInfo, canvasDataResult, canvasStyleResult, canvasViewInfoPreview})
})
}
export const saveDashboardResource = (params: any, callBack: Function) => {
if(params.opt === 'newLeaf'){// create canvas
const reqeustParams = {
...params,
component_data:JSON.stringify(componentData.value),
canvas_style_data:JSON.stringify(canvasStyle.value)
}
dashboardApi.saveCanvas(reqeustParams).then((res: any) => {
dashboardStore.updateDashboardInfo({id:res.id,dataState:'ready'})
callBack(res)
})
}else if(params.opt === 'newFolder'){
dashboardApi.addResource(params).then((res: any) => {
callBack(res)
})
}
}