You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

976 lines
28 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div
v-loading="pageLoading"
loading-text="加载中..."
class="page-manage-wrap"
>
<div class="page-manage-menu">
<!-- 搜索部分 -->
<div class="page-manage-menu-search">
<el-input
v-model="searchKey"
placeholder="请输入名称"
@keyup.enter.native="filterClick"
/>
<!-- 新增页面按钮 -->
<i
class="page-icon el-icon-plus"
@click="openPageMenuDialog"
/>
</div>
<!-- 页面列表 -->
<div class="page-manage-menu-list">
<template v-if="pageDesignListHasLength">
<el-tree
ref="tree"
:key="treeKey"
class="page-list-tree"
node-key="code"
:default-expanded-keys="defaultExpand"
:current-node-key="currentNodeCode"
:data="pageDesignList"
:props="defaultProps"
:filter-node-method="filterNode"
@node-click="nodeClick"
>
<span
slot-scope="{ node, data }"
class="menu-span"
>
<icon-svg :name="pageIconName(data,node)" />
<span
style="padding-left:4px;font-size:14px"
class="tree-node-name"
>{{ data.name }}</span>
<el-dropdown
class="page-list-dropdown"
placement="bottom-start"
node-key="id"
trigger="click"
>
<span class="el-dropdown-link menu-dropdown-link">
<i class="el-icon-more" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="handleDropdownClick('edit',data,node)">编辑 </el-dropdown-item>
<el-dropdown-item
v-if="data.type!=='catalog'"
@click.native="handleDropdownClick('copy',data,node)"
>复制 </el-dropdown-item>
<el-dropdown-item
class="delete-item"
@click.native="handleDropdownClick('delete',data,node)"
>删除 </el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</span>
</el-tree>
</template>
<el-empty
v-else
slot="empty"
/>
</div>
</div>
<!-- 预览部分 -->
<div class="page-manage-content">
<div class="page-manage-content-top">
<div class="page-manage-content-top-name">
<icon-svg
v-if="activePage.code"
:name="pageIconImg(activePage)"
class="active-page-icon"
/>
{{ activePage.type !== 'catalog'? activePage.name:'' }}
</div>
<div>
<el-button
v-if="pageDesignList.length!==0 && activePage.code"
class="top-button"
icon="el-icon-share"
@click="gopagePreview(activePage)"
>
新窗口打开
</el-button>
<el-button
v-if="pageDesignList.length!==0 && activePage.code"
class="page-manage-content-top-page"
type="primary"
@click="gopageDesign(activePage)"
>
设计
</el-button>
</div>
</div>
<div
class="page-manage-content-body-box"
:style="{ padding: activePage.type !== 'dashBoard' ? '16px' : '0' }"
>
<div class="page-manage-content-body">
<el-empty
v-if="!activePage.code"
slot="empty"
description="请在左侧选择页面修改或新增页面"
class="empty-wrap"
/>
<div
v-else
:class="{
'preview-wrap': true,
'inner-preview-wrap': true,
'padding': activePage.type === 'form'
}"
>
<BigScreenRun
v-if="activePage.type === 'bigScreen'"
:key="activePage.code"
:code="activePage.code"
/>
</div>
</div>
</div>
</div>
<!-- 新增或编辑弹窗 -->
<AddDialog
ref="AddDialog"
@refreshData="reSearch"
/>
<!-- 新增目录弹窗 -->
<el-dialog
:title="catalogData.id ? '编辑目录':'新增目录'"
:visible.sync="catalogVisible"
width="30%"
class="bs-dialog-wrap catalog-dialog bs-el-dialog"
@close="handleClose"
>
<el-form
ref="form"
:model="catalogData"
label-width="80px"
:rules="formRules"
class="bs-el-form"
>
<el-form-item
label="上级目录"
>
<el-select
ref="select"
v-model="catalogData.parentCode"
placeholder="请选择上级目录"
clearable
@change="parentCodeChange"
>
<el-option
key="code"
hidden
:value="catalogData.parentCode"
:label="selectName"
/>
<el-tree
:data="catalogList"
:props="defaultProps"
node-key="code"
:check-on-click-node="true"
:expand-on-click-node="false"
@node-click="handleNodeClick"
>
<span
slot-scope="{ data }"
class="menu-span"
>
<span
style="padding-left:4px;font-size:14px"
class="tree-node-name"
>{{ data.name }}</span>
</span>
</el-tree>
</el-select>
</el-form-item>
<el-form-item
label="目录名称"
prop="name"
>
<el-input v-model="catalogData.name" />
</el-form-item>
<el-form-item
label="排序"
>
<el-input-number
v-model="catalogData.orderNum"
:min="0"
:max="30000"
controls-position="right"
/>
</el-form-item>
</el-form>
<span
slot="footer"
class="dialog-footer"
>
<el-button
class="bs-el-button-default"
@click="catalogVisible = false"
>取消</el-button>
<el-button
type="primary"
@click="addCatalog"
>确定</el-button>
</span>
</el-dialog>
<ChooseTemplateDialog
ref="ChooseTemplateDialog"
:loading="templateLoading"
:has-create="true"
@addNew="addNew"
@useIt="useIt"
/>
<pageMenuDialog
ref="pageMenuDialog"
@addPageDesign="addPageDesign"
/>
</div>
</template>
<script>
import AddDialog from './addDialog.vue'
import ChooseTemplateDialog from './ChooseTemplateDialog.vue'
import pageMenuDialog from './pageMenuDialog.vue'
import BigScreenRun from 'data-room-ui/BigScreenRun/index.vue'
import Icon from 'data-room-ui/assets/images/pageIcon/export'
import { getPageType } from './utils'
// import _ from 'lodash'
import cloneDeep from 'lodash/cloneDeep'
import IconSvg from 'data-room-ui/SvgIcon'
let dashBoardPageCode = null
export default {
name: 'PageManage',
components: {
AddDialog,
ChooseTemplateDialog,
pageMenuDialog,
BigScreenRun,
IconSvg
},
// 路由钩子-进入后
beforeRouteEnter (to, from, next) {
next(vm => {
dashBoardPageCode = from.query.code
})
},
props: [],
data () {
return {
isCatalog: false, // 用来判断当前点击的节点是否是目录
parentNode: { code: '' }, // 用来保存当前的父节点
currentTreeNode: {}, // 保存当前点击的节点信息
selectName: '',
catalogList: [],
currentNodeCode: '',
dashBoardConfig: {},
defaultExpand: [], // 默认展开的节点
currentNode: {}, // 默认选中的节点
flag: true,
pageIcon: Icon.getNameList(), // 获取所有的svg
defaultProps: { // el-tree的配置
children: 'children',
label: 'name'
},
showPage: false, // 显示页面
sort: false, // 排序
searchKey: '', // 关键词
parentCode: '', // 当前选中的子节点的父节点的编码
zNodes: [],
ztreeObj: '',
nodeData: {}, // 当前鼠标悬浮时的树节点
activePage: {
code: null,
type: null,
name: null
}, // 当前选中的的树节点
rightClickForm: {
visible: false,
org: {}
},
catalogVisible: false, // 文件夹的弹窗
isAdd: true, // 判断当前目录是新增还是编辑
catalogData: {
id: '',
code: '',
type: 'catalog',
name: '',
parentCode: '',
orderNum: 0
}, // 文件夹数据
// formConf,
formInitInfo: {}, // 初始的数据
pageDesignList: [], // 页面列表
menuList: [{}],
showHover: false,
pageLoading: false,
treeKey: new Date().getTime(),
formRules: {
name: [
{ required: true, message: '目录名称不能为空', trigger: 'blur' }
]
},
catalogDataList: [], // 存储遍历后的所有目录列表
templateLoading: false
}
},
computed: {
pageDesignListHasLength () {
return this.pageDesignList?.length > 0
}
},
watch: {
catalogVisible: {
handler (value) {
if (value) {
this.openCascader(this.currentTreeNode)
}
}
}
},
mounted () {
this.getDataList()
this.chooseCatalog()
},
methods: {
// 关闭新增页面菜单的弹窗
closePageMenuDialog () {
this.$refs.pageMenuDialog.dialogVisible = false
},
// 点击新增打开页面菜单弹窗
openPageMenuDialog () {
this.$refs.pageMenuDialog.dialogVisible = true
},
parentCodeChange (code) {
this.catalogData.parentCode = code
},
// 初始化新增目录时选择上级目录
chooseCatalog () {
this.parentNode = this.activePage?.type === 'catalog' ? this.activePage : { code: '0', name: '根目录' }
this.catalogData.parentCode = this.parentNode.code
this.selectName = this.parentNode.name
},
// 点击下拉选项中的树节点选择上级目录树节点
handleNodeClick (node) {
this.$set(this.catalogData, 'parentCode', node.code)
this.selectName = node.name
this.$refs.select.blur() // 点击后关闭下拉框因为点击树形控件后select不会自动折叠
},
// 获取所有的目录
openCascader (node) {
const excludeCategory = node.type === 'catalog' && !this.isAdd ? node.code : undefined
this.$dataRoomAxios.post('/bigScreen/category/tree', { searchKey: '', typeList: ['catalog'], excludeCategory, sort: false }).then(data => {
const list = [{ name: '根目录', code: '', children: data }]
this.catalogList = list
}).catch(() => {
})
},
// 默认选择第一项
chooseFirstNode () {
this.defaultExpand = []
// 如果存在activePage则将activePage设置为高亮
if (this.activePage && this.activePage.code) {
this.currentNodeCode = this.activePage.code
this.$nextTick(() => {
if (this.$refs.tree) {
this.$refs.tree.setCurrentKey(this.currentNodeCode)
}
})
this.defaultExpand.push(this.currentNodeCode)
this.currentNode = { ...this.activePage }
} else {
// 如果不存在则默认选择第一项(或者是第一个目录的第一项)
if (this.pageDesignList?.length > 0 && !(this.pageDesignList?.length === 1 && this.pageDesignList[0].type === 'catalog' && (!this.pageDesignList[0].children || this.pageDesignList[0].children?.length === 0))) {
const code = this.getDefaultNode(this.pageDesignList)
if (code) {
this.currentNodeCode = code
this.activePage = { ...this.currentNode }
this.defaultExpand.push(code)
this.$nextTick(() => {
this.$refs.tree.setCurrentKey(code)
})
this.isCatalog = false
}
} else {
this.activePage = { code: '', name: '', type: '' }
}
}
},
// 设置默认节点
getDefaultNode (nodeList) {
for (const node of nodeList) {
if (this.flag) {
if (node.children && node.children.length > 0 && node.type === 'catalog') {
return this.getDefaultNode(node.children)
} else if (!(node.children && node.children?.length > 0) && node?.type === 'catalog') {
continue
} else {
this.flag = false
this.currentNode = node
return node.code
}
} else {
return this.currentNode.code
}
}
},
// 左侧菜单图标
pageIconName (data, node) {
if (data.type === 'bigScreen') {
return this.pageIcon[2]
} else {
return node.expanded ? this.pageIcon[1] : this.pageIcon[0]
}
},
// 顶部图标
pageIconImg () {
return this.pageIcon[2]
},
// 树节点查询
filterClick () {
this.$refs.tree.filter(this.searchKey)
},
filterNode (value, data) {
if (!value) return true
return data.name.indexOf(value) !== -1
},
// 预览
gopagePreview (nodeData) {
if (nodeData.code && nodeData.type === 'bigScreen') {
const { href } = this.$router.resolve({
path: window.BS_CONFIG?.routers?.previewUrl || '/big-screen/preview', // 这里写的是要跳转的路由地址
query: {
code: nodeData.code
}
})
window.open(href, '_blank')
} else if (!nodeData.code) {
this.$message.warning('请先选择表单或页面')
}
},
// 点击节点
nodeClick (treeNode, nodeObj, val) {
this.currentTreeNode = treeNode
// 点击的节点为目录,则当前父节点为目录
if (treeNode.type === 'catalog') {
this.parentNode = cloneDeep(treeNode)
this.isCatalog = true
} else {
this.isCatalog = false
this.activePage = treeNode
// 点击的节点非目录,则为当前节点的父节点
this.parentNode = (!treeNode.parentCode || treeNode.parentCode === '0') ? { code: '0', name: '根目录' } : cloneDeep(nodeObj.parent.data)
}
this.catalogData.parentCode = this.parentNode.code
this.selectName = this.parentNode.name
},
handleClose () {
this.catalogVisible = false
this.$refs.form.clearValidate()
},
// 获取页面的列表(获取,搜索,排序)
getDataList () {
this.pageLoading = true
this.$dataRoomAxios.post('/bigScreen/category/tree', { searchKey: this.searchKey, sort: this.sort }).then(data => {
this.pageDesignList = data
// 如果有addModel这个参数说明是从页面直接新增过来的直接进入页面或者表单的填写状态
if (this.$route.query.add) {
this.$refs.AddDialog.init(undefined, this.parentNode, 'form')
}
if (dashBoardPageCode) {
this.$nextTick(() => {
const currentNode = this.findItemBycode(dashBoardPageCode, data)
if (currentNode && currentNode.code) {
this.activePage = currentNode
if (this.$refs.tree) {
this.$refs.tree.setCurrentKey(currentNode)
this.defaultExpand.push(currentNode.code)
}
} else {
this.chooseFirstNode()
}
})
} else {
this.chooseFirstNode()
}
}).catch(() => {
}).finally(() => {
this.pageLoading = false
})
},
// 遍历树节点匹配code
findItemBycode (code, list) {
let node = list.find(item => item.code === code)
if (node) {
return node
} else {
for (let i = 0; i < list?.length; i++) {
if (list[i].children instanceof Array && list[i].children?.length > 0) {
node = this.findItemBycode(code, list[i].children)
if (node) {
return node
}
}
}
return null
}
},
// 对页面进行操作
handleDropdownClick (command, nodeData, node) {
switch (command) {
case 'copy':
this.copyPege(nodeData, node)
break
case 'edit':
this.toEdit(nodeData, node)
break
case 'delete':
this.deletePageDesign(nodeData, node)
break
// case 'code':
// this.code(nodeData, node)
// break
}
},
// code (nodeData, node) {
// axios({
// method: 'get',
// url: `${window.BS_CONFIG.baseUrl}/code/generation/adminPage/${nodeData.code}`,
// headers: {
// },
// // 通过URL传参后端通过 @RequestParam 注解获取参数
// params: {},
// // 通过body传参后端通过 @RequestBody 注解获取参数
// data: {},
// withCredentials: false,
// responseType: 'arraybuffer'
// }).then(res => {
// const fileUrl = window.URL.createObjectURL(new Blob([res.data]))
// // 创建超链接
// const fileLink = document.createElement('a')
// fileLink.href = fileUrl
// // 设置下载文件名
// let responseFileName = res.headers.filename
// // 解决中文乱码
// responseFileName = window.decodeURI(responseFileName)
// fileLink.setAttribute('download', responseFileName)
// document.body.appendChild(fileLink)
// // 模拟人工点击下载超链接
// fileLink.click()
// this.submitLoading = false
// // 释放资源
// document.body.removeChild(fileLink)
// window.URL.revokeObjectURL(fileUrl)
// this.step++
// }).catch((error) => {
// this.submitLoading = false
// console.error(error)
// })
// },
// 复制页面
copyPege (nodeData, node) {
this.$dataRoomAxios.post(`/${nodeData.type}/design/copy/${nodeData.code}`).then(() => {
this.getDataList()
})
},
// 新增大屏或新增页面,从空白新建
addNew (parentNode, type) {
this.$refs.AddDialog.init(undefined, this.parentNode, type)
this.flag = true
},
// 大屏 dashboard从模版新建, 使用某个模版新建
useIt (pageTemplateId, parentNode, type) {
this.templateLoading = true
const className = 'com.gccloud.dataroom.core.module.manage.dto.DataRoomPageDTO'
this.$dataRoomAxios.post(`/bigScreen/${type}/design/add/template`, {
pageTemplateId,
parentCode: parentNode.code,
type,
className
}).then((code) => {
const path = window.BS_CONFIG?.routers?.designUrl || '/big-screen/design'
// const { href } = this.$router.resolve({
// path,
// query: {
// code: code
// }
// })
// window.open(href, '_self')
this.$router.push({
path,
query: {
code: code
}
})
}).finally(() => {
this.templateLoading = true
})
},
// 新增页面/表单/目录
addPageDesign (page) {
const type = page.type
const categories = page.categories
if (type !== 'catalog') {
// 如果是大屏,弹出选择模版页面
if (['bigScreen'].includes(type)) {
this.$refs.ChooseTemplateDialog.init(this.parentNode, type)
return
}
this.$refs.AddDialog.init(undefined, this.parentNode, type, categories)
this.flag = true
} else {
// 新增时初始化目录配置
this.catalogData = {
id: '',
code: '',
type: 'catalog',
name: '',
parentCode: this.parentNode.code,
orderNum: 0
}
this.isAdd = true
this.catalogVisible = true
}
},
// 刷新页面
reSearch (treeNode, id) {
this.getDataList()
},
// 编辑
toEdit (nodeData, nodeObj) {
// 编辑目录
if (nodeData.type === 'catalog') {
this.catalogVisible = true
this.catalogData.name = nodeData.name
this.isAdd = false
this.catalogData.id = nodeData.id
this.catalogData.code = nodeData.code
this.catalogData.orderNum = nodeData.orderNum
this.parentNode = (!nodeData.parentCode || nodeData.parentCode === '0') ? { code: '0', name: '根目录' } : cloneDeep(nodeObj.parent.data)
this.catalogData.parentCode = this.parentNode.code
this.selectName = this.parentNode.name
} else {
this.$refs.AddDialog.init(nodeData, this.parentNode)
}
},
// 点击新增/编辑目录
addCatalog () {
this.$refs.form.validate(async (valid) => {
if (!valid) {
return
}
if (this.isAdd) {
this.$dataRoomAxios.post('/bigScreen/category/add',
{
...this.catalogData,
id: '',
code: ''
}).then(data => {
this.catalogVisible = false
this.getDataList()
this.flag = true
// 关闭页面菜单的弹窗
this.closePageMenuDialog()
}).catch(() => {
})
} else {
this.$dataRoomAxios.post('/bigScreen/category/update', { ...this.catalogData, excludeCategory: this.catalogData.code }).then(data => {
this.catalogVisible = false
this.getDataList()
}).catch(() => {
})
}
})
},
// 删除页面设计
deletePageDesign (nodeData, node) {
const type = getPageType(nodeData.type)// 由于类型与接口不统一需要转化一下
const url = type === 'category' ? `/bigScreen/category/delete/${nodeData.code}` : `/bigScreen/${type}/design/delete/${nodeData.code}`// 接口地址
this.$confirm('确定删除该页面设计?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
customClass: 'bs-el-message-box'
}).then(async () => {
this.$dataRoomAxios.post(url).then(() => {
this.$message({
type: 'success',
message: '删除成功'
})
this.flag = true
this.activePage.code = ''
this.chooseFirstNode()
this.$refs.tree.remove(node)
if (nodeData.type === 'catalog' && this.parentCode === nodeData.code) {
this.parentCode = '0'
}
}).catch(() => {
this.$message({
type: 'error',
message: '删除失败!'
})
})
}).catch()
},
// 点击进入页面设计
gopageDesign (nodeData) {
const path = window.BS_CONFIG?.routers?.designUrl || '/big-screen/design'
const openType = nodeData.type === 'report' ? '_blank' : '_self'
const { href } = this.$router.resolve({
path,
query: {
code: nodeData.code
}
})
window.open(href, openType)
}
}
}
</script>
<style lang="scss" scoped>
.page-type-cover {
position: absolute;
top: 0;
left: 16px;
color: #fff;
background: #00000020;
padding: 4px;
font-size: 12px;
}
.page-manage-wrap{
display: flex;
.page-manage-menu{
width: 260px;
border-right: 2px solid #F5F7FA;
.page-manage-menu-search{
display: flex;
align-items: center;
padding: 10px 15px;
box-sizing: border-box;
justify-content: space-around;
.input-with-select{
margin-bottom: 0px;
}
.page-icon{
font-size: 20px;
margin-left: 10px;
color: var(--bs-el-color-primary);
&:hover{
cursor: pointer;
}
}
}
}
.page-manage-menu-list{
width: 100%;
overflow: auto;
height: calc(100vh - 40px - 50px);
.tree-node-name{
width: 170px;
display: inline-block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.el-icon-document{
font-size: 16px;
padding: 5px 5px 0 0;
color: #007afe;
}
.el-icon-notebook-1{
font-size: 16px;
padding: 5px 5px 0 0;
color: #50D4FD;
}
.el-icon-folder{
font-size: 16px;
padding: 5px 5px 0 0;
color: #6477FF;
}
.el-icon-folder-opened{
font-size: 16px;
padding: 5px 5px 0 0;
color: #6477FF;
}
}
.page-manage-content{
width: calc(100vw - 260px);
height: calc(100vh - 40px);
.page-manage-content-top{
height: 50px;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
.page-name-icon{
color: var(--bs-el-color-primary);
padding-right: 10px;
}
}
.page-manage-content-body-box{
width: 100%;
height: calc(100vh - 40px - 50px);
background-color: #F5F7FA;
.page-manage-content-body{
height: 100%;
background-color: #fff;
position: relative;
overflow: auto;
overflow-x: hidden;
::v-deep .el-input__suffix-inner{
/*pointer-events: none!important;*/
}
.preview-wrap{
/*pointer-events: none;*/
width: 100%;
height: 100%;
position: absolute;
.admin-page-wrap {
height: 100%;
background: #F5F7FA;
}
}
.empty-wrap{
position: absolute;
top:50%;
left:50%;
transform: translate(-50%,-50%);
color: #AAAAAA;
}
}
}
}
}
.el-dropdown{
cursor: pointer;
}
.catalog-dialog{
::v-deep .el-dialog__body{
min-height: 80px;
}
}
.el-icon-delete{
color: #DF2A2A;
}
.el-dropdown-menu--mini .el-dropdown-menu__item i{
padding-top: 6px;
}
.el-dropdown-menu--mini ::v-deep .el-dropdown-menu__item{
display: flex;
min-width: 100px!important;
line-height: 36px;
margin-bottom: 10px;
.page-opt-list-icon{
font-size: 16px;
padding: 10px 5px 0 0;
color: #007afe;
}
.page-dropdown-right{
.page-name{
font-size: 14px;
}
.page-desc{
color: #878A8B;
font-size: 12px;
line-height: 20px;
}
}
}
.menu-span{
width: 100%;
display: flex;
align-items: center;
.el-dropdown{
position: absolute;
right: 10px;
}
}
.disabled{
pointer-events: auto!important;
cursor: not-allowed!important;
}
.page-list-active{
cursor: pointer;
background-color: #F4F4F4;
}
.el-icon-rank{
cursor: move;
}
.active-page-icon{
margin-right: 5px;
}
.sort-icon {
font-size: 20px;
margin-left: 10px;
color: var(--bs-el-color-primary);
&:hover{
cursor: pointer;
}
}
/* 去除tree前面的小三角形*/
.page-list-tree ::v-deep .el-tree-node__content > .el-tree-node__expand-icon{
width: 20px;
opacity: 0 !important;
}
/*选中树节点后*/
.page-list-tree ::v-deep .ztree li a.curSelectedNode span{
color: var(--bs-el-color-primary)!important;
}
#settingDropdown{
display: inline-block;
float: right;
}
::v-deep .el-tree-node{
line-height: 40px;
.el-tree-node__content{
line-height: 40px;
height: 100%;
}
}
/*当前tree节点激活样式*/
.page-list-tree ::v-deep .is-current>.el-tree-node__content{
background: #007aff10;
color: var(--bs-el-color-primary);
}
.page-list-tree ::v-deep .is-current>.el-tree-node__content::before{
position: absolute;
left: 0;
border-left: 4px solid var(--bs-el-color-primary);
content: "";
height: 40px;
width: 4px;
}
::v-deep .el-icon-more{
transform: rotate(90deg);
color: #999999;
font-size: 10px;
}
/*滚动条样式*/
::v-deep ::-webkit-scrollbar {
width: 6px;
border-radius: 4px;
/*height: 4px;*/
}
::v-deep ::-webkit-scrollbar-thumb {
background: #dddddd !important;
border-radius: 10px;
}
.padding {
padding: 20px;
background: #fff;
}
.catalog-cascader{
width: 100%!important;
}
.delete-item{
color:#ea0b30!important;
}
</style>