zn-admin-vue3-wcs/src/views/mapPage/realTimeMap/editMap.vue
2025-02-11 17:04:33 +08:00

1055 lines
28 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="top-tool">
<div class="top-tool-list">
<div v-for="item in state.topToolList" :key="item.switchType" class="top-tool-item">
<el-popover
placement="bottom"
:width="80"
trigger="click"
v-if="item.switchType === 'move' || item.switchType === 'revolve'"
:disabled="currentItemIndex === -1"
>
<template #reference>
<div
class="tool-item"
:class="
toolbarSwitchType === item.switchType
? 'tool-active'
: item.isActive
? 'right-tool-active'
: ''
"
@click="toolbarClick(item)"
>
<Icon :icon="item.icon" :size="24" />
<div class="name"> {{ item.name }} </div>
</div>
</template>
<!-- 位置 -->
<el-form :model="state.moveForm" v-if="item.switchType === 'move'">
<el-form-item label="X">
<el-input v-model="state.moveForm.locationX" placeholder="请输入" />
</el-form-item>
<el-form-item label="Y">
<el-input v-model="state.moveForm.y" placeholder="请输入" />
</el-form-item>
<div style="text-align: right">
<el-button size="small" color="#00329F" @click="moveFormSubmit">确认</el-button>
</div>
</el-form>
<!-- 旋转 -->
<el-form :model="state.rotationForm" v-if="item.switchType === 'revolve'">
<el-form-item label="角度">
<el-input v-model="state.rotationForm.angle" placeholder="请输入" />
</el-form-item>
<div style="text-align: right">
<el-button size="small" color="#00329F" @click="rotationFormSubmit">确认</el-button>
</div>
</el-form>
<!-- 字体 -->
<el-form :model="state.rotationForm" v-if="item.switchType === 'text'">
<el-form-item label="角度">
<el-input v-model="state.rotationForm.angle" placeholder="请输入" />
</el-form-item>
<div style="text-align: right">
<el-button size="small" color="#00329F" @click="rotationFormSubmit">确认</el-button>
</div>
</el-form>
</el-popover>
<div
v-else
class="tool-item"
:class="
toolbarSwitchType === item.switchType
? 'tool-active'
: item.isActive
? 'right-tool-active'
: ''
"
@click="toolbarClick(item)"
>
<Icon :icon="item.icon" :size="24" />
<div class="name"> {{ item.name }} </div>
</div>
<div
class="line"
v-if="
item.switchType === 'saveAs' ||
item.switchType === 'delete' ||
item.switchType === 'grid'
"
></div>
</div>
</div>
<div class="right-tool-list" v-if="state.isShowToolbar">
<div
v-for="item in state.rightToolList"
:key="item.switchType"
class="tool-item"
:class="
toolbarSwitchType === item.switchType
? 'tool-active'
: item.isActive
? 'right-tool-active'
: ''
"
@click="toolbarClick(item)"
>
<Icon :icon="item.icon" :size="24" />
<div class="name"> {{ item.name }} </div>
</div>
</div>
</div>
<!-- @mousewheel.prevent="rollImg" -->
<div
class="map-box"
ref="imgWrap"
style="overflow: hidden"
:style="{ cursor: state.cursorStyle }"
>
<div
class="map-box-inner"
ref="image"
@mousedown.stop="startDrawSelection"
@mousemove.stop="updateDrawSelection"
@mouseup.stop="endDrawSelection"
>
<img :src="imgBgObj.imgUrl" class="map-box-img" id="mapBg" />
<div
class="map-box-inner-dot"
@click="mapClick"
:class="state.isShowGrid ? 'grid-show' : ''"
v-if="interfaceRefreshed"
>
<VueDragResizeRotate
v-for="(item, index) in allHistoryList[currentIndex]"
:key="index"
:parent="true"
:x="item.locationX"
:y="item.locationY"
:w="item.locationWide"
:h="item.locationDeep"
:r="item.angle"
@rotatestop="(degree) => rotateEnd(degree, item, index)"
@dragstop="(x, y) => dragEnd(x, y, item, index)"
@resizestop="(x, y, width, height) => resizeEnd(x, y, width, height, item, index)"
@activated="() => activatedHandle(item, index)"
@deactivated="deactivatedHandle"
:draggable="item.draggable"
:resizable="item.resizable"
:rotatable="item.rotatable"
:lock-aspect-ratio="item.lockAspectRatio"
style="border: none"
>
<div
class="sdiv"
:style="
currentItemIndex === index ? 'border: 1px dashed #000;box-sizing: border-box;' : ''
"
>
<!-- <img
:src="item.img"
alt=""
style="width: 100%; height: 100%"
/> -->
<div
v-if="item.type !== 7"
style="width: 100%; height: 100%; background-color: #000; border-radius: 50%"
></div>
<div
v-if="item.type === 7"
:style="{
fontSize: item.fontSize + 'px',
fontFamily: item.fontFamily,
color: item.fontColor
}"
>
{{ item.text }}
</div>
</div>
</VueDragResizeRotate>
<!-- 文档 https://github.com/a7650/vue3-draggable-resizable/blob/main/docs/document_zh.md#resizable -->
</div>
<!-- 绘制框选区域 -->
<div
v-if="state.drawSelectionArea"
:style="{
position: 'absolute',
left: `${state.drawSelectionAreaBox.x}px`,
top: `${state.drawSelectionAreaBox.y}px`,
width: `${state.drawSelectionAreaBox.width}px`,
height: `${state.drawSelectionAreaBox.height}px`,
border: '1px solid blue',
backgroundColor: 'rgba(0, 0, 255, 0.1)',
zIndex: 99999
}"
></div>
<!-- 文字输入区域 -->
<input
v-if="state.showInputBox"
ref="inputBoxRef"
v-model="state.inputBoxValue"
@keyup.enter="handleInputEnd"
@blur="handleInputEnd"
:style="{
fontSize: state.inputBoxStyle.fontSize + 'px',
fontFamily: state.inputBoxStyle.fontFamily,
color: state.inputBoxStyle.fontColor,
left: state.inputBoxStyle.locationX + 'px',
top: state.inputBoxStyle.locationY + 'px'
}"
class="input-box-class"
/>
</div>
</div>
<!-- 节点编辑 -->
<editNodeProperties
ref="editNodePropertiesRef"
:positionMapId="imgBgObj.positionMapId"
@submitNodeSuccess="submitNodeSuccess"
/>
<!-- 文字输入弹窗 -->
<textFormToolDialog
ref="textFormToolDialogRef"
v-if="state.textFormToolShow"
@textFormSuccess="textFormSuccess"
/>
<!-- 图层选择 -->
<layerSelectionToolDialog v-if="state.isShowLayer" ref="layerSelectionToolDialogRef" />
<!-- 设备弹窗选择 -->
<equipmentToolDialog ref="equipmentToolDialogRef" :positionMapId="imgBgObj.positionMapId" />
</template>
<script setup>
import { ref, defineComponent, reactive, nextTick, onMounted } from 'vue'
import editNodeProperties from './components-tool/editNodeProperties.vue'
import textFormToolDialog from './components-tool/textFormToolDialog.vue'
import equipmentToolDialog from './components-tool/equipmentToolDialog.vue'
import layerSelectionToolDialog from './components-tool/layerSelectionToolDialog.vue'
import * as MapApi from '@/api/map/map'
import cursorCollection from './cursorCollection'
defineOptions({ name: 'editMapPageRealTimeMap' })
const equipmentToolDialogRef = ref() //设备弹窗
const textFormToolDialogRef = ref() //文字输入弹窗
const inputBoxRef = ref() //文字输入框
const message = useMessage() // 消息弹窗
const formLoading = ref(false)
const allHistoryList = ref([]) //全部的历史记录
const currentIndex = ref(0) //用于记录是哪条历史记录的
const currentItemIndex = ref(-1) //用于记录是在编辑那个具体的节点、图标等
const allMapPointInfo = ref([]) //所有的图标的列表
// 缩放停止
const interfaceRefreshed = ref(true)
const resizeEnd = (x, y, w, h, item, index) => {
interfaceRefreshed.value = false
console.log('缩放', w, h)
nextTick(() => {
allMapPointInfo.value[index].locationX = x
allMapPointInfo.value[index].locationY = y
allMapPointInfo.value[index].locationWide = w
allMapPointInfo.value[index].locationDeep = h
addEditHistory()
})
}
// 拖拽停止
const dragEnd = (x, y, item, index) => {
console.log('拖拽')
if (x === item.locationX && y === item.locationY) return
allMapPointInfo.value[index].locationX = x
allMapPointInfo.value[index].locationY = y
addEditHistory()
}
// 旋转
const rotateEnd = (angle, item, index) => {
console.log('旋转')
allMapPointInfo.value[index].angle = angle
addEditHistory()
}
//选中
const editNodePropertiesRef = ref()
const activatedHandle = (item, index) => {
// console.log('选中', item, index)
currentItemIndex.value = index
//节点编辑
if (toolbarSwitchType.value === 'editNode' && item.type !== 7) {
editNodePropertiesRef.value.open(item)
}
}
//非选中
const deactivatedHandle = () => {
console.log('取消选中')
}
//添加历史记录
const addEditHistory = () => {
//要判断是不是在最新的记录上修改 如果不是 要把currentIndex之后的记录都删掉 保持当前修改是最新的
if (currentIndex.value !== allHistoryList.value.length - 1) {
allHistoryList.value = allHistoryList.value.splice(0, currentIndex.value)
currentIndex.value = allHistoryList.value.length
allHistoryList.value.push(JSON.parse(JSON.stringify(allMapPointInfo.value)))
} else {
allHistoryList.value.push(JSON.parse(JSON.stringify(allMapPointInfo.value)))
currentIndex.value++
}
interfaceRefreshed.value = true
console.log(allHistoryList.value, 'allHistoryList')
}
//上一步
const backPreviousStep = () => {
if (currentIndex.value > 0) {
currentIndex.value--
allMapPointInfo.value = allHistoryList.value[currentIndex.value]
console.log('撤销', allHistoryList.value[currentIndex.value])
} else {
message.warning('没了老铁')
}
}
//下一步
const backNextStep = () => {
if (currentIndex.value < allHistoryList.value.length - 1) {
currentIndex.value++
allMapPointInfo.value = allHistoryList.value[currentIndex.value]
console.log('重做', allHistoryList.value[currentIndex.value])
} else {
message.warning('没了老铁')
}
}
//地图点击
const mapClick = (e) => {
if (toolbarSwitchType.value === 'drawNodes') {
//绘制节点
allMapPointInfo.value.push({
locationX: e.offsetX,
locationY: e.offsetY,
locationDeep: 16,
locationWide: 16,
angle: 0,
draggable: false,
resizable: false,
rotatable: false,
lockAspectRatio: false, //横纵比
img: '',
type: 1 //默认类型1 路径节点
})
currentIndex.value++
allHistoryList.value.push(JSON.parse(JSON.stringify(allMapPointInfo.value)))
}
//文字输入
if (toolbarSwitchType.value === 'text') {
state.showInputBox = true
state.inputBoxStyle = {
fontSize: state.textForm.fontSize,
fontFamily: state.textForm.fontFamily,
fontColor: state.textForm.fontColor,
locationX: e.offsetX,
locationY: e.offsetY
}
// 聚焦输入框
setTimeout(() => {
inputBoxRef.value.focus()
}, 0)
}
}
//输入文字样式改变
const textFormSuccess = (form) => {
state.textForm = JSON.parse(JSON.stringify(form))
state.inputBoxStyle = {
fontSize: `${form.fontSize}`,
fontFamily: `${form.fontFamily}`,
fontColor: `${form.fontColor}`
}
}
//输入结束
const handleInputEnd = () => {
if (state.inputBoxValue) {
state.showInputBox = false
allMapPointInfo.value.push({
type: 7, //类型 7文字
mapId: '', //地图的id
locationX: state.inputBoxStyle.locationX, //x
locationY: state.inputBoxStyle.locationY, //y
locationDeep: '', //h
locationWide: '', //w
angle: 0, //旋转角度
draggable: true, //是否可以拖动
resizable: false, //是否可以调整大小
rotatable: false, //是否可以旋转
lockAspectRatio: true, //是否锁定比例
img: '', //图片
text: state.inputBoxValue, //文字内容
fontColor: state.inputBoxStyle.fontColor, //文字颜色
fontFamily: state.inputBoxStyle.fontFamily, //字体类型
fontSize: state.inputBoxStyle.fontSize
})
addEditHistory()
state.inputBoxValue = ''
}
}
//保存地图
const saveMap = async () => {
//节点的保存
await saveNodeList()
}
//节点的保存
const saveNodeList = async () => {
formLoading.value = true
let list = allHistoryList.value[currentIndex.value]
list.forEach((item, index) => {
item.locationX = item.locationX
item.locationY = item.locationY
item.type = item.type || 1
if (item.type === 1) {
item.dataJson = ''
} else {
item.dataJson = item.dataJson
}
})
try {
await MapApi.batchSaveOrEditOrDelMapItem(imgBgObj.positionMapId, list)
message.success('创建成功')
} finally {
formLoading.value = false
}
}
//编辑节点成功
const submitNodeSuccess = (item) => {
allHistoryList.value[currentIndex.value][currentItemIndex.value] = item
}
//工具栏点击
const toolbarSwitchType = ref('')
const state = reactive({
topToolList: [
{
switchType: 'open',
name: '打开',
icon: 'ep:folder-add',
isActive: false
},
{
switchType: 'save',
name: '保存',
icon: 'ep:folder-checked',
isActive: false
},
{
switchType: 'saveAs',
name: '另存为',
icon: 'ep:folder-opened',
isActive: false
},
{
switchType: 'choose',
name: '选择',
icon: 'ep:position',
isActive: false
},
{
switchType: 'move',
name: '移动',
icon: 'ep:rank',
isActive: false
},
{
switchType: 'revolve',
name: '旋转',
icon: 'ep:refresh-right',
isActive: false
},
{
switchType: 'copy',
name: '复制',
icon: 'ep:document',
isActive: false
},
{
switchType: 'paste',
name: '粘贴',
icon: 'ep:copy-document',
isActive: false
},
{
switchType: 'delete',
name: '删除',
icon: 'ep:delete',
isActive: false
},
{
switchType: 'tools',
name: '工具',
icon: 'ep:briefcase',
isActive: false
},
{
switchType: 'lineLibrary',
name: '线库',
icon: 'ep:message-box',
isActive: false
},
{
switchType: 'region',
name: '区域',
icon: 'ep:full-screen',
isActive: false
},
{
switchType: 'text',
name: '文字',
icon: 'ep:edit-pen',
isActive: false
},
{
switchType: 'equipment',
name: '设备',
icon: 'ep:video-camera-filled',
isActive: false
},
{
switchType: 'ranging',
name: '测距',
icon: 'ep:folder-add',
isActive: false
},
{
switchType: 'layer',
name: '图层',
icon: 'ep:copy-document',
isActive: false
},
{
switchType: 'marker',
name: '标记',
icon: 'ep:map-location',
isActive: false
},
{
switchType: 'grid',
name: '网格',
icon: 'ep:grid',
isActive: false
},
{
switchType: 'larger',
name: '放大',
icon: 'ep:zoom-in',
isActive: false
},
{
switchType: 'smaller',
name: '缩小',
icon: 'ep:zoom-out',
isActive: false
},
{
switchType: 'withdraw',
name: '撤回',
icon: 'ep:top-left',
isActive: false
},
{
switchType: 'next',
name: '重做',
icon: 'ep:top-right',
isActive: false
}
],
rightToolList: [
{
switchType: 'drawNodes',
name: '绘制节点',
icon: 'ep:circle-plus-filled',
isActive: false
},
{
switchType: 'editNode',
name: '编辑节点',
icon: 'ep:circle-plus-filled',
isActive: false
},
{
switchType: 'drawRoute',
name: '绘制路线',
icon: 'ep:semi-select',
isActive: false
},
{
switchType: 'editRoute',
name: '编辑路线',
icon: 'ep:semi-select',
isActive: false
}
],
isShowToolbar: false, //工具栏展示隐藏
isShowGrid: false, //网格展示隐藏
moveForm: {
locationX: '',
locationY: ''
}, //移动的表单
rotationForm: {
angle: ''
}, //旋转的表单
copyMapItem: '', //复制的值
cursorStyle: 'auto',
drawSelectionArea: false, //绘制框选区域
drawSelectionAreaBox: { x: 0, y: 0, width: 0, height: 0 }, //绘制区域的位置,长宽
drawSelectionAreaStartPos: { x: 0, y: 0 }, //开始绘制的点位
drawSelectionAreaSelectedPoints: [], //绘制选中的list
textForm: {
fontFamily: 'SimSun',
fontSize: '14',
fontColor: '#000000'
}, //默认宋体14#000000
textFormToolShow: false, //文字表单显示隐藏
showInputBox: false, //输入框显示隐藏
inputBoxStyle: {}, //输入框的样式
inputBoxValue: '', //输入的值
isShowLayer: false //图层显示
})
const toolbarClick = (item) => {
let type = item.switchType
if (
currentItemIndex.value &&
(type === 'move' || type === 'revolve' || type === 'copy' || type === 'delete')
) {
message.warning('请先选择要操作的对象')
return
}
//粘贴
if (type === 'paste' && !state.copyMapItem) {
message.warning('请先复制对象')
return
}
if (
(type === 'tools' || type === 'text' || type === 'layer' || type === 'grid') &&
toolbarSwitchType.value === type
) {
toolbarSwitchType.value = ''
} else {
toolbarSwitchType.value = type
}
if (toolbarSwitchType.value !== 'text') {
state.cursorStyle = `auto`
state.textFormToolShow = false
state.showInputBox = false
state.inputBoxValue = ''
}
switch (type) {
case 'open':
// 打开
break
case 'save':
//保存
saveMap()
break
case 'saveAs':
//另存为 存为json文件 无法直接访问用户的文件系统 不能选择存在那个文件夹里面
const jsonString = JSON.stringify(allHistoryList.value[currentIndex.value], null, 2)
const blob = new Blob([jsonString], { type: 'application/json' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'mapJson.json'
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
URL.revokeObjectURL(url)
message.success('下载成功')
break
case 'choose':
//选择
break
case 'move':
//移动
break
case 'revolve':
break
case 'copy':
//复制
state.copyMapItem = allHistoryList.value[currentIndex.value][currentItemIndex.value]
break
case 'paste':
//粘贴
let copyObj = JSON.parse(JSON.stringify(state.copyMapItem))
copyObj.locationX = copyObj.locationX + 50
copyObj.locationY = copyObj.locationY + 50
allMapPointInfo.value.push(copyObj)
addEditHistory()
break
case 'delete':
//删除
allMapPointInfo.value.splice(currentItemIndex.value, 1)
addEditHistory()
break
case 'tools':
//工具
if (toolbarSwitchType.value === 'tools') {
state.isShowToolbar = true
item.isActive = true
} else {
state.isShowToolbar = false
item.isActive = false
}
break
case 'lineLibrary':
// 线库
break
case 'region':
// 区域
break
case 'text':
//文字
if (toolbarSwitchType.value === 'text') {
state.textFormToolShow = true
state.cursorStyle = `url('${cursorCollection.input}'),auto`
} else {
state.cursorStyle = `auto`
state.textFormToolShow = false
state.showInputBox = false
state.inputBoxValue = ''
}
break
case 'ranging':
// 测距
break
case 'layer':
//图层
if (toolbarSwitchType.value === 'layer') {
state.isShowLayer = true
item.isActive = true
} else {
state.isShowLayer = false
item.isActive = false
}
break
case 'marker':
// 标记
break
case 'grid':
//网格
if (toolbarSwitchType.value === 'grid') {
state.isShowGrid = true
item.isActive = true
} else {
state.isShowGrid = false
item.isActive = false
}
break
case 'larger':
//放大
break
case 'smaller':
//缩小
break
case 'withdraw':
//上一步
backPreviousStep()
break
case 'next':
//下一步
backNextStep()
break
case 'drawNodes':
//绘制节点
break
case 'editNode':
// 编辑节点
break
case 'drawRoute':
//绘制路线
break
case 'editRoute':
// 编辑路线
break
case 'equipment':
// 设备
equipmentToolDialogRef.value.open()
break
}
}
//移动工具表单提交
const moveFormSubmit = () => {
allHistoryList.value[currentIndex.value][currentItemIndex.value].locationX =
state.moveForm.locationX
allHistoryList.value[currentIndex.value][currentItemIndex.value].locationY =
state.moveForm.locationY
}
//旋转工具表单提交
const rotationFormSubmit = () => {
allHistoryList.value[currentIndex.value][currentItemIndex.value].angle = state.rotationForm.angle
}
//开始框选绘制
const startDrawSelection = (event) => {
if (toolbarSwitchType.value !== 'lineLibrary' && toolbarSwitchType.value !== 'region') return
state.drawSelectionArea = true
state.drawSelectionAreaStartPos = { x: event.offsetX, y: event.offsetY }
state.drawSelectionAreaBox = { x: event.offsetX, y: event.offsetY, width: 0, height: 0 }
}
const updateDrawSelection = (event) => {
if (toolbarSwitchType.value !== 'lineLibrary' && toolbarSwitchType.value !== 'region') return
if (state.drawSelectionArea) {
state.drawSelectionAreaBox.width = event.offsetX - state.drawSelectionAreaStartPos.x
state.drawSelectionAreaBox.height = event.offsetY - state.drawSelectionAreaStartPos.y
}
}
//结束框选绘制
const endDrawSelection = () => {
if (toolbarSwitchType.value !== 'lineLibrary' && toolbarSwitchType.value !== 'region') return
let points = allHistoryList.value[currentIndex.value]
state.drawSelectionArea = false
state.drawSelectionAreaSelectedPoints = points.filter((point) => {
return (
point.x >=
Math.min(
state.drawSelectionAreaStartPos.x,
state.drawSelectionAreaStartPos.x + state.drawSelectionAreaBox.width
) &&
point.x <=
Math.max(
state.drawSelectionAreaStartPos.x,
state.drawSelectionAreaStartPos.x + state.drawSelectionAreaBox.width
) &&
point.y >=
Math.min(
state.drawSelectionAreaStartPos.y,
state.drawSelectionAreaStartPos.y + state.drawSelectionAreaBox.height
) &&
point.y <=
Math.max(
state.drawSelectionAreaStartPos.y,
state.drawSelectionAreaStartPos.y + state.drawSelectionAreaBox.height
)
)
})
console.log(state.drawSelectionAreaSelectedPoints, '选中的')
}
//获取地图点位
const list = ref([])
const getMapList = async () => {
let data = await MapApi.getPositionMapGetMap()
let mapList = []
for (let key in data) {
mapList.push({
floor: key,
children: data[key]
})
}
list.value = mapList
//默认取第一个
if (data[1][0]) {
getMapData(data[1][0])
}
}
//获取扫描图
//地图背景
const imgBgObj = reactive({
imgUrl: '',
positionMapId: '',
width: '',
height: ''
})
const getMapData = async (item) => {
let data = await MapApi.getPositionMapdDwnloadPngBase64({
floor: item.floor,
area: item.area
})
imgBgObj.imgUrl = data
imgBgObj.positionMapId = item.id
const img = new Image()
img.src = imgBgObj.imgUrl
imgBgObj.width = img.naturalWidth
imgBgObj.height = img.naturalHeight
console.log(imgBgObj)
getAllNodeList()
}
//获取所有的点位
const getAllNodeList = async () => {
let list = await MapApi.getPositionMapItemList({
positionMapId: imgBgObj.positionMapId
})
list.forEach((item) => {
if (item.type === 2) {
//库位点
let obj = JSON.parse(item.dataJson)[0]
// allMapPointInfo.value.push()
}
})
// allMapPointInfo.value = list.map((item) => {
// return {
// ...JSON.parse(item.dataJson)
// }
// })
// allMapPointInfo.value = allMapPointInfo.value
// console.log(allMapPointInfo.value)
allHistoryList.value[0] = JSON.parse(JSON.stringify(allMapPointInfo.value))
console.log(allHistoryList.value[0])
}
onMounted(() => {
getMapList()
})
</script>
<style lang="scss" scoped>
.map-box {
width: 100%;
position: relative;
.map-box-inner {
position: relative;
width: 100%;
.map-box-img {
width: 100%;
height: auto;
}
.map-box-inner-dot {
width: 100%;
position: absolute;
left: 0;
top: 0;
bottom: 0;
}
.grid-show {
background: linear-gradient(-90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px),
linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px);
background-size:
10px 10px,
10px 10px;
}
}
}
.sdiv {
width: 100%;
height: 100%;
box-sizing: border-box;
}
.top-tool {
.top-tool-list {
display: flex;
align-items: center;
text-align: center;
background-color: #fff;
margin-top: -15px;
margin-left: -20px;
margin-right: -20px;
padding: 0 14px;
margin-bottom: 20px;
box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px;
height: 70px;
.top-tool-item {
display: flex;
align-items: center;
.tool-item {
cursor: pointer;
width: 52px;
height: 70px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.name {
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
font-size: 14px;
color: #0d162a;
line-height: 20px;
text-align: center;
font-style: normal;
}
}
.line {
margin: 0 14px;
width: 1px;
height: 47px;
border: 1px solid #cccccc;
}
}
}
.right-tool-list {
position: absolute;
right: 0;
top: 94px;
background-color: #fff;
z-index: 999;
text-align: center;
box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px;
.tool-item {
cursor: pointer;
padding: 10px;
.name {
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
font-size: 14px;
color: #0d162a;
line-height: 20px;
text-align: center;
font-style: normal;
}
}
}
.tool-active {
background: #ebf1ff;
border-bottom: 2px solid #1677ff;
}
.right-tool-active {
background: #ebf1ff;
}
}
.input-box-class {
position: absolute;
border: 1px solid #00329f;
padding: 4px;
outline: none;
}
</style>