This commit is contained in:
jingna 2025-05-30 18:30:13 +08:00
parent 0816c2d67f
commit d98ee3d32a
15 changed files with 736 additions and 41 deletions

View File

@ -21,10 +21,12 @@
"@codemirror/lang-sql": "^6.4.0",
"@form-create/designer": "^3.2.11",
"@form-create/element-ui": "^3.2.22",
"@monaco-editor/loader": "^1.5.0",
"@npkg/tinymce-plugins": "^0.0.7",
"@tinymce/tinymce-vue": "^5.1.0",
"@turf/centroid": "^7.0.0",
"@videojs-player/vue": "^1.0.0",
"@vue/compiler-sfc": "^3.5.15",
"@vueuse/core": "^9.13.0",
"ace-builds": "^1.15.3",
"axios": "^1.3.3",
@ -47,6 +49,7 @@
"lodash-es": "^4.17.21",
"mathjs": "^11.6.0",
"mitt": "^3.0.0",
"monaco-editor": "^0.52.2",
"net": "^1.0.2",
"normalize.css": "^8.0.1",
"nprogress": "^0.2.0",
@ -66,6 +69,7 @@
"vue-types": "^5.0.2",
"vue-uuid": "^3.0.0",
"vue3-ace-editor": "^2.2.2",
"vue3-sfc-loader": "^0.9.5",
"vuedraggable": "^4.1.0",
"web-storage-cache": "^1.1.1",
"xss": "^1.0.14"

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

View File

@ -226,6 +226,13 @@ export const routes: AppRouteRecordRaw[] = [
hidden: true,
meta: {},
component: () => import('@/viewsnew/application/PreviewSystem.vue')
},
{
path: '/SfcEditor',
name: 'SfcEditor',
hidden: true,
meta: {},
component: () => import('@/viewsnew/application/SfcEditor/index.vue')
}
]

View File

