feat: 应急救援指挥地图扎点及其他展示框绘制

liujun0703-新项目开发
DESKTOP-2ESM03N\zcloud 2024-07-29 08:56:13 +08:00
parent 06f842b97f
commit 8c689b6b29
10 changed files with 706 additions and 297 deletions

View File

@ -27,7 +27,7 @@ module.exports = {
}, },
// Various Dev Server settings // Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST host: '192.168.0.37', // can be overwritten by process.env.HOST 目前设置为本地主机的IP地址,目的是为了让同网络中的其他主机可通过该IP地址访问本脚手架项目
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false, // 是否自动开启浏览器预览能力 autoOpenBrowser: false, // 是否自动开启浏览器预览能力
errorOverlay: true, errorOverlay: true,

6
package-lock.json generated
View File

@ -10,6 +10,7 @@
"dependencies": { "dependencies": {
"@jiaminghi/data-view": "^2.10.0", "@jiaminghi/data-view": "^2.10.0",
"@riophae/vue-treeselect": "^0.4.0", "@riophae/vue-treeselect": "^0.4.0",
"autofit.js": "^3.1.1",
"axios": "^0.21.1", "axios": "^0.21.1",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"echarts": "^5.3.1", "echarts": "^5.3.1",
@ -1747,6 +1748,11 @@
"node": ">= 4.5.0" "node": ">= 4.5.0"
} }
}, },
"node_modules/autofit.js": {
"version": "3.1.1",
"resolved": "https://registry.npmmirror.com/autofit.js/-/autofit.js-3.1.1.tgz",
"integrity": "sha512-ECW7wNUW1e6F+c0lRc9X+xyCrbqY3FsSnCObNDhQAo77E4/45tWx0YeLuiqA7qxrnxl2Plh3lF/pC+vzXC+8ZA=="
},
"node_modules/autoprefixer": { "node_modules/autoprefixer": {
"version": "7.2.6", "version": "7.2.6",
"resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-7.2.6.tgz", "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-7.2.6.tgz",

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -26,6 +26,7 @@ Vue.component('Treeselect', Treeselect)
import Viewer from 'v-viewer' import Viewer from 'v-viewer'
import 'viewerjs/dist/viewer.css' import 'viewerjs/dist/viewer.css'
Vue.use(Viewer, { Vue.use(Viewer, {
defaultOptions: { defaultOptions: {
zIndex: 9999// 解决图片放大的层级问题 zIndex: 9999// 解决图片放大的层级问题
@ -119,4 +120,3 @@ new Vue({
components: { App }, components: { App },
template: '<App/>' template: '<App/>'
}) })

View File

@ -34,7 +34,6 @@ service.interceptors.request.use(
background: 'rgba(0, 0, 0, 0.7)' background: 'rgba(0, 0, 0, 0.7)'
}) })
} }
config.headers['Authorization'] = JSON.parse(sessionStorage.getItem('user')).sessionId || ''
return config return config
}, },
error => { error => {

View File

@ -1,131 +0,0 @@
import axios from 'axios'
import { Message, MessageBox, Loading } from 'element-ui'
// create an axios instance
axios.defaults.withCredentials = true
let loadingService = null
const service = axios.create({
// baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// eslint-disable-next-line no-undef
baseURL: config.httpurl,
// withCredentials: true, // send cookies when cross-domain requests
timeout: 300000, // request timeout
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
// request interceptor
service.interceptors.request.use(
config => {
// do something before request is sent
if (
(
!config.url.includes('getLevels') &&
!config.url.includes('hasMenu') &&
!config.url.includes('hasButton') &&
!config.url.includes('getInfo')
) &&
!loadingService
) {
loadingService = Loading.service({
lock: true,
text: '加载中......',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
}
if (config.url === '/admin/check') {
delete config.headers.Authorization
}
return config
},
error => {
// do something with request error
return Promise.reject(error)
}
)
// response interceptor
service.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
response => {
// console.info('response:' + response)
loadingService && loadingService.close()
loadingService = null
const res = response.data
// if the custom code is not 20000, it is judged as an error.
if (res.result !== 'success' && res.result !== 'fail') {
if (res.response == '302') {
MessageBox.alert('登录失效,请重新登录', {
confirmButtonText: '确定',
callback: action => {
sessionStorage.clear()
location.reload()
}
})
}
if (res.result !== 'exception') {
Message({
message: res.msg || '没有此页面的访问权限,请联系管理员',
type: 'error',
duration: 5 * 1000
})
}
Message({
message: res.msg || '系统开小差了,请联系管理员',
type: 'error',
duration: 5 * 1000
})
return Promise.reject(new Error(res.message || '系统开小差了,请联系管理员'))
} else {
return res
}
},
error => {
if (!error.response || error.response.status == '404' || error.response.status == '302') {
MessageBox.alert('登录失效,请重新登录', {
confirmButtonText: '确定',
callback: action => {
sessionStorage.clear()
location.reload()
}
})
} else {
MessageBox.alert('登录失效,请重新登录', {
confirmButtonText: '确定',
callback: action => {
sessionStorage.clear()
location.reload()
}
})
}
return Promise.reject(error)
}
)
export function requestFN2(url, data) {
// 基础请求方法
const Qs = require('qs')
const method = 'post'
const obj = {
method, // 请求的类型
url // 请求地址
}
obj.data = Qs.stringify(data) // data 带参数
// 返回axios的基础方法
return service(obj).then(r => {
return r // 方法请求的数据
})
}
export default service

View File

@ -0,0 +1,286 @@
<template>
<div class="chat">
<div class="chat-title">
欢迎您,在这里可查看城市的重点隐患信息!
</div>
<div class="content">
<div class="item item-right">
<div class="bubble bubble-right">
刚刚不在不好意思
</div>
<div class="avatar">
<img src="https://tse1-mm.cn.bing.net/th/id/OIP-C.4XP3SrYigaDrlkbG_uFkzQAAAA?rs=1&pid=ImgDetMain">
</div>
</div>
<div class="item item-left">
<div class="avatar">
<img src="https://tse4-mm.cn.bing.net/th/id/OIP-C.-byzt1F3AA9UcVgO_DOIwQAAAA?rs=1&pid=ImgDetMain">
</div>
<div class="bubble bubble-left">
没事
<br>
你继续
</div>
</div>
<!-- 服务端向客户端推送的消息队列 -->
<div v-for="(item, index) in receiveMessageList" :key="index" :class="item.className">
<div style="display: flex;" v-html="item.content" />
</div>
<!-- 客户端向服务端主动发送的消息队列 -->
<div v-for="(item, index) in sendMessageList" :key="index" :class="item.className">
<div style="display: flex;" v-html="item.content" />
</div>
</div>
<div class="input-area">
<textarea id="textarea" v-model="inputTextValue" class="input-text-area" name="text" />
<div class="button-area">
<button class="btnSend" @click="handleSendMessage"> (S) </button>
</div>
</div>
</div>
</template>
<script>
let socketIOInstance
export default {
name: 'Chat',
data() {
return {
websocketonline: '',
inputTextValue: '',
/** 发送消息列表 */
sendMessageList: [],
/** 接收消息列表 */
receiveMessageList: []
}
},
created() {
this.getWebsocketController()
},
beforeDestroy() {
socketIOInstance.close()
},
methods: {
// websocket
getWebsocketController() {
if (window.WebSocket) {
socketIOInstance = new WebSocket(encodeURI('ws://192.168.0.35:8089/getMapData/1'))
socketIOInstance.onopen = () => {
console.log('socket 连接成功!')
}
socketIOInstance.onerror = () => {
console.log('socket 连接失败!')
}
socketIOInstance.onclose = () => {
console.log('socket 连接断开!')
}
socketIOInstance.onmessage = (message) => {
this.handleReceiveMessage(message)
}
}
},
/** 处理服务端向客户端推送的消息并展示到消息列表内 */
handleReceiveMessage(val) {
this.sendMessageList.push({
className: 'item item-left',
content: `<div class="avatar"><img src="https://tse4-mm.cn.bing.net/th/id/OIP-C.-byzt1F3AA9UcVgO_DOIwQAAAA?rs=1&pid=ImgDetMain"></div><div class="bubble bubble-left">${val.data}</div>`
})
},
//
handleSendMessage() {
if (this.inputTextValue === '') {
this.$message('消息不能为空!')
return
}
socketIOInstance.send(this.inputTextValue) // websocket
this.sendMessageList.push({
className: 'item item-right',
content: `<div class="bubble bubble-left">${this.inputTextValue}</div><div class="avatar"><img src="https://tse1-mm.cn.bing.net/th/id/OIP-C.4XP3SrYigaDrlkbG_uFkzQAAAA?rs=1&pid=ImgDetMain" /></div>`
})
this.inputTextValue = ''
this.$nextTick(() => {
//
const height = document.querySelector('.content').scrollHeight
document.querySelector('.content').scrollTop = height
})
}
}
}
</script>
<style lang="scss">
* {
padding: 0;
margin: 0;
font-size: 15px;
font-family: '微软雅黑', "宋体", "Arial Narrow", Helvetica, sans-serif;
}
.chat {
box-sizing: border-box;
width: 100%;
height: 100%;
.chat-title {
font-size: 20px;
text-align: center;
color: #fff;
height: 35px;
border-bottom: 1px solid white
}
.content {
overflow-y: auto;
overflow-x: hidden;
height: 648px;
&::-webkit-scrollbar {
width: 7px;
}
//
&::-webkit-scrollbar-track {
width: 8px;
border-radius: 18px;
background: transparent;
}
//
&::-webkit-scrollbar-thumb {
width: 8px;
border-radius: 18px;
background: rgba(20, 31, 168, .8);
}
.bubble {
max-width: 300px;
padding: 10px;
border-radius: 5px;
position: relative;
color: #000;
word-wrap: break-word;
word-break: normal;
}
.item-left .bubble {
margin-left: 15px;
background-color: #fff;
}
.item-left .bubble:before {
content: "";
position: absolute;
width: 0;
height: 0;
border-left: 10px solid transparent;
border-top: 10px solid transparent;
border-right: 10px solid #fff;
border-bottom: 10px solid transparent;
left: -20px;
}
.item-right .bubble {
margin-right: 15px;
background-color: #9eea6a;
}
.item-right .bubble:before {
content: "";
position: absolute;
width: 0;
height: 0;
border-left: 10px solid #9eea6a;
border-top: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid transparent;
right: -20px;
}
.item {
margin-top: 15px;
display: flex;
width: 100%;
}
.item.item-right {
justify-content: flex-end;
}
.avatar img {
width: 42px;
height: 42px;
border-radius: 50%;
}
}
.input-area {
position: relative;
width: 100%;
height: 100px;
.input-text-area {
//
outline: none;
resize: none;
background: none;
caret-color: #fff;
border: 1px solid #fff;
color: #fff;
width: 100%;
height: 100%;
border-radius: 6px;
padding: 10px;
overflow: auto;
line-height: 20px;
&::-webkit-scrollbar {
width: 7px;
}
//
&::-webkit-scrollbar-track {
width: 8px;
border-radius: 18px;
background: transparent;
}
//
&::-webkit-scrollbar-thumb {
width: 8px;
border-radius: 18px;
background: rgba(20, 31, 168, .8);
}
}
.button-area {
margin-top: 5px;
text-align: right;
.btnSend {
width: 85px;
height: 37px;
background: none;
border: 1px solid #fff;
border-radius: 6px;
color: #fff;
cursor: pointer;
font-weight: 800;
transition: transform ease-in-out .2s;
&:active {
transform: scale(0.9);
}
}
}
}
}
</style>

View File

@ -1,64 +1,105 @@
<template> <template>
<div class="mapAssembly-container"> <div id="mapAssembly_container" class="mapAssembly-container">
<!-- 地图 -->
<div id="map" /> <div id="map" />
<!-- 展示左侧的盒子元素 -->
<div class="left-display-box"> <!-- 悬浮框主体 -->
<!-- 应急机构 --> <div class="mainer">
<div class="emergency-department">
<el-descriptions :column="2" :colon="true" title="应急机构" class="department-list" content-style="huc"> <div v-if="currentSelectPointAccident" class="center">
<template> <div v-for="(item, index) in pointsList" :key="index" class="point" @click="handlePoint(item, index)">
<el-descriptions-item label="专家组名称">看板</el-descriptions-item> <div class="rescue-box">
<el-descriptions-item label="联系电话">18100000000</el-descriptions-item> <img :src="item.check ? item.check_img : item.img" class="rescue-img" alt="">
</template> <p class="rescue-text"> {{ item.label }} </p>
</el-descriptions> </div>
</div>
<!-- 联系人方式 -->
<div class="contact-information">
联系人方式
</div>
</div>
<!-- 展示中间的盒子元素 -->
<div class="center-display-box">
<div v-for="(item, index) in pointsList" :key="index" class="point" @click="handlePoint(item, index)">
<div class="rescue-box">
<img :src="item.check ? item.check_img : item.img" class="rescue-img" alt="">
<p class="rescue-text"> {{ item.label }} </p>
</div> </div>
</div> </div>
</div>
<!-- 展示右侧的盒子元素 --> <div class="left">
<div class="right-display-box"> <!-- 应急机构 -->
展示右侧的盒子元素 <div class="emergency-department">
<h2 class="department-title">应急机构</h2>
<div class="department-body">
<ul
v-for="(item, index) in expertGroupInfo"
:key="index"
class="department-ul"
@click="expertInfoItemClick(item, index)">
<li class="department-li">专家组名称: {{ item.EXPERT_GROUP_NAME }}</li>
<li class="department-li">联系电话: {{ item.CONTACT_TELEPHONE }}</li>
</ul>
</div>
</div>
<div class="line" />
<!-- 联系人方式 -->
<div class="contact-information">
<h2 class="contact-title">联系人方式</h2>
<div v-if="varList.length > 0">
<ul v-for="(item, index) in varList" :key="index" class="contact-ul">
<li class="contact-li">专家姓名: {{ item.GENDER }}</li>
<li class="contact-li">性别: {{ item.EXPERT_NAME }}</li>
<li class="contact-li">专家类型: {{ item.EXPERT_TYPE }}</li>
<li class="contact-li">专家姓名: {{ item.EXPERT_NAME }}</li>
<li class="contact-li">办公电话: {{ item.OFFICE_TELEPHONE }}</li>
<li class="contact-li">移动电话: {{ item.MOBILE_TELEPHONE }}</li>
</ul>
</div>
<div v-else class="contact-empty">
<span>暂无数据</span>
</div>
</div>
</div>
<!-- 对话框 -->
<div class="right">
<!-- 对话框组件渲染 -->
<chat />
</div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { requestFN } from '@/utils/request' import { requestFN } from '@/utils/request'
import autofit from 'autofit.js'
import chat from './chat.vue'
let mapInstance let mapInstance
export default { export default {
components: { chat },
data() { data() {
return { return {
config: config,
pointsList: [ pointsList: [
{ {
img: require('@/assets/map/emergency_rescue/ico1.png'), img: require('@/assets/map/emergency_rescue/ico1.png'),
check_img: require('@/assets/map/emergency_rescue/ico1_on.png'), check_img: require('@/assets/map/emergency_rescue/ico1_on.png'),
label: '物资', label: '分类一',
check: true check: true,
type: 1
}, },
{ {
img: require('@/assets/map/emergency_rescue/ico2.png'), img: require('@/assets/map/emergency_rescue/ico2.png'),
check_img: require('@/assets/map/emergency_rescue/ico2_on.png'), check_img: require('@/assets/map/emergency_rescue/ico2_on.png'),
label: '消防', label: '分类二',
check: false check: false,
type: 2
}, },
{ {
img: require('@/assets/map/emergency_rescue/ico3.png'), img: require('@/assets/map/emergency_rescue/ico3.png'),
check_img: require('@/assets/map/emergency_rescue/ico3_on.png'), check_img: require('@/assets/map/emergency_rescue/ico3_on.png'),
label: '更多', label: '更多',
check: false check: false,
type: 3
},
{
img: require('@/assets/map/emergency_rescue/reset_point.png'),
check_img: null,
label: '重置',
check: false,
type: 4
} }
], ],
// //
@ -66,18 +107,27 @@ export default {
page: 1, page: 1,
limit: 10 limit: 10
}, },
KEYWORDS: '' KEYWORDS: '',
/** 应急救援专家组状态变量 */
expertGroupInfo: [],
/** 存储某个专家组的所在成员 */
varList: [],
/** 当前选择的事故信息 */
currentSelectPointAccident: ''
} }
}, },
mounted() { mounted() {
this.mapInit() // // 使 autofit PC
this.initPoints() // autofit.init({
el: '#mapAssembly_container',
resize: true
})
/** 调用地图初始化方法 */
this.mapInit()
/** 调用初始化点位绘制方法 */
this.initPoints()
this.getYjExpertGroupInfo() this.getYjExpertGroupInfo()
}, },
//
beforeDestroy() {
mapInstance = null
},
methods: { methods: {
/** 地图初始化 */ /** 地图初始化 */
mapInit() { mapInit() {
@ -85,43 +135,108 @@ export default {
mapInstance.centerAndZoom(new window.BMapGL.Point('119.645516', '39.934547'), 15) // mapInstance.centerAndZoom(new window.BMapGL.Point('119.645516', '39.934547'), 15) //
mapInstance.enableScrollWheelZoom(true) // mapInstance.enableScrollWheelZoom(true) //
}, },
// /** 扎点方法 */
// addPoint(anchor) { addPoint(anchor) {
// if (!anchor.iconImg) throw new Error('') if (!anchor.iconUrl) throw new Error('请传入图标')
// if (!anchor.imageSize) throw new Error('')
// if (!anchor.lng) throw new Error('')
// if (!anchor.lat) throw new Error('')
// const imageSize = new window.BMapGL.Size(23, 30)
// const icon = new window.BMapGL.Icon(anchor.iconImg, imageSize, { imageSize })
// const point = new window.BMapGL.Point(anchor.lng, anchor.lat)
// const marker = new window.BMapGL.Marker(point, { icon }) //
// mapInstance.addOverlay(marker) //
// },
//
addPointCallback(anchor) {
// if (!anchor.iconImg) throw new Error('')
// if (!anchor.imageSize) throw new Error('') // if (!anchor.imageSize) throw new Error('')
if (!anchor.longitude) throw new Error('请传入经度')
if (!anchor.latitude) throw new Error('请传入纬度')
const imageSize = new window.BMapGL.Size(23, 30)
const icon = new window.BMapGL.Icon(config.fileUrl + anchor.iconUrl, imageSize, { imageSize })
const point = new window.BMapGL.Point(anchor.longitude, anchor.latitude)
const marker = new window.BMapGL.Marker(point, { icon }) //
const anchorOpts = {
width: 90,
height: 70,
title: '资源信息'
}
const infoWindow = new window.BMapGL.InfoWindow(`<p">资源名称: ${anchor.name || '无'}</p>`, anchorOpts)
marker.addEventListener('mouseover', () => {
mapInstance.openInfoWindow(infoWindow, point)
})
mapInstance.addOverlay(marker) //
},
handleClickInfo() {
console.log('你惦记了')
},
/** 标点的信息窗口控制器 */
infoWindowPointerController(config) {
const { point, marker, info } = config
var opts = {
width: 300,
height: 200,
title: '事故点位信息'
}
const sContent = `
<div>
<ul>
<li>机主姓名: ${info.accident.OWNER_NAME || '无'}</li>
<li>访问模式: ${info.accident.ACCESS_MODE || '无'}</li>
<li>呼入电话: ${info.accident.INCOMING_PHONE || '无'}</li>
<li>事件类型: ${info.accident.EVENT_TYPE || '无'}</li>
<li>接报时间: ${info.accident.REPORT_TIME || '无'}</li>
<li>发生时间: ${info.accident.OCCURRENCE_TIME || '无'}</li>
<li>救援情况: ${info.accident.RESCUE_SITUATION || '无'}</li>
</ul>
</div>
`
const infoWindow = new window.BMapGL.InfoWindow(sContent, opts)
marker.addEventListener('mouseover', () => {
mapInstance.openInfoWindow(infoWindow, point)
})
},
/** 给地图扎点标记事件事故 */
addPointCallback(anchor) {
if (!anchor.iconUrl) throw new Error('请传入图标')
if (!anchor.LONGITUDE) throw new Error('请传入经度') if (!anchor.LONGITUDE) throw new Error('请传入经度')
if (!anchor.LATITUDE) throw new Error('请传入纬度') if (!anchor.LATITUDE) throw new Error('请传入纬度')
const { LONGITUDE, LATITUDE } = anchor const { LONGITUDE, LATITUDE } = anchor
const imageSize = new window.BMapGL.Size(33, 40)
const icon = new window.BMapGL.Icon(config.fileUrl + anchor.iconUrl, imageSize, { imageSize }) // icon
var point = new window.BMapGL.Point(LONGITUDE, LATITUDE) var point = new window.BMapGL.Point(LONGITUDE, LATITUDE)
var marker = new window.BMapGL.Marker(point) // const marker = new window.BMapGL.Marker(point, { icon }) //
mapInstance.addOverlay(marker) // mapInstance.addOverlay(marker) //
// //
marker.addEventListener('click', function() { marker.addEventListener('click', async() => {
let accidentParams = {}
let nearbyResourcesList = []
// //
requestFN('major/comprehensive/scope', { this.currentSelectPointAccident = anchor
accidentId: anchor.id
}) const result = await this.getQueryScopeAsync(anchor)
.then((data) => {
const { LONGITUDE, LATITUDE } = anchor if (result.code === 200) {
var point = new window.BMapGL.Point(LONGITUDE, LATITUDE) mapInstance.clearOverlays() //
var marker = new window.BMapGL.Marker(point) // const { accident, nearbyResources } = result.data
mapInstance.addOverlay(marker) accidentParams = accident
}).catch((e) => { }) nearbyResourcesList = nearbyResources
const point = new window.BMapGL.Point(accidentParams.LONGITUDE, accidentParams.LATITUDE)
const marker = new window.BMapGL.Marker(point, { icon })
mapInstance.addOverlay(marker)
this.infoWindowPointerController({ point, marker, info: result.data })
if (nearbyResourcesList.length === 0) return
nearbyResourcesList.forEach(item => {
this.addPoint(item)
})
}
}) })
}, },
// /** 获取指定点位所在周围范围等详细信息 */
getQueryScopeAsync(enterParams) {
return new Promise((resolve, reject) => {
requestFN('major/comprehensive/scope', {
accidentId: enterParams.id,
type: enterParams.type ? enterParams.type : ''
}).then((data) => {
resolve(data)
return data
}).catch((error) => {
reject(error)
})
})
},
/** 初始化定位点 */
getInfo(id) { getInfo(id) {
requestFN('/dictionaries/listTree').then((data) => { requestFN('/dictionaries/listTree').then((data) => {
this.treeData = JSON.parse(data.zTreeNodes) this.treeData = JSON.parse(data.zTreeNodes)
@ -129,6 +244,7 @@ export default {
console.error('获取树形数据失败', e) console.error('获取树形数据失败', e)
}) })
}, },
/** 初始化点位绘制方法 */
async initPoints() { async initPoints() {
const result = await this.getAccidentList() const result = await this.getAccidentList()
result.data.forEach((item) => { result.data.forEach((item) => {
@ -152,17 +268,71 @@ export default {
name: this.KEYWORDS name: this.KEYWORDS
} }
).then((data) => { ).then((data) => {
console.log('data HHHHHHHh红红火火恍恍惚惚 :>> ', data) this.expertGroupInfo = data.varList
}) })
.catch((e) => { .catch((e) => {
this.listISLOADing = false this.listISLOADing = false
}) })
}, },
/** 点击某一项专家组的处理事件 */
async expertInfoItemClick(item, index) {
requestFN(
'/yjExpertGroup/groupExpertlist?showCount=' + this.listQuery.limit + '&currentPage=' + this.listQuery.page,
{
name: null,
id: item.EXPERT_GROUP_ID
}
).then((data) => {
this.varList = data.varList
})
.catch((e) => { })
},
/** 处理分类下的扎点坐标渲染任务 */
async baseClassifyPointer(type) {
mapInstance.clearOverlays() //
let accidentParams = {}
let nearbyResourcesList = []
const response = await this.getQueryScopeAsync({
id: this.currentSelectPointAccident.id,
type
})
const { accident, nearbyResources } = response.data
accidentParams = accident
nearbyResourcesList = nearbyResources
const imageSize = new window.BMapGL.Size(33, 40)
const icon = new window.BMapGL.Icon(config.fileUrl + this.currentSelectPointAccident.iconUrl, imageSize, { imageSize }) // icon
const point = new window.BMapGL.Point(accidentParams.LONGITUDE, accidentParams.LATITUDE)
const marker = new window.BMapGL.Marker(point, { icon })
mapInstance.addOverlay(marker)
if (nearbyResourcesList.length === 0) return
nearbyResourcesList.forEach(item => {
this.addPoint(item)
})
},
/** 处理点坐标 */ /** 处理点坐标 */
handlePoint(item, index) { async handlePoint(item, index) {
console.log('当前点击的点坐标信息 :>> ', item) switch (index) {
console.log('当前点击的点坐标索引值 :>>', index) case 0: {
this.pointsList[index].check = !this.pointsList[index].check this.pointsList[index].check = !this.pointsList[index].check
this.baseClassifyPointer(item.type)
break
}
case 1: {
this.pointsList[index].check = !this.pointsList[index].check
this.baseClassifyPointer(item.type)
break
}
case 2: {
this.pointsList[index].check = !this.pointsList[index].check
this.baseClassifyPointer(item.type)
break
}
case 3: {
mapInstance.clearOverlays()
this.initPoints()
}
}
} }
} }
} }
@ -170,108 +340,188 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
.mapAssembly-container { .mapAssembly-container {
position: relative; width: 100vw;
height: 100vh;
font-family: '微软雅黑', "宋体", "Arial Narrow", Helvetica, sans-serif;
overflow: hidden;
margin: 0;
//
#map { #map {
width: calc(100vw - 44px); width: 100%;
height: calc(100vh - 84px); height: 91%;
} }
.el-descriptions { .mainer {
background-color: transparent !important;
}
.el-descriptions__body {
background-color: red !important;
color: #fff !important;
}
.left-display-box {
z-index: 99;
position: absolute;
left: 20px;
top: 20px;
width: 26vw;
height: 83vh;
background: rgba(20, 31, 168, .7);
border: 1px solid #0060d7;
border-top: none;
padding: 8px;
color: #fff;
border-radius: 8px;
box-sizing: border-box; box-sizing: border-box;
display: flex; width: 100%;
flex-direction: column; height: 100%;
gap: 8px;
// .center {
.emergency-department { width: 340px;
border-radius: 8px; position: absolute;
width: 100%; left: 50%;
height: 50%; top: 765px;
transform: translateX(-170px);
.department-list { z-index: 99;
color: rgb(255, 255, 255);
}
}
//
.contact-information {
border-radius: 8px;
border: 1px solid greenyellow;
width: 100%;
height: 50%;
}
}
//
.center-display-box {
z-index: 99;
color: #fff;
position: absolute;
top: 72vh;
left: 50%;
transform: translateX(-20vw);
width: 40vw;
height: 13vh;
border-radius: 8px;
display: flex;
flex-direction: row;
justify-content: space-evenly;
align-items: center;
.rescue-box {
display: flex; display: flex;
justify-content: center; flex-direction: row;
justify-content: space-between;
align-items: center; align-items: center;
flex-direction: column;
width: 4vw; .point {
height: 4vw; display: flex;
.rescue-img { justify-content: center;
width: 100%; align-items: center;
height: 100%;
cursor: pointer; cursor: pointer;
width: 50px;
height: 60px;
} }
.rescue-text {
margin: 0; .rescue-box {
padding: 0; display: flex;
color: rgb(255, 255, 255); justify-content: center;
align-items: center;
flex-direction: column;
width: 45px;
height: 45px;
.rescue-img {
width: 100%;
height: 100%;
}
.rescue-text {
margin: 0;
padding: 0;
color: rgb(0, 52, 221);
font-weight: 800;
font-size: 14px;
}
} }
} }
}
// .left {
.right-display-box { width: 477px;
z-index: 99; height: 850px;
color: #fff; max-height: 850px;
position: absolute; background: rgba(20, 31, 168, .7);
top: 20px; border: 1px solid #0060d7;
right: 20px; z-index: 99;
width: 25vw; position: absolute;
height: 83vh; top: 20px;
background: rgba(20, 31, 168, .7); left: 18px;
border: 1px solid #0060d7; border-radius: 8px;
border-radius: 8px; box-sizing: border-box;
padding: 12px;
//
.emergency-department {
max-height: 420px;
overflow: auto;
border-radius: 8px;
width: 100%;
.department-title {
padding: 0;
margin: 0;
color: rgba(255, 255, 255, 1);
padding: 5px 0 5px 6px;
font-size: 21px;
}
.department-body {
height: 85%;
overflow: auto;
&::-webkit-scrollbar {
display: none;
}
.department-ul {
width: 100%;
margin-bottom: 9px;
border-radius: 8px;
padding: 5px;
display: flex;
flex-direction: column;
gap: 5px;
cursor: pointer;
&:hover {
box-shadow:
inset -1px -3px 4px rgba(255, 255, 255, .9), inset 8px 6px 12px rgba(0, 0, 0, .4);
}
.department-li {
color: rgb(255, 255, 255);
}
}
}
}
// 线
.line {
width: 100%;
height: 1px;
border-bottom: 1px solid #fff;
margin: 10px 0;
}
//
.contact-information {
border-radius: 8px;
width: 100%;
.contact-title {
padding: 0;
margin: 0;
color: rgba(255, 255, 255, 1);
padding: 5px 0 5px 6px;
font-size: 21px;
}
.contact-ul {
max-height: 420px;
overflow: auto;
width: 100%;
margin-bottom: 9px;
border-radius: 8px;
padding: 5px;
display: flex;
flex-direction: column;
gap: 5px;
.contact-li {
color: rgb(255, 255, 255);
}
}
.contact-empty {
width: 100%;
height: 600px;
display: flex;
justify-content: center;
align-items: center;
color: white;
}
}
}
.right {
box-sizing: border-box;
z-index: 99;
background: rgba(20, 31, 168, .7);
border: 1px solid #0060d7;
width: 477px;
height: 850px;
max-height: 850px;
position: absolute;
top: 20px;
right: 265px;
border-radius: 8px;
padding: 12px;
}
} }
} }
</style> </style>

