预览提交
This commit is contained in:
parent
ac50f51518
commit
a6ccedc85b
@ -585,4 +585,30 @@ defineExpose({
|
|||||||
.ed-select-group__wrap:not(:last-of-type)::after{
|
.ed-select-group__wrap:not(:last-of-type)::after{
|
||||||
background: #434343 !important;
|
background: #434343 !important;
|
||||||
}
|
}
|
||||||
|
.ed-select .ed-input.is-focus .ed-input__wrapper{
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
.ed-select:hover:not(.ed-select--disabled) .ed-input__wrapper{
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
.ed-select .ed-input__wrapper.is-focus{
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
.ed-dropdown-menu{
|
||||||
|
background-color: rgb(41, 41, 41);
|
||||||
|
|
||||||
|
}
|
||||||
|
.ed-dropdown-menu__item{
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.ed-dropdown-menu__item--divided{
|
||||||
|
border-top: 1px solid #5f5f5f;
|
||||||
|
}
|
||||||
|
.ed-dropdown-menu__item:not(.is-disabled):hover{
|
||||||
|
background-color: rgb(61, 61, 61);
|
||||||
|
}
|
||||||
|
.ed-dropdown__popper.ed-popper{
|
||||||
|
border: 1px solid #5f5f5f;
|
||||||
|
background:transparent;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -228,11 +228,18 @@ export const routes: AppRouteRecordRaw[] = [
|
|||||||
component: () => import('@/viewsnew/application/PreviewSystem.vue')
|
component: () => import('@/viewsnew/application/PreviewSystem.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/SfcEditor',
|
path: '/editNavbar',
|
||||||
name: 'SfcEditor',
|
name: 'editNavbar',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
meta: {},
|
meta: {},
|
||||||
component: () => import('@/viewsnew/application/SfcEditor/index.vue')
|
component: () => import('@/viewsnew/application/SfcEditor/NavbarEditor/editNavbar.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/editLogin',
|
||||||
|
name: 'editLogin',
|
||||||
|
hidden: true,
|
||||||
|
meta: {},
|
||||||
|
component: () => import('@/viewsnew/application/SfcEditor/LoginEditor/editlogin.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/SystemLogin',
|
path: '/SystemLogin',
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
// import Navbar from '@/viewsnew/application/SfcEditor/Navbar.vue'
|
import Navbar from '@/viewsnew/application/sfcEditor/NavbarEditor/previewNavSfc.vue'
|
||||||
import Navbar from '@/viewsnew/application/sfcEditor/previewNavSfc.vue'
|
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { getMenuTree } from '@/api/permission/menu'
|
import { getMenuTree } from '@/api/permission/menu'
|
||||||
import { moduleList } from '@/api/application/module'
|
import { moduleList } from '@/api/application/module'
|
||||||
|
@ -0,0 +1,353 @@
|
|||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
<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" @click="importTemplate">导入模板</el-button>
|
||||||
|
<el-button type="primary" @click="saveClick">保存</el-button>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="预览" name="预览" style="height: calc(100vh - 190px);">
|
||||||
|
<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 { ElMessage } from 'element-plus-secondary'
|
||||||
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
import * as Vue from 'vue/dist/vue.esm-bundler.js'
|
||||||
|
import ElementPlus from 'element-plus'
|
||||||
|
import * as VueRouter from 'vue-router'
|
||||||
|
import { loadModule } from 'vue3-sfc-loader'
|
||||||
|
import less from 'less'
|
||||||
|
import defaultTemplate from '@/viewsnew/application/SfcEditor/LoginEditor/login.vue?raw'
|
||||||
|
import 'element-plus/dist/index.css'
|
||||||
|
import { i18n } from '@/plugins/vue-i18n'
|
||||||
|
import { moduleUpdate,moduleById } from '@/api/application/module'
|
||||||
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
const activeName: any = ref('代码')
|
||||||
|
const hearderName: any = ref('')
|
||||||
|
const sfcCode = ref('')
|
||||||
|
const previewContainer = ref(null)
|
||||||
|
let prevApp = null
|
||||||
|
const applicationId: any = ref('')
|
||||||
|
const menuList: any = ref([])
|
||||||
|
const appname: any = ref('')
|
||||||
|
const dvId: 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,
|
||||||
|
'vue-router': VueRouter
|
||||||
|
},
|
||||||
|
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
|
||||||
|
// 增强的Less处理(支持scoped)
|
||||||
|
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({
|
||||||
|
id: route.query.dvId,
|
||||||
|
name: route.query.appname,
|
||||||
|
isExecuteEvent:true
|
||||||
|
})
|
||||||
|
// prevApp = Vue.createApp({
|
||||||
|
// render: () => Vue.h(component, dynamicProps.value)
|
||||||
|
// })
|
||||||
|
prevApp = Vue.createApp({
|
||||||
|
render: () => Vue.h(component, {
|
||||||
|
...dynamicProps.value,
|
||||||
|
router: router,
|
||||||
|
route: route
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 显式提供路由实例
|
||||||
|
prevApp.use(router)
|
||||||
|
prevApp.use(ElementPlus)
|
||||||
|
prevApp.use(i18n)
|
||||||
|
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
|
||||||
|
dvId.value = route.query.dvId
|
||||||
|
getmenuinfo()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
function importTemplate(){
|
||||||
|
sfcCode.value = defaultTemplate
|
||||||
|
}
|
||||||
|
function getmenuinfo() {
|
||||||
|
moduleById(dvId.value).then(res => {
|
||||||
|
if(res.data.data.canvas_style_data){
|
||||||
|
sfcCode.value = res.data.data.canvas_style_data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function goBack() {
|
||||||
|
router.push({
|
||||||
|
path: '/module',
|
||||||
|
query: {
|
||||||
|
id: route.query.appId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function handleClick() {
|
||||||
|
if (activeName.value == '预览') {
|
||||||
|
runCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function saveClick(){
|
||||||
|
const params = {
|
||||||
|
canvasStyleData:sfcCode.value,
|
||||||
|
componentData:'',
|
||||||
|
id:dvId.value
|
||||||
|
}
|
||||||
|
moduleUpdate(params).then(res => {
|
||||||
|
if(res.data.code == '0'){
|
||||||
|
ElMessage.success('保存成功')
|
||||||
|
}else{
|
||||||
|
ElMessage.error('保存失败')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</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>
|
@ -1,11 +1,13 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, watch, onMounted, onBeforeUnmount, shallowRef } from 'vue'
|
import { ref, watch, onMounted, onBeforeUnmount, shallowRef } from 'vue'
|
||||||
import type { FormInstance, FormRules } from 'element-plus'
|
import type { FormInstance, FormRules } from 'element-plus'
|
||||||
import { useRouter } from 'vue-router'
|
import {useRoute, useRouter } from 'vue-router'
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
id: String,
|
id: String,
|
||||||
name: String
|
name: String,
|
||||||
|
isExecuteEvent: Boolean,
|
||||||
})
|
})
|
||||||
const form = ref({
|
const form = ref({
|
||||||
username: '',
|
username: '',
|
||||||
@ -22,6 +24,9 @@ const loginRules = ref({
|
|||||||
const ruleFormRef = ref<FormInstance>()
|
const ruleFormRef = ref<FormInstance>()
|
||||||
const loginTitle: any = ref('')
|
const loginTitle: any = ref('')
|
||||||
const submitForm = async (formEl: FormInstance | undefined) => {
|
const submitForm = async (formEl: FormInstance | undefined) => {
|
||||||
|
if(props.isExecuteEvent){
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
await formEl.validate((valid, fields) => {
|
await formEl.validate((valid, fields) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
@ -74,7 +79,6 @@ onBeforeUnmount(() => {
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div class="login-button" @click="submitForm(ruleFormRef)">登录</div>
|
<div class="login-button" @click="submitForm(ruleFormRef)">登录</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -0,0 +1,192 @@
|
|||||||
|
<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 * as VueRouter from 'vue-router'
|
||||||
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
import { moduleUpdate,moduleById } from '@/api/application/module'
|
||||||
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
const props = defineProps({
|
||||||
|
name:String,
|
||||||
|
id:String,
|
||||||
|
isExecuteEvent: Boolean,
|
||||||
|
})
|
||||||
|
const sfcCode = ref('')
|
||||||
|
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.unmount()
|
||||||
|
previewContainer.value.innerHTML = ''
|
||||||
|
}
|
||||||
|
const options = {
|
||||||
|
moduleCache: {
|
||||||
|
vue: Vue,
|
||||||
|
'element-plus': ElementPlus,
|
||||||
|
'vue/dist/vue.esm-bundler.js': Vue,
|
||||||
|
'vue-router': VueRouter
|
||||||
|
},
|
||||||
|
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
|
||||||
|
// 增强的Less处理(支持scoped)
|
||||||
|
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({
|
||||||
|
id: props.id,
|
||||||
|
name: props.name,
|
||||||
|
isExecuteEvent:props.isExecuteEvent
|
||||||
|
})
|
||||||
|
prevApp = Vue.createApp({
|
||||||
|
render: () => Vue.h(component, {
|
||||||
|
...dynamicProps.value,
|
||||||
|
router: router,
|
||||||
|
route: route
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 显式提供路由实例
|
||||||
|
prevApp.use(router)
|
||||||
|
prevApp.use(ElementPlus)
|
||||||
|
prevApp.use(i18n)
|
||||||
|
prevApp.mount(previewContainer.value)
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('运行时错误:', error)
|
||||||
|
previewContainer.value.innerHTML = `
|
||||||
|
<div class="error">
|
||||||
|
<h3>错误</h3>
|
||||||
|
<pre>${error.message}</pre>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
init()
|
||||||
|
})
|
||||||
|
function init(){
|
||||||
|
moduleById(props.id).then(res => {
|
||||||
|
if(res.data.data.canvas_style_data){
|
||||||
|
sfcCode.value = res.data.data.canvas_style_data
|
||||||
|
runCode()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
/* 保留原有样式并补充 */
|
||||||
|
.editor {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
flex: 1;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-family: Monaco, monospace;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview {
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,7 +1,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref,watch, onMounted,onBeforeUnmount,shallowRef } from 'vue'
|
import { ref,watch, onMounted,onBeforeUnmount,shallowRef } from 'vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import Assocmodule from '@/viewsnew/application/SfcEditor/assocPage.vue'
|
import Assocmodule from '@/viewsnew/application/SfcEditor/NavbarEditor/assocPage.vue'
|
||||||
|
import PermissionSet from '@/viewsnew/application/permissionset/index.vue'
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
menuList: {
|
menuList: {
|
||||||
type: Array, // 根据实际数据结构调整
|
type: Array, // 根据实际数据结构调整
|
||||||
@ -19,12 +20,12 @@ const navmenulist:any = ref([
|
|||||||
const checkindex = ref(null)
|
const checkindex = ref(null)
|
||||||
const showmodule = ref(false)
|
const showmodule = ref(false)
|
||||||
const currentMoudleId = ref('')
|
const currentMoudleId = ref('')
|
||||||
|
const showermission = ref(false)
|
||||||
watch(
|
watch(
|
||||||
() => props.menuList,
|
() => props.menuList,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
navmenulist.value = newVal
|
navmenulist.value = newVal
|
||||||
console.log(newVal)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true } // 立即执行一次
|
{ immediate: true } // 立即执行一次
|
||||||
@ -36,13 +37,14 @@ function menuclick(index:any) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
currentMoudleId.value = navmenulist.value[index].module_id
|
currentMoudleId.value = navmenulist.value[index].module_id
|
||||||
|
showmodule.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function childmenuclick(item:any){
|
function childmenuclick(item:any){
|
||||||
console.log(item,props.isExecuteEvent)
|
|
||||||
if(props.isExecuteEvent){
|
if(props.isExecuteEvent){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
showermission.value = false
|
||||||
showmodule.value = false
|
showmodule.value = false
|
||||||
if(item.module_id && item.module_id !== ''){
|
if(item.module_id && item.module_id !== ''){
|
||||||
currentMoudleId.value = item.module_id
|
currentMoudleId.value = item.module_id
|
||||||
@ -98,6 +100,10 @@ onMounted(() => {
|
|||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
function permissionClick(){
|
||||||
|
showmodule.value = false
|
||||||
|
showermission.value = true
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="system-box">
|
<div class="system-box">
|
||||||
@ -122,7 +128,7 @@ onBeforeUnmount(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="Navbar-box-right">
|
<div class="Navbar-box-right">
|
||||||
<div style="margin-right: 10px;"><img src="@/assets/img/nav1.png" alt=""></div>
|
<div style="margin-right: 10px;cursor: pointer;" @click="permissionClick"><img src="@/assets/img/nav1.png" alt=""></div>
|
||||||
<div style="margin-right: 15px;min-width: 45px;">admin</div>
|
<div style="margin-right: 15px;min-width: 45px;">admin</div>
|
||||||
<div style="margin-right: 15px;"><img src="@/assets/img/nav3.png" alt=""></div>
|
<div style="margin-right: 15px;"><img src="@/assets/img/nav3.png" alt=""></div>
|
||||||
<div><img src="@/assets/img/nav4.png" alt=""></div>
|
<div><img src="@/assets/img/nav4.png" alt=""></div>
|
||||||
@ -132,6 +138,7 @@ onBeforeUnmount(() => {
|
|||||||
<div v-if="!props.isExecuteEvent" class="system-box-content" :style="{height:props.isFixed?'calc(100vh - 65px)':'calc(100vh - 125px)'}">
|
<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"
|
<Assocmodule v-if="showmodule" :applicationId="props.applicationId"
|
||||||
:moduleinfo="{module_id:currentMoudleId}" />
|
:moduleinfo="{module_id:currentMoudleId}" />
|
||||||
|
<!-- <PermissionSet v-if="showermission" /> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
@ -5,7 +5,7 @@ import FormCreate from '@/viewsnew/common/FormCreate.vue'
|
|||||||
import { initCanvasData } from '@/utils/canvasUtils'
|
import { initCanvasData } from '@/utils/canvasUtils'
|
||||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||||
import { moduleList } from '@/api/application/module'
|
import { moduleList } from '@/api/application/module'
|
||||||
import Navbar from '@/viewsnew/application/SfcEditor/assocPage.vue'
|
import Navbar from '@/viewsnew/application/SfcEditor/NavbarEditor/assocPage.vue'
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
moduleinfo:Object,
|
moduleinfo:Object,
|
||||||
applicationId:String
|
applicationId:String
|
||||||
@ -89,16 +89,20 @@ function handleNodeClick(e){
|
|||||||
if(e.type == '0301'){
|
if(e.type == '0301'){
|
||||||
busiFlag.value = 'dashboard'
|
busiFlag.value = 'dashboard'
|
||||||
loadCanvasData(e.id,9,0)
|
loadCanvasData(e.id,9,0)
|
||||||
|
loading.value = false
|
||||||
}else if(e.type == '03'){
|
}else if(e.type == '03'){
|
||||||
busiFlag.value = 'dataV'
|
busiFlag.value = 'dataV'
|
||||||
|
loading.value = false
|
||||||
loadCanvasData(e.id,9,0)
|
loadCanvasData(e.id,9,0)
|
||||||
}else if(e.type == '09'){
|
}else if(e.type == '04'||e.type == '05'||e.type == '06'){
|
||||||
moduleInfo.value = e
|
moduleInfo.value = e
|
||||||
isFormCreate.value = true
|
isFormCreate.value = true
|
||||||
|
loading.value = false
|
||||||
} else if(e.type == '02'){
|
} else if(e.type == '02'){
|
||||||
isNavbar.value = true
|
isNavbar.value = true
|
||||||
}
|
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
@ -1,7 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<!-- <h1>Vue 3 SFC 在线编辑器</h1>
|
|
||||||
<SfcEditor /> -->
|
|
||||||
<div class="sfc-header">
|
<div class="sfc-header">
|
||||||
<div class="sfc-header-left">
|
<div class="sfc-header-left">
|
||||||
<!-- <div class="return-box"><img src="@/assets/newimg/u594.png" alt=""></div> -->
|
<!-- <div class="return-box"><img src="@/assets/newimg/u594.png" alt=""></div> -->
|
||||||
@ -17,7 +15,7 @@
|
|||||||
<textarea v-model="sfcCode"></textarea>
|
<textarea v-model="sfcCode"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="sfc-content-bottom">
|
<div class="sfc-content-bottom">
|
||||||
<el-button type="primary">导入模板</el-button>
|
<el-button type="primary" @click="importNav">导入模板</el-button>
|
||||||
<el-button type="primary" @click="saveClick">保存</el-button>
|
<el-button type="primary" @click="saveClick">保存</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@ -37,7 +35,7 @@ import { loadModule } from 'vue3-sfc-loader'
|
|||||||
import * as Vue from 'vue/dist/vue.esm-bundler.js'
|
import * as Vue from 'vue/dist/vue.esm-bundler.js'
|
||||||
import ElementPlus from 'element-plus'
|
import ElementPlus from 'element-plus'
|
||||||
import less from 'less'
|
import less from 'less'
|
||||||
import defaultTemplate from '@/viewsnew/application/SfcEditor/Navbar.vue?raw'
|
import defaultTemplate from '@/viewsnew/application/SfcEditor/NavbarEditor/Navbar.vue?raw'
|
||||||
import { getMenuTree } from '@/api/permission/menu'
|
import { getMenuTree } from '@/api/permission/menu'
|
||||||
import { moduleUpdate,moduleById } from '@/api/application/module'
|
import { moduleUpdate,moduleById } from '@/api/application/module'
|
||||||
import 'element-plus/dist/index.css'
|
import 'element-plus/dist/index.css'
|
||||||
@ -81,8 +79,8 @@ const runCode = async () => {
|
|||||||
vue: Vue,
|
vue: Vue,
|
||||||
'element-plus': ElementPlus,
|
'element-plus': ElementPlus,
|
||||||
'vue/dist/vue.esm-bundler.js': Vue,
|
'vue/dist/vue.esm-bundler.js': Vue,
|
||||||
'@/viewsnew/application/SfcEditor/assocPage.vue': Vue.defineAsyncComponent(() =>
|
'@/viewsnew/application/SfcEditor/NavbarEditor/assocPage.vue': Vue.defineAsyncComponent(() =>
|
||||||
import('@/viewsnew/application/SfcEditor/assocPage.vue'))
|
import('@/viewsnew/application/SfcEditor/NavbarEditor/assocPage.vue'))
|
||||||
},
|
},
|
||||||
getFile: async (fileName) => {
|
getFile: async (fileName) => {
|
||||||
if (fileName.startsWith('@/')) {
|
if (fileName.startsWith('@/')) {
|
||||||
@ -198,7 +196,6 @@ function getmenuinfo() {
|
|||||||
if(res.data.data.canvas_style_data){
|
if(res.data.data.canvas_style_data){
|
||||||
sfcCode.value = res.data.data.canvas_style_data
|
sfcCode.value = res.data.data.canvas_style_data
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function goBack() {
|
function goBack() {
|
||||||
@ -216,7 +213,6 @@ function handleClick() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function saveClick(){
|
function saveClick(){
|
||||||
// console.log(typeof(sfcCode.value))
|
|
||||||
const params = {
|
const params = {
|
||||||
canvasStyleData:sfcCode.value,
|
canvasStyleData:sfcCode.value,
|
||||||
componentData:'',
|
componentData:'',
|
||||||
@ -230,6 +226,9 @@ function saveClick(){
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
function importNav(){
|
||||||
|
sfcCode.value = defaultTemplate
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
@ -4,15 +4,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted,onUnmounted } from 'vue'
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
import { loadModule } from 'vue3-sfc-loader'
|
import { loadModule } from 'vue3-sfc-loader'
|
||||||
import * as Vue from 'vue/dist/vue.esm-bundler.js'
|
import * as Vue from 'vue/dist/vue.esm-bundler.js'
|
||||||
import ElementPlus from 'element-plus'
|
import ElementPlus from 'element-plus'
|
||||||
import 'element-plus/dist/index.css'
|
import 'element-plus/dist/index.css'
|
||||||
import less from 'less'
|
import less from 'less'
|
||||||
|
import * as VueRouter from 'vue-router'
|
||||||
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { i18n } from '@/plugins/vue-i18n'
|
import { i18n } from '@/plugins/vue-i18n'
|
||||||
import defaultTemplate from '@/viewsnew/application/SfcEditor/Navbar.vue?raw'
|
import defaultTemplate from '@/viewsnew/application/SfcEditor/NavbarEditor/Navbar.vue?raw'
|
||||||
import { moduleUpdate,moduleById } from '@/api/application/module'
|
import { moduleUpdate, moduleById } from '@/api/application/module'
|
||||||
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
menuList: {
|
menuList: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@ -62,9 +66,13 @@ const runCode = async () => {
|
|||||||
vue: Vue,
|
vue: Vue,
|
||||||
'element-plus': ElementPlus,
|
'element-plus': ElementPlus,
|
||||||
'vue/dist/vue.esm-bundler.js': Vue,
|
'vue/dist/vue.esm-bundler.js': Vue,
|
||||||
'@/viewsnew/application/SfcEditor/assocPage.vue': Vue.defineAsyncComponent(() =>
|
'vue-router': VueRouter,
|
||||||
import('@/viewsnew/application/SfcEditor/assocPage.vue')
|
'@/viewsnew/application/SfcEditor/NavbarEditor/assocPage.vue': Vue.defineAsyncComponent(() =>
|
||||||
|
import('@/viewsnew/application/SfcEditor/NavbarEditor/assocPage.vue')
|
||||||
),
|
),
|
||||||
|
'@/viewsnew/application/permissionset/index.vue': Vue.defineAsyncComponent(() =>
|
||||||
|
import('@/viewsnew/application/permissionset/index.vue')
|
||||||
|
)
|
||||||
},
|
},
|
||||||
getFile: async (fileName) => {
|
getFile: async (fileName) => {
|
||||||
if (fileName === 'dynamic.vue') {
|
if (fileName === 'dynamic.vue') {
|
||||||
@ -121,8 +129,15 @@ const runCode = async () => {
|
|||||||
isExecuteEvent: props.isExecuteEvent
|
isExecuteEvent: props.isExecuteEvent
|
||||||
})
|
})
|
||||||
// 修改createApp方式
|
// 修改createApp方式
|
||||||
|
// prevApp = Vue.createApp({
|
||||||
|
// render: () => Vue.h(component, dynamicProps)
|
||||||
|
// })
|
||||||
prevApp = Vue.createApp({
|
prevApp = Vue.createApp({
|
||||||
render: () => Vue.h(component, dynamicProps)
|
render: () => Vue.h(component, {
|
||||||
|
...dynamicProps,
|
||||||
|
router: router,
|
||||||
|
route: route
|
||||||
|
})
|
||||||
})
|
})
|
||||||
prevApp.use(i18n)
|
prevApp.use(i18n)
|
||||||
prevApp.use(ElementPlus)
|
prevApp.use(ElementPlus)
|
||||||
@ -141,10 +156,11 @@ const runCode = async () => {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
init()
|
init()
|
||||||
})
|
})
|
||||||
function init(){
|
function init() {
|
||||||
moduleById(props.projectId).then(res => {
|
moduleById(props.projectId).then(res => {
|
||||||
if(res.data.data.canvas_style_data){
|
if (res.data.data.canvas_style_data) {
|
||||||
sfcCode.value = res.data.data.canvas_style_data
|
// sfcCode.value = res.data.data.canvas_style_data
|
||||||
|
sfcCode.value = defaultTemplate
|
||||||
runCode()
|
runCode()
|
||||||
}
|
}
|
||||||
})
|
})
|
@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref,watch, onMounted,onBeforeUnmount } from 'vue'
|
import { ref, watch, onMounted, onBeforeUnmount } from 'vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import * as VueRouter from 'vue-router'
|
import * as VueRouter from 'vue-router'
|
||||||
@ -8,7 +8,8 @@ import * as Vue from 'vue/dist/vue.esm-bundler.js'
|
|||||||
import { i18n } from '@/plugins/vue-i18n'
|
import { i18n } from '@/plugins/vue-i18n'
|
||||||
import ElementPlus from 'element-plus'
|
import ElementPlus from 'element-plus'
|
||||||
import less from 'less'
|
import less from 'less'
|
||||||
import defaultTemplate from '@/viewsnew/application/SfcEditor/login.vue?raw'
|
import defaultTemplate from '@/viewsnew/application/SfcEditor/LoginEditor/login.vue?raw'
|
||||||
|
import { moduleList, moduleById } from '@/api/application/module'
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const sfcCode = ref(defaultTemplate)
|
const sfcCode = ref(defaultTemplate)
|
||||||
@ -117,6 +118,7 @@ const runCode = async () => {
|
|||||||
const dynamicProps = ref({
|
const dynamicProps = ref({
|
||||||
id: route.query.id,
|
id: route.query.id,
|
||||||
name: route.query.name,
|
name: route.query.name,
|
||||||
|
isExecuteEvent: false
|
||||||
})
|
})
|
||||||
// prevApp = Vue.createApp({
|
// prevApp = Vue.createApp({
|
||||||
// render: () => Vue.h(component, dynamicProps.value)
|
// render: () => Vue.h(component, dynamicProps.value)
|
||||||
@ -146,8 +148,31 @@ const runCode = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
runCode()
|
init()
|
||||||
})
|
})
|
||||||
|
function init() {
|
||||||
|
const paramss = { appId: route.query.id }
|
||||||
|
moduleList(paramss).then(ress => {
|
||||||
|
var arr = ress.data.data
|
||||||
|
let list: any = {}
|
||||||
|
arr.forEach((item: any) => {
|
||||||
|
if (item.type == '01' && item.node_type == '02') {
|
||||||
|
list = item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (list.id) {
|
||||||
|
moduleById(list.id).then(res2 => {
|
||||||
|
if (res2.data.data.canvas_style_data) {
|
||||||
|
sfcCode.value = res2.data.data.canvas_style_data
|
||||||
|
runCode()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
sfcCode.value = defaultTemplate
|
||||||
|
runCode()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -163,4 +188,14 @@ onBeforeUnmount(() => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
.no-login{
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #151515;
|
||||||
|
color: #787878;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 100vh;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -231,6 +231,7 @@ function preview(row){
|
|||||||
border-color: rgba(51, 51, 51, 1);
|
border-color: rgba(51, 51, 51, 1);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
.application_list_text{
|
.application_list_text{
|
||||||
font-family: 'Arial Normal', 'Arial';
|
font-family: 'Arial Normal', 'Arial';
|
||||||
|
@ -9,7 +9,7 @@ import { ElTree,FormInstance } from 'element-plus'
|
|||||||
import { publicTree } from '@/utils/validate';
|
import { publicTree } from '@/utils/validate';
|
||||||
import { setModuleId } from '@/api/permission/menu'
|
import { setModuleId } from '@/api/permission/menu'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import Navbar from '@/viewsnew/application/SfcEditor/previewNavSfc.vue'
|
import Navbar from '@/viewsnew/application/SfcEditor/NavbarEditor/previewNavSfc.vue'
|
||||||
import { getMenuTree } from '@/api/permission/menu'
|
import { getMenuTree } from '@/api/permission/menu'
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
applicationId:String,
|
applicationId:String,
|
||||||
@ -93,7 +93,7 @@ const handleNodeClick = (e: any) => {
|
|||||||
}else if(e.type == '03'){
|
}else if(e.type == '03'){
|
||||||
busiFlag.value = 'dataV'
|
busiFlag.value = 'dataV'
|
||||||
loadCanvasData(e.id,9,0)
|
loadCanvasData(e.id,9,0)
|
||||||
}else if(e.type == '09'){
|
}else if(e.type == '04'||e.type == '05'||e.type == '06'){
|
||||||
moduleInfo.value = e
|
moduleInfo.value = e
|
||||||
isFormCreate.value = true
|
isFormCreate.value = true
|
||||||
} else if(e.type == '02'){
|
} else if(e.type == '02'){
|
||||||
|
@ -5,7 +5,7 @@ import FormCreate from '@/viewsnew/common/FormCreate.vue'
|
|||||||
import { initCanvasData } from '@/utils/canvasUtils'
|
import { initCanvasData } from '@/utils/canvasUtils'
|
||||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||||
import { moduleList } from '@/api/application/module'
|
import { moduleList } from '@/api/application/module'
|
||||||
import Navbar from '@/viewsnew/application/SfcEditor/assocPage.vue'
|
import Navbar from '@/viewsnew/application/SfcEditor/NavbarEditor/assocPage.vue'
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
moduleinfo:Object,
|
moduleinfo:Object,
|
||||||
applicationId:String
|
applicationId:String
|
||||||
|
@ -66,7 +66,6 @@ onMounted(()=>{
|
|||||||
|
|
||||||
const canvas_style_data= {"width":1920,"height":1080,"refreshViewEnable":false,"refreshViewLoading":false,"refreshUnit":"minute","refreshTime":5,"scale":60,"scaleWidth":100,"scaleHeight":100,"backgroundColorSelect":false,"backgroundImageEnable":true,"backgroundType":"backgroundColor","background":"/static-resource/7127292608094670848.png","openCommonStyle":true,"opacity":1,"fontSize":14,"themeId":"10001","color":"#000000","backgroundColor":"rgba(245, 246, 247, 1)","dashboard":{"gap":"yes","gapSize":5,"resultMode":"all","resultCount":1000,"themeColor":"light","mobileSetting":{"customSetting":false,"imageUrl":null,"backgroundType":"image","color":"#000"}},"component":{"chartTitle":{"show":true,"fontSize":"18","hPosition":"left","vPosition":"top","isItalic":false,"isBolder":true,"remarkShow":false,"remark":"","fontFamily":"Microsoft YaHei","letterSpace":"0","fontShadow":false,"color":"#000000","remarkBackgroundColor":"#ffffff","modifyName":"color"},"chartColor":{"basicStyle":{"colorScheme":"default","colors":["#1E90FF","#90EE90","#00CED1","#E2BD84","#7A90E0","#3BA272","#2BE7FF","#0A8ADA","#FFD700"],"alpha":100,"gradient":true,"mapStyle":"normal","areaBaseColor":"#FFFFFF","areaBorderColor":"#303133","gaugeStyle":"default","tableBorderColor":"#E6E7E4","tableScrollBarColor":"#00000024"},"misc":{"mapLineGradient":false,"mapLineSourceColor":"#146C94","mapLineTargetColor":"#576CBC","nameFontColor":"#000000","valueFontColor":"#5470c6"},"tableHeader":{"tableHeaderBgColor":"#1E90FF","tableHeaderFontColor":"#000000"},"tableCell":{"tableItemBgColor":"#FFFFFF","tableFontColor":"#000000"},"modifyName":"gradient"},"chartCommonStyle":{"backgroundColorSelect":true,"backgroundImageEnable":false,"backgroundType":"innerImage","innerImage":"board/board_1.svg","outerImage":null,"innerPadding":12,"borderRadius":8,"backgroundColor":"rgba(255, 255, 255, 1)","innerImageColor":"rgba(16, 148, 229,1)"},"filterStyle":{"layout":"horizontal","titleLayout":"left","labelColor":"#1F2329","titleColor":"#1F2329","color":"#1f2329","borderColor":"#BBBFC4","text":"#1F2329","bgColor":"#FFFFFF"},"tabStyle":{"headPosition":"left","headFontColor":"#000000","headFontActiveColor":"#000000","headBorderColor":"#ffffff","headBorderActiveColor":"#ffffff"}}}
|
const canvas_style_data= {"width":1920,"height":1080,"refreshViewEnable":false,"refreshViewLoading":false,"refreshUnit":"minute","refreshTime":5,"scale":60,"scaleWidth":100,"scaleHeight":100,"backgroundColorSelect":false,"backgroundImageEnable":true,"backgroundType":"backgroundColor","background":"/static-resource/7127292608094670848.png","openCommonStyle":true,"opacity":1,"fontSize":14,"themeId":"10001","color":"#000000","backgroundColor":"rgba(245, 246, 247, 1)","dashboard":{"gap":"yes","gapSize":5,"resultMode":"all","resultCount":1000,"themeColor":"light","mobileSetting":{"customSetting":false,"imageUrl":null,"backgroundType":"image","color":"#000"}},"component":{"chartTitle":{"show":true,"fontSize":"18","hPosition":"left","vPosition":"top","isItalic":false,"isBolder":true,"remarkShow":false,"remark":"","fontFamily":"Microsoft YaHei","letterSpace":"0","fontShadow":false,"color":"#000000","remarkBackgroundColor":"#ffffff","modifyName":"color"},"chartColor":{"basicStyle":{"colorScheme":"default","colors":["#1E90FF","#90EE90","#00CED1","#E2BD84","#7A90E0","#3BA272","#2BE7FF","#0A8ADA","#FFD700"],"alpha":100,"gradient":true,"mapStyle":"normal","areaBaseColor":"#FFFFFF","areaBorderColor":"#303133","gaugeStyle":"default","tableBorderColor":"#E6E7E4","tableScrollBarColor":"#00000024"},"misc":{"mapLineGradient":false,"mapLineSourceColor":"#146C94","mapLineTargetColor":"#576CBC","nameFontColor":"#000000","valueFontColor":"#5470c6"},"tableHeader":{"tableHeaderBgColor":"#1E90FF","tableHeaderFontColor":"#000000"},"tableCell":{"tableItemBgColor":"#FFFFFF","tableFontColor":"#000000"},"modifyName":"gradient"},"chartCommonStyle":{"backgroundColorSelect":true,"backgroundImageEnable":false,"backgroundType":"innerImage","innerImage":"board/board_1.svg","outerImage":null,"innerPadding":12,"borderRadius":8,"backgroundColor":"rgba(255, 255, 255, 1)","innerImageColor":"rgba(16, 148, 229,1)"},"filterStyle":{"layout":"horizontal","titleLayout":"left","labelColor":"#1F2329","titleColor":"#1F2329","color":"#1f2329","borderColor":"#BBBFC4","text":"#1F2329","bgColor":"#FFFFFF"},"tabStyle":{"headPosition":"left","headFontColor":"#000000","headFontActiveColor":"#000000","headBorderColor":"#ffffff","headBorderActiveColor":"#ffffff"}}}
|
||||||
|
|
||||||
console.log(canvas_style_data)
|
|
||||||
|
|
||||||
projectInfo.value = props.projectInfo
|
projectInfo.value = props.projectInfo
|
||||||
})
|
})
|
||||||
@ -134,14 +133,19 @@ function editClic(data:any){
|
|||||||
window.open('/#/formcreatedesigner?moduleId=' +data.id + '&appId='+projectInfo.value.id, '_blank');
|
window.open('/#/formcreatedesigner?moduleId=' +data.id + '&appId='+projectInfo.value.id, '_blank');
|
||||||
} else if(data.type == '02'){
|
} else if(data.type == '02'){
|
||||||
const route = router.resolve({
|
const route = router.resolve({
|
||||||
path: '/SfcEditor',
|
path: '/editNavbar',
|
||||||
|
query: { dvId: data.id,appId:projectInfo.value.id,name:data.name,appname:projectInfo.value.name }
|
||||||
|
});
|
||||||
|
window.open(route.href, '_blank');
|
||||||
|
} else if(data.type == '01'){
|
||||||
|
const route = router.resolve({
|
||||||
|
path: '/editLogin',
|
||||||
query: { dvId: data.id,appId:projectInfo.value.id,name:data.name,appname:projectInfo.value.name }
|
query: { dvId: data.id,appId:projectInfo.value.id,name:data.name,appname:projectInfo.value.name }
|
||||||
});
|
});
|
||||||
window.open(route.href, '_blank');
|
window.open(route.href, '_blank');
|
||||||
}
|
}
|
||||||
// window.open('/#/dvCanvas?dvId=' + "1097641013486424064", '_blank');
|
|
||||||
}
|
}
|
||||||
function addTreeChildNode(event:any,level:any,data:any){ // // 添加子节点
|
function addTreeChildNode(event:any,level:any,data:any){ // 添加子节点
|
||||||
let element = document.getElementById("drag_main_area")
|
let element = document.getElementById("drag_main_area")
|
||||||
if(element !=null){
|
if(element !=null){
|
||||||
const x = event.clientX; // 水平坐标(相对于元素边界)
|
const x = event.clientX; // 水平坐标(相对于元素边界)
|
||||||
|
@ -7,7 +7,8 @@ import { findApplicationById } from "@/api/application/application";
|
|||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import DvPreview from '@/viewsnew/data-visualization/DvPreview.vue'
|
import DvPreview from '@/viewsnew/data-visualization/DvPreview.vue'
|
||||||
import FormCreate from '@/viewsnew/common/FormCreate.vue'
|
import FormCreate from '@/viewsnew/common/FormCreate.vue'
|
||||||
import Navbar from '@/viewsnew/application/sfcEditor/previewNavSfc.vue'
|
import Navbar from '@/viewsnew/application/sfcEditor/NavbarEditor/previewNavSfc.vue'
|
||||||
|
import Login from '@/viewsnew/application/sfcEditor/LoginEditor/previewLogin.vue'
|
||||||
import DePreview from '@/components/data-visualization/canvas/DePreview.vue'
|
import DePreview from '@/components/data-visualization/canvas/DePreview.vue'
|
||||||
import { initCanvasData, initCanvasDataPrepare, onInitReady } from '@/utils/canvasUtils'
|
import { initCanvasData, initCanvasDataPrepare, onInitReady } from '@/utils/canvasUtils'
|
||||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||||
@ -29,6 +30,7 @@ const downloadStatus = ref(false)
|
|||||||
const dvPreviewRef = ref(null)
|
const dvPreviewRef = ref(null)
|
||||||
const showPosition = ref("preview")
|
const showPosition = ref("preview")
|
||||||
const isNavbar = ref(false)
|
const isNavbar = ref(false)
|
||||||
|
const isLogin = ref(false)
|
||||||
// const noClose = ref(false)
|
// const noClose = ref(false)
|
||||||
// const props = defineProps({
|
// const props = defineProps({
|
||||||
// showPosition: {
|
// showPosition: {
|
||||||
@ -105,7 +107,7 @@ const loadCanvasData = (dvId, weight?, ext?) => {
|
|||||||
dvPreviewRef.value?.restore()
|
dvPreviewRef.value?.restore()
|
||||||
})
|
})
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
onInitReloadCanvasDataady({ resourceId: dvId })
|
// onInitReloadCanvasDataady({ resourceId: dvId })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -116,6 +118,7 @@ function handleNodeClick(e){
|
|||||||
isFormCreate.value = false
|
isFormCreate.value = false
|
||||||
dataInitState.value = false
|
dataInitState.value = false
|
||||||
isNavbar.value = false
|
isNavbar.value = false
|
||||||
|
isLogin.value = false
|
||||||
if(e.type == '0301'){
|
if(e.type == '0301'){
|
||||||
busiFlag.value = 'dashboard'
|
busiFlag.value = 'dashboard'
|
||||||
loadCanvasData(e.id,9,0)
|
loadCanvasData(e.id,9,0)
|
||||||
@ -137,6 +140,9 @@ function handleNodeClick(e){
|
|||||||
menuList.value = res.data
|
menuList.value = res.data
|
||||||
isNavbar.value = true
|
isNavbar.value = true
|
||||||
})
|
})
|
||||||
|
}else if(e.type == '01'){
|
||||||
|
projectId.value = e.id
|
||||||
|
isLogin.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +170,7 @@ onBeforeMount(() => {
|
|||||||
<form-create v-if="isFormCreate" :moduleInfo="moduleInfo"></form-create>
|
<form-create v-if="isFormCreate" :moduleInfo="moduleInfo"></form-create>
|
||||||
<Navbar class="navbarpreview" v-if="isNavbar" :isFixed="true" :applicationId="applicationId"
|
<Navbar class="navbarpreview" v-if="isNavbar" :isFixed="true" :applicationId="applicationId"
|
||||||
:menuList="menuList" :projectId="projectId" :projectName="projectInfo.name" :isExecuteEvent="isExecuteEvent"></Navbar>
|
:menuList="menuList" :projectId="projectId" :projectName="projectInfo.name" :isExecuteEvent="isExecuteEvent"></Navbar>
|
||||||
|
<Login class="loginpreview" v-if="isLogin" :id="projectId" :name="projectInfo.name" :isExecuteEvent="true"></Login>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -190,6 +197,10 @@ onBeforeMount(() => {
|
|||||||
height: calc(100vh - 60px);
|
height: calc(100vh - 60px);
|
||||||
// overflow: hidden;
|
// overflow: hidden;
|
||||||
}
|
}
|
||||||
|
.loginpreview{
|
||||||
|
width: calc(100% - 260px);
|
||||||
|
height: calc(100vh - 60px);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<style>
|
<style>
|
||||||
.ed-message-box{
|
.ed-message-box{
|
||||||
|
@ -30,7 +30,7 @@ function menuclick(name){
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<Header :projectInfo="projectInfo"/>
|
<Header v-if="!route.query.name" :projectInfo="projectInfo"/>
|
||||||
<div class="permission-box">
|
<div class="permission-box">
|
||||||
<div class="permission-leftbox">
|
<div class="permission-leftbox">
|
||||||
<div class="permission-leftbox-menu" :class="curmenu == '组织机构配置' ? 'permission-leftbox-menu-active' : ''" @click="menuclick('组织机构配置')">组织机构配置</div>
|
<div class="permission-leftbox-menu" :class="curmenu == '组织机构配置' ? 'permission-leftbox-menu-active' : ''" @click="menuclick('组织机构配置')">组织机构配置</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user