@ -1,6 +1,6 @@
<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import Navbar from '@/viewsnew/application/module/Navbar/index.vue'
import Navbar from '@/viewsnew/application/SfcEditor/Navbar.vue'
import { useRoute, useRouter } from 'vue-router'
import { getMenuTree } from '@/api/permission/menu'
const route = useRoute()
@ -30,7 +30,8 @@ function getmenuinfo() {
<template>
<div class="system-box">
<Navbar v-if="isNavbar" :menuList="menuList" :projectName="projectName"
:isFixed="true" :applicationId="applicationId"></Navbar>
:isFixed="true" :applicationId="applicationId" :isExecuteEvent ="false">
</Navbar>
</div>
</template>

View File

@ -1,12 +1,17 @@
<script lang="ts" setup>
import { ref, onMounted,onBeforeUnmount,shallowRef } from 'vue'
import { ref,watch, onMounted,onBeforeUnmount,shallowRef } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import Assocmodule from '@/viewsnew/application/menuconfig/assocmodule.vue'
import Assocmodule from '@/viewsnew/application/SfcEditor/assocPage.vue'
const props = defineProps({
menuList:Object,
menuList: {
type: Array, //
required: true, //
default: () => [] //
},
isFixed: Boolean,
projectName:String,
applicationId:String
applicationId:String,
isExecuteEvent: Boolean
})
const navtitle = ref('')
const navmenulist:any = ref([
@ -14,19 +19,38 @@ const navmenulist:any = ref([
const checkindex = ref(null)
const showmodule = ref(false)
const currentMoudleId = ref('')
watch(
() => props.menuList,
(newVal) => {
if (newVal) {
navmenulist.value = newVal
console.log(newVal)
}
},
{ immediate: true } //
)
function menuclick(index:any) {
if(navmenulist.value[index].children.length == 0 || navmenulist.value[index].children == undefined){
checkindex.value = index
if(props.isExecuteEvent){
return
}
currentMoudleId.value = navmenulist.value[index].module_id
}
}
function childmenuclick(item:any){
console.log(item,props.isExecuteEvent)
if(props.isExecuteEvent){
return
}
showmodule.value = false
if(item.module_id && item.module_id !== ''){
currentMoudleId.value = item.module_id
showmodule.value = true
}else{
showmodule.value = false
}
// console.log(' Assocmodule props:',Assocmodule)
}
//
const TimeDisplay = {
@ -68,6 +92,7 @@ const TimeDisplay = {
}
}
onMounted(() => {
console.log(props,66)
navmenulist.value = props.menuList
navtitle.value = props.projectName
})
@ -85,10 +110,10 @@ onBeforeUnmount(() => {
<div class="Navbar-menu-item"
:class="{ 'Navbar-menu-items': checkindex == index && item.children.length == 0 }"
v-for="(item, index) in navmenulist" :key="index" @click="menuclick(index)">
<div v-if="item.children.length == 0">{{ item.name }}</div>
<el-popover v-else class="tsmenu" placement="bottom" popper-class="tsmenu-popover">
<div v-if="!item.children || item.children.length == 0">{{ item.name }}</div>
<el-popover v-else :show-arrow="false" class="tsmenu" placement="bottom" popper-class="tsmenu-popover">
<div v-for="(items, indexs) in item.children" :key="indexs"
class="Navbar-menu-item-child-item" @click.stop="childmenuclick(items)">
class="Navbar-menu-item-child-item" @click="()=>childmenuclick(items)">
{{ items.name }}
</div>
<template #reference>
@ -105,8 +130,9 @@ onBeforeUnmount(() => {
</div>
</div>
</div>
<div class="system-box-content" :style="{height:props.isFixed?'calc(100vh - 65px)':'calc(100vh - 125px)'}">
<Assocmodule v-if="showmodule" :applicationId="applicationId" :moduleinfo="{module_id:currentMoudleId}" />
<div v-if="!props.isExecuteEvent" class="system-box-content" :style="{height:props.isFixed?'calc(100vh - 65px)':'calc(100vh - 125px)'}">
<Assocmodule v-if="showmodule" :applicationId="props.applicationId"
:moduleinfo="{module_id:currentMoudleId}" />
</div>
</div>
</template>
@ -122,7 +148,7 @@ onBeforeUnmount(() => {
display: flex;
align-items: center;
color: #fff;
background: url(@/assets/img/navbg.png) no-repeat;
background: url(/images/navbg.png) no-repeat;
background-size: 100% 100%;
padding-left: 25px;
.Navbar-box-titie {
@ -165,7 +191,7 @@ onBeforeUnmount(() => {
.Navbar-menu-item {
font-size: 14px;
padding: 5px 15px;
background: url(@/assets/img/navmenu.png) no-repeat;
background: url(/images/navmenu.png) no-repeat;
background-size: 100% 100%;
margin-left: 15px;
cursor: pointer;
@ -173,7 +199,7 @@ onBeforeUnmount(() => {
}
.Navbar-menu-items {
background: url(@/assets/img/navmenucheck.png) no-repeat;
background: url(/images/navmenucheck.png) no-repeat;
background-size: 100% 100%;
}
@ -188,21 +214,28 @@ onBeforeUnmount(() => {
}
}
.system-box-content {
width: 100%;
}
}
</style>
<style>
.tsmenu-popover.ed-popover.ed-popper {
background: linear-gradient(to bottom, rgba(0, 52, 102, 1), rgba(0, 55, 110, 0.5));
.tsmenu-popover.el-popover.el-popper {
background: linear-gradient(to bottom, rgba(0, 52, 102, 1), rgba(0, 55, 110, 0.5)) !important;;
color: #fff;
border: none;
border-radius: 0px;
padding: 5px 0px;
z-index: 9001 !important;
}
.tsmenu-popover.ed-popover.ed-popper {
background: linear-gradient(to bottom, rgba(0, 52, 102, 1), rgba(0, 55, 110, 0.5)) !important;;
color: #fff;
border: none;
border-radius: 0px;
padding: 5px 0px;
z-index: 9001 !important;
}
.tsmenu-popover .Navbar-menu-item-child-item {
padding: 5px 15px;
cursor: pointer;

View File

@ -0,0 +1,124 @@
<script lang="ts" setup>
import { ref, onMounted, onUnmounted,computed, reactive,nextTick,onBeforeMount, watch } from 'vue'
import DvPreview from '@/viewsnew/data-visualization/DvPreview.vue'
import FormCreate from '@/viewsnew/common/FormCreate.vue'
import { initCanvasData } from '@/utils/canvasUtils'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { moduleList } from '@/api/application/module'
import Navbar from '@/viewsnew/application/SfcEditor/assocPage.vue'
const props = defineProps({
moduleinfo:Object,
applicationId:String
})
const dvMainStore = dvMainStoreWithOut()
const showPosition = ref("preview")
const dvPreviewRef = ref(null)
const state = reactive({
canvasDataPreview: null,
canvasStylePreview: null,
canvasViewInfoPreview: null,
dvInfo: null,
curPreviewGap: 0
})
const moduleInfo = ref({})
const isFormCreate = ref(false)
const busiFlag = ref('dataV')
const dataInitState = ref(true)
const downloadStatus = ref(false)
const loading = ref(false)
const isNavbar = ref(false)
const loadCanvasData = (dvId, weight?, ext?) => {
const initMethod = initCanvasData
dataInitState.value = false
initMethod(
dvId,
busiFlag.value,
function ({
canvasDataResult,
canvasStyleResult,
dvInfo,
canvasViewInfoPreview,
curPreviewGap
}) {
dvInfo['weight'] = weight
dvInfo['ext'] = ext || 0
state.canvasDataPreview = canvasDataResult
state.canvasStylePreview = canvasStyleResult
state.canvasViewInfoPreview = canvasViewInfoPreview
state.dvInfo = dvInfo
state.curPreviewGap = curPreviewGap
dataInitState.value = true
dvMainStore.updateCurDvInfo(dvInfo)
nextTick(() => {
dvPreviewRef.value?.restore()
})
}
)
}
onMounted(() => {
isFormCreate.value = false
dataInitState.value = false
getInit()
})
watch(() => props.moduleinfo, (val) => {
getInit()
isFormCreate.value = false
dataInitState.value = false
})
onBeforeMount(() => {
dvMainStore.canvasDataInit()
})
function getInit() {
loading.value = true
let params = {appId:props.applicationId}
moduleList(params).then(res => {
let list:any = {}
const arr = res.data.data
arr.forEach((item:any) => {
if(item.id === props.moduleinfo.module_id){
list = item
}
})
handleNodeClick(list)
})
}
function handleNodeClick(e){
isFormCreate.value = false
dataInitState.value = false
isNavbar.value = false
if(e.type == '0301'){
busiFlag.value = 'dashboard'
loadCanvasData(e.id,9,0)
}else if(e.type == '03'){
busiFlag.value = 'dataV'
loadCanvasData(e.id,9,0)
}else if(e.type == '09'){
moduleInfo.value = e
isFormCreate.value = true
} else if(e.type == '02'){
isNavbar.value = true
}
loading.value = false
}
</script>
<template>
<div v-loading="loading" style="width: 100%;height: 100%;overflow: hidden;">
<dv-preview
ref="dvPreviewRef"
class="dvPreviewRef"
v-if="state.canvasStylePreview && dataInitState"
:show-position="showPosition"
:canvas-data-preview="state.canvasDataPreview"
:canvas-style-preview="state.canvasStylePreview"
:canvas-view-info-preview="state.canvasViewInfoPreview"
:dv-info="state.dvInfo"
:cur-preview-gap="state.curPreviewGap"
:download-status="downloadStatus"
></dv-preview>
<form-create v-if="isFormCreate" :moduleInfo="moduleInfo"></form-create>
<Navbar v-if="isNavbar"></Navbar>
</div>
</template>
<style lang="less" scoped>
</style>

View File

@ -0,0 +1,329 @@
<template>
<div id="app">
<!-- <h1>Vue 3 SFC 在线编辑器</h1>
<SfcEditor /> -->
<div class="sfc-header">
<div class="sfc-header-left">
<!-- <div class="return-box"><img src="@/assets/newimg/u594.png" alt=""></div> -->
<div class="sfc-header-icon"><img src="@/assets/newimg/logosmall.png" alt=""></div>
<div class="sfc-header-title">{{ hearderName }}</div>
</div>
</div>
<div class="sfc-content">
<el-tabs v-model="activeName" type="border-card" class="demo-tabs" @tab-change="handleClick"
style="height: calc(100vh - 100px);">
<el-tab-pane label="代码" name="代码">
<div style="height: calc(100vh - 215px);">
<textarea v-model="sfcCode"></textarea>
</div>
<div class="sfc-content-bottom">
<el-button type="primary">导入模板</el-button>
<el-button type="primary">保存</el-button>
</div>
</el-tab-pane>
<el-tab-pane label="预览" name="预览">
<div ref="previewContainer" class="preview"></div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, reactive, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { loadModule } from 'vue3-sfc-loader'
import * as Vue from 'vue/dist/vue.esm-bundler.js'
import ElementPlus from 'element-plus'
import less from 'less'
import defaultTemplate from '@/viewsnew/application/SfcEditor/Navbar.vue?raw'
import { getMenuTree } from '@/api/permission/menu'
import 'element-plus/dist/index.css'
const route = useRoute()
const router = useRouter()
const activeName: any = ref('代码')
const hearderName: any = ref('')
const sfcCode = ref(defaultTemplate)
const previewContainer = ref(null)
let prevApp = null
const applicationId: any = ref('')
const menuList: any = ref([])
const appname: any = ref('')
// Base64
const convertToBase64 = async (imagePath) => {
try {
//
const resolvedPath = imagePath.replace('@/', '/src/')
const response = await fetch(resolvedPath)
if (!response.ok) throw new Error(`图片加载失败: ${response.status}`)
const blob = await response.blob()
return new Promise((resolve) => {
const reader = new FileReader()
reader.onloadend = () => resolve(reader.result)
reader.readAsDataURL(blob)
})
} catch (error) {
console.error('Base64转换失败:', error.message)
return ''
}
}
const runCode = async () => {
try {
if (prevApp) {
prevApp.unmount()
previewContainer.value.innerHTML = ''
}
const options = {
moduleCache: {
vue: Vue,
'element-plus': ElementPlus,
'vue/dist/vue.esm-bundler.js': Vue,
'@/viewsnew/application/SfcEditor/assocPage.vue': Vue.defineAsyncComponent(() =>
import('@/viewsnew/application/SfcEditor/assocPage.vue'))
},
getFile: async (fileName) => {
if (fileName.startsWith('@/')) {
const resolvedPath = fileName.replace('@/', '/src/')
try {
const response = await fetch(resolvedPath)
return { content: await response.text() }
} catch (e) {
console.error(`文件加载失败: ${resolvedPath}`, e)
return { content: '<!-- 文件加载失败 -->' }
}
}
if (fileName === 'dynamic.vue') {
let code = sfcCode.value
// Lessscoped
const lessRegex = /<style\s+.*?lang="less".*?>(.*?)<\/style>/gis
let match
while ((match = lessRegex.exec(code)) !== null) {
const [full, content] = match
try {
const { css } = await less.render(content, {
paths: ['.'], //
filename: 'dynamic.less'
})
code = code.replace(full, `<style>${css}</style>`)
} catch (e) {
console.error('Less编译错误:', e.message)
code = code.replace(full, `<style>/* Less Error: ${e.message} */</style>`)
}
}
//
const imgRegex = /src=['"](.+?\.(png|jpg|jpeg))['"]/gi
let imgMatch
while ((imgMatch = imgRegex.exec(code)) !== null) {
const [full, path] = imgMatch
const base64 = await convertToBase64(path)
code = code.replace(full, `src="${base64}"`)
}
return code
.replace(/<\/script>/g, '<\\/script>')
.replace(/\\\//g, '/')
}
// Less
if (fileName.endsWith('.less')) {
const resolvedPath = fileName.replace('@/', '/src/')
try {
const response = await fetch(resolvedPath)
const content = await response.text()
const { css } = await less.render(content, { filename: fileName })
return { content: css, mediaType: 'text/css' }
} catch (e) {
return { content: `/* Less Error: ${e.message} */`, mediaType: 'text/css' }
}
}
return ''
},
addStyle: (css) => {
const style = document.createElement('style')
style.textContent = css
document.head.appendChild(style)
},
compiledCache: new Map(),
compileTemplate: true
}
const componentModule = await loadModule('dynamic.vue', options)
const component = componentModule.default || componentModule
const dynamicProps = ref({
menuList: menuList.value, //
isFixed: false,
projectName: appname.value, //
applicationId: applicationId.value, //id
isExecuteEvent: false //
})
prevApp = Vue.createApp({
render: () => Vue.h(component, dynamicProps.value)
})
prevApp.use(ElementPlus)
prevApp.mount(previewContainer.value)
} catch (error) {
console.error('运行时错误:', error)
previewContainer.value.innerHTML = `
<div class="error">
<h3>错误</h3>
<pre>${error.message}</pre>
</div>
`
}
}
onMounted(() => {
hearderName.value = route.query.name
if (route.query.appId) {
applicationId.value = route.query.appId
appname.value = route.query.appname
getmenuinfo()
}
})
function getmenuinfo() {
const params = {
appId: applicationId.value,
name: '',
isdisplay: ''
}
getMenuTree(params).then(res => {
menuList.value = res.data
})
}
function goBack() {
router.push({
path: '/module',
query: {
id: route.query.appId
}
})
}
function handleClick() {
if (activeName.value == '预览') {
console.log('预览')
runCode()
}
}
</script>
<style scoped>
#app {
font-family: Arial, sans-serif;
margin: 0 auto;
width: 100%;
height: 100vh;
background: rgb(21, 21, 21);
}
.sfc-header {
width: 100%;
height: 60px;
background-color: #252626;
border-bottom: 1px solid #4f5052;
display: flex;
align-items: center;
color: #fff;
padding: 0px 20px;
}
.sfc-header-left {
display: flex;
align-items: center;
}
.sfc-header-icon {
display: flex;
justify-content: center;
align-items: center;
width: 36px;
height: 36px;
cursor: pointer;
}
.return-box {
display: flex;
justify-content: center;
align-items: center;
width: 36px;
height: 36px;
cursor: pointer;
}
.return-box:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.sfc-header-title {
font-family: 'Arial Negreta', 'Arial Normal', 'Arial';
font-weight: 700;
font-style: normal;
font-size: 16px;
color: #F2F4F5;
padding-left: 14px;
}
.sfc-content {
height: calc(100vh -60px);
padding: 10px 20px;
color: #fff;
}
textarea {
flex: 1;
margin-bottom: 10px;
font-family: Monaco, monospace;
padding: 10px;
background: #252626;
width: 100%;
height: 100%;
color: #ffffff;
}
.sfc-content-bottom {
margin-top: 10px;
display: flex;
justify-content: flex-end;
}
.preview {
width: 100%;
height: 100%;
}
:deep(.ed-tabs__item) {
color: #fff !important;
padding-right: 0px;
}
:deep(.ed-tabs__header) {
border-bottom: 1px solid #4f5052;
}
:deep(.ed-tabs__item.is-active) {
color: #0089ff !important;
}
:deep(.ed-tabs__active-bar) {
background-color: #0089ff !important;
}
:deep(.ed-tabs--border-card) {
background: rgb(21, 21, 21);
border-color: #4f5052;
}
:deep(.ed-tabs--border-card>.ed-tabs__header) {
background: rgb(21, 21, 21);
}
:deep(.ed-tabs--border-card>.ed-tabs__header .ed-tabs__item.is-active) {
background: rgb(21, 21, 21);
border-color: #4f5052;
border-bottom: none;
}
:deep(.ed-button) {
background-color: #0089ff;
}
</style>

View File

@ -0,0 +1,165 @@
<template>
<div class="editor">
<div ref="previewContainer" class="preview"></div>
</div>
</template>
<script setup>
import { ref, onMounted,onUnmounted } from 'vue'
import { loadModule } from 'vue3-sfc-loader'
import * as Vue from 'vue/dist/vue.esm-bundler.js'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import less from 'less'
import { i18n } from '@/plugins/vue-i18n'
import defaultTemplate from '@/viewsnew/application/SfcEditor/Navbar.vue?raw'
const props = defineProps({
menuList: {
type: Array,
required: true,
default: () => []
},
isFixed: Boolean,
projectName: String,
applicationId: String,
isExecuteEvent: Boolean
})
const sfcCode = ref(defaultTemplate)
const previewContainer = ref(null)
let prevApp = null
// Base64
const convertToBase64 = async (imagePath) => {
try {
//
const resolvedPath = imagePath.replace('@/', '/src/')
const response = await fetch(resolvedPath)
if (!response.ok) throw new Error(`图片加载失败: ${response.status}`)
const blob = await response.blob()
return new Promise((resolve) => {
const reader = new FileReader()
reader.onloadend = () => resolve(reader.result)
reader.readAsDataURL(blob)
})
} catch (error) {
console.error('Base64转换失败:', error.message)
return ''
}
}
const runCode = async () => {
try {
if (prevApp) {
prevApp._container.innerHTML = ''
prevApp.unmount()
prevApp._container.remove()
prevApp = null
await Vue.nextTick()
}
const options = {
moduleCache: {
vue: Vue,
'element-plus': ElementPlus,
'vue/dist/vue.esm-bundler.js': Vue,
'@/viewsnew/application/SfcEditor/assocPage.vue': Vue.defineAsyncComponent(() =>
import('@/viewsnew/application/SfcEditor/assocPage.vue')
),
},
getFile: async (fileName) => {
if (fileName === 'dynamic.vue') {
let code = sfcCode.value
// Lessscoped
const lessRegex = /<style\s+.*?lang="less".*?>(.*?)<\/style>/gis
let match
while ((match = lessRegex.exec(code)) !== null) {
const [full, content] = match
try {
const { css } = await less.render(content, {
paths: ['.'], //
filename: 'dynamic.less'
})
code = code.replace(full, `<style>${css}</style>`)
} catch (e) {
console.error('Less编译错误:', e.message)
code = code.replace(full, `<style>/* Less Error: ${e.message} */</style>`)
}
}
//
const imgRegex = /src=['"](.+?\.(png|jpg|jpeg))['"]/gi
let imgMatch
while ((imgMatch = imgRegex.exec(code)) !== null) {
const [full, path] = imgMatch
const base64 = await convertToBase64(path)
code = code.replace(full, `src="${base64}"`)
}
return code
.replace(/<\/script>/g, '<\\/script>')
.replace(/\\\//g, '/')
}
return ''
},
//
addStyle: (css) => {
const style = document.createElement('style')
style.textContent = css
document.head.appendChild(style)
},
compiledCache: new Map(),
compileTemplate: true
}
const componentModule = await loadModule('dynamic.vue', options)
const component = componentModule.default || componentModule
const dynamicProps = Vue.reactive({
menuList: props.menuList,
isFixed: props.isFixed,
projectName: props.projectName,
applicationId: props.applicationId,
isExecuteEvent: props.isExecuteEvent
})
// createApp
prevApp = Vue.createApp({
render: () => Vue.h(component, dynamicProps)
})
prevApp.use(i18n)
prevApp.use(ElementPlus)
prevApp.mount(previewContainer.value)
} catch (error) {
console.error('运行时错误:', error)
previewContainer.value.innerHTML = `
<div class="error">
<h3>错误</h3>
<pre>${error.message}</pre>
</div>
`
}
}
onMounted(() => {
console.log(props.menuList,999)
runCode()
})
</script>
<style>
/* 保留原有样式并补充 */
.editor {
display: flex;
flex-direction: column;
width: 100%;
height: calc(100vh - 65px);
}
textarea {
flex: 1;
margin-bottom: 10px;
font-family: Monaco, monospace;
padding: 10px;
}
.preview {
flex: 1;
overflow: auto;
}
</style>

View File

@ -9,12 +9,14 @@ import { ElTree,FormInstance } from 'element-plus'
import { publicTree } from '@/utils/validate';
import { setModuleId } from '@/api/permission/menu'
import { ElMessage, ElMessageBox } from 'element-plus'
import Navbar from '@/viewsnew/application/module/Navbar/index.vue'
import Navbar from '@/viewsnew/application/SfcEditor/previewNavSfc.vue'
import { getMenuTree } from '@/api/permission/menu'
const props = defineProps({
applicationId:String,
assoccurrentid:String,
assocmenuname:String,
currentNodeId:String
currentNodeId:String,
projectname:String
})
const defaultPropss = {
children: 'children',
@ -45,6 +47,7 @@ const moduletreeData = ref([])
const moduletreeRef = ref<InstanceType<typeof ElTree>>()
const assoccurrentid = ref('')
const isNavbar = ref(false)
const menuList:any = ref([])
const loadCanvasData = (dvId, weight?, ext?) => {
const initMethod = initCanvasData
dataInitState.value = false
@ -94,7 +97,15 @@ const handleNodeClick = (e: any) => {
moduleInfo.value = e
isFormCreate.value = true
} else if(e.type == '02'){
const params = {
appId: props.applicationId,
name:'',
isdisplay:''
}
getMenuTree(params).then(res => {
menuList.value = res.data
isNavbar.value = true
})
}
rightloading.value = false
}
@ -203,7 +214,8 @@ function handleDatasetName() {
:download-status="downloadStatus"
></dv-preview>
<form-create v-if="isFormCreate" :moduleInfo="moduleInfo"></form-create>
<Navbar v-if="isNavbar"></Navbar>
<Navbar v-if="isNavbar" :isFixed="true" :applicationId="props.applicationId"
:menuList="menuList" :projectName="props.projectname" :isExecuteEvent="true" ></Navbar>
</div>
</div>

View File

@ -5,7 +5,7 @@ import FormCreate from '@/viewsnew/common/FormCreate.vue'
import { initCanvasData } from '@/utils/canvasUtils'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { moduleList } from '@/api/application/module'
import Navbar from '@/viewsnew/application/module/Navbar/index.vue'
import Navbar from '@/viewsnew/application/SfcEditor/assocPage.vue'
const props = defineProps({
moduleinfo:Object,
applicationId:String
@ -56,9 +56,10 @@ const loadCanvasData = (dvId, weight?, ext?) => {
)
}
onMounted(() => {
getInit()
isFormCreate.value = false
dataInitState.value = false
isNavbar.value = false
getInit()
})
watch(() => props.moduleinfo, (val) => {
getInit()

View File

@ -2,7 +2,7 @@
import Header from './header.vue'
import Assocmodule from './assocmodule.vue'
import Assocmenu from './assocmenu.vue'
import { findApplicationById } from "@/api/application/application";
import { findApplicationById } from "@/api/application/application"
import { useRoute, useRouter } from 'vue-router'
import { ref, onMounted,reactive,nextTick } from 'vue'
import menuconfig_treeadd_white from '@/assets/svg/menuconfig_treeadd_white.svg'
@ -276,7 +276,7 @@ function assocsubmit(){
</template>
</el-dialog>
<Assocmenu v-if="assocdialog" :assoccurrentid="assoccurrentid"
:applicationId="applicationId" :assocmenuname="assocmenuname"
:applicationId="applicationId" :assocmenuname="assocmenuname" :projectname="projectInfo.name"
:currentNodeId="currentNodeId" @assochandleClose="assochandleClose" @assocsubmit="assocsubmit" />
</div>
</template>

View File

@ -7,6 +7,7 @@ import { publicTree } from '@/utils/validate';
import { moduleList,moduleAdd,moduleUpdate,moduleDel } from '@/api/application/module'
const emit = defineEmits(['handleNodeClick'])
const { t } = useI18n()
const router = useRouter()
const props = defineProps({
projectInfo: {
type: String,
@ -130,6 +131,12 @@ function editClic(data:any){
window.open('/#/dashboard?resourceId=' + data.id + '&appId='+projectInfo.value.id, '_blank');
}else if(data.type == '09'){
window.open('/#/formcreatedesigner?moduleId=' +data.id + '&appId='+projectInfo.value.id, '_blank');
} else if(data.type == '02'){
const route = router.resolve({
path: '/SfcEditor',
query: { dvId: data.id,appId:projectInfo.value.id,name:data.name,appname:projectInfo.value.name }
});
window.open(route.href, '_blank');
}
// window.open('/#/dvCanvas?dvId=' + "1097641013486424064", '_blank');
}

View File

@ -7,11 +7,11 @@ import { findApplicationById } from "@/api/application/application";
import { useRouter, useRoute } from 'vue-router'
import DvPreview from '@/viewsnew/data-visualization/DvPreview.vue'
import FormCreate from '@/viewsnew/common/FormCreate.vue'
import Navbar from '@/viewsnew/application/module/Navbar/index.vue'
import Navbar from '@/viewsnew/application/sfcEditor/previewNavSfc.vue'
import DePreview from '@/components/data-visualization/canvas/DePreview.vue'
import { initCanvasData, initCanvasDataPrepare, onInitReady } from '@/utils/canvasUtils'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { getMenuTree } from '@/api/permission/menu'
import { storeToRefs } from 'pinia'
import { t } from '@/hooks/web/useI18n';
const dvMainStore = dvMainStoreWithOut()
@ -42,7 +42,7 @@ const isNavbar = ref(false)
// }
// })
const menuList = ref([])
const dataVKeepSize = computed(() => {
return state.canvasStylePreview?.screenAdaptor === 'keep'
})
@ -65,6 +65,7 @@ const route = useRoute()
const projectInfo:any = ref({})
const applicationId:any = ref('')
const busiFlag = ref('dataV')
const isExecuteEvent = ref(false)
onMounted(() => {
applicationId.value = route.query.id
getInit()
@ -122,9 +123,19 @@ function handleNodeClick(e){
moduleInfo.value = e
isFormCreate.value = true
} else if(e.type == '02'){
isExecuteEvent.value = true
const params = {
appId: applicationId.value,
name:'',
isdisplay:''
}
getMenuTree(params).then(res => {
menuList.value = res.data
isNavbar.value = true
})
}
}
onBeforeMount(() => {
dvMainStore.canvasDataInit()
})
@ -147,7 +158,8 @@ onBeforeMount(() => {
:download-status="downloadStatus"
></dv-preview>
<form-create v-if="isFormCreate" :moduleInfo="moduleInfo"></form-create>
<Navbar v-if="isNavbar"></Navbar>
<Navbar v-if="isNavbar" :isFixed="true" :applicationId="applicationId"
:menuList="menuList" :projectName="projectInfo.name" :isExecuteEvent="isExecuteEvent"></Navbar>
</div>
</div>
</template>