View File

@ -100,7 +100,6 @@
<script> <script>
import { requestFN } from '@/utils/request' import { requestFN } from '@/utils/request'
import { requestFN2 } from '@/utils/request2'
import SIdentify from './components/sidentify' import SIdentify from './components/sidentify'
import JSEncrypt from '../../../static/js/jsencrypt.min.js' import JSEncrypt from '../../../static/js/jsencrypt.min.js'
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
@ -270,7 +269,7 @@ export default {
jsencrypt.setPublicKey(config.publicKey) jsencrypt.setPublicKey(config.publicKey)
const loginData = jsencrypt.encrypt('qdkjchina' + this.loginForm.username + ',qd,' + this.loginForm.password) const loginData = jsencrypt.encrypt('qdkjchina' + this.loginForm.username + ',qd,' + this.loginForm.password)
this.loading = true this.loading = true
requestFN2( requestFN(
'/admin/check', '/admin/check',
{ {
KEYDATA: loginData KEYDATA: loginData

View File

@ -2,7 +2,7 @@
const config = { const config = {
weburl: 'http://192.168.0.37:8080/', // 前台地址 weburl: 'http://192.168.0.37:8080/', // 前台地址
// httpurl: 'http://192.168.0.29:8091/', // 后台地址 // httpurl: 'http://192.168.0.29:8091/', // 后台地址
httpurl: 'http://192.168.0.35:8089/', // 后台地址 httpurl: '/api', // 后台地址
qyurl: 'https://qgqy.qhdsafety.com/', // 企业前台 qyurl: 'https://qgqy.qhdsafety.com/', // 企业前台
adminurl: 'https://www.qdkjchina.com/qa-prevention-admin/', adminurl: 'https://www.qdkjchina.com/qa-prevention-admin/',
// 正式 // 正式