修改测试bug 优化页面
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user