地图编辑
This commit is contained in:
parent
c4a5ea4bb1
commit
2853959c19
@ -4,7 +4,7 @@ NODE_ENV=development
|
||||
VITE_DEV=true
|
||||
|
||||
# 请求路径
|
||||
VITE_BASE_URL='http://192.168.0.74:48080'
|
||||
VITE_BASE_URL='http://192.168.0.66:48080'
|
||||
# VITE_BASE_URL='http://192.168.0.189:48080'
|
||||
|
||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
|
||||
|
@ -79,3 +79,11 @@ export const getDeviceInformationList = async (params) => {
|
||||
export const mapBindDeviceInfo = async (data) => {
|
||||
return await request.post({ url: `/system/device/information/mapBindDeviceInfo`, data })
|
||||
}
|
||||
//创建修改删除库区
|
||||
export const createOrEditOrDelHouseArea = async (data) => {
|
||||
return await request.post({ url: `/system/ware/house-area/createOrEditOrDel`, data })
|
||||
}
|
||||
//创建修改删除线库
|
||||
export const createOrEditOrDelHouseLane = async (data) => {
|
||||
return await request.post({ url: `/system/ware/house-lane/createOrEditOrDel`, data })
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<!-- 新增设备 -->
|
||||
<Dialog
|
||||
v-model="dialogFormVisible"
|
||||
title="物料区域设置"
|
||||
width="600"
|
||||
class="equipment-form-dialog"
|
||||
>
|
||||
<el-form :model="form" label-width="110">
|
||||
<el-form-item label="物料区域名称" prop="skuInfo" required>
|
||||
<el-input v-model="form.skuInfo" placeholder="请输入物料区域名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物料名称" prop="areaName" required>
|
||||
<el-input v-model="form.areaName" placeholder="请输入物料名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="库位数量" prop="areaNumber">
|
||||
<el-input v-model="form.areaNumber" :disabled="true" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm"> 确定 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import * as MapApi from '@/api/map/map'
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const props = defineProps({
|
||||
positionMapId: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
}
|
||||
})
|
||||
|
||||
const dialogFormVisible = ref(false) //列表的
|
||||
|
||||
//新增
|
||||
const form = ref({
|
||||
positionMapId: '',
|
||||
skuInfo: '', //物料名称
|
||||
areaName: '', //物料区域名称
|
||||
areaNumber: 0,
|
||||
mapItemIds: []
|
||||
})
|
||||
|
||||
const open = (list) => {
|
||||
dialogFormVisible.value = true
|
||||
form.value.mapItemIds = list.map((item) => item.id)
|
||||
form.value.areaNumber = form.value.mapItemIds.length
|
||||
}
|
||||
|
||||
const submitForm = async () => {
|
||||
form.value.positionMapId = props.positionMapId
|
||||
await MapApi.createOrEditOrDelHouseArea(form.value)
|
||||
dialogFormVisible.value = false
|
||||
message.success('设置成功')
|
||||
}
|
||||
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.equipment-form-dialog {
|
||||
padding: 0px;
|
||||
|
||||
.el-dialog__footer {
|
||||
padding: 0px 20px 20px 0;
|
||||
border-top: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<!-- 新增设备 -->
|
||||
<Dialog
|
||||
v-model="dialogFormVisible"
|
||||
title="物料区域设置"
|
||||
width="600"
|
||||
class="equipment-form-dialog"
|
||||
>
|
||||
<el-form :model="form" label-width="110">
|
||||
<el-form-item label="线库名称" prop="laneName" required>
|
||||
<el-input v-model="form.laneName" placeholder="请输入线库名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="库位数量" prop="areaNumber" required>
|
||||
<el-input v-model="form.areaNumber" :disabled="true" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm"> 确定 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import * as MapApi from '@/api/map/map'
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const props = defineProps({
|
||||
positionMapId: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
}
|
||||
})
|
||||
|
||||
const dialogFormVisible = ref(false) //列表的
|
||||
|
||||
//新增
|
||||
const form = ref({
|
||||
positionMapId: '',
|
||||
laneName: '', //线库名称
|
||||
areaNumber: 0,
|
||||
mapItemIds: []
|
||||
})
|
||||
|
||||
const open = (list) => {
|
||||
dialogFormVisible.value = true
|
||||
form.value.mapItemIds = list.map((item) => item.id)
|
||||
form.value.areaNumber = form.value.mapItemIds.length
|
||||
}
|
||||
|
||||
const submitForm = async () => {
|
||||
form.value.positionMapId = props.positionMapId
|
||||
await MapApi.createOrEditOrDelHouseLane(form.value)
|
||||
dialogFormVisible.value = false
|
||||
message.success('设置成功')
|
||||
}
|
||||
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.equipment-form-dialog {
|
||||
padding: 0px;
|
||||
|
||||
.el-dialog__footer {
|
||||
padding: 0px 20px 20px 0;
|
||||
border-top: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -72,14 +72,27 @@
|
||||
<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'
|
||||
item.switchType === 'grid' ||
|
||||
(item.switchType === 'next' &&
|
||||
(toolbarSwitchType === 'lineLibrary' || toolbarSwitchType === 'region'))
|
||||
"
|
||||
></div>
|
||||
<el-button
|
||||
v-if="
|
||||
item.switchType === 'next' &&
|
||||
(toolbarSwitchType === 'lineLibrary' || toolbarSwitchType === 'region')
|
||||
"
|
||||
type="danger"
|
||||
class="selection-area-btn"
|
||||
@click="clickDrawSelectionArea"
|
||||
>确定</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-tool-list" v-if="state.isShowToolbar">
|
||||
@ -230,9 +243,24 @@
|
||||
<!-- 文档 https://github.com/a7650/vue3-draggable-resizable/blob/main/docs/document_zh.md#resizable -->
|
||||
</div>
|
||||
|
||||
<!-- 绘制框选区域 -->
|
||||
<!-- 框选区域 -->
|
||||
<div
|
||||
v-if="state.drawSelectionAreaSelectedPoints"
|
||||
v-for="(box, index) in state.allDrawSelectionAreaBox"
|
||||
:key="index"
|
||||
:style="{
|
||||
position: 'absolute',
|
||||
left: `${box.x}px`,
|
||||
top: `${box.y}px`,
|
||||
width: `${box.width}px`,
|
||||
height: `${box.height}px`,
|
||||
border: '2px dashed #007bff',
|
||||
backgroundColor: 'rgba(0, 123, 255, 0.1)',
|
||||
zIndex: 999
|
||||
}"
|
||||
></div>
|
||||
<!-- 当前框选区域 -->
|
||||
<div
|
||||
v-if="state.drawSelectionAreaShow"
|
||||
:style="{
|
||||
position: 'absolute',
|
||||
left: `${state.drawSelectionAreaBox.x}px`,
|
||||
@ -241,10 +269,10 @@
|
||||
height: `${state.drawSelectionAreaBox.height}px`,
|
||||
border: '2px dashed #007bff',
|
||||
backgroundColor: 'rgba(0, 123, 255, 0.1)',
|
||||
zIndex: 99999
|
||||
zIndex: 999
|
||||
}"
|
||||
@click="clickDrawSelectionArea"
|
||||
></div>
|
||||
|
||||
<!-- 文字输入区域 -->
|
||||
<input
|
||||
v-if="state.showInputBox"
|
||||
@ -259,6 +287,7 @@
|
||||
left: state.inputBoxStyle.locationX + 'px',
|
||||
top: state.inputBoxStyle.locationY + 'px'
|
||||
}"
|
||||
:maxlength="30"
|
||||
class="input-box-class"
|
||||
/>
|
||||
</div>
|
||||
@ -284,6 +313,13 @@
|
||||
/>
|
||||
<!-- 设备弹窗选择 -->
|
||||
<equipmentToolDialog ref="equipmentToolDialogRef" :positionMapId="imgBgObj.positionMapId" />
|
||||
<!-- 区域选择 -->
|
||||
<itemAreaSettingDialog ref="itemAreaSettingDialogRef" :positionMapId="imgBgObj.positionMapId" />
|
||||
<!-- 线库设置 -->
|
||||
<lineLibrarySettingDialog
|
||||
ref="lineLibrarySettingDialogRef"
|
||||
:positionMapId="imgBgObj.positionMapId"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@ -291,6 +327,8 @@ 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 itemAreaSettingDialog from './components-tool/itemAreaSettingDialog.vue'
|
||||
import lineLibrarySettingDialog from './components-tool/lineLibrarySettingDialog.vue'
|
||||
import layerSelectionToolDialog from './components-tool/layerSelectionToolDialog.vue'
|
||||
|
||||
import * as MapApi from '@/api/map/map'
|
||||
@ -298,6 +336,8 @@ import cursorCollection from './cursorCollection'
|
||||
|
||||
defineOptions({ name: 'editMapPageRealTimeMap' })
|
||||
|
||||
const lineLibrarySettingDialogRef = ref() //线库设置
|
||||
const itemAreaSettingDialogRef = ref() //物料区域设置
|
||||
const equipmentToolDialogRef = ref() //设备弹窗
|
||||
const textFormToolDialogRef = ref() //文字输入弹窗
|
||||
const inputBoxRef = ref() //文字输入框
|
||||
@ -643,9 +683,10 @@ const state = reactive({
|
||||
copyMapItem: '', //复制的值
|
||||
cursorStyle: 'auto',
|
||||
drawSelectionAreaShow: false, //绘制框选区域
|
||||
allDrawSelectionAreaBox: [], // 所有框选区域
|
||||
drawSelectionAreaBox: { x: 0, y: 0, width: 0, height: 0 }, //绘制区域的位置,长宽
|
||||
drawSelectionAreaStartPos: { x: 0, y: 0 }, //开始绘制的点位
|
||||
drawSelectionAreaSelectedPoints: [], //绘制选中的list
|
||||
drawSelectionStartPoint: { x: 0, y: 0 }, //开始绘制的点位
|
||||
drawSelectionPointList: [], //绘制选中的list
|
||||
textFormToolShow: false, //文字表单显示隐藏
|
||||
showInputBox: false, //输入框显示隐藏
|
||||
inputBoxStyle: {
|
||||
@ -689,6 +730,13 @@ const toolbarClick = (item) => {
|
||||
state.inputBoxValue = ''
|
||||
}
|
||||
|
||||
//工具切换 不适用框选的 要把框选的信息都删掉
|
||||
if (toolbarSwitchType.value !== 'lineLibrary' && toolbarSwitchType.value !== 'region') {
|
||||
state.drawSelectionAreaShow = false
|
||||
state.allDrawSelectionAreaBox = []
|
||||
state.drawSelectionPointList = []
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'open':
|
||||
// 打开
|
||||
@ -869,57 +917,69 @@ const rotationFormSubmit = () => {
|
||||
const startDrawSelection = (event) => {
|
||||
if (toolbarSwitchType.value !== 'lineLibrary' && toolbarSwitchType.value !== 'region') return
|
||||
state.drawSelectionAreaShow = true
|
||||
state.drawSelectionAreaStartPos = { x: event.offsetX, y: event.offsetY }
|
||||
state.drawSelectionStartPoint = { x: event.offsetX, y: event.offsetY }
|
||||
state.drawSelectionAreaBox = { x: event.offsetX, y: event.offsetY, width: 0, height: 0 }
|
||||
// 阻止默认行为(避免选中图片或文本)
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
// 更新框选区域
|
||||
const updateDrawSelection = (event) => {
|
||||
if (toolbarSwitchType.value !== 'lineLibrary' && toolbarSwitchType.value !== 'region') return
|
||||
if (state.drawSelectionAreaShow) {
|
||||
state.drawSelectionAreaBox.width = event.offsetX - state.drawSelectionAreaStartPos.x
|
||||
state.drawSelectionAreaBox.height = event.offsetY - state.drawSelectionAreaStartPos.y
|
||||
state.drawSelectionAreaBox.width = event.offsetX - state.drawSelectionStartPoint.x
|
||||
state.drawSelectionAreaBox.height = event.offsetY - state.drawSelectionStartPoint.y
|
||||
}
|
||||
// 阻止默认行为(避免选中图片或文本)
|
||||
event.preventDefault()
|
||||
}
|
||||
//结束框选绘制
|
||||
const endDrawSelection = () => {
|
||||
if (toolbarSwitchType.value !== 'lineLibrary' && toolbarSwitchType.value !== 'region') return
|
||||
state.drawSelectionAreaShow = false
|
||||
let points = allHistoryList.value[currentIndex.value]
|
||||
state.drawSelectionAreaSelectedPoints = points.filter((point) => {
|
||||
return (
|
||||
point.locationX >=
|
||||
Math.min(
|
||||
state.drawSelectionAreaStartPos.x,
|
||||
state.drawSelectionAreaStartPos.x + state.drawSelectionAreaBox.width
|
||||
) &&
|
||||
point.locationX <=
|
||||
Math.max(
|
||||
state.drawSelectionAreaStartPos.x,
|
||||
state.drawSelectionAreaStartPos.x + state.drawSelectionAreaBox.width
|
||||
) &&
|
||||
point.locationY >=
|
||||
Math.min(
|
||||
state.drawSelectionAreaStartPos.y,
|
||||
state.drawSelectionAreaStartPos.y + state.drawSelectionAreaBox.height
|
||||
) &&
|
||||
point.locationY <=
|
||||
Math.max(
|
||||
state.drawSelectionAreaStartPos.y,
|
||||
state.drawSelectionAreaStartPos.y + state.drawSelectionAreaBox.height
|
||||
)
|
||||
)
|
||||
})
|
||||
state.allDrawSelectionAreaBox.push({ ...state.drawSelectionAreaBox })
|
||||
state.drawSelectionAreaBox = { x: 0, y: 0, width: 0, height: 0 }
|
||||
}
|
||||
//点击区域
|
||||
const clickDrawSelectionArea = () => {
|
||||
let points = allHistoryList.value[currentIndex.value]
|
||||
|
||||
state.drawSelectionPointList = []
|
||||
state.allDrawSelectionAreaBox.forEach((box) => {
|
||||
points.forEach((point) => {
|
||||
if (
|
||||
point.locationX >= box.x &&
|
||||
point.locationX <= box.x + box.width &&
|
||||
point.locationY >= box.y &&
|
||||
point.locationY <= box.y + box.height
|
||||
) {
|
||||
state.drawSelectionPointList.push(point)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
console.log(state.drawSelectionPointList, '选中的')
|
||||
|
||||
// 清空框选区域
|
||||
state.allDrawSelectionAreaBox = []
|
||||
//只要库位的
|
||||
let binLocation = state.drawSelectionPointList.filter((item) => item.type === 2)
|
||||
|
||||
if (toolbarSwitchType.value === 'lineLibrary') {
|
||||
//线库
|
||||
if (binLocation.length < 2) {
|
||||
message.warning('至少选择两个库位')
|
||||
} else {
|
||||
lineLibrarySettingDialogRef.value.open(binLocation)
|
||||
}
|
||||
}
|
||||
if (toolbarSwitchType.value === 'region') {
|
||||
//区域
|
||||
if (binLocation.length < 1) {
|
||||
message.warning('至少选择两个库位')
|
||||
} else {
|
||||
itemAreaSettingDialogRef.value.open(binLocation)
|
||||
}
|
||||
}
|
||||
|
||||
// console.log(state.drawSelectionAreaSelectedPoints, '选中的')
|
||||
}
|
||||
|
||||
//获取扫描图 地图背景相关的信息
|
||||
@ -989,7 +1049,7 @@ const getAllNodeList = async () => {
|
||||
item.dataList = JSON.parse(item.dataJson)
|
||||
item.locationDeep = item.dataList[0].locationDeep
|
||||
item.locationWide = item.dataList[0].locationWide
|
||||
item.draggable = false
|
||||
item.draggable = true
|
||||
item.resizable = false
|
||||
item.rotatable = false
|
||||
item.lockAspectRatio = true
|
||||
@ -998,7 +1058,7 @@ const getAllNodeList = async () => {
|
||||
item.dataList = []
|
||||
item.locationDeep = item.dataObj.locationDeep
|
||||
item.locationWide = item.dataObj.locationWide
|
||||
item.draggable = false
|
||||
item.draggable = true
|
||||
item.resizable = false
|
||||
item.rotatable = false
|
||||
item.lockAspectRatio = true
|
||||
@ -1185,4 +1245,9 @@ onMounted(() => {
|
||||
padding: 4px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.selection-area-btn {
|
||||
width: 80px;
|
||||
margin-left: 6px;
|
||||
}
|
||||
</style>
|
||||
|
@ -19,20 +19,21 @@
|
||||
}"
|
||||
></div>
|
||||
|
||||
<!-- 坐标点 -->
|
||||
<div
|
||||
v-for="(point, index) in points"
|
||||
<!-- 图片 -->
|
||||
<img
|
||||
v-for="(img, index) in images"
|
||||
:key="index"
|
||||
:src="img.src"
|
||||
:style="{
|
||||
position: 'absolute',
|
||||
left: `${point.x}px`,
|
||||
top: `${point.y}px`,
|
||||
width: '10px',
|
||||
height: '10px',
|
||||
backgroundColor: selectedPoints.includes(point) ? 'red' : 'blue',
|
||||
borderRadius: '50%'
|
||||
left: `${img.x}px`,
|
||||
top: `${img.y}px`,
|
||||
width: '100px',
|
||||
height: '100px',
|
||||
userSelect: isSelecting ? 'none' : 'auto', // 动态禁用选择
|
||||
pointerEvents: isSelecting ? 'none' : 'auto' // 动态禁用鼠标事件
|
||||
}"
|
||||
></div>
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -41,13 +42,11 @@ import { ref } from 'vue'
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
// 坐标数组
|
||||
const points = ref([
|
||||
{ x: 300, y: 400 },
|
||||
{ x: 400, y: 400 },
|
||||
{ x: 200, y: 360 },
|
||||
{ x: 570, y: 260 },
|
||||
{ x: 600, y: 477 }
|
||||
// 图片数据
|
||||
const images = ref([
|
||||
{ src: 'https://via.placeholder.com/100', x: 100, y: 100 },
|
||||
{ src: 'https://via.placeholder.com/100', x: 300, y: 200 },
|
||||
{ src: 'https://via.placeholder.com/100', x: 500, y: 300 }
|
||||
])
|
||||
|
||||
// 框选区域
|
||||
@ -61,64 +60,52 @@ export default {
|
||||
// 是否正在框选
|
||||
const isSelecting = ref(false)
|
||||
|
||||
// 选中的点
|
||||
const selectedPoints = ref([])
|
||||
|
||||
// 框选起始位置
|
||||
const startPos = ref({ x: 0, y: 0 })
|
||||
|
||||
// 开始框选
|
||||
const startSelection = (event) => {
|
||||
isSelecting.value = true
|
||||
startPos.value = { x: event.offsetX, y: event.offsetY }
|
||||
startPos.value = { x: event.clientX, y: event.clientY }
|
||||
selectionBox.value = {
|
||||
x: event.offsetX,
|
||||
y: event.offsetY,
|
||||
x: event.clientX,
|
||||
y: event.clientY,
|
||||
width: 0,
|
||||
height: 0
|
||||
}
|
||||
|
||||
// 阻止默认行为(避免选中图片或文本)
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
// 更新框选区域
|
||||
const updateSelection = (event) => {
|
||||
if (!isSelecting.value) return
|
||||
|
||||
const offsetX = event.offsetX
|
||||
const offsetY = event.offsetY
|
||||
const currentX = event.clientX
|
||||
const currentY = event.clientY
|
||||
|
||||
selectionBox.value = {
|
||||
x: Math.min(startPos.value.x, offsetX),
|
||||
y: Math.min(startPos.value.y, offsetY),
|
||||
width: Math.abs(offsetX - startPos.value.x),
|
||||
height: Math.abs(offsetY - startPos.value.y)
|
||||
x: Math.min(startPos.value.x, currentX),
|
||||
y: Math.min(startPos.value.y, currentY),
|
||||
width: Math.abs(currentX - startPos.value.x),
|
||||
height: Math.abs(currentY - startPos.value.y)
|
||||
}
|
||||
|
||||
// 阻止默认行为(避免选中图片或文本)
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
// 结束框选
|
||||
const endSelection = () => {
|
||||
isSelecting.value = false
|
||||
checkSelectedPoints()
|
||||
}
|
||||
|
||||
// 判断哪些点在框选区域内
|
||||
const checkSelectedPoints = () => {
|
||||
selectedPoints.value = points.value.filter((point) => {
|
||||
return (
|
||||
point.x >= selectionBox.value.x &&
|
||||
point.x <= selectionBox.value.x + selectionBox.value.width &&
|
||||
point.y >= selectionBox.value.y &&
|
||||
point.y <= selectionBox.value.y + selectionBox.value.height
|
||||
)
|
||||
})
|
||||
|
||||
console.log('选中的点:', selectedPoints.value)
|
||||
console.log('框选区域:', selectionBox.value)
|
||||
}
|
||||
|
||||
return {
|
||||
points,
|
||||
images,
|
||||
selectionBox,
|
||||
isSelecting,
|
||||
selectedPoints,
|
||||
startSelection,
|
||||
updateSelection,
|
||||
endSelection
|
||||
@ -128,5 +115,11 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 可选:添加一些样式 */
|
||||
/* 禁用用户选择 */
|
||||
img {
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user