<template> <app-container id="addroute"> <el-collapse v-model="activeNames" class="route-coll" @change="handleChange"> <el-collapse-item title="(一)基本信息" name="1" > <el-form ref="dataForm" :rules="rules" :model="routeForm" size="small" label-position="right" label-width="130px" style="padding-top:20px;padding-right: 40px"> <el-row :gutter="20"> <el-col :span="8"> <el-form-item label="路线描述" prop="routeName" > <el-input v-model.trim="routeForm.routeName" :disabled="canclick2==false" :placeholder="canclick2==false?'':'必填'" type="text"/> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="报警类型" prop="alarmType"> <el-select v-model="routeForm.alarmType" :disabled="canclick2==false" :placeholder="canclick2==false?'':'必填'" filterable clearable value="" style="width: 100%"> <el-option v-for="item in alarmlist" :key="item.value" :label="item.name" :value="item.value"/> </el-select> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="偏离报警距离(米)" prop="alarmDistance"> <el-input v-model.trim="routeForm.alarmDistance" :disabled="canclick2==false" :placeholder="canclick2==false?'':'必填'" type="text" oninput="value=value.replace(/^\.+|[^\d.]/g,'')"/> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="8"> <el-form-item label="起点地址"> <el-input v-model.trim="routeForm.startAddress" :disabled="canclick2==false" :placeholder="canclick2==false?'':'起点地址'" type="text"/> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="终点地址"> <el-input v-model.trim="routeForm.endAddress" :disabled="canclick2==false" :placeholder="canclick2==false?'':'终点地址'" type="text"/> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="主要途径道路"> <el-input v-model.trim="routeForm.mainRoad" :disabled="canclick2==false" :placeholder="canclick2==false?'':'主要途径道路'" type="text"/> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="8"> <el-form-item label="开始日期"> <el-date-picker v-model="routeForm.startDate" :disabled="canclick2==false" :placeholder="canclick2==false?'':'开始日期'" style="width: 100%" type="date" value-format="yyyy-MM-dd"/> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="结束日期"> <el-date-picker v-model="routeForm.endDate" :disabled="canclick2==false" :placeholder="canclick2==false?'':'结束日期'" style="width: 100%" type="date" value-format="yyyy-MM-dd"/> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="准行时间段"> <el-select v-model="routeForm.accessTime" :disabled="canclick2==false" :placeholder="canclick2==false?'':'准行时间段'" filterable clearable value="" style="width: 100%" @change="accessTimeSelect"> <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"/> </el-select> </el-form-item> </el-col> </el-row> <el-row v-if="timechoose" :gutter="20"> <el-col :span="24"> <el-form-item label="自定义时间段"> <el-checkbox-group v-model="accessTime"> <el-checkbox v-for="time in times" :label="time" :key="time" :disabled="canclick2==false" style="width: 90px;line-height: 10px">{{ time }}:00</el-checkbox> </el-checkbox-group> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="24"> <el-form-item label="备注"> <el-input v-model.trim="routeForm.remarks" :disabled="canclick2==false" :placeholder="canclick2==false?'':'备注'" type="textarea" /> </el-form-item> </el-col> </el-row> </el-form> <div v-if="canclick2==true" style="text-align:center"> <el-button :disabled="!click1" type="primary" style="width: 200px;font-size: 15px;font-weight: bold" @click="saveData"> >> 下一步,关联车辆</el-button> </div> </el-collapse-item> <el-collapse-item :disabled="canclick2" title="(二)关联车辆" name="2"> <div style="padding-top: 20px;padding-left: 40px"> <el-form ref="selectForm" :inline="true" :model="listQuery" size="small"> <el-form-item prop="keywords"> <el-input v-model.trim="listQuery.description" placeholder="车辆描述" clearable/> </el-form-item> <el-form-item prop="keywords"> <el-input v-model="listQuery.carCode" placeholder="车牌号" clearable/> </el-form-item> <el-form-item prop="keywords"> <el-select v-model="listQuery.carType" filterable placeholder="车辆类型" clearable value="" @change="fetchData()"> <el-option v-for="item in cartypelist" :key="item.value" :label="item.name" :value="item.value"/> </el-select> </el-form-item> <el-form-item prop="keywords"> <dept-select v-if="canclick2==false" v-model="listQuery.deptId" :dept-show="deptShow" placeholder="使用单位" clearable value=""/> </el-form-item> <el-button :disabled="canclick3==false" class="filter-item" size="small" type="primary" icon="el-icon-search" @click="search">查 询</el-button> </el-form> </div> <div class="infinite-list-wrapper" style="overflow:auto;height: 100px;padding-left: 40px"> <el-checkbox-group v-model="carlist" class="checkbox"> <el-checkbox v-for="item in list" :label="item.id" :key="item.id" :disabled="canclick3==false" style="width: 150px">{{ item.description }}</el-checkbox> </el-checkbox-group> </div> <div v-if="canclick3==true" style="text-align:center;padding-top: 10px"> <el-button :disabled="!click2" type="primary" style="width: 200px;font-size: 15px;font-weight: bold" @click="saveCar"> >> 下一步,规划路线</el-button> </div> </el-collapse-item> <el-collapse-item :disabled="canclick3" title="(三)地图操作" name="3"> <div id="map"> <el-button v-if="canclick3==false" class="remove_btn" @click="removeall"/> </div> <div v-if="canclick3==false" style="text-align:center;padding-top: 10px;padding-bottom: 50px"> <el-button :disabled="!click3" type="primary" style="width: 200px;font-size: 15px;font-weight: bold" @click="saveRoute">提交规划路线</el-button> </div> </el-collapse-item> </el-collapse> </app-container> </template> <script> import { getDictCode } from '@/api/dict' import { addRouteInfo, listUnbindCar, bindCar, addPath } from '@/api/routeInfo' import DeptSelect from '@/components/DeptSelect' import L from 'leaflet' import 'leaflet/dist/leaflet.css' export default { components: { DeptSelect }, data() { return { activeNames: ['1', '3'], deptShow: true, map: null, list: [], alarmlist: [], cartypelist: [], canclick2: true, canclick3: true, timechoose: false, click1: true, click2: true, click3: true, accessTime: [], carlist: [], baselayer: [], markerlayer: null, pointForm: { routeId: '', pointlist: [] }, carForm: { routeId: '', carIds: [] }, listQuery: { routeId: '', description: '', carCode: '', carType: '', deptId: '' }, routeForm: { id: '', routeName: '', alarmType: '', alarmDistance: '', startAddress: '', endAddress: '', mainRoad: '', startDate: '', endDate: '', accessTime: '', remarks: '' }, // 表单 times: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23], options: [{ value: '0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23', label: '全天(0-23)' }, { value: '8,9,10,11,12,13,14,15,16,17,18', label: '工作时间段(8-18)' }, { value: '8,9,10,11,12', label: '上午工作时间段(8-12)' }, { value: '14,15,16,17,18', label: '下午工作时间段(14-18)' }, { value: '-1', label: '自定义时间段' }], rules: { routeName: [{ required: true, message: '路线描述不能为空', trigger: ['blur', 'change'] }], alarmType: [{ required: true, message: '报警类型必选', trigger: ['blur', 'change'] }], alarmDistance: [{ required: true, message: '偏离报警距离不能为空', trigger: ['blur', 'change'] }] } } }, mounted() { getDictCode('routeAlarmType').then(response => { this.alarmlist = response.data }) getDictCode('carType').then(response => { this.cartypelist = response.data }) }, methods: { removeall() { var base = this.baselayer this.map.eachLayer(function(layer) { if (layer !== base[0] && layer !== base[1]) { layer.remove() } }) this.pointForm.pointlist = [] }, initMap() { const map = L.map('map', { minZoom: 3, maxZoom: 18, center: [27.75962, 116.06021], zoom: 11, zoomControl: false, attributionControl: false, crs: L.CRS.EPSG3857 }) this.map = map // data上需要挂载 window.map = map this.baselayer.push(L.tileLayer( 'https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8', { subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'] } ).addTo(map)) this.baselayer.push(L.tileLayer( 'https://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8', { subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'] } ).addTo(map)) debugger this.map.pm.addControls({ position: 'topleft', drawPolygon: false, // 添加绘制多边形 drawMarker: false, // 添加按钮以绘制标记 drawCircleMarker: false, // 添加按钮以绘制圆形标记 drawPolyline: true, // 添加按钮绘制线条 drawRectangle: false, // 添加按钮绘制矩形 drawCircle: false, // 添加按钮绘制圆圈 editMode: false, // 添加按钮编辑多边形 dragMode: false, // 添加按钮拖动多边形 cutPolygon: false, // 添加一个按钮以删除图层里面的部分内容 removalMode: false // 清除图层 }) // 设置绘制后的线条颜色等 this.map.pm.setPathOptions({ color: '#409eff', fillColor: 'green', fillOpacity: 0.4 }) this.map.pm.setLang('zh') this.map.on('pm:create', e => { if (this.pointForm.pointlist.length !== 0) { this.$message.warning('一次只能绘制一条路线') e.layer.remove() } else { console.log(e, '绘制完成时调用') console.log(e.layer._latlngs[0].lat) var Icon var removepoints = [] for (var i = 0; i < e.layer._latlngs.length; i++) { if (i === 0) { Icon = L.icon({ iconUrl: require('../../assets/global_images/start.png'), iconSize: [35, 35] }) } else if (i === e.layer._latlngs.length - 1) { Icon = L.icon({ iconUrl: require('../../assets/global_images/end.png'), iconSize: [35, 35] }) } else { Icon = L.divIcon({ className: 'my-div-icon', // 自定义icon css样式 iconSize: [10, 10]// 点大小 }) } var marker = L.marker([e.layer._latlngs[i].lat, e.layer._latlngs[i].lng], { icon: Icon }) removepoints.push(marker) } this.markerlayer = L.layerGroup(removepoints) map.addLayer(this.markerlayer) this.pointForm.pointlist = e.layer._latlngs } }) }, fetchData() { console.log('fetchData') listUnbindCar(this.listQuery).then(response => { this.list = response.data }) }, accessTimeSelect(val) { if (val === '-1') { this.timechoose = true } else { this.timechoose = false } }, search() { this.fetchData(false) }, saveRoute() { this.click3 = false if (this.pointForm.pointlist.length === 0) { this.click3 = true this.$message.warning('请规划路线') } else { addPath(this.pointForm).then(response => { if (response.code === 200) { this.$message.success('新增路线成功!') this.$router.push({ path: '/route/list' }) } }) } }, saveCar() { this.click2 = false if (this.carlist.length === 0) { this.$message.warning('请至少选择一辆车') this.click2 = true } else { for (var i = 0; i < this.carlist.length; i++) { this.carForm.carIds.push(Number(this.carlist[i])) } console.log(this.carForm) bindCar(this.carForm).then(response => { if (response.code === 200) { this.$message.success('绑定车辆信息成功!') this.canclick3 = false this.initMap() } }) } }, saveData() { this.click1 = false this.$refs['dataForm'].validate((valid) => { if (valid) { if (this.routeForm.startDate > this.routeForm.endDate) { this.$message.warning('请确认输入正确起止时间') this.click1 = true } else if (this.routeForm.accessTime === '-1' && this.accessTime.length === 0) { this.$message.warning('请选择时间段') this.click1 = true } else { var timeselect = false if (this.routeForm.accessTime === '-1') { timeselect = true this.routeForm.accessTime = this.accessTime[0] for (var i = 1; i < this.accessTime.length; i++) { this.routeForm.accessTime += (',' + this.accessTime[i]) } } addRouteInfo(this.routeForm).then(response => { if (response.code === 200) { this.$message.success('添加规划路线基本信息成功!') if (timeselect) { this.routeForm.accessTime = '自定义时间段' } this.canclick2 = false this.carForm.routeId = response.data this.listQuery.routeId = response.data this.pointForm.routeId = response.data this.activeNames.push('2') this.fetchData() } }) } } else { this.click1 = true } }) }, handleChange(val) { console.log(val) } } } </script> <style rel="stylesheet/scss" lang="scss"> #addroute .el-checkbox__label { font-size: 15px ; font-weight: bold; } #addroute .el-form-item { margin-bottom: 18px; } #map { width:100%; height:50vh; } .my-div-icon { width: 10px; height: 10px; background-color: orange; border-radius: 50%; } .remove_btn { margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; z-index: 1000; background-image: url("../../assets/global_images/delete.png"); background-position:center; background-repeat:no-repeat; width: 30px !important; height: 30px; position: absolute; left: 10px; top:50px; padding: 15px; justify-content: center; align-items: center; border: 2px solid #ccc; } .route-coll{ .el-collapse-item__header{ font-weight: bolder; margin-left: 10px; } } </style>