新增批量导出导入功能
优化画图软件
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="icon" href="/favicon.ico" type="image/svg+xml" />
|
<link rel="icon" href="/favicon.ico" type="image/svg+xml" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>南京灿能web组态编辑器</title>
|
<title>南京灿能组态</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import loadSvg from '@/utils/loadSvg'
|
import { loadSvg } from '@/utils/loadSvg'
|
||||||
loadSvg()
|
loadSvg()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,23 @@ export function addElement(params: any) {
|
|||||||
data: params
|
data: params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 批量导入
|
||||||
|
export function addByZip(params: any) {
|
||||||
|
return http.request({
|
||||||
|
url: '/cs-system-boot/csElement/addByZip',
|
||||||
|
method: 'post',
|
||||||
|
data: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 下载
|
||||||
|
export function downloadByZip(params: any) {
|
||||||
|
return http.request({
|
||||||
|
url: '/cs-system-boot/csElement/downloadByZip',
|
||||||
|
method: 'post',
|
||||||
|
params,
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 删除图元
|
// 删除图元
|
||||||
export function deleteElement(params: any) {
|
export function deleteElement(params: any) {
|
||||||
|
|||||||
155
src/components/mt-edit/components/add-element/download.vue
Normal file
155
src/components/mt-edit/components/add-element/download.vue
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
<template>
|
||||||
|
<div class="add-element">
|
||||||
|
<el-dialog
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
v-model="open"
|
||||||
|
title="批量导出"
|
||||||
|
width="500px"
|
||||||
|
destroy-on-close
|
||||||
|
@close="closeDialog"
|
||||||
|
>
|
||||||
|
<el-form :model="element" ref="ruleFormRef" :rules="rules" label-width="120px">
|
||||||
|
<el-form-item label="下载分类:" prop="name">
|
||||||
|
<el-select v-model="element.name" placeholder="请选择下载分类" style="width: 100%">
|
||||||
|
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div class="mt-10px flex justify-end">
|
||||||
|
<el-button @click="closeDialog">取消</el-button>
|
||||||
|
<el-button @click="addNewComponent(ruleFormRef)" type="primary">导出</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { getCurrentInstance, onMounted, ref, watch, reactive } from 'vue'
|
||||||
|
import { ElInput, ElFormItem, ElForm, ElDialog, ElUpload, ElMessage, ElButton, ElSelect, ElOption } from 'element-plus'
|
||||||
|
import type { CheckboxValueType } from 'element-plus'
|
||||||
|
import type { UploadInstance, UploadProps, FormInstance, FormRules, UploadFile, UploadUserFile } from 'element-plus'
|
||||||
|
import { downloadByZip, download } from '@/api/index'
|
||||||
|
import { leftAsideStore } from '@/export'
|
||||||
|
import { getSvg } from '@/utils/loadSvg'
|
||||||
|
const instance = getCurrentInstance() // 获取当前组件实例
|
||||||
|
|
||||||
|
const open = ref(false)
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
show: Boolean,
|
||||||
|
checked_keys: Array
|
||||||
|
})
|
||||||
|
|
||||||
|
const element: any = ref({
|
||||||
|
elementCode: '', //组件编码
|
||||||
|
elementForm: '', // 图元状态
|
||||||
|
elementMark: '', //组件标识
|
||||||
|
elementName: '', //图元名称
|
||||||
|
name: '', //组件子类型 图元分类
|
||||||
|
elementType: '', //组件分类
|
||||||
|
multipartFile: '' // 图元文件
|
||||||
|
})
|
||||||
|
|
||||||
|
interface RuleForm {
|
||||||
|
elementCode: string
|
||||||
|
elementForm: string
|
||||||
|
elementMark: string
|
||||||
|
elementName: string
|
||||||
|
name: string
|
||||||
|
elementType: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const options: any = ref([])
|
||||||
|
const isAdding = ref(false)
|
||||||
|
const value = ref<CheckboxValueType[]>([])
|
||||||
|
const optionName = ref('')
|
||||||
|
const fileList = ref<UploadFile[]>([]) // 上传文件列表
|
||||||
|
const dialogImageUrl = ref('')
|
||||||
|
const dialogVisible = ref(false) // 上传图片预览
|
||||||
|
|
||||||
|
const ruleFormRef = ref<FormInstance>()
|
||||||
|
const rules = reactive<FormRules<RuleForm>>({
|
||||||
|
name: [{ required: true, message: '请选择需要下载的分类', trigger: 'change' }]
|
||||||
|
})
|
||||||
|
onMounted(() => {})
|
||||||
|
|
||||||
|
const setOptions = () => {
|
||||||
|
let list = JSON.parse(JSON.stringify(props.checked_keys))
|
||||||
|
|
||||||
|
const uniqueArray = [...new Set(list)]
|
||||||
|
|
||||||
|
// 步骤2:定义需要删除的元素列表
|
||||||
|
const removeItems = ['基础图元', '数据绑定图元']
|
||||||
|
|
||||||
|
// 步骤3:过滤掉需要删除的元素
|
||||||
|
const finalArray = uniqueArray.filter(item => !removeItems.includes(item))
|
||||||
|
options.value = finalArray.map(item => ({
|
||||||
|
value: item,
|
||||||
|
label: item
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
open.value = false
|
||||||
|
if (instance) {
|
||||||
|
const emit = instance.emit
|
||||||
|
emit('update:show', false) // 向父组件发送更新后的状态
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.show,
|
||||||
|
val => {
|
||||||
|
if (val === true) {
|
||||||
|
setOptions()
|
||||||
|
open.value = true
|
||||||
|
element.value = {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 新增保存
|
||||||
|
|
||||||
|
const addNewComponent = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return
|
||||||
|
await formEl.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
downloadByZip({
|
||||||
|
name: element.value.name
|
||||||
|
}).then((res: any) => {
|
||||||
|
console.log('🚀 ~ addNewComponent ~ res:', res)
|
||||||
|
downloadBlobFile(res, element.value.name + '.zip')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用Blob下载工具函数(核心复用)
|
||||||
|
* @param {Blob} blob 二进制文件流对象
|
||||||
|
* @param {String} fileName 下载后的文件名(必须带.zip后缀)
|
||||||
|
*/
|
||||||
|
function downloadBlobFile(blob: any, fileName: string) {
|
||||||
|
// 1. 创建文件下载的临时URL
|
||||||
|
const url = window.URL.createObjectURL(blob)
|
||||||
|
// 2. 创建a标签(隐藏的,用于触发下载)
|
||||||
|
const aLink = document.createElement('a')
|
||||||
|
aLink.style.display = 'none'
|
||||||
|
aLink.href = url
|
||||||
|
// 3. 设置下载文件名
|
||||||
|
aLink.download = fileName
|
||||||
|
// 4. 把a标签插入到页面,触发点击事件
|
||||||
|
document.body.appendChild(aLink)
|
||||||
|
aLink.click()
|
||||||
|
// 5. ✅ 关键优化:释放临时URL,防止内存泄漏
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
// 6. 移除a标签,清理DOM
|
||||||
|
document.body.removeChild(aLink)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.option-input {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
273
src/components/mt-edit/components/add-element/importZip.vue
Normal file
273
src/components/mt-edit/components/add-element/importZip.vue
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
<template>
|
||||||
|
<div class="add-element">
|
||||||
|
<el-dialog
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
v-model="open"
|
||||||
|
title="批量导入"
|
||||||
|
width="500px"
|
||||||
|
destroy-on-close
|
||||||
|
@close="closeDialog"
|
||||||
|
>
|
||||||
|
<el-form :model="element" ref="ruleFormRef" :rules="rules" label-width="120px">
|
||||||
|
<el-form-item label="图元分类:" prop="elementSonType">
|
||||||
|
<el-select v-model="element.elementSonType" placeholder="请选择图元分类" style="width: 100%">
|
||||||
|
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
|
<template #footer>
|
||||||
|
<el-button v-if="!isAdding" text bg size="small" type="primary" @click="onAddOption">
|
||||||
|
新增分类
|
||||||
|
</el-button>
|
||||||
|
<template v-else>
|
||||||
|
<el-input
|
||||||
|
v-model="optionName"
|
||||||
|
class="option-input"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入分类名称"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
<el-button type="primary" size="small" @click="onConfirm">保存</el-button>
|
||||||
|
<el-button size="small" @click="clear">取消</el-button>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="上传zip文件:">
|
||||||
|
<el-upload
|
||||||
|
ref="upload"
|
||||||
|
v-model="fileList"
|
||||||
|
style="width: 415px"
|
||||||
|
action="#"
|
||||||
|
multiple
|
||||||
|
accept=".zip"
|
||||||
|
:http-request="UploadSvg"
|
||||||
|
:on-remove="handleRemove"
|
||||||
|
:before-upload="beforeAvatarUpload"
|
||||||
|
:limit="1"
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
>
|
||||||
|
<el-button type="primary">上传</el-button>
|
||||||
|
</el-upload>
|
||||||
|
<el-dialog :close-on-click-modal="false" v-model="dialogVisible">
|
||||||
|
<img w-full :src="dialogImageUrl" alt="Preview Image" />
|
||||||
|
</el-dialog>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div class="mt-10px flex justify-end">
|
||||||
|
<el-button @click="closeDialog">取消</el-button>
|
||||||
|
<el-button @click="addNewComponent(ruleFormRef)" type="primary">保存</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { getCurrentInstance, onMounted, ref, watch, reactive } from 'vue'
|
||||||
|
import { ElInput, ElFormItem, ElForm, ElDialog, ElUpload, ElMessage, ElButton, ElSelect, ElOption } from 'element-plus'
|
||||||
|
import type { CheckboxValueType } from 'element-plus'
|
||||||
|
import type { UploadInstance, UploadProps, FormInstance, FormRules, UploadFile, UploadUserFile } from 'element-plus'
|
||||||
|
import { addByZip, download } from '@/api/index'
|
||||||
|
import { leftAsideStore } from '@/export'
|
||||||
|
import { getSvg } from '@/utils/loadSvg'
|
||||||
|
const instance = getCurrentInstance() // 获取当前组件实例
|
||||||
|
|
||||||
|
const open = ref(false)
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
show: Boolean,
|
||||||
|
checked_keys: Array
|
||||||
|
})
|
||||||
|
|
||||||
|
const element: any = ref({
|
||||||
|
elementCode: '', //组件编码
|
||||||
|
elementForm: '', // 图元状态
|
||||||
|
elementMark: '', //组件标识
|
||||||
|
elementName: '', //图元名称
|
||||||
|
elementSonType: '', //组件子类型 图元分类
|
||||||
|
elementType: '', //组件分类
|
||||||
|
multipartFile: '' // 图元文件
|
||||||
|
})
|
||||||
|
|
||||||
|
interface RuleForm {
|
||||||
|
elementCode: string
|
||||||
|
elementForm: string
|
||||||
|
elementMark: string
|
||||||
|
elementName: string
|
||||||
|
elementSonType: string
|
||||||
|
elementType: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const options: any = ref([])
|
||||||
|
const isAdding = ref(false)
|
||||||
|
const value = ref<CheckboxValueType[]>([])
|
||||||
|
const optionName = ref('')
|
||||||
|
const fileList = ref<UploadFile[]>([]) // 上传文件列表
|
||||||
|
const dialogImageUrl = ref('')
|
||||||
|
const dialogVisible = ref(false) // 上传图片预览
|
||||||
|
|
||||||
|
const handleRemove = (file: UploadFile) => {
|
||||||
|
fileList.value = []
|
||||||
|
}
|
||||||
|
// 文件校验
|
||||||
|
const beforeAvatarUpload: UploadProps['beforeUpload'] = rawFile => {
|
||||||
|
if (!rawFile.name.includes('.zip')) {
|
||||||
|
ElMessage.error('只能上传zip格式文件!')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
const handleExceed: UploadProps['onExceed'] = files => {
|
||||||
|
return ElMessage.error('只能上传1个zip文件!')
|
||||||
|
}
|
||||||
|
// 上传svg
|
||||||
|
// const UploadSvg = (params:any) => {
|
||||||
|
// fileList.value.push(params.file);
|
||||||
|
// };
|
||||||
|
|
||||||
|
const UploadSvg = (params: any) => {
|
||||||
|
return new Promise<void>(resolve => {
|
||||||
|
fileList.value.push(params.file)
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const ruleFormRef = ref<FormInstance>()
|
||||||
|
const rules = reactive<FormRules<RuleForm>>({
|
||||||
|
elementCode: [{ required: true, message: '请输入组件编码', trigger: 'blur' }],
|
||||||
|
elementForm: [{ required: true, message: '请选择图元状态', trigger: 'change' }],
|
||||||
|
elementMark: [{ required: true, message: '请输入组件标识', trigger: 'blur' }],
|
||||||
|
elementName: [{ required: true, message: '请输入图元名称', trigger: 'blur' }],
|
||||||
|
elementSonType: [{ required: true, message: '请选择父类型', trigger: 'change' }],
|
||||||
|
elementType: [{ required: true, message: '请选择组件分类', trigger: 'change' }]
|
||||||
|
})
|
||||||
|
onMounted(() => {})
|
||||||
|
|
||||||
|
const setOptions = () => {
|
||||||
|
let list = JSON.parse(JSON.stringify(props.checked_keys))
|
||||||
|
|
||||||
|
list.push('特殊图元')
|
||||||
|
const uniqueArray = [...new Set(list)]
|
||||||
|
|
||||||
|
// 步骤2:定义需要删除的元素列表
|
||||||
|
const removeItems = ['基础图元', '数据绑定图元']
|
||||||
|
|
||||||
|
// 步骤3:过滤掉需要删除的元素
|
||||||
|
const finalArray = uniqueArray.filter(item => !removeItems.includes(item))
|
||||||
|
options.value = finalArray.map(item => ({
|
||||||
|
value: item,
|
||||||
|
label: item
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
const onAddOption = () => {
|
||||||
|
isAdding.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const onConfirm = () => {
|
||||||
|
if (optionName.value) {
|
||||||
|
options.value.push({
|
||||||
|
label: optionName.value,
|
||||||
|
value: optionName.value
|
||||||
|
})
|
||||||
|
clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
open.value = false
|
||||||
|
if (instance) {
|
||||||
|
const emit = instance.emit
|
||||||
|
emit('update:show', false) // 向父组件发送更新后的状态
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.show,
|
||||||
|
val => {
|
||||||
|
if (val === true) {
|
||||||
|
setOptions()
|
||||||
|
open.value = true
|
||||||
|
element.value = {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const clear = () => {
|
||||||
|
optionName.value = ''
|
||||||
|
isAdding.value = false
|
||||||
|
}
|
||||||
|
// 新增保存
|
||||||
|
|
||||||
|
const addNewComponent = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return
|
||||||
|
await formEl.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
if (fileList.value.length == 0) {
|
||||||
|
ElMessage({
|
||||||
|
message: '请上传zip文件!',
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
return Promise.resolve() // 显式返回 Promise<void>
|
||||||
|
}
|
||||||
|
let form = new FormData()
|
||||||
|
|
||||||
|
form.append('elementCode', element.value.elementName)
|
||||||
|
form.append('elementForm', '普通图元')
|
||||||
|
form.append('elementMark', element.value.elementName)
|
||||||
|
form.append('elementName', element.value.elementName)
|
||||||
|
form.append('elementSonType', element.value.elementSonType)
|
||||||
|
form.append('elementType', 'zip文件')
|
||||||
|
form.append('zipFile', fileList.value[0])
|
||||||
|
|
||||||
|
addByZip(form).then((res: any) => {
|
||||||
|
if (res.code == 'A0000') {
|
||||||
|
ElMessage({
|
||||||
|
message: '新增成功',
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
closeDialog()
|
||||||
|
if (!props.checked_keys?.includes(element.value.elementSonType)) {
|
||||||
|
leftAsideStore.registerConfig(element.value.elementSonType, [])
|
||||||
|
}
|
||||||
|
ElMessage.info(`加载图元中,请稍等!`)
|
||||||
|
getSvg()
|
||||||
|
// setTimeout(() => {
|
||||||
|
// // 左侧列表渲染新增的图元
|
||||||
|
// download({ filePath: res.data.path }).then((Svg: any) => {
|
||||||
|
// // 动态添加svg
|
||||||
|
// leftAsideStore.svgPush(res.data.elementSonType, [
|
||||||
|
// {
|
||||||
|
// id: res.data.id,
|
||||||
|
// title: res.data.elementName,
|
||||||
|
// type: 'svg',
|
||||||
|
// thumbnail:
|
||||||
|
// 'data:image/svg+xml;utf8,' +
|
||||||
|
// encodeURIComponent(Svg.replace(/(\sfill=(["']))[^"']*(\2)/g, '$1#000000$3')),
|
||||||
|
// svg: Svg.replace(/\sfill=(["'])[^"']*\1/g, ''),
|
||||||
|
// props: {
|
||||||
|
// fill: {
|
||||||
|
// type: 'color',
|
||||||
|
// val: '#FF0000',
|
||||||
|
// title: '填充色'
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ])
|
||||||
|
// })
|
||||||
|
// }, 100)
|
||||||
|
} else {
|
||||||
|
ElMessage({
|
||||||
|
message: res.message,
|
||||||
|
type: 'info'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return Promise.resolve() // 确保所有分支都返回 Promise<void>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.option-input {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -12,6 +12,22 @@
|
|||||||
<el-form-item label="图元分类:" prop="elementSonType">
|
<el-form-item label="图元分类:" prop="elementSonType">
|
||||||
<el-select v-model="element.elementSonType" placeholder="请选择图元分类" style="width: 100%">
|
<el-select v-model="element.elementSonType" placeholder="请选择图元分类" style="width: 100%">
|
||||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
|
<template #footer>
|
||||||
|
<el-button v-if="!isAdding" text bg size="small" type="primary" @click="onAddOption">
|
||||||
|
新增分类
|
||||||
|
</el-button>
|
||||||
|
<template v-else>
|
||||||
|
<el-input
|
||||||
|
v-model="optionName"
|
||||||
|
class="option-input"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入分类名称"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
<el-button type="primary" size="small" @click="onConfirm">保存</el-button>
|
||||||
|
<el-button size="small" @click="clear">取消</el-button>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- <el-form-item label="组件子类型:" prop="elementSonType">
|
<!-- <el-form-item label="组件子类型:" prop="elementSonType">
|
||||||
@@ -111,28 +127,31 @@
|
|||||||
<img w-full :src="dialogImageUrl" alt="Preview Image" />
|
<img w-full :src="dialogImageUrl" alt="Preview Image" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
|
||||||
<el-button @click="addNewComponent(ruleFormRef)" type="primary">保存</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
|
<div class="mt-10px flex justify-end">
|
||||||
|
<el-button @click="closeDialog">取消</el-button>
|
||||||
|
<el-button @click="addNewComponent(ruleFormRef)" type="primary">保存</el-button>
|
||||||
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineProps, getCurrentInstance, onMounted, ref, watch, reactive } from 'vue'
|
import { getCurrentInstance, onMounted, ref, watch, reactive } from 'vue'
|
||||||
import { ElInput, ElFormItem, ElForm, ElDialog, ElUpload, ElMessage, ElButton, ElSelect, ElOption } from 'element-plus'
|
import { ElInput, ElFormItem, ElForm, ElDialog, ElUpload, ElMessage, ElButton, ElSelect, ElOption } from 'element-plus'
|
||||||
|
import type { CheckboxValueType } from 'element-plus'
|
||||||
import type { UploadInstance, UploadProps, FormInstance, FormRules, UploadFile, UploadUserFile } from 'element-plus'
|
import type { UploadInstance, UploadProps, FormInstance, FormRules, UploadFile, UploadUserFile } from 'element-plus'
|
||||||
|
|
||||||
import { addElement, download } from '@/api/index'
|
import { addElement, download } from '@/api/index'
|
||||||
import { leftAsideStore } from '@/export'
|
import { leftAsideStore } from '@/export'
|
||||||
|
import { getSvg } from '@/utils/loadSvg'
|
||||||
const instance = getCurrentInstance() // 获取当前组件实例
|
const instance = getCurrentInstance() // 获取当前组件实例
|
||||||
|
|
||||||
const open = ref(false)
|
const open = ref(false)
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
show: Boolean
|
show: Boolean,
|
||||||
|
checked_keys: Array
|
||||||
})
|
})
|
||||||
|
|
||||||
const element: any = ref({
|
const element: any = ref({
|
||||||
@@ -154,21 +173,10 @@ interface RuleForm {
|
|||||||
elementType: string
|
elementType: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = [
|
const options: any = ref([])
|
||||||
{
|
const isAdding = ref(false)
|
||||||
value: '电力基础图元',
|
const value = ref<CheckboxValueType[]>([])
|
||||||
label: '电力基础图元'
|
const optionName = ref('')
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '自定义',
|
|
||||||
label: '自定义'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '特殊图元',
|
|
||||||
label: '特殊图元'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const fileList = ref<UploadFile[]>([]) // 上传文件列表
|
const fileList = ref<UploadFile[]>([]) // 上传文件列表
|
||||||
const dialogImageUrl = ref('')
|
const dialogImageUrl = ref('')
|
||||||
const dialogVisible = ref(false) // 上传图片预览
|
const dialogVisible = ref(false) // 上传图片预览
|
||||||
@@ -213,6 +221,36 @@ const rules = reactive<FormRules<RuleForm>>({
|
|||||||
elementSonType: [{ required: true, message: '请选择父类型', trigger: 'change' }],
|
elementSonType: [{ required: true, message: '请选择父类型', trigger: 'change' }],
|
||||||
elementType: [{ required: true, message: '请选择组件分类', trigger: 'change' }]
|
elementType: [{ required: true, message: '请选择组件分类', trigger: 'change' }]
|
||||||
})
|
})
|
||||||
|
onMounted(() => {})
|
||||||
|
const setOptions = () => {
|
||||||
|
let list = JSON.parse(JSON.stringify(props.checked_keys))
|
||||||
|
|
||||||
|
list.push('特殊图元')
|
||||||
|
const uniqueArray = [...new Set(list)]
|
||||||
|
|
||||||
|
// 步骤2:定义需要删除的元素列表
|
||||||
|
const removeItems = ['基础图元', '数据绑定图元']
|
||||||
|
|
||||||
|
// 步骤3:过滤掉需要删除的元素
|
||||||
|
const finalArray = uniqueArray.filter(item => !removeItems.includes(item))
|
||||||
|
options.value = finalArray.map(item => ({
|
||||||
|
value: item,
|
||||||
|
label: item
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
const onAddOption = () => {
|
||||||
|
isAdding.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const onConfirm = () => {
|
||||||
|
if (optionName.value) {
|
||||||
|
options.value.push({
|
||||||
|
label: optionName.value,
|
||||||
|
value: optionName.value
|
||||||
|
})
|
||||||
|
clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const closeDialog = () => {
|
const closeDialog = () => {
|
||||||
open.value = false
|
open.value = false
|
||||||
@@ -226,12 +264,17 @@ watch(
|
|||||||
() => props.show,
|
() => props.show,
|
||||||
val => {
|
val => {
|
||||||
if (val === true) {
|
if (val === true) {
|
||||||
|
setOptions()
|
||||||
open.value = true
|
open.value = true
|
||||||
element.value = {}
|
element.value = {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const clear = () => {
|
||||||
|
optionName.value = ''
|
||||||
|
isAdding.value = false
|
||||||
|
}
|
||||||
// 新增保存
|
// 新增保存
|
||||||
|
|
||||||
const addNewComponent = async (formEl: FormInstance | undefined) => {
|
const addNewComponent = async (formEl: FormInstance | undefined) => {
|
||||||
@@ -262,28 +305,35 @@ const addNewComponent = async (formEl: FormInstance | undefined) => {
|
|||||||
type: 'success'
|
type: 'success'
|
||||||
})
|
})
|
||||||
closeDialog()
|
closeDialog()
|
||||||
// 左侧列表渲染新增的图元
|
if (!props.checked_keys?.includes(element.value.elementSonType)) {
|
||||||
download({ filePath: res.data.path }).then((Svg: any) => {
|
leftAsideStore.registerConfig(element.value.elementSonType, [])
|
||||||
// 动态添加svg
|
}
|
||||||
leftAsideStore.svgPush(res.data.elementSonType, [
|
ElMessage.info(`加载图元中,请稍等!`)
|
||||||
{
|
getSvg()
|
||||||
id: res.data.id,
|
// setTimeout(() => {
|
||||||
title: res.data.elementName,
|
// // 左侧列表渲染新增的图元
|
||||||
type: 'svg',
|
// download({ filePath: res.data.path }).then((Svg: any) => {
|
||||||
thumbnail:
|
// // 动态添加svg
|
||||||
'data:image/svg+xml;utf8,' +
|
// leftAsideStore.svgPush(res.data.elementSonType, [
|
||||||
encodeURIComponent(Svg.replace(/(\sfill=(["']))[^"']*(\2)/g, '$1#000000$3')),
|
// {
|
||||||
svg: Svg.replace(/\sfill=(["'])[^"']*\1/g, ''),
|
// id: res.data.id,
|
||||||
props: {
|
// title: res.data.elementName,
|
||||||
fill: {
|
// type: 'svg',
|
||||||
type: 'color',
|
// thumbnail:
|
||||||
val: '#FF0000',
|
// 'data:image/svg+xml;utf8,' +
|
||||||
title: '填充色'
|
// encodeURIComponent(Svg.replace(/(\sfill=(["']))[^"']*(\2)/g, '$1#000000$3')),
|
||||||
}
|
// svg: Svg.replace(/\sfill=(["'])[^"']*\1/g, ''),
|
||||||
}
|
// props: {
|
||||||
}
|
// fill: {
|
||||||
])
|
// type: 'color',
|
||||||
})
|
// val: '#FF0000',
|
||||||
|
// title: '填充色'
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ])
|
||||||
|
// })
|
||||||
|
// }, 100)
|
||||||
} else {
|
} else {
|
||||||
ElMessage({
|
ElMessage({
|
||||||
message: res.message,
|
message: res.message,
|
||||||
@@ -296,3 +346,9 @@ const addNewComponent = async (formEl: FormInstance | undefined) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style>
|
||||||
|
.option-input {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
<div class="h-[calc(10%-1px)] flex justify-center items-center ct-border" style="padding-top: 10px">
|
<div class="h-[calc(10%-1px)] flex justify-center items-center ct-border" style="padding-top: 10px">
|
||||||
<el-button class="w-80/100" @click="onManageClick">管理</el-button>
|
<el-button class="w-80/100" :icon="Tools" @click="onManageClick">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@@ -100,8 +100,6 @@
|
|||||||
>
|
>
|
||||||
<el-button type="primary">本地上传</el-button>
|
<el-button type="primary">本地上传</el-button>
|
||||||
</el-upload> -->
|
</el-upload> -->
|
||||||
<el-button type="primary" @click="checkClick()">新增图元</el-button>
|
|
||||||
<add-element :show="openCheck" @update:show="updateOpenCheck"></add-element>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -129,7 +127,8 @@
|
|||||||
v-if="
|
v-if="
|
||||||
selected_node_key !== '数据绑定图元' &&
|
selected_node_key !== '数据绑定图元' &&
|
||||||
selected_node_key !== '基础图元' &&
|
selected_node_key !== '基础图元' &&
|
||||||
show_del_local_file == item.id
|
show_del_local_file == item.id &&
|
||||||
|
hasAdmin
|
||||||
"
|
"
|
||||||
class="absolute w-160px h-160px left-0 top-0 opacity-80 bg-light-300 flex justify-center items-center"
|
class="absolute w-160px h-160px left-0 top-0 opacity-80 bg-light-300 flex justify-center items-center"
|
||||||
>
|
>
|
||||||
@@ -141,7 +140,18 @@
|
|||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="mt10">
|
||||||
|
<el-button type="primary" :icon="Plus" @click="checkClick()">新增图元</el-button>
|
||||||
|
<el-button type="primary" :icon="Upload" @click="zipCheck()">批量导入</el-button>
|
||||||
|
<el-button type="primary" :icon="Download" @click="downloadCheck()">批量导出</el-button>
|
||||||
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<!-- 新增图元 -->
|
||||||
|
<add-element :show="openCheck" :checked_keys="checked_keys" @update:show="updateOpenCheck"></add-element>
|
||||||
|
<!-- 批量导入图元 -->
|
||||||
|
<importZip :show="zipOpen" :checked_keys="checked_keys" @update:show="updateZip"></importZip>
|
||||||
|
<!-- 下载图元 -->
|
||||||
|
<download :show="downloadOpen" :checked_keys="checked_keys" @update:show="updateDown"></download>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -165,6 +175,7 @@ import {
|
|||||||
ElMessage,
|
ElMessage,
|
||||||
type UploadFile
|
type UploadFile
|
||||||
} from 'element-plus'
|
} from 'element-plus'
|
||||||
|
import { Plus, Tools, Upload, Download } from '@element-plus/icons-vue'
|
||||||
import SvgAnalysis from '@/components/mt-edit/components/svg-analysis/index.vue'
|
import SvgAnalysis from '@/components/mt-edit/components/svg-analysis/index.vue'
|
||||||
import { useDark, useLocalStorage } from '@vueuse/core'
|
import { useDark, useLocalStorage } from '@vueuse/core'
|
||||||
import type {
|
import type {
|
||||||
@@ -175,6 +186,8 @@ import type {
|
|||||||
import { globalStore } from '@/components/mt-edit/store/global'
|
import { globalStore } from '@/components/mt-edit/store/global'
|
||||||
import { blobToBase64 } from '@/components/mt-edit/utils'
|
import { blobToBase64 } from '@/components/mt-edit/utils'
|
||||||
import AddElement from '@/components/mt-edit/components/add-element/index.vue'
|
import AddElement from '@/components/mt-edit/components/add-element/index.vue'
|
||||||
|
import importZip from '@/components/mt-edit/components/add-element/importZip.vue'
|
||||||
|
import download from '@/components/mt-edit/components/add-element/download.vue'
|
||||||
import { deleteElement } from '@/api/index'
|
import { deleteElement } from '@/api/index'
|
||||||
import { leftAsideStore } from '@/export'
|
import { leftAsideStore } from '@/export'
|
||||||
import { useDataStore } from '@/stores/menuList'
|
import { useDataStore } from '@/stores/menuList'
|
||||||
@@ -188,6 +201,11 @@ const leftAsideProps = withDefaults(defineProps<LeftAsideProps>(), {
|
|||||||
const isDark = useDark({
|
const isDark = useDark({
|
||||||
selector: '#mt-edit'
|
selector: '#mt-edit'
|
||||||
})
|
})
|
||||||
|
const adminInfo: any = window.localStorage.getItem('adminInfo')
|
||||||
|
const hasAdmin =
|
||||||
|
JSON.parse(adminInfo)?.roleCode.some(item => item.includes('operation_manager') || item.includes('root')) ||
|
||||||
|
JSON.parse(adminInfo)?.userType == 1
|
||||||
|
|
||||||
const uploadRef = ref()
|
const uploadRef = ref()
|
||||||
// 从本地储存中查被禁用的类别
|
// 从本地储存中查被禁用的类别
|
||||||
const disable_classify = useLocalStorage<string[]>('mt-disable-classify', [])
|
const disable_classify = useLocalStorage<string[]>('mt-disable-classify', [])
|
||||||
@@ -282,6 +300,10 @@ const onDragStart = (config_item_key: string, item_id: string) => {
|
|||||||
}
|
}
|
||||||
const onManageClick = () => {
|
const onManageClick = () => {
|
||||||
manage_dialog_visiable.value = true
|
manage_dialog_visiable.value = true
|
||||||
|
setTimeout(() => {
|
||||||
|
treeRef.value?.setCurrentKey(classify_list.value[0])
|
||||||
|
onNodeClick(classify_list.value[0])
|
||||||
|
}, 100)
|
||||||
}
|
}
|
||||||
const handleCheckChange = (data: { label: string }, checked: boolean, indeterminate: boolean) => {
|
const handleCheckChange = (data: { label: string }, checked: boolean, indeterminate: boolean) => {
|
||||||
if (checked && !checked_keys.value.includes(data.label)) {
|
if (checked && !checked_keys.value.includes(data.label)) {
|
||||||
@@ -369,14 +391,28 @@ function onDelLocalFile(item: ILeftAsideConfigItem) {
|
|||||||
|
|
||||||
// 新增图元
|
// 新增图元
|
||||||
const openCheck = ref(false)
|
const openCheck = ref(false)
|
||||||
|
const zipOpen = ref(false)
|
||||||
|
const downloadOpen = ref(false)
|
||||||
//打开弹窗按钮
|
//打开弹窗按钮
|
||||||
function checkClick() {
|
function checkClick() {
|
||||||
openCheck.value = true
|
openCheck.value = true
|
||||||
}
|
}
|
||||||
|
function zipCheck() {
|
||||||
|
zipOpen.value = true
|
||||||
|
}
|
||||||
|
function downloadCheck() {
|
||||||
|
downloadOpen.value = true
|
||||||
|
}
|
||||||
//接收到子页面关闭弹窗的事件,改变openCheck的值,否则在刷新页面之前openCheck会一直是true,导致无法第二次打开弹窗
|
//接收到子页面关闭弹窗的事件,改变openCheck的值,否则在刷新页面之前openCheck会一直是true,导致无法第二次打开弹窗
|
||||||
const updateOpenCheck = (value: boolean) => {
|
const updateOpenCheck = (value: boolean) => {
|
||||||
openCheck.value = value
|
openCheck.value = value
|
||||||
}
|
}
|
||||||
|
const updateZip = (value: boolean) => {
|
||||||
|
zipOpen.value = value
|
||||||
|
}
|
||||||
|
const updateDown = (value: boolean) => {
|
||||||
|
downloadOpen.value = value
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
#mt-left-aside .el-collapse-item__header,
|
#mt-left-aside .el-collapse-item__header,
|
||||||
|
|||||||
@@ -267,8 +267,13 @@ const fetchData = async () => {
|
|||||||
try {
|
try {
|
||||||
const response = await lineTree({})
|
const response = await lineTree({})
|
||||||
treeData.value = buildLevel3Tree(response.data) // 转换数据格式并赋值给 transformedData
|
treeData.value = buildLevel3Tree(response.data) // 转换数据格式并赋值给 transformedData
|
||||||
|
if (useData.treeIndexs.length > 0) {
|
||||||
|
treeIndexs.value = useData.treeIndexs
|
||||||
|
return
|
||||||
|
}
|
||||||
if (useData.graphicDisplay == 'ypt') {
|
if (useData.graphicDisplay == 'ypt') {
|
||||||
const res = await eleEpdChooseTree_ypt()
|
const res = await eleEpdChooseTree_ypt()
|
||||||
|
useData.settreeIndexs(res.data)
|
||||||
treeIndexs.value = res.data // 转换数据格式并赋值给 transformedData
|
treeIndexs.value = res.data // 转换数据格式并赋值给 transformedData
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -301,10 +306,10 @@ const indexList = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const response = await targetList({ lineId: lineId })
|
// const response = await targetList({ lineId: lineId })
|
||||||
if (response.data) {
|
// if (response.data) {
|
||||||
treeIndexs.value = response.data // 转换数据格式并赋值给 transformedData
|
// treeIndexs.value = response.data // 转换数据格式并赋值给 transformedData
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching data:', error)
|
console.error('Error fetching data:', error)
|
||||||
@@ -375,6 +380,11 @@ const handleSelectUID = (uid: []) => {
|
|||||||
} else {
|
} else {
|
||||||
selectItemSettingProps.itemJson.UIDNames = [name.join(' / ')]
|
selectItemSettingProps.itemJson.UIDNames = [name.join(' / ')]
|
||||||
}
|
}
|
||||||
|
// 单个指标绑定
|
||||||
|
if (item_title.value == '绑定指标') {
|
||||||
|
console.log(123)
|
||||||
|
selectItemSettingProps.itemJson.UIDType = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取选中的数据名称
|
// 获取选中的数据名称
|
||||||
@@ -386,10 +396,13 @@ const handleSelectUID = (uid: []) => {
|
|||||||
.getCheckedNodes()
|
.getCheckedNodes()
|
||||||
.map((item: any) => item.data.unit)
|
.map((item: any) => item.data.unit)
|
||||||
.filter((text: string) => text !== '' && text !== null && text !== undefined)
|
.filter((text: string) => text !== '' && text !== null && text !== undefined)
|
||||||
|
console.log(123)
|
||||||
|
|
||||||
if (is2DArray(uid)) {
|
if (is2DArray(uid)) {
|
||||||
if (selectItemSettingProps.itemJson) {
|
if (selectItemSettingProps.itemJson) {
|
||||||
selectItemSettingProps.itemJson.UIDNames = nameList
|
selectItemSettingProps.itemJson.UIDNames = nameList
|
||||||
selectItemSettingProps.itemJson.unit = unitList
|
selectItemSettingProps.itemJson.unit = unitList
|
||||||
|
|
||||||
indexString.value = selectItemSettingProps.itemJson.UIDNames
|
indexString.value = selectItemSettingProps.itemJson.UIDNames
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -397,14 +410,28 @@ const handleSelectUID = (uid: []) => {
|
|||||||
// 配置里面的输入框内容更新
|
// 配置里面的输入框内容更新
|
||||||
if (selectItemSettingProps.itemJson && selectItemSettingProps.itemJson.props) {
|
if (selectItemSettingProps.itemJson && selectItemSettingProps.itemJson.props) {
|
||||||
if (selectItemSettingProps.itemJson?.props.text.type == 'input') {
|
if (selectItemSettingProps.itemJson?.props.text.type == 'input') {
|
||||||
|
selectItemSettingProps.itemJson.unit = unitList
|
||||||
// selectItemSettingProps.itemJson.props.text.val = name.join(' / ')
|
// selectItemSettingProps.itemJson.props.text.val = name.join(' / ')
|
||||||
let names = name.reverse()
|
let names = name.reverse()
|
||||||
let str = ''
|
let str = ''
|
||||||
|
let key =
|
||||||
|
names[0] == 'max'
|
||||||
|
? '最大值'
|
||||||
|
: names[0] == 'min'
|
||||||
|
? '最小值'
|
||||||
|
: names[0] == 'avg'
|
||||||
|
? '平均值'
|
||||||
|
: names[0] == 'cp95'
|
||||||
|
? 'CP95值'
|
||||||
|
: names[0]
|
||||||
if (names[1] == '无相别') {
|
if (names[1] == '无相别') {
|
||||||
name[1] = ''
|
name[1] = ''
|
||||||
str = names[2] + '-' + names[0] + ':###'
|
str = names[2] + '-' + key + ':###'
|
||||||
} else {
|
} else {
|
||||||
str = names[1] + '相' + names[2] + '-' + names[0] + ':###'
|
str =
|
||||||
|
names.length == 2
|
||||||
|
? names[1] + '-' + key + ':###'
|
||||||
|
: names[1] + '相' + names[2] + '-' + key + ':###'
|
||||||
}
|
}
|
||||||
selectItemSettingProps.itemJson.props.text.val = str
|
selectItemSettingProps.itemJson.props.text.val = str
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,13 +72,14 @@
|
|||||||
() =>
|
() =>
|
||||||
renderCoreProps.onElementClick &&
|
renderCoreProps.onElementClick &&
|
||||||
item.lineId &&
|
item.lineId &&
|
||||||
|
item.title != '绑定指标' &&
|
||||||
renderCoreProps.onElementClick(item.lineId, item.lineName)
|
renderCoreProps.onElementClick(item.lineId, item.lineName)
|
||||||
"
|
"
|
||||||
></render-item>
|
></render-item>
|
||||||
</mt-dzr>
|
</mt-dzr>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick, reactive, ref } from 'vue'
|
import { nextTick, reactive, ref, onMounted } from 'vue'
|
||||||
import MtDzr from '@/components/mt-dzr/index.vue'
|
import MtDzr from '@/components/mt-dzr/index.vue'
|
||||||
import RenderItem from '@/components/mt-edit/components/render-item/index.vue'
|
import RenderItem from '@/components/mt-edit/components/render-item/index.vue'
|
||||||
import type {
|
import type {
|
||||||
@@ -102,6 +103,8 @@ import SysButtonVue from '@/components/custom-components/sys-button-vue/index.vu
|
|||||||
import BindDotVue from '@/components/custom-components/bind-dot-vue/index.vue'
|
import BindDotVue from '@/components/custom-components/bind-dot-vue/index.vue'
|
||||||
import BindIndexVue from '@/components/custom-components/bind-index-vue/index.vue'
|
import BindIndexVue from '@/components/custom-components/bind-index-vue/index.vue'
|
||||||
import { ElPopover } from 'element-plus'
|
import { ElPopover } from 'element-plus'
|
||||||
|
import { leftAsideStore } from '@/export'
|
||||||
|
|
||||||
const instance = getCurrentInstance()
|
const instance = getCurrentInstance()
|
||||||
const now_include_keys = Object.keys(instance?.appContext?.components as any)
|
const now_include_keys = Object.keys(instance?.appContext?.components as any)
|
||||||
if (!now_include_keys.includes('text-vue')) {
|
if (!now_include_keys.includes('text-vue')) {
|
||||||
@@ -233,6 +236,7 @@ const onItemMove = (e: any, id: string) => {
|
|||||||
})
|
})
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCoreEmits('onItemMove', item_move_params)
|
renderCoreEmits('onItemMove', item_move_params)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -298,4 +302,9 @@ const onLineMouseUp = () => {
|
|||||||
cacheStore.addHistory(globalStore.done_json)
|
cacheStore.addHistory(globalStore.done_json)
|
||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
// console.log(123, leftAsideStore.list)
|
||||||
|
}, 5000)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="w-1/1 h-1/1">
|
<div class="w-1/1 h-1/1">
|
||||||
<svg-render
|
<svg-render
|
||||||
v-if="item_json.type === 'svg'"
|
v-if="
|
||||||
|
item_json.type === 'svg' &&
|
||||||
|
leftAsideStore.list.some(k => k.symbol?.symbol_id === item_json.symbol?.symbol_id)
|
||||||
|
"
|
||||||
draggable="false"
|
draggable="false"
|
||||||
:symbol-id="item_json.symbol!.symbol_id"
|
:symbol-id="item_json.symbol!.symbol_id"
|
||||||
:symbol-str="item_json.symbol!.symbol_str"
|
:symbol-str="item_json.symbol!.symbol_str"
|
||||||
@@ -53,6 +56,8 @@ import GroupRender from '@/components/mt-edit/components/group-render/index.vue'
|
|||||||
import { prosToVBind } from '@/components/mt-edit/utils'
|
import { prosToVBind } from '@/components/mt-edit/utils'
|
||||||
import LineRender from '@/components/mt-edit/components/line-render/index.vue'
|
import LineRender from '@/components/mt-edit/components/line-render/index.vue'
|
||||||
import CustomSvgRender from '@/components/mt-edit/components/custom-svg-render/index.vue'
|
import CustomSvgRender from '@/components/mt-edit/components/custom-svg-render/index.vue'
|
||||||
|
import { leftAsideStore } from '@/export'
|
||||||
|
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
type RenderItemProps = {
|
type RenderItemProps = {
|
||||||
itemJson: IDoneJson
|
itemJson: IDoneJson
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ export const useExportJsonToDoneJson = (json: IExportJson) => {
|
|||||||
init_configs = [...init_configs, ...iterator]
|
init_configs = [...init_configs, ...iterator]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const importDoneJson: IDoneJson[] = json.json.map(m => {
|
const importDoneJson: IDoneJson[] = json?.json?.map(m => {
|
||||||
let props: ILeftAsideConfigItemPublicProps = {}
|
let props: ILeftAsideConfigItemPublicProps = {}
|
||||||
let symbol = undefined
|
let symbol = undefined
|
||||||
// 找到原始的props
|
// 找到原始的props
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export const leftAsideStore: ILeftAside = reactive({
|
|||||||
['基础图元', configStore.sysComponent],
|
['基础图元', configStore.sysComponent],
|
||||||
['数据绑定图元', bingStore.sysComponent]
|
['数据绑定图元', bingStore.sysComponent]
|
||||||
]),
|
]),
|
||||||
|
list: [],
|
||||||
registerConfig: (title: string, config: ILeftAsideConfigItemPublic[]) => {
|
registerConfig: (title: string, config: ILeftAsideConfigItemPublic[]) => {
|
||||||
if (title == '本地文件' || title == '基础图元') {
|
if (title == '本地文件' || title == '基础图元') {
|
||||||
ElMessage.info(`title:${title}已被系统占用,请更换名称!`)
|
ElMessage.info(`title:${title}已被系统占用,请更换名称!`)
|
||||||
@@ -18,7 +19,7 @@ export const leftAsideStore: ILeftAside = reactive({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (leftAsideStore.config.has(title)) {
|
if (leftAsideStore.config.has(title)) {
|
||||||
ElMessage.info(`title:${title}已存在,已经将其配置覆盖`)
|
// ElMessage.info(`title:${title}已存在,已经将其配置覆盖`)
|
||||||
}
|
}
|
||||||
const cfg: ILeftAsideConfigItem[] = config.map(m => {
|
const cfg: ILeftAsideConfigItem[] = config.map(m => {
|
||||||
if (m.type == 'svg') {
|
if (m.type == 'svg') {
|
||||||
@@ -49,6 +50,7 @@ export const leftAsideStore: ILeftAside = reactive({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
leftAsideStore.list.push(...cfg)
|
||||||
leftAsideStore.config.set(title, cfg)
|
leftAsideStore.config.set(title, cfg)
|
||||||
},
|
},
|
||||||
svgPush: (title: string, config: ILeftAsideConfigItemPublic[]) => {
|
svgPush: (title: string, config: ILeftAsideConfigItemPublic[]) => {
|
||||||
|
|||||||
@@ -229,6 +229,7 @@ export interface IGlobalStore {
|
|||||||
// 左侧配置
|
// 左侧配置
|
||||||
export interface ILeftAside {
|
export interface ILeftAside {
|
||||||
config: ILeftAsideConfig
|
config: ILeftAsideConfig
|
||||||
|
list: any
|
||||||
registerConfig: (title: string, config: ILeftAsideConfigItemPublic[]) => void
|
registerConfig: (title: string, config: ILeftAsideConfigItemPublic[]) => void
|
||||||
svgPush: (title: string, config: ILeftAsideConfigItemPublic[]) => void
|
svgPush: (title: string, config: ILeftAsideConfigItemPublic[]) => void
|
||||||
svgDelete: (title: string, id: string) => void
|
svgDelete: (title: string, id: string) => void
|
||||||
|
|||||||
@@ -6,10 +6,12 @@
|
|||||||
@mouseup="onMouseUp"
|
@mouseup="onMouseUp"
|
||||||
@mouseleave="onMouseUp"
|
@mouseleave="onMouseUp"
|
||||||
@wheel="onMouseWheel"
|
@wheel="onMouseWheel"
|
||||||
|
style="height: 100vh; overflow: hidden"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-loading="useData.loading"
|
v-loading="useData.loading"
|
||||||
:style="canvasStyle"
|
:style="canvasStyle"
|
||||||
|
style="overflow: hidden"
|
||||||
:class="`canvasArea ${isDragging ? 'cursor-grabbing' : mtPreviewProps.canDrag ? 'cursor-grab' : ''} `"
|
:class="`canvasArea ${isDragging ? 'cursor-grabbing' : mtPreviewProps.canDrag ? 'cursor-grab' : ''} `"
|
||||||
>
|
>
|
||||||
<!-- <el-button type="primary" class="backBtn" @click="onBack" v-if="!useData.display">返回</el-button> -->
|
<!-- <el-button type="primary" class="backBtn" @click="onBack" v-if="!useData.display">返回</el-button> -->
|
||||||
@@ -512,6 +514,7 @@ const setImportJson = (exportJson: IExportJson) => {
|
|||||||
if (exportJson == null) {
|
if (exportJson == null) {
|
||||||
setDoneJson(useData.dataTree[0].kId)
|
setDoneJson(useData.dataTree[0].kId)
|
||||||
publish(useData.dataTree[0])
|
publish(useData.dataTree[0])
|
||||||
|
singlePublish(useData.dataTree[0])
|
||||||
} else {
|
} else {
|
||||||
executeOperations()
|
executeOperations()
|
||||||
}
|
}
|
||||||
@@ -523,6 +526,7 @@ const setImportJson = (exportJson: IExportJson) => {
|
|||||||
if (newVal === false) {
|
if (newVal === false) {
|
||||||
// 当loading变为true时执行操作
|
// 当loading变为true时执行操作
|
||||||
if (exportJson == null) {
|
if (exportJson == null) {
|
||||||
|
singlePublish(useData.dataTree[0])
|
||||||
setDoneJson(useData.dataTree[0].kId)
|
setDoneJson(useData.dataTree[0].kId)
|
||||||
publish(useData.dataTree[0])
|
publish(useData.dataTree[0])
|
||||||
} else {
|
} else {
|
||||||
@@ -676,7 +680,7 @@ const init = async () => {
|
|||||||
}, 100)
|
}, 100)
|
||||||
}
|
}
|
||||||
const timer = ref()
|
const timer = ref()
|
||||||
|
const list: any = ref([])
|
||||||
// 连接mqtt
|
// 连接mqtt
|
||||||
const mqttClient = ref()
|
const mqttClient = ref()
|
||||||
const setMqtt = async () => {
|
const setMqtt = async () => {
|
||||||
@@ -687,20 +691,50 @@ const setMqtt = async () => {
|
|||||||
await mqttClient.value.init()
|
await mqttClient.value.init()
|
||||||
|
|
||||||
// 订阅主题
|
// 订阅主题
|
||||||
|
await mqttClient.value.subscribe('/zl/rtData/#')
|
||||||
await mqttClient.value.subscribe('/zl/TemperData/#') //实时数据
|
await mqttClient.value.subscribe('/zl/TemperData/#') //实时数据
|
||||||
await mqttClient.value.subscribe('/zl/csConfigRtData/#') //指标
|
await mqttClient.value.subscribe('/zl/csConfigRtData/#') //指标
|
||||||
|
|
||||||
// 设置消息接收回调
|
// 设置消息接收回调
|
||||||
mqttClient.value.onMessage((subscribe: string, message: any) => {
|
mqttClient.value.onMessage((subscribe: string, message: any) => {
|
||||||
const msg: any = uint8ArrayToObject(message)
|
const msg: any = uint8ArrayToObject(message)
|
||||||
// console.log('🚀 ~ setMqtt ~ msg:', msg)
|
console.log('🚀 ~ setMqtt ~ msg:', msg)
|
||||||
|
|
||||||
|
if (subscribe.split('/')[2] === 'rtData') {
|
||||||
|
// 指标数据
|
||||||
|
|
||||||
|
// await setImportJson(savedExportJson.value)
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (done_json.value) {
|
||||||
|
// list.value = [
|
||||||
|
// ...new Set(msg.filter((item: any) => item.devStatus === 1).map((item: any) => item.lineId))
|
||||||
|
// ]
|
||||||
|
done_json.value?.forEach(item => {
|
||||||
|
msg.forEach((msgValue: any) => {
|
||||||
|
if (item.id == msgValue.id) {
|
||||||
|
const unit = item?.unit && Array.isArray(item.unit) ? item.unit[0] : ''
|
||||||
|
item.props.text.val = item.props.text.val.replace(
|
||||||
|
/#{3}/g,
|
||||||
|
msgValue.value == 3.1415926 ? '暂无数据' : msgValue.value + unit
|
||||||
|
) //'B相负载电流-CP95:31'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// list.value.forEach((listValue: any) => {
|
||||||
|
// if (listValue == item.lineId && item.type == 'svg') {
|
||||||
|
// item.props.fill.val = '#ff0000'
|
||||||
|
// // item.common_animations.val = 'flash'
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
if (subscribe.split('/')[2] === 'csConfigRtData') {
|
if (subscribe.split('/')[2] === 'csConfigRtData') {
|
||||||
// 指标数据
|
// 指标数据
|
||||||
dataList.value = JSON.parse(msg.message)
|
dataList.value = JSON.parse(msg.message)
|
||||||
//console.log('🚀 ~ setMqtt ~ dataList:', dataList.value)
|
//console.log('🚀 ~ setMqtt ~ dataList:', dataList.value)
|
||||||
// keyList.value = JSON.parse(list.path).canvasCfg.lineList
|
// keyList.value = JSON.parse(list.path).canvasCfg.lineList
|
||||||
}
|
} else if (subscribe.split('/')[2] === 'TemperData') {
|
||||||
if (subscribe.split('/')[2] === 'TemperData') {
|
|
||||||
// 表格数据
|
// 表格数据
|
||||||
tableData.value = []
|
tableData.value = []
|
||||||
tableData.value = JSON.parse(msg.message)
|
tableData.value = JSON.parse(msg.message)
|
||||||
@@ -726,6 +760,25 @@ const setMqtt = async () => {
|
|||||||
console.error('MQTT 初始化失败:', error)
|
console.error('MQTT 初始化失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const singlePublish = async (id: string) => {
|
||||||
|
console.log(123)
|
||||||
|
|
||||||
|
if (mqttClient.value) {
|
||||||
|
await mqttClient.value.subscribe('zl/askRtData/' + storedSelectedId)
|
||||||
|
// 发送消息
|
||||||
|
await mqttClient.value.publish('/zl/askRtData/' + storedSelectedId, '{}')
|
||||||
|
if (timer.value) {
|
||||||
|
clearInterval(timer.value)
|
||||||
|
timer.value = null
|
||||||
|
}
|
||||||
|
timer.value = setInterval(
|
||||||
|
() => {
|
||||||
|
mqttClient.value.publish('/zl/askRtData/' + storedSelectedId, '{}')
|
||||||
|
},
|
||||||
|
3 * 60 * 1000
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
const publish = async (list: any) => {
|
const publish = async (list: any) => {
|
||||||
console.log('🚀 ~ publish ~ list:', JSON.parse(list.path).canvasCfg.lineList)
|
console.log('🚀 ~ publish ~ list:', JSON.parse(list.path).canvasCfg.lineList)
|
||||||
if (mqttClient.value) {
|
if (mqttClient.value) {
|
||||||
|
|||||||
@@ -38,7 +38,6 @@
|
|||||||
@drag-canvas-mouse-move="dragCanvasMouseMove"
|
@drag-canvas-mouse-move="dragCanvasMouseMove"
|
||||||
@drag-canvas-mouse-up="dragCanvasMouseUp"
|
@drag-canvas-mouse-up="dragCanvasMouseUp"
|
||||||
></drag-canvas>
|
></drag-canvas>
|
||||||
<!-- </el-scrollbar> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ export const useDataStore = defineStore('data-store', {
|
|||||||
wxqr: '',
|
wxqr: '',
|
||||||
loading: true,
|
loading: true,
|
||||||
display: false, //无锡项目进去是true,其他项目是false 控制预览的时候返回按钮的展示
|
display: false, //无锡项目进去是true,其他项目是false 控制预览的时候返回按钮的展示
|
||||||
graphicDisplay: 'zl' //无锡项目进去是true,其他项目是false 控制点击设计的时候左侧列表数据绑定图元的展示
|
graphicDisplay: 'zl', //无锡项目进去是true,其他项目是false 控制点击设计的时候左侧列表数据绑定图元的展示
|
||||||
|
treeIndexs: [] //树形结构选中的索引
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@@ -87,6 +88,9 @@ export const useDataStore = defineStore('data-store', {
|
|||||||
item.path = data
|
item.path = data
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
settreeIndexs(data: any) {
|
||||||
|
this.treeIndexs = data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -12,4 +12,5 @@ export interface DataStoreState {
|
|||||||
keyName?: String
|
keyName?: String
|
||||||
display?: Boolean //是否展示返回按钮
|
display?: Boolean //是否展示返回按钮
|
||||||
graphicDisplay?: string //是否展示数据绑定图元
|
graphicDisplay?: string //是否展示数据绑定图元
|
||||||
|
treeIndexs?: any //是否展示数据绑定图元
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { leftAsideStore } from '@/export'
|
|||||||
import demo from '/svgs/demo.svg?raw'
|
import demo from '/svgs/demo.svg?raw'
|
||||||
import { find, download, queryPage } from '@/api/index'
|
import { find, download, queryPage } from '@/api/index'
|
||||||
import { useDataStore } from '@/stores/menuList'
|
import { useDataStore } from '@/stores/menuList'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
// 定义类型接口
|
// 定义类型接口
|
||||||
interface ElementItem {
|
interface ElementItem {
|
||||||
id: string
|
id: string
|
||||||
@@ -83,73 +84,7 @@ const loadSvg = async () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// // 添加页面svg
|
await getSvg()
|
||||||
// await find().then(async res => {
|
|
||||||
// let result: any = {}
|
|
||||||
// res.data.forEach((item: any) => {
|
|
||||||
// const type = item.elementSonType
|
|
||||||
|
|
||||||
// // 如果该类型还没有在结果中,初始化一个空数组
|
|
||||||
// if (!result[type]) {
|
|
||||||
// result[type] = []
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 将当前项添加到对应类型的数组中
|
|
||||||
// result[type].push(item)
|
|
||||||
// })
|
|
||||||
// for (const key in result) {
|
|
||||||
// // 创建一个存放所有Promise的数组
|
|
||||||
// const promises = result[key].map((item: any) => {
|
|
||||||
// return download({ filePath: item.path }).then((Svg: any) => {
|
|
||||||
// return {
|
|
||||||
// id: item.id,
|
|
||||||
// title: item.elementName,
|
|
||||||
// type: 'svg',
|
|
||||||
// thumbnail:
|
|
||||||
// 'data:image/svg+xml;utf8,' +
|
|
||||||
// encodeURIComponent(Svg.replace(/(\sfill=(["']))[^"']*(\2)/g, '$1#FF0000$3')),
|
|
||||||
// svg: Svg.replace(/\sfill=(["'])[^"']*\1/g, ''),
|
|
||||||
// props: {
|
|
||||||
// fill: {
|
|
||||||
// type: 'color',
|
|
||||||
// val: '#FF0000',
|
|
||||||
// title: '填充色'
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
|
|
||||||
// // 等待所有下载操作完成
|
|
||||||
// const svgList = await Promise.all(promises)
|
|
||||||
|
|
||||||
// // 所有异步操作完成后再执行注册
|
|
||||||
// leftAsideStore.registerConfig(key, svgList)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// 主逻辑
|
|
||||||
try {
|
|
||||||
const res = await find()
|
|
||||||
const groupedElements: Record<string, ElementItem[]> = {}
|
|
||||||
|
|
||||||
// 按类型分组元素
|
|
||||||
res.data.forEach((item: ElementItem) => {
|
|
||||||
const { elementSonType: type } = item
|
|
||||||
if (!groupedElements[type]) {
|
|
||||||
groupedElements[type] = []
|
|
||||||
}
|
|
||||||
groupedElements[type].push(item)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 处理每个类型的元素并注册
|
|
||||||
for (const [type, items] of Object.entries(groupedElements)) {
|
|
||||||
const svgConfigs = await Promise.all(items.map(item => processSvgItem(item, type)))
|
|
||||||
leftAsideStore.registerConfig(type, svgConfigs)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('加载和处理SVG元素时发生错误:', error)
|
|
||||||
// 可以在这里添加错误恢复逻辑或用户提示
|
|
||||||
}
|
|
||||||
await useData.set('loading', false)
|
await useData.set('loading', false)
|
||||||
|
|
||||||
// const electrical_modules_files = import.meta.glob('@/assets/svgs/electrical/face/**.svg', {
|
// const electrical_modules_files = import.meta.glob('@/assets/svgs/electrical/face/**.svg', {
|
||||||
@@ -338,4 +273,31 @@ const loadSvg = async () => {
|
|||||||
// }
|
// }
|
||||||
// ])
|
// ])
|
||||||
}
|
}
|
||||||
export default loadSvg
|
|
||||||
|
const getSvg = async () => {
|
||||||
|
// 主逻辑
|
||||||
|
try {
|
||||||
|
const res = await find()
|
||||||
|
const groupedElements: Record<string, ElementItem[]> = {}
|
||||||
|
|
||||||
|
// 按类型分组元素
|
||||||
|
res.data.forEach((item: ElementItem) => {
|
||||||
|
const { elementSonType: type } = item
|
||||||
|
if (!groupedElements[type]) {
|
||||||
|
groupedElements[type] = []
|
||||||
|
}
|
||||||
|
groupedElements[type].push(item)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 处理每个类型的元素并注册
|
||||||
|
for (const [type, items] of Object.entries(groupedElements)) {
|
||||||
|
const svgConfigs = await Promise.all(items.map(item => processSvgItem(item, type)))
|
||||||
|
leftAsideStore.registerConfig(type, svgConfigs)
|
||||||
|
}
|
||||||
|
ElMessage.success(`图元加载完成!`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载和处理SVG元素时发生错误:', error)
|
||||||
|
// 可以在这里添加错误恢复逻辑或用户提示
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export { loadSvg, getSvg }
|
||||||
|
|||||||
@@ -52,11 +52,11 @@ class MQTT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const mqttUrl = 'ws://192.168.1.103:8083/mqtt'
|
// const mqttUrl = 'ws://192.168.1.103:8083/mqtt'
|
||||||
// const mqttUrl =
|
const mqttUrl =
|
||||||
// localStorage.getItem('MQTTZUTAI') == 'null'
|
localStorage.getItem('MQTTZUTAI') == 'null'
|
||||||
// ? 'ws://192.168.1.103:8083/mqtt'
|
? 'ws://192.168.1.103:8083/mqtt'
|
||||||
// : localStorage.getItem('MQTTZUTAI')
|
: localStorage.getItem('MQTTZUTAI')
|
||||||
console.log('🚀 ~ MQTT ~ init ~ mqttUrl:', mqttUrl)
|
console.log('🚀 ~ MQTT ~ init ~ mqttUrl:', mqttUrl)
|
||||||
this.client = mqtt.connect(mqttUrl, this.defaultOptions as IClientOptions)
|
this.client = mqtt.connect(mqttUrl, this.defaultOptions as IClientOptions)
|
||||||
this.setupEventListeners()
|
this.setupEventListeners()
|
||||||
@@ -135,7 +135,7 @@ class MQTT {
|
|||||||
console.error('订阅失败:', error)
|
console.error('订阅失败:', error)
|
||||||
reject(error)
|
reject(error)
|
||||||
} else {
|
} else {
|
||||||
console.log('订阅成功')
|
console.log('订阅成功', subscribe)
|
||||||
resolve()
|
resolve()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ class HttpRequest {
|
|||||||
instance.interceptors.request.use(
|
instance.interceptors.request.use(
|
||||||
config => {
|
config => {
|
||||||
// 添加全局的loading..
|
// 添加全局的loading..
|
||||||
// config.headers['Authorization'] =
|
|
||||||
// 'bearer ' + JSON.parse(window.localStorage.getItem('adminInfo') || '{}').access_token // 请求头带上token token要在登录的时候保存在localStorage中
|
|
||||||
config.headers['Authorization'] =
|
config.headers['Authorization'] =
|
||||||
'bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5kZXgiOiJmYTM3YjkzY2M5MGQ0YzE3ODRjYThmNmRlYmRkZWUxYSIsInVzZXJfbmFtZSI6InJvb3QiLCJzY29wZSI6WyJhbGwiXSwibmlja25hbWUiOiLotoXnuqfnrqHnkIblkZgiLCJ1c2VyVHlwZSI6MCwiZGVwdEluZGV4IjoiNTY5OWU1OTE2YTE4YTYzODFlMWFjOTJkYTViZDI2MjgiLCJleHAiOjE4MjE4MTc2MTksImF1dGhvcml0aWVzIjpbInJvb3QiXSwianRpIjoiMmJiM2Q5ZTYtNmY3Yy00Yjg1LThiM2EtZDI2ODdmMTUzMDg5IiwiY2xpZW50X2lkIjoibmpjbnRlc3QiLCJoZWFkU2N1bHB0dXJlIjoicmVzb3VyY2VEYXRhLzMxNzRDRUFFOUQ0MjRGMjJCQjkxQTU4OURENjdCMDUxLmpwZyJ9.WjeYl1lvvJdDE1FUGIhS99rE5qKaBXOypWxmxK0svWweGqEbu1XCLjKm_YkiTwjZJ_oIcn5JOO9rvHFkkea76BUsYo5wlzuBBiy7sKqM1fFzOFQq6hdFevNTJAbYH9FiBxYxI-e9DZ5mvLGE6umOjUfn_FAsku2w6Uj5DtvpOKBWYzLEPTEifOqNI9he4zJAmVZniUUMf26SDoEdfu0TyrIS1j_qKaEb-cqR1XDhivdthEBK5m9vxJyXFZ5kofNxwQQkit_oiqJRkCZIt9TWAjCh-frzMHCvA30hkAr-VCD2JfCmmEr3hW_lmwfINaPtFVbHCdCKqdrl6VmF1HObaQ'
|
'bearer ' + JSON.parse(window.localStorage.getItem('adminInfo') || '{}').access_token // 请求头带上token token要在登录的时候保存在localStorage中
|
||||||
|
// config.headers['Authorization'] =
|
||||||
|
// 'bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5kZXgiOiJmYTM3YjkzY2M5MGQ0YzE3ODRjYThmNmRlYmRkZWUxYSIsInVzZXJfbmFtZSI6InJvb3QiLCJzY29wZSI6WyJhbGwiXSwibmlja25hbWUiOiLotoXnuqfnrqHnkIblkZgiLCJ1c2VyVHlwZSI6MCwiZGVwdEluZGV4IjoiNTY5OWU1OTE2YTE4YTYzODFlMWFjOTJkYTViZDI2MjgiLCJleHAiOjE4MjE4MTc2MTksImF1dGhvcml0aWVzIjpbInJvb3QiXSwianRpIjoiMmJiM2Q5ZTYtNmY3Yy00Yjg1LThiM2EtZDI2ODdmMTUzMDg5IiwiY2xpZW50X2lkIjoibmpjbnRlc3QiLCJoZWFkU2N1bHB0dXJlIjoicmVzb3VyY2VEYXRhLzMxNzRDRUFFOUQ0MjRGMjJCQjkxQTU4OURENjdCMDUxLmpwZyJ9.WjeYl1lvvJdDE1FUGIhS99rE5qKaBXOypWxmxK0svWweGqEbu1XCLjKm_YkiTwjZJ_oIcn5JOO9rvHFkkea76BUsYo5wlzuBBiy7sKqM1fFzOFQq6hdFevNTJAbYH9FiBxYxI-e9DZ5mvLGE6umOjUfn_FAsku2w6Uj5DtvpOKBWYzLEPTEifOqNI9he4zJAmVZniUUMf26SDoEdfu0TyrIS1j_qKaEb-cqR1XDhivdthEBK5m9vxJyXFZ5kofNxwQQkit_oiqJRkCZIt9TWAjCh-frzMHCvA30hkAr-VCD2JfCmmEr3hW_lmwfINaPtFVbHCdCKqdrl6VmF1HObaQ'
|
||||||
// 请求头携带token
|
// 请求头携带token
|
||||||
return config
|
return config
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const MtEditRef = ref<InstanceType<typeof MtEdit>>()
|
|||||||
const onPreviewClick = (exportJson: IExportJson) => {
|
const onPreviewClick = (exportJson: IExportJson) => {
|
||||||
sessionStorage.setItem('exportJson', JSON.stringify(exportJson))
|
sessionStorage.setItem('exportJson', JSON.stringify(exportJson))
|
||||||
const routeUrl = router.resolve({
|
const routeUrl = router.resolve({
|
||||||
name: 'preview'
|
name: 'preview_YPT'
|
||||||
})
|
})
|
||||||
window.open(routeUrl.href, '_blank')
|
window.open(routeUrl.href, '_blank')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const MtEditRef = ref<InstanceType<typeof MtEdit>>()
|
|||||||
const onPreviewClick = (exportJson: IExportJson) => {
|
const onPreviewClick = (exportJson: IExportJson) => {
|
||||||
sessionStorage.setItem('exportJson', JSON.stringify(exportJson))
|
sessionStorage.setItem('exportJson', JSON.stringify(exportJson))
|
||||||
const routeUrl = router.resolve({
|
const routeUrl = router.resolve({
|
||||||
name: 'preview'
|
name: 'preview_YPT'
|
||||||
})
|
})
|
||||||
window.open(routeUrl.href, '_blank')
|
window.open(routeUrl.href, '_blank')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const useData = useDataStore()
|
|||||||
const onPreviewClick = (exportJson: IExportJson) => {
|
const onPreviewClick = (exportJson: IExportJson) => {
|
||||||
sessionStorage.setItem('exportJson', JSON.stringify(exportJson))
|
sessionStorage.setItem('exportJson', JSON.stringify(exportJson))
|
||||||
const routeUrl = router.resolve({
|
const routeUrl = router.resolve({
|
||||||
name: 'preview'
|
name: 'preview_YPT'
|
||||||
})
|
})
|
||||||
window.open(routeUrl.href, '_blank')
|
window.open(routeUrl.href, '_blank')
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user