提交代码

This commit is contained in:
guanj
2025-09-25 11:34:55 +08:00
commit 448b8df85b
188 changed files with 21433 additions and 0 deletions

View File

@@ -0,0 +1,218 @@
<template>
<div class="w-1/1 h-100vh">
<mt-edit ref="MtEditRef" @on-return-click="onReturnClick" @on-preview-click="onPreviewClick"></mt-edit>
</div>
</template>
<script setup lang="ts">
import type { IExportJson } from '@/components/mt-edit/components/types'
import { MtEdit } from '@/export'
import { onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const MtEditRef = ref<InstanceType<typeof MtEdit>>()
const onPreviewClick = (exportJson: IExportJson) => {
sessionStorage.setItem('exportJson', JSON.stringify(exportJson))
const routeUrl = router.resolve({
name: 'preview'
})
window.open(routeUrl.href, '_blank')
}
const onReturnClick = () => {
router.go(-1)
}
onMounted(() => {
MtEditRef.value?.setImportJson({
canvasCfg: {
width: 1920,
height: 1080,
scale: 1,
color: '#000000',
img: '',
guide: false,
adsorp: false,
adsorp_diff: 3,
transform_origin: {
x: 0,
y: 0
},
drag_offset: {
x: 0,
y: 0
}
},
gridCfg: {
enabled: false,
align: true,
size: 10
},
json: [
{
id: 'sys-button-vue-mDvwKZN8o8',
title: '按钮',
type: 'vue',
binfo: {
left: 551,
top: 301,
width: 230,
height: 50,
angle: 0
},
resize: true,
rotate: true,
lock: false,
active: false,
hide: false,
props: {
text: '连续点我更改发电机颜色',
type: 'primary',
round: false
},
tag: 'sys-button-vue',
common_animations: {
val: '',
delay: 'delay-0s',
speed: 'slow',
repeat: 'infinite'
},
events: [
{
id: 'B3WIAOMhsX',
type: 'click',
action: 'changeAttr',
change_attr: [
{
id: 'urxZScYkBI',
target_id: '交流发电机-n3chkyZXmm',
target_attr: 'props.fill.val',
target_value: '#FF0000'
}
],
custom_code: '',
trigger_rule: {
trigger_id: '交流发电机-n3chkyZXmm',
trigger_attr: 'props.fill.val',
operator: '=',
value: '#0000FF'
}
},
{
id: '8sTLbGQJlg',
type: 'click',
action: 'changeAttr',
change_attr: [
{
id: 'mSEryeWrAq',
target_id: '交流发电机-n3chkyZXmm',
target_attr: 'props.fill.val',
target_value: '#0000FF'
}
],
custom_code: '',
trigger_rule: {
trigger_id: '交流发电机-n3chkyZXmm',
trigger_attr: 'props.fill.val',
operator: '=',
value: '#FF0000'
}
}
]
},
{
id: '交流发电机-n3chkyZXmm',
title: '交流发电机',
type: 'svg',
binfo: {
left: 320,
top: 140,
width: 50,
height: 50,
angle: 0
},
resize: true,
rotate: true,
lock: false,
active: false,
hide: false,
props: {
fill: '#FF0000'
},
tag: '交流发电机',
common_animations: {
val: '',
delay: 'delay-0s',
speed: 'slow',
repeat: 'infinite'
},
events: []
},
{
id: 'text-vue-11VSQoJxa6',
title: '文字',
type: 'vue',
binfo: {
left: 560,
top: 60,
width: 600,
height: 50,
angle: 0
},
resize: true,
rotate: true,
lock: false,
active: false,
hide: false,
props: {
text: '请先将点击右上角预览,再点击按钮查看效果',
fontFamily: '黑体',
fontSize: 18,
fill: '#FFF700',
vertical: false
},
tag: 'text-vue',
common_animations: {
val: '',
delay: 'delay-0s',
speed: 'slow',
repeat: 'infinite'
},
events: []
},
{
id: 'text-vue-eoZAkwVSHu',
title: '文字',
type: 'vue',
binfo: {
left: 964,
top: 194,
width: 341,
height: 50,
angle: 0
},
resize: true,
rotate: true,
lock: false,
active: false,
hide: false,
props: {
text: '编辑模式下选中按钮可查看事件如何配置',
fontFamily: '黑体',
fontSize: 18,
fill: '#FFF700',
vertical: false
},
tag: 'text-vue',
common_animations: {
val: '',
delay: 'delay-0s',
speed: 'slow',
repeat: 'infinite'
},
events: []
}
]
})
})
</script>
<style scoped></style>

View File

@@ -0,0 +1,259 @@
<template>
<div class="w-1/1 h-100vh">
<mt-edit ref="MtEditRef" @on-return-click="onReturnClick"></mt-edit>
</div>
</template>
<script setup lang="ts">
import { MtEdit } from '@/export'
import { onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const MtEditRef = ref<InstanceType<typeof MtEdit>>()
const onReturnClick = () => {
router.go(-1)
}
onMounted(() => {
const res = MtEditRef.value?.setImportJson({
canvasCfg: {
width: 1920,
height: 1080,
scale: 1,
color: '#000000',
img: '',
guide: true,
adsorp: true,
adsorp_diff: 3,
transform_origin: {
x: 0,
y: 0
},
drag_offset: {
x: -333,
y: -4
}
},
gridCfg: {
enabled: false,
align: true,
size: 10
},
json: [
{
id: 'text-vue-rfEqQD4y2G',
title: '文字',
type: 'vue',
binfo: {
left: 738,
top: 38,
width: 383,
height: 50,
angle: 0
},
resize: true,
rotate: true,
lock: false,
active: false,
hide: false,
props: {
text: '加载已有数据',
fontFamily: '黑体',
fontSize: 18,
fill: '#FFF700',
vertical: false
},
tag: 'text-vue',
common_animations: {
val: '',
delay: 'delay-0s',
speed: 'slow',
repeat: 'infinite'
},
events: []
},
{
id: 'sys-line-kgIM4cL60s',
title: '自由连线',
type: 'sys-line',
binfo: {
left: 501,
top: 177,
width: 711,
height: 0,
angle: 0
},
resize: false,
rotate: false,
lock: false,
active: false,
hide: false,
props: {
stroke: '#ff0000',
'stroke-width': 2,
'marker-start': false,
'marker-end': true,
point_position: [
{
x: 0,
y: 0
},
{
x: 711,
y: 0
}
],
ani_type: 'none',
ani_dur: 20,
ani_color: '#0a7ae2',
ani_reverse: false,
ani_play: true,
bind_anchors: {
start: null,
end: null
}
},
tag: 'sys-line',
common_animations: {
val: '',
delay: 'delay-0s',
speed: 'slow',
repeat: 'infinite'
},
events: []
},
{
id: 'sys-line-sfHoJjRCDO',
title: '自由连线',
type: 'sys-line',
binfo: {
left: 501,
top: 233,
width: 735,
height: 0,
angle: 0
},
resize: false,
rotate: false,
lock: false,
active: false,
hide: false,
props: {
stroke: '#ff0000',
'stroke-width': 2,
'marker-start': false,
'marker-end': false,
point_position: [
{
x: 0,
y: 0
},
{
x: 735,
y: 0
}
],
ani_type: 'electricity',
ani_dur: 20,
ani_color: '#FF0000',
ani_reverse: false,
ani_play: true,
bind_anchors: {
start: null,
end: null
}
},
tag: 'sys-line',
common_animations: {
val: '',
delay: 'delay-0s',
speed: 'slow',
repeat: 'infinite'
},
events: []
},
{
id: 'sys-line-Rr3SVNwuSU',
title: '自由连线',
type: 'sys-line',
binfo: {
left: 498,
top: 313,
width: 742,
height: 0,
angle: 0
},
resize: false,
rotate: false,
lock: false,
active: false,
hide: false,
props: {
stroke: '#FFFFFF',
'stroke-width': 10,
'marker-start': false,
'marker-end': false,
point_position: [
{
x: 0,
y: 0
},
{
x: 742,
y: 0
}
],
ani_type: 'waterdrop',
ani_dur: 20,
ani_color: '#0a7ae2',
ani_reverse: true,
ani_play: true,
bind_anchors: {
start: null,
end: null
}
},
tag: 'sys-line',
common_animations: {
val: '',
delay: 'delay-0s',
speed: 'slow',
repeat: 'infinite'
},
events: []
},
{
id: 'demo-6bmwf6LJ0M',
title: '演示svg文件',
type: 'svg',
binfo: {
left: 791,
top: 401,
width: 50,
height: 50,
angle: 0
},
resize: true,
rotate: true,
lock: false,
active: false,
hide: false,
props: {
fill: '#FF0000'
},
tag: 'demo',
common_animations: {
val: 'rotate360',
delay: 'delay-0s',
speed: 'slow',
repeat: 'infinite'
},
events: []
}
]
})
if (res) {
console.log('加载成功')
}
})
</script>
<style scoped></style>

View File

@@ -0,0 +1,126 @@
<template>
<div class="w-1/1 h-100vh">
<mt-edit ref="MtEditRef" @on-return-click="onReturnClick" @on-preview-click="onPreviewClick"></mt-edit>
</div>
</template>
<script setup lang="ts">
import type { IExportJson } from '@/components/mt-edit/components/types'
import { MtEdit } from '@/export'
import { onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const MtEditRef = ref<InstanceType<typeof MtEdit>>()
const onPreviewClick = (exportJson: IExportJson) => {
sessionStorage.setItem('exportJson', JSON.stringify(exportJson))
const routeUrl = router.resolve({
name: 'preview'
})
window.open(routeUrl.href, '_blank')
}
const onReturnClick = () => {
router.go(-1)
}
onMounted(() => {
MtEditRef.value?.setImportJson({
canvasCfg: {
width: 1920,
height: 1080,
scale: 1,
color: '#000000',
img: '',
guide: true,
adsorp: true,
adsorp_diff: 3,
transform_origin: {
x: 0,
y: 0
},
drag_offset: {
x: 0,
y: 0
}
},
gridCfg: {
enabled: false,
align: true,
size: 10
},
json: [
{
id: 'demo-nPL9aqhnSl',
title: '演示svg文件',
type: 'svg',
binfo: {
left: 650,
top: 160,
width: 50,
height: 50,
angle: 0
},
resize: true,
rotate: true,
lock: false,
active: false,
hide: false,
props: {
fill: '#FF0000'
},
tag: 'demo',
common_animations: {
val: '',
delay: 'delay-0s',
speed: 'slow',
repeat: 'infinite'
},
events: [
{
id: 'pJwJOIUIat',
type: 'click',
action: 'customCode',
change_attr: [],
custom_code: "$mtEventCallBack('test-dialog',$item_info.id)\nconsole.log(111)",
trigger_rule: {
value: null
}
}
]
},
{
id: 'text-vue-T19K6wCQZ2',
title: '文字',
type: 'vue',
binfo: {
left: 590,
top: 80,
width: 250,
height: 50,
angle: 0
},
resize: true,
rotate: true,
lock: false,
active: false,
hide: false,
props: {
text: '请点击预览查看事件触发',
fontFamily: '黑体',
fontSize: 18,
fill: '#FFF700',
vertical: false
},
tag: 'text-vue',
common_animations: {
val: '',
delay: 'delay-0s',
speed: 'slow',
repeat: 'infinite'
},
events: []
}
]
})
})
</script>
<style scoped></style>

74
src/views/demo/index.vue Normal file
View File

@@ -0,0 +1,74 @@
<template>
<div>
<el-divider>插件能力展示</el-divider>
<div class="flex flex-wrap mx-20px justify-center items-center">
<el-card
v-for="item in ability"
:key="item.title"
class="flex justify-center items-center m-10px cursor-pointer"
@click="item.onClick"
>
<img :src="item.img" class="w-300px h-300px" />
<div>{{ item.title }}</div>
</el-card>
</div>
</div>
</template>
<script lang="ts" setup>
import { ElDivider, ElCard } from 'element-plus'
import { useRouter } from 'vue-router'
const router = useRouter()
const ability = [
{
title: '基础编辑页',
img: '/imgs/edit.png',
onClick: () => {
router.push({
name: 'edit',
params: {}
})
}
},
{
title: '加载已保存数据',
img: '/imgs/edit-load.png',
onClick: () => {
router.push({
name: 'edit-load',
params: {}
})
}
},
{
title: '外部修改图形属性',
img: '/imgs/set-node-attr.gif',
onClick: () => {
router.push({
name: 'set-node-attr',
params: {}
})
}
},
{
title: '回调外部项目函数',
img: '/imgs/event-callback.png',
onClick: () => {
router.push({
name: 'event-callback',
params: {}
})
}
},
{
title: '事件-属性更改',
img: '/imgs/change-attr.png',
onClick: () => {
router.push({
name: 'change-attr',
params: {}
})
}
}
]
</script>

View File

@@ -0,0 +1,79 @@
<!-- eslint-disable vue/html-indent -->
<template>
<div>
<el-button @click="changeRed">改成红色</el-button>
<el-button @click="changeGreen">改成绿色</el-button>
<mt-preview ref="svgPreviewRef" :export-json="export_json"></mt-preview>
</div>
</template>
<script setup lang="ts">
import { MtPreview } from '@/export'
import { ElButton } from 'element-plus'
import { ref } from 'vue'
const svgPreviewRef = ref<InstanceType<typeof MtPreview>>()
const export_json = ref<any>({
canvasCfg: {
width: 1920,
height: 1080,
scale: 1,
color: '',
img: '',
guide: true,
adsorp: true,
adsorp_diff: 3,
transform_origin: {
x: 0,
y: 0
},
drag_offset: {
x: 0,
y: 0
}
},
gridCfg: {
enabled: true,
align: true,
size: 10
},
json: [
{
id: 'demo-4Y2Eq7UPBm',
title: '演示svg文件',
type: 'svg',
binfo: {
left: 510,
top: 200,
width: 50,
height: 50,
angle: 0
},
resize: true,
rotate: true,
lock: false,
active: false,
hide: false,
props: {
fill: '#FF0000'
},
tag: 'demo',
common_animations: {
val: '',
delay: 'delay-0s',
speed: 'slow',
repeat: 'infinite'
},
events: []
}
]
})
const changeRed = () => {
svgPreviewRef.value?.setItemAttrByID('demo-4Y2Eq7UPBm', 'props.fill.val', '#FF0000').then(res => {
console.log(res)
})
}
const changeGreen = () => {
svgPreviewRef.value?.setItemAttrByID('demo-4Y2Eq7UPBm', 'props.fill.val', '#00FF00').then(res => {
console.log(res)
})
}
</script>

87
src/views/edit/index.vue Normal file
View File

@@ -0,0 +1,87 @@
<script setup lang="ts">
import type { IExportJson } from '@/components/mt-edit/components/types'
import { useGenThumbnail } from '@/components/mt-edit/composables/thumbnail'
import { MtEdit } from '@/export'
import { useRouter } from 'vue-router'
import { addCanvas, audit } from '@/api/index'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useDataStore } from '@/stores/menuList'
const router = useRouter()
const useData = useDataStore()
const onPreviewClick = (exportJson: IExportJson) => {
sessionStorage.setItem('exportJson', JSON.stringify(exportJson))
const routeUrl = router.resolve({
name: 'preview'
})
window.open(routeUrl.href, '_blank')
}
const onSaveClick = (e: IExportJson) => {
console.log(e, '这是要保存的数据')
}
const onSaveAll = (data: any) => {
let params = { fileContent: '', id: useData.pid, name: useData.name }
addCanvas(data).then((res: any) => {
if (res.code == 'A0000') {
ElMessage({
message: '保存成功',
type: 'success'
})
// 获取截图参数
useGenThumbnail().then(item => {
params.fileContent = item ?? ''
audit(params).then(() => {
if (res.code == 'A0000') {
//
}
})
})
ElMessageBox.confirm('是否关闭页面?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
try {
// 尝试关闭窗口
window.close()
// 检查是否关闭成功(某些情况下窗口可能未关闭)
setTimeout(() => {
if (!window.closed) {
// 如果未成功关闭,使用替代方案
window.location.href = 'about:blank'
}
}, 1000)
} catch (error) {
// 出现异常时使用替代方案
window.location.href = 'about:blank'
}
})
.catch(() => {})
}
})
}
const onReturnClick = () => {
router.go(-1)
}
const onThumbnailClick = () => {
useGenThumbnail()
}
</script>
<template>
<div class="w-1/1 h-100vh" v-loading="useData.loading">
<mt-edit
:use-thumbnail="true"
@on-preview-click="onPreviewClick"
@on-return-click="onReturnClick"
@on-save-click="onSaveClick"
@on-thumbnail-click="onThumbnailClick"
@on-save-all="onSaveAll"
></mt-edit>
</div>
</template>
<style scoped></style>

View File

@@ -0,0 +1,19 @@
<template>
<mt-preview ref="MtPreviewRef" @on-event-call-back="onEventCallBack"></mt-preview>
</template>
<script setup lang="ts">
import { MtPreview } from '@/export'
import { onMounted, ref } from 'vue'
import { ElMessage } from 'element-plus'
const MtPreviewRef = ref<InstanceType<typeof MtPreview>>()
const onEventCallBack = (type: string, item_id: string) => {
console.log(type, item_id)
if (type == 'test-dialog') {
ElMessage.success(`获取到了id:${item_id}`)
}
}
onMounted(() => {
MtPreviewRef.value?.setImportJson(JSON.parse(sessionStorage.getItem('exportJson') as any))
})
</script>