修改测试bug 优化页面

This commit is contained in:
guanj
2026-01-04 14:55:31 +08:00
parent cc0f8bc8b6
commit a765cdf9ee
68 changed files with 5396 additions and 3096 deletions

View File

@@ -1,10 +1,10 @@
<template>
<div>
<el-dialog v-model="dialogVisible" title="自定义功能管理" width="600">
<el-dialog v-model="dialogVisible" title="自定义功能管理" width="650">
<div style="display: flex; justify-content: end" class="mb10">
<el-button icon="el-icon-Plus" type="primary" @click="add">新增</el-button>
</div>
<div style="height: calc(100vh / 2); max-height: 400px">
<div style="height: 300px; max-height: 400px">
<vxe-table
border
ref="tableRef"
@@ -25,6 +25,7 @@
<el-switch
v-model="row.state"
inline-prompt
:disabled="!hasAdmin && row.scope"
:active-value="1"
:inactive-value="0"
active-text="已激活"
@@ -33,11 +34,29 @@
/>
</template>
</vxe-column>
<vxe-column field="startTime" title="是否全局" v-if="hasAdmin">
<template #default="{ row }">
<el-switch
v-model="row.scope"
inline-prompt
:active-value="1"
width="50px"
:inactive-value="0"
active-text=""
inactive-text=""
:before-change="() => beforeChange1(row)"
/>
</template>
</vxe-column>
<vxe-column field="startTime" title="操作">
<template #default="{ row }">
<el-button type="primary" link @click="edit(row)">编辑</el-button>
<el-button type="primary" link @click="edit(row)" v-if="!(!hasAdmin && row.scope)">
编辑
</el-button>
<el-button type="danger" link @click="deletes(row)">删除</el-button>
<el-button type="danger" link @click="deletes(row)" v-if="!(!hasAdmin && row.scope)">
删除
</el-button>
</template>
</vxe-column>
</vxe-table>
@@ -49,18 +68,20 @@
import { ref, reactive } from 'vue'
import { useRouter } from 'vue-router'
import { defaultAttribute } from '@/components/table/defaultAttribute'
import { getDashboardPageByUserId, deleteDashboard, activatePage } from '@/api/system-boot/csstatisticalset'
import { getDashboardPageByUserId, deleteDashboard, activatePage, scopePage } from '@/api/system-boot/csstatisticalset'
import { useAdminInfo } from '@/stores/adminInfo'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useNavTabs } from '@/stores/navTabs'
import { getMenu } from '@/utils/router'
const { push } = useRouter()
const dialogVisible = ref(false)
const route = useRouter()
const navTabs = useNavTabs()
const adminInfo = useAdminInfo()
const pageList: any = ref([])
const hasAdmin = adminInfo.roleCode.some(item => item.includes('operation_manager') || item.includes('root'))
const open = () => {
dialogVisible.value = true
@@ -68,7 +89,10 @@ const open = () => {
}
const init = () => {
getDashboardPageByUserId({ id: adminInfo.id, state: false }).then(res => {
pageList.value = res.data
pageList.value = res.data.filter(item => {
item.scope = item.userId == '0' ? 1 : 0
return item
})
})
}
// 新增
@@ -93,7 +117,7 @@ const beforeChange = (row: any): Promise<boolean> => {
type: 'warning'
})
.then(() => {
activatePage({ id: row.id, state: row.state == 0 ? 1 : 0 }).then( async(res: any) => {
activatePage({ id: row.id, state: row.state == 0 ? 1 : 0 }).then(async (res: any) => {
if (res.code == 'A0000') {
ElMessage({
type: 'success',
@@ -102,19 +126,45 @@ const beforeChange = (row: any): Promise<boolean> => {
}
init()
resolve(true)
await getMenu()
await setTimeout(() => {
navTabs.refresh()
await getMenu()
await setTimeout(() => {
navTabs.refresh()
}, 1000)
})
})
.catch(() => {
ElMessage({
type: 'info',
message: '已取消删除'
.catch(() => {})
})
}
// 全局
const beforeChange1 = (row: any): Promise<boolean> => {
return new Promise(resolve => {
// setTimeout(() => {
// loading1.value = false
// ElMessage.success('Switch success')
// return resolve(true)
// }, 1000)
ElMessageBox.confirm('此操作将页面配置成全局, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
scopePage({ id: row.id, userId: row.scope == 0 ? '0' : adminInfo.id }).then(async (res: any) => {
if (res.code == 'A0000') {
ElMessage({
type: 'success',
message: '操作成功!'
})
}
init()
resolve(true)
await getMenu()
await setTimeout(() => {
navTabs.refresh()
}, 1000)
})
})
.catch(() => {})
})
}
// 删除

View File

@@ -12,7 +12,9 @@
</el-form-item>
</template>
<template v-slot:operation>
<el-button type="primary" icon="el-icon-Edit" @click="editd">编辑</el-button>
<el-button type="primary" icon="el-icon-Edit" v-if="hasAdmin || adminInfo.id == userId" @click="editd">
编辑
</el-button>
<el-button
type="primary"
icon="el-icon-Tools"
@@ -46,7 +48,13 @@
{{ (item as LayoutItem).name }}
</div>
<!-- <FullScreen class="HelpFilled" style="cursor: pointer" @click="setZoom(item)" /> -->
<img :src="flag ? img : img1" style="cursor: pointer; height: 16px" @click="setZoom(item)" />
<span style="display: flex; align-items: center">
<img
:src="flag ? img : img1"
style="cursor: pointer; height: 16px"
@click="setZoom(item)"
/>
</span>
</div>
<div>
<component
@@ -82,12 +90,15 @@ import { queryActivatePage, queryByPagePath } from '@/api/system-boot/csstatisti
import RoutingConfig from '@/views/pqs/cockpit/homePage/components/routingConfig.vue'
import { useRouter, useRoute } from 'vue-router'
import { useTimeCacheStore } from '@/stores/timeCache'
import { Sort } from '@element-plus/icons-vue'
const { push } = useRouter()
const datePickerRef = ref()
const router = useRouter()
const route = useRoute()
const timeCacheStore = useTimeCacheStore()
import { useAdminInfo } from '@/stores/adminInfo'
const adminInfo = useAdminInfo()
const hasAdmin = adminInfo.roleCode.some(item => item.includes('operation_manager') || item.includes('root'))
defineOptions({
// name: 'dashboard/index'
})
@@ -109,6 +120,7 @@ interface LayoutItem {
}
const zoom = ref(1)
const RoutingConfigRef = ref()
const userId = ref('')
const key = ref(0)
const img = new URL(`@/assets/img/amplify.png`, import.meta.url).href
const img1 = new URL(`@/assets/img/reduce.png`, import.meta.url).href
@@ -219,6 +231,7 @@ const seRowHeight = (value: any) => {
const fetchLayoutData = async () => {
try {
const { data } = await queryByPagePath({ pagePath: router.currentRoute.value.name })
userId.value = data.userId
dataList.value = data
const parsedLayout = JSON.parse(data.containerConfig || '[]') as LayoutItem[]
// 处理布局数据

View File

@@ -0,0 +1,146 @@
<template>
<el-dialog
class="cn-operate-dialog"
width="1200px"
append-to-body
v-model.trim="dialogVisible"
title="绑定"
>
<el-form ref="formRef" label-width="80px" class="form">
<el-form-item label="项目名称">
<el-input
maxlength="32"
show-word-limit
clearable
style="width: 240px"
v-model.trim="searchValue"
placeholder="请输入项目名称"
></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="info" icon="el-icon-Search">查询</el-button>
</el-form-item>
</el-form>
<div style="height: calc(60vh - 120px); overflow-y: auto" v-loading="loading">
<el-row :gutter="10" style="width: 100%; margin: auto">
<el-col :span="6" v-for="item in list" :key="item.id" class="mt10">
<el-card class="box-card" shadow="hover">
<div slot="header" class="clearfix mb10">
<span style="display: flex; align-items: center;justify-content: space-between;">
{{ item.name }}
<!-- <el-tooltip
class="item"
effect="dark"
content="绑定实时数据"
placement="top"
v-if="bindId != item.id"
>
<Sort
style="margin-left: 5px; width: 16px"
class="xiaoshou color"
@click="activate(item)"
/>
</el-tooltip> -->
<el-button type="primary" v-if="bindId != item.id" @click="activate(item)" icon="el-icon-Sort" link>绑定</el-button>
</span>
</div>
<img v-if="item.fileContent" :src="item.fileContent" class="image" />
<el-empty v-else description="暂无设计" style="height: 220px" />
</el-card>
</el-col>
</el-row>
</div>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref, inject } from 'vue'
import { reactive } from 'vue'
import { coFqueryPage, getByUserId, savePageIdWithUser } from '@/api/cs-harmonic-boot/mxgraph'
import { useAdminInfo } from '@/stores/adminInfo'
import { Sort } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
const adminInfo = useAdminInfo()
const emit = defineEmits(['bindClick'])
const dialogVisible = ref(false)
const searchValue = ref('')
const bindId = ref('')
const list = ref([])
const loading = ref(false)
const open = (text: string, data: anyObj) => {
searchValue.value = ''
list.value = []
info()
dialogVisible.value = true
}
const info = () => {
loading.value = true
getBindId()
coFqueryPage({
currentUserId: adminInfo.id,
roleCode: adminInfo.roleCode.join(','),
searchValue: searchValue.value,
pageNum: 1,
pageSize: 1000
})
.then(res => {
list.value = res.data.records
loading.value = false
})
.catch(err => {
loading.value = false
})
}
const getBindId = () => {
getByUserId({ userId: adminInfo.id }).then(res => {
bindId.value = res.data.pageId
})
}
const activate = (e: any) => {
ElMessageBox.confirm('是否绑定页面?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
savePageIdWithUser({ pageId: e.id, userId: adminInfo.id }).then(res => {
if (res.code == 'A0000') {
ElMessage({
type: 'success',
message: '操作成功'
})
bindId.value = e.id
emit('bindClick', bindId.value)
}
})
})
.catch(() => {})
}
defineExpose({ open })
</script>
<style lang="scss" scoped>
.form {
display: flex;
justify-content: space-between;
height: 35px;
}
.image {
display: block;
width: 100%;
height: 220px;
}
.xiaoshou {
cursor: pointer;
}
.color {
color: var(--el-color-primary);
}
.box-card {
width: 100%;
// border: 1px solid #000;
box-shadow: var(--el-box-shadow-light);
}
:deep(.el-card__body) {
padding: 10px;
}
</style>

View File

@@ -12,6 +12,8 @@
style="position: relative"
>
<iframe
v-if="bindId"
:key="bindId"
:src="iframeSrc"
width="100%"
height="100%"
@@ -20,6 +22,7 @@
id="iframeLeft"
@load="onIframeLoad"
></iframe>
<el-empty v-else description="暂无绑定页面" style="height: 100%" />
</div>
</div>
<div class="bottom-container">
@@ -28,13 +31,15 @@
:icon="show ? 'el-icon-ArrowDownBold' : 'el-icon-ArrowUpBold'"
@click="show = !show"
style="width: 100%"
v-if="bindId"
>
事件列表
</el-button>
<el-button class="bindBut" type="primary" icon="el-icon-Sort" @click="bindClick">绑定</el-button>
<!-- <div class="buttonBox">
<el-button type="primary" icon="el-icon-Aim" @click="reset">复位</el-button>
</div> -->
<transition name="table-fade">
<div class="tableBox" v-if="show">
<vxe-table border auto-resize height="230px" :data="tableData" ref="tableRef">
@@ -46,6 +51,8 @@
</div>
</transition>
</div>
<!--绑定实时数据 -->
<Bind ref="bindRef" @bindClick="info" />
</div>
</template>
<script setup lang="ts">
@@ -53,11 +60,16 @@ import { ref, watch, onMounted, onUnmounted, provide } from 'vue'
import Table from '@/components/table/index.vue'
import TableStore from '@/utils/tableStore'
import { mainHeight } from '@/utils/layout'
import { useAdminInfo } from '@/stores/adminInfo'
import { audit, add, coFqueryPage, getByUserId } from '@/api/cs-harmonic-boot/mxgraph'
import Bind from './bind.vue'
// import { getActive } from "@/api/manage_wx/index";
// const props = defineProps<{
// project: { id: string; name: string } | null
// }>()
const adminInfo = useAdminInfo()
const show = ref(false)
const prop = defineProps({
width: { type: [String, Number] },
@@ -65,10 +77,9 @@ const prop = defineProps({
timeKey: { type: Array as () => string[] },
timeValue: { type: Object }
})
const tableData = ref([
])
const bindRef = ref()
const tableData = ref([])
const bindId = ref('')
// 在父页面中添加事件监听器
window.addEventListener('message', function (event) {
@@ -83,6 +94,9 @@ window.addEventListener('message', function (event) {
const tableRef = ref()
const pageHeight = mainHeight(40)
const bindClick = () => {
bindRef.value.open()
}
const reset = () => {
// 向 iframe 发送复位事件
@@ -128,15 +142,10 @@ const iframeSrc = ref('')
// { immediate: true, deep: true }
// )
onMounted(() => {
iframeSrc.value =
window.location.origin + `/zutai/?id=4b4f7f4260198776594f5f9d93a532e8&&name=stt&&preview=true#/preview_YPT`
onMounted(async () => {
info()
// tableStore.index()
// 监听来自 eventStatistics 组件的消息
window.addEventListener('message', handleMessage)
// getActive({}).then((res: any) => {
// if (res.code == "A0000") {
// // window.location.origin
@@ -148,7 +157,31 @@ onMounted(() => {
// }
// });
})
const info = async () => {
iframeSrc.value = ''
await getByUserId({ userId: adminInfo.id })
.then(res => {
bindId.value = res.data.pageId
})
.catch(async err => {
// bindId.value = '4b4f7f4260198776594f5f9d93a532e8'
await coFqueryPage({
currentUserId: adminInfo.id,
roleCode: adminInfo.roleCode.join(','),
searchValue: '',
pageNum: 1,
pageSize: 1000
}).then(res => {
bindId.value = res.data.records.filter(item => item.scope == 1)[0]?.id || null
})
})
await setTimeout(() => {
iframeSrc.value = window.location.origin + `/zutai/?id=${bindId.value}&&name=stt&&preview=true#/preview_YPT`
// iframeSrc.value = `http://192.168.2.128:4001/zutai/?id=${bindId.value}&&name=stt&&preview=true#/preview_YPT`
window.addEventListener('message', handleMessage)
}, 0)
}
onUnmounted(() => {
// 清理事件监听器
window.removeEventListener('message', handleMessage)
@@ -258,4 +291,9 @@ const sendKeysToIframe = (keyList: string[]) => {
.table-fade-enter-active {
transition-delay: 0.05s;
}
.bindBut {
position: absolute;
right: 0px;
top: -35px;
}
</style>

View File

@@ -1,136 +1,195 @@
<template>
<div class="pd10">
<el-card>
<el-form ref="formRef" inline :rules="rules" :model="form" label-width="auto" class="form-four">
<el-form-item label="页面名称" prop="pageName">
<el-input
style="width: 100%"
maxlength="32"
show-word-limit
v-model.trim="form.pageName"
placeholder="请输入页面名称"
></el-input>
</el-form-item>
<el-form-item label="图标">
<IconSelector v-model.trim="form.icon" style="width: 80%" placeholder="请选择图标" />
</el-form-item>
<el-form-item label="页面排序" prop="sort">
<el-input-number style="width: 100%" v-model.trim="form.sort" :min="0" :max="10000" :step="1" />
</el-form-item>
<el-form-item label="是否激活">
<el-switch
v-model="form.state"
inline-prompt
:disabled="form.pagePath == 'dashboard/index'"
:active-value="1"
:inactive-value="0"
active-text=""
inactive-text=""
/>
</el-form-item>
<el-form-item label="备注" class="top">
<el-input
maxlength="300"
show-word-limit
type="textarea"
:rows="1"
placeholder="请输入内容"
v-model.trim="form.remark"
></el-input>
</el-form-item>
<el-form-item>
<div style="width: 100%; display: flex; justify-content: end">
<el-button type="primary" icon="el-icon-Check" @click="onSubmit">保存</el-button>
<back-component />
</div>
</el-form-item>
</el-form>
</el-card>
<el-card class="mt10" :style="height">
<div style="display: flex">
<div style="width: 605px; overflow: auto" :style="indicatorHeight" class="mr10">
<el-collapse v-model="activeNames" :expand-icon-position="position">
<el-collapse-item
v-for="item in treeComponents"
:key="item.id"
:title="item.name"
:name="item.id"
>
<el-collapse v-model="activeNames1" class="ml20">
<el-collapse-item v-for="k in item.children" :key="k.id" :title="k.name" :name="k.id">
<div class="Box">
<div
v-for="(s, index) in k.children"
:key="index"
class="mr10 mb10 imgBox"
draggable="true"
unselectable="on"
@drag="drag(s)"
@dragend="dragEnd(s)"
>
<div class="textName">{{ s.name }}</div>
<img :src="s.image" style="width: 180px" />
<div class="default-main pd10">
<div style="width: 100%; display: flex; justify-content: end">
<el-button type="primary" icon="el-icon-Check" @click="onSubmit">保存</el-button>
<back-component />
</div>
<div style="display: flex" class="mt10">
<!-- <el-tabs type="border-card">
<el-tab-pane label="组件">
<div style="width: 520px; overflow: auto" :style="indicatorHeight" class="mr10">
<el-collapse v-model="activeNames" :expand-icon-position="position">
<el-collapse-item
v-for="item in treeComponents"
:key="item.id"
:title="item.name"
:name="item.id"
>
<el-collapse v-model="activeNames1" class="ml20">
<el-collapse-item
v-for="k in item.children"
:key="k.id"
:title="k.name"
:name="k.id"
>
<div class="Box">
<div
v-for="(s, index) in k.children"
:key="index"
class="mr10 mb10 imgBox"
draggable="true"
unselectable="on"
@drag="drag(s)"
@dragend="dragEnd(s)"
>
<div class="textName">{{ s.name }}</div>
<img :src="s.image" style="width: 150px" />
</div>
</div>
</div>
</el-collapse-item>
</el-collapse>
</el-collapse-item>
</el-collapse>
</div>
<div style="flex: 1" ref="wrapper">
<GridLayout
class="GridLayout"
ref="gridLayout"
v-model:layout="layout"
style="width: 100%"
:style="{ height: GridHeight + 'px' }"
:row-height="rowHeight"
:col-num="12"
prevent-collision
:vertical-compact="false"
>
<template #item="{ item }">
<div class="imgBox">
<div class="textName">{{ item.name }}</div>
<img
:src="getImg(item.path)"
:style="{
height:
item.h * rowHeight -
(item.h == 1
? 30
: item.h == 2
? 20
: item.h == 3
? 10
: item.h == 4
? -0
: item.h == 5
? -10
: -20) +
'px'
}"
/>
<CloseBold class="remove" @click="removeItem(item.i)" />
</el-collapse-item>
</el-collapse>
</el-collapse-item>
</el-collapse>
</div>
</el-tab-pane>
</el-tabs> -->
<el-tabs v-model="tableName" type="border-card" @tab-change="changeTab">
<el-tab-pane v-for="item in treeComponents" :key="item.name" :label="item.name" :name="item.name">
<el-tabs v-model="tableName1" tab-position="top">
<el-tab-pane v-for="k in item?.children" :key="k.name" :label="k.name" :name="k.name">
<div :style="indicatorHeight" style="overflow-y: auto; overflow-x: hidden">
<el-row :gutter="10" class="pl5 pr5 pt5" style="width: 520px">
<el-col :span="8" v-for="component in k.children" :key="component.id" class="mb10">
<el-card
class="box-card"
shadow="hover"
@drag="drag(component)"
@dragend="dragEnd(component)"
>
<div slot="header" class="clearfix">
<span style="display: flex; align-items: center">
{{ component.name }}
</span>
</div>
<img v-if="component.image" :src="component.image" class="image xiaoshou" />
</el-card>
</el-col>
</el-row>
</div>
<!-- <span class="text">{{ `${item?.name}` }}</span>
</el-tab-pane>
</el-tabs>
</el-tab-pane>
</el-tabs>
<div style="flex: 1" ref="wrapper" class="ml10">
<el-tabs type="border-card" class="mb10">
<el-tab-pane label="基础信息">
<el-form ref="formRef" inline :rules="rules" :model="form" label-width="auto" class="form-four">
<el-form-item label="页面名称" prop="pageName">
<el-input
style="width: 100%"
maxlength="32"
show-word-limit
v-model.trim="form.pageName"
placeholder="请输入页面名称"
></el-input>
</el-form-item>
<el-form-item label="图标">
<IconSelector v-model.trim="form.icon" placeholder="请选择图标" />
</el-form-item>
<el-form-item label="页面排序" prop="sort">
<el-input-number
style="width: 100%"
v-model.trim="form.sort"
:min="0"
:max="10000"
:step="1"
/>
</el-form-item>
<el-form-item label="是否激活">
<el-switch
v-model="form.state"
inline-prompt
width="60px"
:disabled="form.pagePath == 'dashboard/index'"
:active-value="1"
:inactive-value="0"
active-text=" "
inactive-text=" "
/>
</el-form-item>
<el-form-item label="是否全局" v-if="hasAdmin">
<el-switch
v-model="form.scope"
inline-prompt
width="60px"
:active-value="1"
:inactive-value="0"
:disabled="form.pagePath == 'dashboard/index'"
active-text=" "
inactive-text=" "
/>
</el-form-item>
<el-form-item label="备注" class="top">
<el-input
maxlength="300"
show-word-limit
style="width: 100%"
type="textarea"
:rows="1"
placeholder="请输入内容"
v-model.trim="form.remark"
></el-input>
</el-form-item>
<el-form-item></el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
<div ref="PaneRef">
<el-tabs type="border-card">
<el-tab-pane label="画布" :style="height">
<GridLayout
class="GridLayout"
ref="gridLayout"
v-model:layout="layout"
style="width: 100%"
:style="{ height: GridHeight + 'px' }"
:row-height="rowHeight"
:col-num="12"
prevent-collision
:is-bounded="true"
:vertical-compact="false"
>
<template #item="{ item }">
<div class="imgBox">
<div class="textName">{{ item.name }}</div>
<img
:src="getImg(item.path)"
:style="{
height:
item.h * rowHeight -
(item.h == 1
? 30
: item.h == 2
? 20
: item.h == 3
? 10
: item.h == 4
? -0
: item.h == 5
? -10
: -20) +
'px'
}"
/>
<CloseBold class="remove" @click="removeItem(item.i)" />
</div>
<!-- <span class="text">{{ `${item?.name}` }}</span>
-->
</template>
</GridLayout>
</template>
</GridLayout>
</el-tab-pane>
</el-tabs>
</div>
</div>
</el-card>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
import { ref, reactive, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import BackComponent from '@/components/icon/back/index.vue'
import { mainHeight } from '@/utils/layout'
@@ -145,17 +204,22 @@ import { addDashboard, updateDashboard, queryById } from '@/api/system-boot/csst
import html2canvas from 'html2canvas'
import { useRoute } from 'vue-router'
import { getMenu } from '@/utils/router'
import { useAdminInfo } from '@/stores/adminInfo'
const tableName = ref('')
const tableName1 = ref('')
import { useNavTabs } from '@/stores/navTabs'
// defineOptions({
// name: 'cockpit/popup'
// })
const adminInfo = useAdminInfo()
const hasAdmin = adminInfo.roleCode.some(item => item.includes('operation_manager') || item.includes('root'))
const { go } = useRouter()
const navTabs = useNavTabs()
const { query } = useRoute()
const router = useRouter()
const height = mainHeight(148)
const indicatorHeight = mainHeight(168)
const height = mainHeight(295)
const indicatorHeight = mainHeight(180)
const rowHeight = ref(0)
const pageList: any = ref([])
const GridHeight = ref(0)
@@ -167,6 +231,7 @@ const form: any = reactive({
sort: '100',
id: '',
state: 1,
scope: 0,
icon: '',
pagePath: '',
remark: '',
@@ -205,6 +270,8 @@ const info = () => {
activeNames1.value = []
componentTree().then(res => {
treeComponents.value = res.data
tableName.value = tableName.value == '' ? treeComponents.value[0].name : tableName.value
tableName1.value = tableName1.value == '' ? treeComponents.value[0].children[0].name : tableName1.value
activeNames.value = treeComponents.value.map(item => item.id)
res.data.forEach(item => {
item.children.forEach(k => {
@@ -223,6 +290,7 @@ const info = () => {
form.remark = res.data.remark
form.id = res.data.id
form.state = res.data.state
form.scope = res.data.userId == 0 ? 1 : 0
form.icon = res.data.icon
})
} else {
@@ -251,6 +319,10 @@ const tree2List = (list: any, id: any) => {
// 返回结果数组
return arr
}
const changeTab = (e: any) => {
console.log('🚀 ~ changeTab ~ e:', e)
tableName1.value = treeComponents.filter(item => item.name == e)[0].children[0].name
}
// 删除拖拽
const removeItem = (id: string) => {
const index = layout.value.findIndex(item => item.i === id)
@@ -260,6 +332,7 @@ const removeItem = (id: string) => {
}
}
const wrapper = ref<HTMLElement>()
const PaneRef = ref<HTMLElement>()
const gridLayout = ref<InstanceType<typeof GridLayout>>()
const mouseAt = { x: -1, y: -1 }
@@ -365,6 +438,12 @@ const onSubmit = () => {
if (layout.value.length == 0) {
return ElMessage.warning('页面设计不能为空!')
}
console.log(123, findDuplicateNames(layout.value))
let repeat = findDuplicateNames(layout.value) || []
if (repeat.length > 0) {
return ElMessage.warning(repeat.join('、')+' 组件重复,请删除重复组件!')
}
// const maxValue = Math.max(...layout.value.map(item => item.y + item.h))
// if (maxValue > 6) {
// return ElMessage.warning('组件不能超出当前容器!')
@@ -381,21 +460,27 @@ const onSubmit = () => {
if (valid) {
if (form.id == '') {
await addDashboard({ ...form, containerConfig: JSON.stringify(layout.value), thumbnail: url }).then(
async (res: any) => {
ElMessage.success('新增页面成功!')
// go(-1)
await getMenu()
}
)
await addDashboard({
...form,
containerConfig: JSON.stringify(layout.value),
thumbnail: url,
userId: form.scope == 1 ? '0' : adminInfo.id
}).then(async (res: any) => {
ElMessage.success('新增页面成功!')
// go(-1)
await getMenu()
})
} else {
await updateDashboard({ ...form, containerConfig: JSON.stringify(layout.value), thumbnail: url }).then(
async (res: any) => {
ElMessage.success('修改页面成功!')
// go(-1)
await getMenu()
}
)
await updateDashboard({
...form,
containerConfig: JSON.stringify(layout.value),
thumbnail: url,
userId: form.scope == 1 ? '0' : adminInfo.id
}).then(async (res: any) => {
ElMessage.success('修改页面成功!')
// go(-1)
await getMenu()
})
}
await setTimeout(() => {
router.push({
@@ -406,17 +491,47 @@ const onSubmit = () => {
}
})
}
// 查找重复的name
const findDuplicateNames = (arr: any) => {
// 用于记录每个name出现的次数
const nameCount = {}
// 用于存储重复的name
const duplicates = []
// 遍历数组统计每个name的出现次数
arr.forEach(item => {
const name = item.name
if (nameCount[name]) {
nameCount[name]++
} else {
nameCount[name] = 1
}
})
// 筛选出出现次数大于1的name
for (const name in nameCount) {
if (nameCount[name] > 1) {
duplicates.push(name)
}
}
return duplicates
}
const getImg = throttle((path: string) => {
if (path != undefined) return treeComponentsCopy.value.filter(item => item.path == path)[0]?.image
})
onMounted(() => {
info()
GridHeight.value = wrapper.value?.offsetWidth / 1.77777
rowHeight.value = GridHeight.value / 6 - 11.5
document.documentElement.style.setProperty('--GridLayout-height', rowHeight.value + 10 + 'px')
document.addEventListener('dragover', syncMousePosition)
nextTick(() => {
GridHeight.value = PaneRef.value?.offsetHeight - 60 //wrapper.value?.offsetWidth / 1.77777
setTimeout(() => {
console.log('🚀 ~ wrapper.value?.offsetWidth:', PaneRef.value?.offsetWidth)
}, 500)
rowHeight.value = GridHeight.value / 6 - 11.5
document.documentElement.style.setProperty('--GridLayout-height', rowHeight.value + 10 + 'px')
document.addEventListener('dragover', syncMousePosition)
})
})
onBeforeUnmount(() => {
@@ -436,7 +551,7 @@ onBeforeUnmount(() => {
display: flex;
// flex: 1;
// align-items: center;
width: 24%;
width: 32%;
.el-form-item__content {
width: 100%;
flex: 1;
@@ -516,4 +631,24 @@ onBeforeUnmount(() => {
:deep(.el-form--inline .el-form-item) {
margin-right: 0px;
}
:deep(.el-card__header) {
padding: 13px 20px;
height: 44px;
}
:deep(.el-card__body) {
padding: 10px;
}
.xiaoshou {
cursor: pointer;
}
.image {
display: block;
width: 100%;
height: 100px;
}
.box-card {
width: 100%;
// border: 1px solid #000;
box-shadow: var(--el-box-shadow-light);
}
</style>