lion 1 year ago
parent 59353d7748
commit 52f8ea1470

@ -2,15 +2,15 @@
ENV='development'
# base api
VUE_APP_BASE_API = http://192.168.60.99:9004/
VUE_APP_UPLOAD_API = http://192.168.60.99:9004/api/admin/upload-file
VUE_APP_OA_URL = http://192.168.60.18:2021
VUE_APP_OA_URL_TYPE = '{"领用":"37","处置":"38","应急":"39"}'
#VUE_APP_BASE_API = http://192.168.60.99:9004/
#VUE_APP_UPLOAD_API = http://192.168.60.99:9004/api/admin/upload-file
#VUE_APP_OA_URL = http://192.168.60.18:2021
#VUE_APP_OA_URL_TYPE = '{"领用":"37","处置":"38","应急":"39"}'
#VUE_APP_BASE_API = http://192.168.60.99:8004/
#VUE_APP_UPLOAD_API = http://192.168.60.99:8004/api/admin/upload-file
#VUE_APP_OA_URL= http://suzhouhedaooa.langye.net
#VUE_APP_OA_URL_TYPE = '{"领用":"31","处置":"32","应急":"33"}'
VUE_APP_BASE_API = http://192.168.60.99:8004/
VUE_APP_UPLOAD_API = http://192.168.60.99:8004/api/admin/upload-file
VUE_APP_OA_URL= http://suzhouhedaooa.langye.net
VUE_APP_OA_URL_TYPE = '{"领用":"31","处置":"32","应急":"33"}'

@ -2,8 +2,9 @@
ENV = 'production'
# base api
VUE_APP_BASE_API = http://192.168.60.99:9004/
VUE_APP_UPLOAD_API = http://192.168.60.99:9004/api/admin/upload-file
#http://192.168.60.99:9004/
VUE_APP_BASE_API =
VUE_APP_UPLOAD_API = /api/admin/upload-file
VUE_APP_OA_URL = http://192.168.60.18:2021
VUE_APP_OA_URL_TYPE = '{"领用":"37","处置":"38","应急":"39"}'

@ -4,5 +4,11 @@ NODE_ENV = production
ENV = 'staging'
# base api
VUE_APP_BASE_API = '/stage-api'
#http://192.168.60.99:9004/
VUE_APP_BASE_API =
VUE_APP_UPLOAD_API = /api/admin/upload-file
VUE_APP_OA_URL = http://192.168.60.18:2021
VUE_APP_OA_URL_TYPE = '{"领用":"37","处置":"38","应急":"39"}'
#VUE_APP_BASE_API = '/stage-api'

@ -29,7 +29,9 @@
"moment": "^2.29.2",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"ol": "^7.1.0",
"path-to-regexp": "2.4.0",
"proj4": "^2.8.0",
"qrcodejs2": "^0.0.2",
"tinymce": "^5.10.7",
"view-design": "^4.7.0",

@ -0,0 +1,41 @@
import request from '@/utils/request'
export function list(data) {
return request({
url: '/api/admin/section-boat/index',
method: 'get',
params:data
})
}
export function get(params) {
return request({
url: '/api/admin/section-boat/show',
method: 'get',
params
})
}
export function store(data) {
return request({
url: '/api/admin/section-boat/store',
method: 'post',
data
})
}
export function save(data) {
return request({
url: '/api/admin/section-boat/save',
method: 'post',
data
})
}
export function destroy(id) {
return request({
url: '/api/admin/section-boat/destroy',
method: 'get',
params:{ id }
})
}

@ -0,0 +1,46 @@
import request from "@/utils/request";
export function getPlayBack(params){
return request({
method:'get',
url:'/api/admin/gps/get-place',
params
})
}
export function getLocation(params){
return request({
method:'get',
url:'/api/admin/gps/actual-time',
params
})
}
export function getEquipmentList(params){
return request({
method:'get',
url:'/api/admin/gps/equipment-detail',
params
})
}
export function getStop(params){
return request({
method:'get',
url:'/api/admin/gps/stop-place',
params
})
}
export function getHome(params){
return request({
method:'get',
url:'/api/admin/gps/home',
params
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 KiB

@ -104,7 +104,8 @@ export default {
Object.keys(form).map((key)=>{
formItems.push(
<el-form-item
prop={key}>
prop={key}
class={key}>
{eval(`{$scopedSlots.${key} ? $scopedSlots.${key}() : ''}`)}
</el-form-item>
)

@ -0,0 +1,167 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
const animationDuration = 6000
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '500px'
},
chartData: {
type: Object
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
window.addEventListener('resize', () => {
this.chart.resize();
//
})
},
watch: {
chartData: {
deep: true,
handler(val) {
this.setOptions(val)
}
}
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons');
this.setOptions(this.chartData);
},
setOptions(chartdata) {
this.chart.setOption({
dataZoom: [
//x
// {
// startValue: 0,
// endValue: 6, //
// type: 'slider',
// show: true,
// xAxisIndex: [0],
// handleSize: 0, // 2
// height: 8, //
// left: 50, //
// right: 40, //
// bottom: 26, //
// handleColor: '#EFEFEF', //h
// handleStyle: {
// borderColor: '#409EFF',
// borderWidth: '1',
// shadowBlur: 2,
// background: '#EFEFEF',
// shadowColor: '#EFEFEF'
// },
// fillerColor: new echarts.graphic.LinearGradient(1, 0, 0, 0, [{
// // 410
// //01
// offset: 0,
// color: '#409EFF'
// },
// {
// offset: 1,
// color: '#409EFF'
// }
// ]),
// backgroundColor: '#EFEFEF', //
// showDataShadow: false, // auto
// showDetail: false, // true
// handleIcon: 'M-292,322.2c-3.2,0-6.4-0.6-9.3-1.9c-2.9-1.2-5.4-2.9-7.6-5.1s-3.9-4.8-5.1-7.6c-1.3-3-1.9-6.1-1.9-9.3c0-3.2,0.6-6.4,1.9-9.3c1.2-2.9,2.9-5.4,5.1-7.6s4.8-3.9,7.6-5.1c3-1.3,6.1-1.9,9.3-1.9c3.2,0,6.4,0.6,9.3,1.9c2.9,1.2,5.4,2.9,7.6,5.1s3.9,4.8,5.1,7.6c1.3,3,1.9,6.1,1.9,9.3c0,3.2-0.6,6.4-1.9,9.3c-1.2,2.9-2.9,5.4-5.1,7.6s-4.8,3.9-7.6,5.1C-285.6,321.5-288.8,322.2-292,322.2z',
// filterMode: 'filter'
// }
//
// {
// type: 'inside',
// show: true,
// xAxisIndex: [0],
// start: 0, //1
// end: 50,
// },
],
tooltip: { // XY
trigger: 'axis',
backgroundColor: 'rgba(32, 33, 36,.7)',
borderColor: 'rgba(32, 33, 36,0.20)',
borderWidth: 1,
textStyle: { //
color: '#fff',
fontSize: '12'
},
axisPointer: { // 线
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
},
},
grid: {
top: 10,
left: '2%',
right: '2%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
data: chartdata.xArr,
axisTick: {
alignWithLabel: true
}
}],
yAxis: [{
type: 'value',
minInterval: 1,
axisTick: {
show: false
}
}],
series: chartdata.series
// [{
// name: ',
// type: 'bar',
// stack: 'vistors',
// barWidth: '60%',
// data: chartdata.yArr,
// animationDuration
// }]
})
}
}
}
</script>

@ -0,0 +1,163 @@
<template>
<div :class="className" :style="{height:height,width:width}" autoresize />
</template>
<script>
import * as echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
const animationDuration = 6000
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '180px'
},
chartData: {
type: Object
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
window.addEventListener('resize', () => {
this.chart.resize();
//
})
},
watch: {
chartData: {
deep: true,
handler(val) {
this.setOptions(val)
}
}
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons');
this.setOptions(this.chartData);
},
setOptions(chartdata) {
this.chart.setOption({
dataZoom: [
// //x
// {
// startValue: 0,
// endValue: 500, //
// type: 'slider',
// show: true,
// xAxisIndex: [0],
// // handleSize: 0, // 2
// height: 8, //
// left: 50, //
// right: 40, //
// bottom: 26, //
// handleColor: '#EFEFEF', //h
// handleStyle: {
// borderColor: '#409EFF',
// borderWidth: '1',
// shadowBlur: 2,
// background: '#EFEFEF',
// shadowColor: '#EFEFEF'
// },
// fillerColor: new echarts.graphic.LinearGradient(1, 0, 0, 0, [{
// // 410
// //01
// offset: 0,
// color: '#409EFF'
// },
// {
// offset: 1,
// color: '#409EFF'
// }
// ]),
// backgroundColor: '#EFEFEF', //
// showDataShadow: false, // auto
// showDetail: false, // true
// handleIcon: 'M-292,322.2c-3.2,0-6.4-0.6-9.3-1.9c-2.9-1.2-5.4-2.9-7.6-5.1s-3.9-4.8-5.1-7.6c-1.3-3-1.9-6.1-1.9-9.3c0-3.2,0.6-6.4,1.9-9.3c1.2-2.9,2.9-5.4,5.1-7.6s4.8-3.9,7.6-5.1c3-1.3,6.1-1.9,9.3-1.9c3.2,0,6.4,0.6,9.3,1.9c2.9,1.2,5.4,2.9,7.6,5.1s3.9,4.8,5.1,7.6c1.3,3,1.9,6.1,1.9,9.3c0,3.2-0.6,6.4-1.9,9.3c-1.2,2.9-2.9,5.4-5.1,7.6s-4.8,3.9-7.6,5.1C-285.6,321.5-288.8,322.2-292,322.2z',
// filterMode: 'filter'
// },
// //
// {
// type: 'inside',
// show: true,
// xAxisIndex: [0],
// start: 0, //1
// end: 50,
// },
],
legendArr: [],
legend: {
orient: 'horizontal',
bottom: '3%',
data: chartdata.legendArr
},
tooltip: { // XY
trigger: 'axis',
backgroundColor: 'rgba(32, 33, 36,.7)',
borderColor: 'rgba(32, 33, 36,0.20)',
borderWidth: 1,
textStyle: { //
color: '#fff',
fontSize: '12'
},
axisPointer: { // 线
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
},
formatter:function (params) {
return params[0].value + "km/h"
}
},
backgroundColor: "#fff",
grid: {
top: '4%',
left: '2%',
right: '2%',
bottom: '6%',
containLabel: true
},
xAxis: [{
type: 'category',
data: chartdata.xArr,
}],
yAxis: [{
type: 'value',
minInterval: 1,
}],
series: chartdata.series
})
}
}
}
</script>

@ -0,0 +1,55 @@
import { debounce } from '@/utils'
export default {
data() {
return {
$_sidebarElm: null,
$_resizeHandler: null
}
},
mounted() {
this.$_resizeHandler = debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)
this.$_initResizeEvent()
this.$_initSidebarResizeEvent()
},
beforeDestroy() {
this.$_destroyResizeEvent()
this.$_destroySidebarResizeEvent()
},
// to fixed bug when cached by keep-alive
// https://github.com/PanJiaChen/vue-element-admin/issues/2116
activated() {
this.$_initResizeEvent()
this.$_initSidebarResizeEvent()
},
deactivated() {
this.$_destroyResizeEvent()
this.$_destroySidebarResizeEvent()
},
methods: {
// use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_initResizeEvent() {
window.addEventListener('resize', this.$_resizeHandler)
},
$_destroyResizeEvent() {
window.removeEventListener('resize', this.$_resizeHandler)
},
$_sidebarResizeHandler(e) {
if (e.propertyName === 'width') {
this.$_resizeHandler()
}
},
$_initSidebarResizeEvent() {
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
},
$_destroySidebarResizeEvent() {
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
}
}
}

@ -0,0 +1,151 @@
/**
* 配置对象用于配置地图地址和其他通用配置
*/
const CONFIGS = [
// {
// title: "天地图",
// id: "M2",
// type: "overlay",
// visible: true,
// projection: "EPSG:4326",
// layerType: "TD地图",
// opacity: 1,
// url: "http://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=82526d64e8504a0341f775c087863825"
// },
// {
// title: "遥感图",
// id: "M3",
// type: "overlay",
// visible: false,
// projection: "EPSG:4490",
// layerType: "TD地图",
// opacity: 1,
// url: "http://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=82526d64e8504a0341f775c087863825"
// },
// {
// title: "水利图",
// id: "S1",
// type: "overlay",
// visible: false,
// projection: "EPSG:4490",
// layerType: "GIS地图",
// opacity: 1,
// url: "http://172.17.50.65:6080/arcgis/rest/services/hcdt/苏州市矢量图0916/MapServer/tile/{z}/{y}/{x}"
// },
// {
// title: "河道图",
// id: "H1",
// type: "overlay",
// visible: false,
// projection: "EPSG:4490",
// layerType: "GIS地图",
// opacity: 1,
// url: "http://172.17.50.65:6080/arcgis/rest/services/hcdt/%E8%8B%8F%E5%B7%9E%E6%B0%B4%E7%B3%BB%E5%9B%BE%E9%AB%98%E4%BA%AE%E7%89%88/MapServer/tile/{z}/{y}/{x}"
// },
// {
// title: "高清影像",
// id: "M1",
// type: "overlay",
// visible: true,
// projection: "EPSG:4490",
// layerType: "地图",
// opacity: 1,
// url: "http://192.168.60.22:6080/arcgis/rest/services/szhd/yx449010/MapServer"
// },
// {
// title: "路网",
// id: "L1",
// type: "overlay",
// visible: true,
// projection: "EPSG:4490",
// layerType: "地图",
// opacity: 1,
// url: "http://192.168.60.22:6080/arcgis/rest/services/szhd/dlzx/MapServer"
// },
// {
// title: "主干管",
// id: "M4",
// type: "overlay",
// visible: true,
// projection: "EPSG:4490",
// layerType: "数据",
// opacity: 1,
// url: "http://192.168.60.22:6080/arcgis/rest/services/szhd/ysxzgg/MapServer"
// },
// {
// title: "主干管边井管",
// id: "M5",
// type: "overlay",
// visible: true,
// projection: "EPSG:4490",
// layerType: "数据",
// opacity: 1,
// url: "http://192.168.60.22:6080/arcgis/rest/services/szhd/ysxzggbjg/MapServer"
// },
// {
// title: "检查井",
// id: "M6",
// type: "overlay",
// visible: true,
// projection: "EPSG:4490",
// layerType: "数据",
// opacity: 1,
// url: "http://192.168.60.22:6080/arcgis/rest/services/szhd/ysjszjcj/MapServer"
// },
// {
// title: "出水口",
// id: "M7",
// type: "overlay",
// visible: true,
// projection: "EPSG:4490",
// layerType: "数据",
// opacity: 1,
// url: "http://192.168.60.22:6080/arcgis/rest/services/szhd/ysjszcsk/MapServer"
// },
// {
// title: "雨篦",
// id: "M8",
// type: "overlay",
// visible: true,
// projection: "EPSG:4490",
// layerType: "数据",
// opacity: 1,
// url: "http://192.168.60.22:6080/arcgis/rest/services/szhd/ysjszyb/MapServer"
// },
// {
// title: "其他井",
// id: "M9",
// type: "overlay",
// visible: true,
// projection: "EPSG:4490",
// layerType: "数据",
// opacity: 1,
// url: "http://192.168.60.22:6080/arcgis/rest/services/szhd/ysjszqtj/MapServer"
// }
]
/**
* 定义地图页面配置文件
*/
//
const MAPCONFIGS = {
Map_Code: "EPSG:4490",//坐标系名
// Map_extent: [390000, 3500000, 490000, 3360000], //范围框
Map_units: "degrees",//单位 m/degrees等
Map_axisOrientation: "neu",//轴
Map_global: false, //全球
MAP_center: [120.6126391, 31.3029816],//定义中心点
Map_Zooms: [12, 23, 10],//定义地图初始层级、最大层级、最小层级
Map_ID: "maps",//地图标识ID
}
export {
MAPCONFIGS,
CONFIGS
}

@ -0,0 +1,174 @@
<template>
<div :style="{'height':mapHeight,'width':'100%','position':'relative'}">
<div id="maps" class="map" :style="{'height':'100%'}">
</div>
<slot name="maptime"></slot>
<slot name="mapindex"></slot>
</div>
</template>
<script>
import "ol/ol.css";
import {
Tile as TileLayer,
Vector as VectorLayer
} from "ol/layer";
import XYZ from "ol/source/XYZ";
import {
TileArcGISRest
} from "ol/source"
import tilegrid from "ol/tilegrid/TileGrid"
import {
defaults as defaultControls
} from "ol/control";
import {
get as getprojection
} from "ol/proj"
import {
Projection,
addProjection
} from "ol/proj"
import Map from "ol/Map.js";
import View from "ol/View.js";
//
import {
Vector as VectorSource
} from "ol/source";
import * as olProj from "ol/proj";
import {
Feature,
Overlay
} from "ol"
import {
Point
} from "ol/geom";
import {
Style,
Fill,
Stroke,
Circle as sCircle
} from "ol/style";
import proj4 from 'proj4'
export default {
components: {
},
data() {
return {
map: null,
projection: "EPSG:4490",
mapHeight:"400px",
mapConfigs : {
Map_Code: "EPSG:4490",//
// Map_extent: [390000, 3500000, 490000, 3360000], //
Map_units: "degrees",// m/degrees
Map_axisOrientation: "neu",//
Map_global: false, //
MAP_center: [120.582031, 31.304329],//
Map_Zooms: [13, 23, 10],//
Map_ID: "maps",//ID
}
};
},
created() {},
mounted() {
//
proj4.defs("EPSG:4490", '+proj=longlat +ellps=GRS80 +no_defs')
this.projection = new Projection({
code: this.mapConfigs.Map_Code,
units: this.mapConfigs.Map_units,
axisOrientation: this.mapConfigs.Map_axisOrientation,
global: this.mapConfigs.Map_global,
});
addProjection(this.projection);
this.initLoad();
},
watch: {
},
methods: {
initLoad() {
var that = this;
var clientHeight = document.documentElement.clientHeight
var topHeight = 50; //
let tableHeight = clientHeight - topHeight;
that.mapHeight = tableHeight + "px";
this.showMaps()
},
showMaps() {
this.$nextTick(function() {
this.initMap();
})
},
initMap() {
let map = new Map({
target: "maps",
view: new View({
center: this.mapConfigs.MAP_center, //
zoom: this.mapConfigs.Map_Zooms[0], //
maxZoom: this.mapConfigs.Map_Zooms[1],
minZoom: this.mapConfigs.Map_Zooms[2],
projection: this.projection,
}),
layers: [],
// interactions: defaultControls({
// doubleClickZoom: false,
// }),
});
this.map = map;
//
let url = "http://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}";
url = `${url}&T=vec_c&tk=2eecd3d615e01cf6dbe6d4b8b686d264`;
let tdtLayer = new TileLayer({
title: "天地图",
id: "M2",
type: "overlay",
visible: true,
layerType: "TD地图",
opacity: 1,
source: new XYZ({
crossOrigin: 'anonymous',
url: url,
projection: "EPSG:4326"
})
});
this.map.addLayer(tdtLayer);
this.ShowLayers()
// this.map.layer2.setVisible(false)
},
//
ShowLayers() {
let layer = new TileLayer({
title: "高清影像",
id: "M1",
type: "overlay",
visible: true,
layerType: "地图",
opacity: 1,
source: new TileArcGISRest({
url: "http://192.168.60.22:6080/arcgis/rest/services/szhd/xmqyx4490/MapServer",
projection: "EPSG:4490"
}),
});
this.map.addLayer(layer);
}
}
}
</script>
<style scoped>
/deep/ .ol-zoom{
display: none;
}
</style>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,490 @@
<template>
<div :style="{'height':mapHeight,'width':mapwidth,'position':'relative'}">
<div id="maps" :style="{'height':'100%'}">
</div>
<slot name="maptime"></slot>
<slot name="mapbar"></slot>
<slot name="mapindex"></slot>
<showCamera ref="showCamera"></showCamera>
</div>
</template>
<script>
import {
getCameraLive
} from '@/utils/camera.js'
import showCamera from '@/views/monitor/camera/components/showCamera.vue'
export default {
components: {
showCamera
},
props: {
//
pointsArr: {
type: Array,
default: () => []
},
mapwidth: {
type: String,
default: "100%"
},
datasArr: {
type: Object,
default: () => {}
},
// clickNumber:{
// type: String,
// default: ""
// },
boatInfo: {
type: Object,
default: () => {}
}
},
data() {
return {
mapHeight: "400px",
map: null,
mapcenter: [120.58328, 31.29665],
start_icon: require("@/assets/imgs/map-start.png"),
end_icon: require("@/assets/imgs/map-end.png"),
play_back: require("@/assets/imgs/playback.png"),
camera: require("@/assets/imgs/camera.png"),
clickNumber: "",
// marker:[],
// markerInfoWin:[]
// points:this.pointsArr,
}
},
mounted() {
this.initMap()
window.showPlayBack = this.showPlayBack
window.showCamera = this.showCamera
},
watch: {
pointsArr(val, oldval) {
if (oldval != val) {
this.$nextTick(function() {
this.pointsArr = val
this.playMap()
})
}
},
datasArr(val, oldval) {
if (oldval != val) {
this.$nextTick(function() {
this.datasArr = val
this.nowLocationShow()
})
}
}
// clickNumber(val){
// if(val){
// this.clickNumber = val
// this.$nextTick(function(){
// this.panto()
// })
// }
// }
},
created() {
},
methods: {
initLoad() {
var that = this;
var clientHeight = document.documentElement.clientHeight
var topHeight = 50; //
let tableHeight = clientHeight - topHeight;
that.mapHeight = tableHeight + "px";
this.$emit('mapHeight', that.mapHeight)
},
playMap() {
this.$nextTick(function() {
this.playBack()
})
},
nowLocationShow() {
this.$nextTick(function() {
this.nowLocation()
})
},
//
initMap() {
this.initLoad()
this.$nextTick(function() {
this.loadTdt()
})
},
loadTdt(elId) {
console.log("开始执行")
let that = this
return new Promise((resolve, reject) => {
console.log("开始执行2")
let script = document.createElement('script');
script.type = 'text/JavaScript';
script.src = "http://api.tianditu.gov.cn/api?v=4.0&tk=2eecd3d615e01cf6dbe6d4b8b686d264"
console.log("开始执行3")
script.onload = function() {
console.log("js加载完成")
that.map = new T.Map('maps', {
projection: 'EPSG:4490'
});
that.map.centerAndZoom(new T.LngLat(120.582031, 31.304329), 16);
that.map.setMinZoom(1);
that.map.setMaxZoom(18);
that.map.enableDrag();
// if(that.datasArr.length>0){
// that.nowLocationShow()
// }
if (that.pointsArr.length > 0) {
that.playMap()
}
// that.nowLocationShow()
}
let head = document.head;
head.appendChild(script);
})
},
//
playBack() {
// market
if (this.map) {
var a = this.map.getOverlays()
for (var i = 0; i < a.length; i++) {
this.map.removeOverLay(a[i])
}
}
if (this.pointsArr.length == 0) {
this.$message({
message: '该时间段暂无点位信息',
type: 'warning'
});
return
}
//
this.map.centerAndZoom(new T.LngLat(this.pointsArr[0].longitude, this.pointsArr[0].latitude), 16);
let gjPoints = []
for (var m of this.pointsArr) {
gjPoints.push(
new T.LngLat(m.longitude, m.latitude)
)
}
//
var startIcon = new T.Icon({
iconUrl: this.start_icon,
iconSize: new T.Point(65, 65),
iconAnchor: new T.Point(32, 32)
});
var start_marker = new T.Marker(new T.LngLat(this.pointsArr[0].longitude, this.pointsArr[0].latitude), {
icon: startIcon
});
var endIcon = new T.Icon({
iconUrl: this.end_icon,
iconSize: new T.Point(65, 65),
iconAnchor: new T.Point(32, 32)
});
var end_marker = new T.Marker(new T.LngLat(this.pointsArr[this.pointsArr.length - 1].longitude, this.pointsArr[
this.pointsArr.length - 1].latitude), {
icon: endIcon
});
this.map.addOverLay(start_marker);
this.map.addOverLay(end_marker);
//线
var polygon = new T.Polyline(gjPoints, {
color: "blue",
weight: 3,
opacity: 0.5,
fillColor: "#FFFFFF",
fillOpacity: 0.5
});
polygon.id = "lines"
this.map.addOverLay(polygon);
},
//
nowLocation() {
//
this.panto(this.datasArr.location)
this.map.centerAndZoom(new T.LngLat(this.datasArr.location.longitude, this.datasArr.location.latitude), 16);
var that = this
var marker = new T.Marker(new T.LngLat(this.datasArr.location.longitude, this.datasArr.location
.latitude)); //
var eNum = this.datasArr.location.equipment_number
var cStatus = this.datasArr.camera ? this.datasArr.camera.state : ""
var cNo = this.datasArr.camera ? this.datasArr.camera.idno : "";
var direction = this.toGetDirection(Number(this.datasArr.location.direction))
var warning = this.toGetWarn(this.datasArr.location.alarm_message);
var status = this.toGetStatus(this.datasArr.location.status);
var content = "<div class='infowindow'>" +
"<div class='infoheader'>" +
"<span>" + this.datasArr.location.equipment_number + "</span></div>" +
"<div class='infowrap'>" +
"<table width='100%'>" +
"<tr>" +
"<td>定位时间</td>" +
"<td>" + this.datasArr.location.created_at + "</td>" +
"</tr>" +
"<tr>" +
"<td>行驶速度</td>" +
"<td>" + this.datasArr.location.speed + " km/h</td>" +
"</tr>" +
"<tr>" +
"<td>行驶方向</td>" +
"<td>" + direction + " </td>" +
"</tr>" +
"<tr>" +
"<td>当前告警</td>" +
"<td>" + warning + "</td>" +
"</tr>" +
"<tr class='bm1'>" +
"<td>设备状态</td>" +
"<td>" + status + "</td>" +
"</tr>" +
"<tr class='bm1'>" +
"<td>里程</td>" +
"<td>" + (this.datasArr.location.mileage / 10) + "km</td>" +
"</tr>" +
"<tr>" +
"<td>地理位置</td>" +
"<td>" + this.isEmpty(this.datasArr.location.address) + "</td>" +
"</tr>" +
"</table>" +
"<div class='playback'>" +
"<li onClick=showPlayBack('" + eNum + "'," + this.datasArr.location.status + ")>" +
"<img src='" + this.play_back + "'/>轨迹</li>" +
"<li onClick=showCamera('" + cStatus + "','" + cNo + "')>" +
"<img src='" + this.camera + "'/>摄像头</li>" +
"</div>"
// "<div class='infotop'></div>"+
// "<div class='infocenter'></div>"+
// "<div class='infobottom'></div>"+
"</div>" +
"</div>";
// this.markerInfoWin[i] = new T.InfoWindow(content, {
// offset: new T.Point(0, -20)
// });
// that.openInfo(this.markerInfoWin[i], this.marker[i])
that.map.addOverLay(marker); //
this.addClickHandler(content, marker);
// this.marker[i].click()
that.autoOpen(content, marker)
},
toGetDirection(num) {
let name = "未知";
if (num >= 0 && num < 90) {
name = num == 0 ? "正北" : "东北"
} else if (num >= 90 && num < 180) {
name = num == 90 ? "正东" : "东南"
} else if (num >= 180 && num < 270) {
name = num == 180 ? "正南" : "西南"
} else if (num >= 270 && num < 360) {
name = num == 270 ? "正北" : "西北"
}
return name;
},
toGetWarn(str) {
if (str.indexOf(1) > -1) {
return "有";
} else {
return "无";
}
},
toGetStatus(str) {
console.log("Number(str)", Number(str))
if (Number(str) != 11) {
return "异常信号";
} else {
return "正常信号";
}
},
panto(pot) {
let that = this
var a = this.map.getPanes()
console.log("pane", a)
this.map.panTo(new T.LngLat(pot.longitude, pot.latitude));
},
removeLocation(data) {
if (this.map) {
var a = this.map.getOverlays()
if (data.isSelect) {
this.datasArr = data
this.nowLocationShow()
} else {
for (var i = 0; i < a.length; i++) {
a[i].closeInfoWindow()
let point = a[i].getLngLat()
if (point.lat == data.location.latitude) {
this.map.removeOverLay(a[i])
}
// this.map.removeOverLay(a[i])
}
}
}
},
addClickHandler(content, marker) {
var that = this
// that.openInfo(content, e)
marker.addEventListener("click", function(e) {
that.openInfo(content, e)
that.$emit('showDataInfo')
});
},
openInfo(content, e) {
console.log("e", e)
var point = e.lnglat;
var marker = new T.Marker(point); //
var markerInfoWin = new T.InfoWindow(content, {
offset: new T.Point(0, -20)
}); //
this.map.openInfoWindow(markerInfoWin, point); //
},
autoOpen(content, marker) {
var point = marker.getLngLat();
var marker = new T.Marker(point); //
var markerInfoWin = new T.InfoWindow(content, {
offset: new T.Point(0, -20)
}); //
this.map.openInfoWindow(markerInfoWin, point); //
},
//
showPlayBack(gps, num) {
this.$router.push({
path: '/monitor/gps/playback',
query: {
boatEquipment: gps,
boatNum: num
}
});
},
isEmpty(val) {
if (val) {
return val
} else {
return ''
}
},
//
showCamera(deviceSerial) {
let that = this
let obj = {
cStatus: 1,
deviceSerial: deviceSerial
}
if (obj.cStatus == 1) {
getCameraLive(obj.deviceSerial, function(res) {
let url = res.data.url
that.$refs.showCamera.cUrl = url
that.$refs.showCamera.mountePlay()
that.$refs.showCamera.isShow = true
})
} else if (obj.cStatus == 2) {
this.$message({
message: '当前未匹配到设备',
type: 'warning'
});
} else {
this.$message({
message: '当前未匹配不在线',
type: 'warning'
});
}
},
}
}
</script>
<style scoped>
#maps {
width: 100%;
}
/deep/ .tdt-infowindow-content-wrapper {
padding: 0
}
/deep/ .tdt-infowindow-content {
margin: 0;
width: 350px !important;
/* height:200px */
}
/deep/ .tdt-container a.tdt-infowindow-close-button {
color: #fff
}
.infowindow {}
/deep/ .infoheader {
color: rgb(255, 255, 255);
width: 100%;
padding: 5px;
background-color: rgb(64, 150, 209);
}
/deep/ .infowrap {}
/deep/ .infowrap table {
font-size: 0;
border: none;
border-collapse: separate;
border-spacing: 0 0px;
border-bottom: 1px solid rgb(214, 214, 214);
}
/deep/ .infowrap table tr {
background-color: #f1f1f1;
}
/deep/ .infowrap table tr td {
padding: 3px 10px;
font-size: 14px;
}
/deep/ .infowrap table tr td:first-child {
width: 80px;
display: inline-block;
color: rgb(44, 120, 191);
}
/deep/ .infowrap table tr td:first-child+td {
background-color: #fff;
}
/deep/ .bm1 td {
border-bottom: 1px solid rgb(214, 214, 214);
border-top: 1px solid rgb(214, 214, 214);
}
/deep/ .playback {
padding: 10px;
font-size: 16px;
}
/deep/ .playback li {
display: inline-block;
margin-right: 10px
}
/deep/ .playback li img {
width: 20px;
vertical-align: sub;
margin-right: 5px
}
</style>

@ -251,7 +251,78 @@ let base = {
nodes.unshift(_node)
}
return nodes
}
},
//深拷贝数据
deepCopy(data) {
//string,number,bool,null,undefined,symbol
//object,array,date
if (data && typeof data === "object") {
//针对函数的拷贝
if (typeof data === "function") {
let tempFunc = data.bind(null);
tempFunc.prototype = this.deepCopy(data.prototype);
return tempFunc;
}
switch (Object.prototype.toString.call(data)) {
case "[object String]":
return data.toString();
case "[object Number]":
return Number(data.toString());
case "[object Boolean]":
return Boolean(data.toString());
case "[object Date]":
return new Date(data.getTime());
case "[object Array]":
let arr = [];
for (let i = 0; i < data.length; i++) {
arr[i] = this.deepCopy(data[i]);
}
return arr;
//js自带对象或用户自定义类实例
case "[object Object]":
let obj = {};
for (let key in data) {
//会遍历原型链上的属性方法可以用hasOwnProperty来控制 obj.hasOwnProperty(prop)
obj[key] = this.deepCopy(data[key]);
}
return obj;
}
} else {
//string,number,bool,null,undefined,symbol
return data;
}
},
// 按顺序把接口返回值 赋给 form
requestToForm(requestObj, form) {
// 获取a对象中属性的顺序和值
let aKeys = Object.keys(form);
let aValues = aKeys.map(key => form[key]);
// 遍历b对象将属性等于a中属性值的对象深拷贝给a中的相应属性
for (let i = 0; i < aKeys.length; i++) {
let key = aKeys[i];
let value = aValues[i];
if (requestObj[key] === value) {
// 深拷贝对象
Object.assign(form, {
[key]: this.deepCopy(requestObj[key])
});
}
}
// 遍历b对象将b中独有的属性按照a的顺序插入到a中
for (let key in requestObj) {
if (!form[key]) {
// 深拷贝属性值
Object.assign(form, {
[key]: this.deepCopy(requestObj[key])
});
}
}
return form
},
}
export default base

@ -0,0 +1,170 @@
<template>
<div class="container">
<div style="padding: 0px 20px">
<div ref="lxHeader">
<lx-header icon="md-apps" text="泵车管理" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
<div slot="content"></div>
<slot>
<div style="display: flex;justify-content: flex-start;flex-wrap: wrap;">
<div class="selector-item">
<Input v-model="paginations.keyword" style="width: 120px;margin-right: 10px;" placeholder="关键词搜索" />
</div>
<Button type="primary" style="margin-left: 10px;" @click="load"></Button>
<Button type="primary" style="margin-left: 10px;" @click="edit('','add')"></Button>
</div>
</slot>
</lx-header>
</div>
<div ref="lxtable">
<xy-table :list="list" :table-item="columns" @pageSizeChange="pageSizeChange" @pageIndexChange="pageChange">
<template v-slot:btns>
<!-- <div></div> -->
<el-table-column fixed="right" align="center" label="操作" width="120" header-align="center">
<template slot-scope="scope">
<Button type="primary" size="small" @click="edit(scope.row.id,'editor')"></Button>
<Poptip transfer confirm title="确认要删除吗?" @on-ok="del(scope.row.id)">
<Button type="primary" style="margin-left: 10px;" size="small" ghost>删除</Button>
</Poptip>
</template>
</el-table-column>
</template>
</xy-table>
</div>
</div>
<!-- 新增 编辑 -->
<editSection ref="editSection" @refresh="load"></editSection>
</div>
</template>
<script>
import {
list,
destroy
} from '@/api/car/basic.js'
import editSection from './components/editSection.vue'
export default {
components: {
editSection,
},
data() {
return {
paginations: {
page: 1,
page_size: 15,
total: 0,
keyword: ''
},
list: [], // table
columns: [{
label: '序号',
type: 'index',
fixed: 'left',
width: 80,
}, {
prop: 'name',
label: '车船名称',
align: 'left',
}, {
prop: 'type',
label: '设备类型',
align: 'left',
width: 120,
formatter: (row, column, cellValue) => {
if (row.type == 1) {
return '公务用车'
} else if (row.type == 2) {
return '船舶'
}
}
}, {
prop: 'describe',
label: '设备描述',
align: 'left',
width: 240,
}, {
prop: 'branch',
label: '品牌名称',
align: 'center',
width: 240,
}, {
prop: 'model',
label: '型号名称',
align: 'left',
width: 240
}, {
prop: 'buy_date',
label: '购买时间',
align: 'center',
width: 120,
}, {
prop: 'gps',
label: 'GPS',
align: 'left',
width: 240,
// width: 120,
}, {
prop: 'plate',
label: '车牌/船号',
align: 'left',
width: 240,
// width: 120,
}],
}
},
created() {
this.load()
},
methods: {
load() {
list({
page: this.paginations.page,
page_size: this.paginations.page_size,
...this.searchFileds
}).then(res => {
this.list = res.data
this.paginations.total = res.total
})
},
onSearch(val) {
this.searchFileds = val
this.load()
},
handleCurrentChange(page) {
this.paginations.page = page;
this.load();
},
pageChange(e) {
this.paginations.page = e
this.load()
},
pageSizeChange(e) {
this.paginations.page_size = e
this.load()
},
edit(id, type) {
if (type === 'editor') {
this.$refs.editSection.id = id
}
this.$refs.editSection.type = type
this.$refs.editSection.isShow = true
},
del(id) {
var that = this;
destroy({
id: id,
}).then(res => {
Message({
type: 'success',
message: '删除成功'
})
this.load()
})
}
}
}
</script>
<style>
</style>

@ -0,0 +1,172 @@
<template>
<div>
<!-- 保洁船只管理 -->
<xy-dialog :title="title" :is-show.sync="isShow" @resetform="resetform('form')">
<template v-slot:content>
<el-form :model="form" :rules="rules" ref="form" label-position="right" :label-width="labelwidth">
<el-row>
<el-col :span="11">
<el-form-item label="类型" prop="type">
<el-select class="width100" v-model="form.type" placeholder="请选择类型">
<el-option v-for="item in [{id:1,value:''},{id:2,value:''}]" :key="item.id" :label="item.value"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item label="车船名称" prop="name">
<el-input v-model="form.name" placeholder="请填写车船名称" autocomplete="off"></el-input>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="品牌名称" prop="branch">
<el-input v-model="form.branch" placeholder="请填写品牌名称" autocomplete="off"></el-input>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item label="型号名称" prop="model">
<el-input v-model="form.model" placeholder="请填写型号名称" autocomplete="off"></el-input>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="购买时间" prop="buy_date">
<el-date-picker style="width:100%" v-model="form.buy_date" value-format="yyyy-MM-dd" format="yyyy-MM-dd" type="date" placeholder="选择日期">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item label="GPS" prop="gps">
<el-input v-model="form.gps" placeholder="请填写GPS" autocomplete="off"></el-input>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="车牌/船号" prop="plate">
<el-input v-model="form.plate" placeholder="请填写车牌/船号" autocomplete="off"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="设备描述" prop="describe">
<el-input v-model="form.describe" type="textarea" placeholder="请填写设备描述" autocomplete="off"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<template v-slot:footerbtn>
<el-button type="primary" v-preventReClick @click="submitForm('form')"></el-button>
</template>
</xy-dialog>
</div>
</template>
<script>
import {
get,
store,
save
} from '@/api/car/basic.js'
export default {
components: {},
data() {
return {
title: "车船信息",
labelwidth: '120px',
type:'add',
isShow: false,
showform: false,
infoId: "",
form: {
type: 1,
name:'',
describe: '',
branch: '',
model: '',
buy_date: '',
gps: '',
plate:'',
// sort_number: '',
// remark: ''
},
rules: {
num: [{
required: true,
message: '请填写船号',
trigger: 'blur',
}],
type: [{
required: true,
message: '请选择船型',
trigger: 'blur',
}],
river_id: [{
required: true,
message: '请选择作业河道',
trigger: 'blur',
}],
}
}
},
created() {},
watch: {
},
methods: {
getInfo(id) {
let that = this
if (id) {
get(id).then(res => {
let result = Object.assign(that.form, res);
that.form = result;
}).catch(error => {
//reject(error)
})
}
},
submitForm(formName) {
let that = this
this.$refs[formName].validate((valid) => {
if (valid) {
if (that.infoId) {
save(that.form).then(response => {
this.$Message.success('操作成功');
this.$emit("auditSuccess")
that.isShow = false;
}).catch(error => {
//reject(error)
})
} else {
store(that.form).then(response => {
this.$Message.success('操作成功');
this.$emit("auditSuccess")
that.isShow = false;
}).catch(error => {
//reject(error)
})
}
} else {
this.$Message.error('数据校验失败');
console.log('error submit!!');
return false;
}
});
},
resetform(formName) {
this.infoId = ""
this.showform = false
this.$refs[formName].resetFields();
}
}
}
</script>
<style scoped>
.width100 {
width: 100%;
}
</style>

@ -0,0 +1,201 @@
<template>
<div>
<xy-dialog ref="dialog" :width="70" :is-show.sync="isShow" :type="'form'" :title="$route.meta.title" :form="form"
:rules='rules' @submit="submit">
<template v-slot:type>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;">*</span>类型
</div>
<div class="xy-table-item-content">
<el-select style="width: 300px;" v-model="form.type" placeholder="请选择类型">
<el-option v-for="item in [{id:1,value:''},{id:2,value:''}]" :key="item.id" :label="item.value"
:value="item.id">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:name>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;">*</span>泵车名称
</div>
<div class="xy-table-item-content">
<el-input style="width: 300px;" v-model="form.name" placeholder="请填写泵车名称" autocomplete="off"></el-input>
</div>
</div>
</template>
<template v-slot:branch>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>品牌名称
</div>
<div class="xy-table-item-content">
<el-input style="width: 300px;" v-model="form.branch" placeholder="请填写品牌名称" autocomplete="off"></el-input>
</div>
</div>
</template>
<template v-slot:model>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>型号名称
</div>
<div class="xy-table-item-content">
<el-input style="width: 300px;" v-model="form.model" placeholder="请填写型号名称" autocomplete="off"></el-input>
</div>
</div>
</template>
<template v-slot:buy_date>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>购买时间
</div>
<div class="xy-table-item-content">
<el-date-picker style="width: 300px;" v-model="form.buy_date" value-format="yyyy-MM-dd" format="yyyy-MM-dd"
type="date" placeholder="选择日期">
</el-date-picker>
</div>
</div>
</template>
<template v-slot:gps>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>GPS
</div>
<div class="xy-table-item-content">
<el-input style="width: 300px;" v-model="form.gps" placeholder="请填写GPS" autocomplete="off"></el-input>
</div>
</div>
</template>
<template v-slot:plate>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>车牌/船号
</div>
<div class="xy-table-item-content">
<el-input style="width: 300px;" v-model="form.plate" placeholder="请填写车牌/船号" autocomplete="off"></el-input>
</div>
</div>
</template>
<template v-slot:describe>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>设备描述
</div>
<div class="xy-table-item-content">
<el-input style="width: 300px;" v-model="form.describe" type="textarea" placeholder="请填写设备描述" autocomplete="off"></el-input>
</div>
</div>
</template>
</xy-dialog>
</div>
</template>
<script>
import {
get,
store,
save
} from '@/api/car/basic.js'
export default {
components: {
},
data() {
return {
isShow: false,
type: 'add',
id: '',
form: {
type: 1,
name: '',
branch: '',
model: '',
buy_date: '',
gps: '',
plate: '',
describe: '',
},
rules: {
type: [{
required: true,
message: '请选择'
}],
name: [{
required: true,
message: '请输入'
}]
}
}
},
created() {},
methods: {
submit() {
if (this.id) {
this.form.id = this.id
}
if (this.type == 'add') {
this.form.id = ''
}
if (this.id) {
save(this.form).then(response => {
this.$Message.success('操作成功');
this.$emit("refresh")
this.isShow = false;
}).catch(error => {
//reject(error)
})
} else {
store(this.form).then(response => {
this.$Message.success('操作成功');
this.$emit("refresh")
this.isShow = false;
}).catch(error => {
//reject(error)
})
}
},
getDetail() {
get({
id: this.id,
}).then(res => {
this.form = this.base.requestToForm(res, this.form)
})
}
},
watch: {
isShow(newVal) {
if (newVal) {
if (this.type === 'editor') {
this.getDetail()
}
} else {
this.id = ''
this.type = "add"
this.form = {
type: 1,
name: '',
branch: '',
model: '',
buy_date: '',
gps: '',
plate: '',
describe: '',
}
this.$refs['dialog'].reset()
}
},
}
}
</script>
<style scoped lang="scss">
</style>

@ -0,0 +1,307 @@
<template>
<div class="demo-split">
<Split v-model="split1">
<template #right>
<div class="demo-split-pane no-padding">
<!-- <Split v-model="split2" mode="vertical" @on-moving="toMoveSplit">
<template #top> -->
<div class="demo-split-pane">
<maps ref="maps" @mapHeight="getmapHeight" :locationObj="locationObj"
@showDataInfo="showDataInfo">
</maps>
</div>
<!-- </template> -->
<!-- <template #bottom>
<div class="demo-split-pane">
<div class="mapsInfo">
<mytable :list="list" style="height:100%" :columns="columns" :optdefault="optdefault"
:paginations="tablepaginations">
</mytable>
</div>
</div>
</template> -->
<!-- </Split> -->
</div>
</template>
<template #left>
<div class="demo-split-pane">
<div class="leftMenu" :style="{'height':leftHeight}">
<div slot="title" class="clearfix" style="height: 32px;line-height: 32px;">
<span>实时定位</span>
</div>
<div class="treewrap">
<el-input class="treeInput" placeholder="输入关键字进行查找" v-model="filterText">
</el-input>
<el-tree ref="boatTree" :filter-node-method="filterNode" node-key="num" :data="data" :props="defaultProps"
default-expand-all>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span @click="()=>nodeClick(data)"><i
:class="data.isSelect?'isSelect el-icon-check':'el-icon-check'"></i>
</span>
<span @click="toMove(data)" :class="data.isSelect?'isSelect':''"> {{ data.name }}
<span v-if="data.plate">({{data.plate}})</span>
</span>
</span>
</el-tree>
</div>
</div>
</div>
</template>
</Split>
</div>
</template>
<script>
import {
getLocation
} from "@/api/monitor/gps"
import {
list as listSection
} from '@/api/car/basic.js'
import maps from "@/components/maps/maps"
export default {
components: {
maps
},
data() {
return {
split1: 0.2,
split2: 0.75,
leftHeight: "0",
menuHeight: "0",
locationObj: {},
listUnit: [],
isSelect: false,
locationArr: [],
paginations: {
page: 1,
page_size: 999,
total: 0
},
tablepaginations: {
page: 1,
page_size: 5,
total: 0,
noShow: true
},
optdefault: {
noOpt: true
},
list: [],
filterText: "",
data: [],
checkedId: [],
defaultProps: {
children: 'children',
label: 'name',
gps: "gps"
},
equipmentNumber: [],
clickNumber: ""
}
},
mounted() {
this.$store.dispatch('app/toggleSideBar')
this.$nextTick(function() {
// this.getBoat()
this.getData()
})
},
created() {
// this.getList()
this.getmapHeight();
},
watch: {
filterText(val) {
this.$refs.boatTree.filter(val);
}
},
methods: {
//
filterNode(value, data) {
if (!value) return true;
return data.num.indexOf(value) !== -1;
},
toMoveSplit(e) {
console.log(e);
this.menuHeight = e.y + "px"
},
toputInSeaction(obj) {
if (obj.gps) {
var box = this.data[0].children.filter(item => {
return item.id == obj.section
})[0];
box.children.push(obj);
}
},
async getData() {
await getLocation({
equipment_number: this.equipmentNumber
}).then(res => {
this.locationArr = res
}).catch(error => {
//reject(error)
})
await listSection({
page: this.paginations.page,
page_size: this.paginations.page_size
}).then(res => {
let data = res.data;
// this.data = res.data
for (var m of data) {
for (var k of this.locationArr) {
if (m.gps == k.equipment_number) {
m['location'] = k
m.isSelect = false
break
}
}
// this.toputInSeaction(m);
}
this.data = data
this.list.push(...res.data)
})
},
// maps
getmapHeight(val) {
this.leftHeight = val
this.menuHeight = (parseInt(val) - 100) + 'px'
},
//
toMove(data) {
if (data.isSelect) {
this.$refs.maps.moveto(data.location.longitude, data.location.latitude)
} else {
this.nodeClick(data)
}
},
nodeClick(data) {
if (data.location) {
let isSe = false
isSe = !data.isSelect
console.log("isSe", isSe)
if (isSe) {
this.list.push(data)
console.log("data", data)
this.locationObj = data
} else {
for (var i = 0; i < this.list.length; i++) {
if (this.list[i].gps == data.gps) {
this.list.splice(i, 1)
this.locationObj = data
}
}
// this.$refs.maps.removeLocation(data)
}
data.isSelect = isSe
this.$refs.boatTree.updateKeyChildren(data.num, data)
// return data
// this.$set(data,'isSelect',isSe)
} else {
this.$message({
message: '暂无点位信息',
type: 'warning'
});
}
},
// table
showDataInfo() {
console.log("show")
}
}
}
</script>
<style scoped>
.mapwraper {
position: relative;
display: flex;
justify-content: space-between;
}
.leftMenu {
background: #fff;
padding: 10% 5%;
/* overflow: auto; */
}
.treewrap {
height: 95%;
overflow: hidden;
}
.treeInput {
margin: 10px 0;
}
.treewrap .el-tree {
height: calc(100% - 60px);
overflow: auto;
}
.maptime {
position: absolute;
left: 10px;
bottom: 10px;
background: #fff;
padding: 20px;
z-index: 1000;
}
.mapsInfo {
height: 300px;
overflow: auto;
}
.el-icon-close {
position: absolute;
top: 3px;
right: 3px;
font-size: 20px;
cursor: pointer;
}
.el-icon-plus {
font-size: 20px;
cursor: pointer;
}
.popper .el-icon-rank {
cursor: pointer;
}
.isSelect {
color: #409eff
}
</style>
<style>
.demo-split {
height: 94vh;
border: 1px solid #dcdee2;
margin: 0px 5px;
}
.demo-split-pane {
padding: 2px;
}
.demo-split-pane.no-padding {
height: 94vh;
padding: 0;
}
</style>

@ -0,0 +1,762 @@
<template>
<div class="mapwraper">
<div class="leftMenu" :style="{'height':menuHeight}">
<div slot="title" class="clearfix" style="height: 32px;line-height: 32px;">
<span>轨迹回放</span>
</div>
<div class="treewrap">
<el-input class="treeInput" placeholder="输入关键字进行查找" v-model="filterText">
</el-input>
<el-tree ref="boatTree" :filter-node-method="filterNode" :style="{}" @node-click="getNodeList" node-key="num"
:data="data" :props="defaultProps" default-expand-all>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>
{{ data.name }}<span v-if="data.plate">({{data.plate}})</span>
<el-popover popper-class="popper" placement="right-start" title="" width="500" trigger="hover">
<el-radio-group v-model="callDay" @change="changeCallDay">
<el-radio :label="7">近七天</el-radio>
<el-radio :label="10">近十天</el-radio>
<el-radio :label="15">近十五天</el-radio>
</el-radio-group>
<el-table :data="lastdata" height="250" width="100%">
<el-table-column type="index" width="50" fixed label="序号" align="center"> </el-table-column>
<el-table-column prop="date" label="日期"></el-table-column>
<el-table-column width="100" align="right" prop="callback" label="轨迹">
<template slot-scope="scope">
<i class="el-icon-rank" @click="getListTime(node,scope.row['date'])"></i>
</template>
</el-table-column>
</el-table>
<i class="el-icon-setting" slot="reference" v-if="!data.children"></i>
</el-popover>
</span>
</span>
</el-tree>
</div>
<div class="leftbottom">
<div>
<p>基本信息</p>
<div>
名称{{boatName}}
</div>
<div>
品牌{{boatBranch}}
</div>
<div>
类型{{modelName}}
</div>
<div>
GPS{{boatEquipment}}
</div>
<div>
车牌/船号{{boatPlate}}
</div>
</div>
<div class="searchmap">
<div>
<el-form>
<el-form-item label="开始时间" prop="start_time">
<el-date-picker style="width:60%" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
v-model="starttime" type="datetime" placeholder="选择日期时间">
</el-date-picker>
</el-form-item>
</el-col>
<el-form-item label="结束时间" prop="end_time">
<el-date-picker style="width:60%" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
v-model="endtime" type="datetime" placeholder="选择日期时间">
</el-date-picker>
</el-form-item>
<el-form-item style="text-align: center;">
<el-button type="primary" @click="searchTime"></el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
</div>
<!-- 地图 -->
<maps ref="maps" :mapwidth="mapwidth" @mapHeight="getmapHeight" :pointsArr="pointsArr">
<template v-slot:maptime>
<div class="maptime">
<div v-if="showMapTime">
<i class="el-icon-close" @click="showMapTime=false"></i>
<div>名称{{boatName}}</div>
<div>
车牌/船号{{boatPlate}}
</div>
<div>GPS{{boatEquipment}}</div>
<div>开始{{start_time}}</div>
<div>结束{{end_time}}</div>
</div>
<div v-if="!showMapTime" @click="showMapTime=true">
<i class="el-icon-plus"></i>
</div>
</div>
</template>
<!-- <template v-slot:mapbar>
<div class="mapbar">
<div style="text-align: center;">
<i @click="showMapBars" :class="barIcon" style="font-size: 60px;color:#00AAFF"></i>
</div>
<el-tabs v-if="showMapBar" v-model="activeName" type="border-card" tab-position="bottom"
@tab-click="handleClick">
<el-tab-pane label="轨迹明细" name="first">
<el-table style="height:200px" height="200" class="v-table" v-el-table-infinite-scroll="loadMore"
:data="tbdata" ref="mutipleTable" row-key="id" default-expand-all>
<el-table-column type="index" width="100" fixed label="序号" align="center">
</el-table-column>
<template v-for="(column, index) in (boatType=='zhenjiang'?columnsZJ:columns)">
<el-table-column :prop="column.prop" :key='column.label' :label="column.label" :align="column.align"
:width="column.width" :fixed="column.fixed">
<template slot-scope="scope">
<template v-if="!column.render">
<template v-if="column.formatter">
<span v-html="column.formatter(scope.row, column)"></span>
</template>
<template v-else-if="column.customFn">
{{column.customFn(scope.row, column)}}
</template>
<template v-else-if="column.fprop">
<span v-if="scope.row[column.fprop]">{{scope.row[column.fprop][column.prop]}}</span>
</template>
<template v-else>
<span>{{scope.row[column.prop]}}</span>
</template>
</template>
<template v-else>
<expand-dom :column="column" :row="scope.row" :render="column.render" :index="index">
</expand-dom>
</template>
</template>
</el-table-column>
</template>
</el-table>
</el-tab-pane>
<el-tab-pane label="速度分析" name="second" v-if="boatType==''">
<div style="width:100%;padding:10px">
<line-chart :chartData="speedArr" ref="lineChart" autoresize />
</div>
</el-tab-pane>
<el-tab-pane label="停船分析" name="third" v-if="boatType==''">
<mytable style="height:200px" :list="list2" :optdefault="optdefault" :columns="columns2"
:paginations="tablepaginations">
</mytable>
</el-tab-pane>
</el-tabs>
</div>
</template> -->
</maps>
</div>
</template>
<script>
// import ElTableInfiniteScroll from "el-table-infinite-scroll";
import {
getPlayBack,
getStop
} from "@/api/monitor/gps"
import {
list as listSection
} from '@/api/car/basic.js'
import maps from "@/components/maps/maps"
import lineChart from '@/components/echarts/lineChart'
export default {
// directives: {
// 'el-table-infinite-scroll': ElTableInfiniteScroll
// },
components: {
maps,
lineChart
},
data() {
return {
page: {
total: 0,
currentPage: 1,
pageSize: 50,
},
tbdata: [],
showMapTime: false,
menuHeight: "0",
pointsArr: [],
boatName: '',
boatBranch: '',
modelName: "",
boatEquipment: "",
boatPlate:'',
start_time: "",
end_time: "",
mapwidth: "78%",
status: "",
paginations: {
page: 1,
page_size: 999,
total: 0
},
filterText: "",
data: [
],
defaultProps: {
children: 'children',
label: 'name'
},
callDay: 7,
lastdata: [],
boatType: "",
starttime: "",
endtime: "",
showMapBar: false,
barIcon: "el-icon-caret-top",
activeName: "first",
tablepaginations: {
page: 1,
page_size: 999,
total: 0,
noShow: true
},
optdefault: {
noOpt: true
},
list1: [],
list2: [],
columns: [{
prop: 'area',
label: '状态',
align: 'center',
width: "120",
formatter: (row, column, cellValue) => {
return `<i class="iconfont icon-daohang" style="color:#00AAFF;display:inline-block !important;transform:rotate(${row.direction}deg)"></i>`
}
}, {
prop: 'created_at',
label: '定位时间',
align: 'center',
width: "180"
}, {
prop: 'speed',
label: '行驶速度',
align: 'center',
width: "120",
customFn: (row, column, cellValue) => {
return (Number(row.speed) / 10) + "km/h"
}
}, {
prop: 'mileage',
label: '里程',
align: 'center',
width: "120",
customFn: (row, column, cellValue) => {
return (Number(row.mileage) / 10) + "km"
}
}, {
prop: 'status',
label: '定位信号',
align: 'center',
customFn: (row, column, cellValue) => {
return this.toGetStatus(row.status)
}
}, {
prop: 'alarm_message',
label: '告警状态',
align: 'center',
customFn: (row, column, cellValue) => {
return this.toGetWarn(row.alarm_message)
}
}, {
prop: 'addr',
label: '地理位置',
align: 'left'
}, {
prop: 'longitude',
label: '经度',
align: 'center',
width: "180"
}, {
prop: 'latitude',
label: '纬度',
align: 'center',
width: "180"
}],
columns2: [{
prop: 'start_time',
label: '开始时间',
align: 'center',
width: "180"
}, {
prop: 'end_time',
label: '结束时间',
align: 'center',
width: "180"
}, {
prop: 'stoptime',
label: '停止时长',
align: 'center',
customFn: (row, column, cellValue) => {
return this.timeRange(row.start_time, row.end_time) + "分钟"
}
}, {
prop: 'mileage',
label: '里程',
align: 'center',
customFn: (row, column, cellValue) => {
return (Number(row.mileage) / 10) + "km"
}
}, {
prop: 'addr',
label: '地理位置',
align: 'left'
}, {
prop: 'longitude',
label: '经度',
align: 'center'
}, {
prop: 'latitude',
label: '纬度',
align: 'center'
}],
columnsZJ: [{
prop: 'area',
label: '状态',
align: 'center',
width: "120",
formatter: (row, column, cellValue) => {
return `<i class="iconfont icon-daohang" style="color:#00AAFF;display:inline-block !important;transform:rotate(${row.direction}deg)"></i>`
}
}, {
prop: 'created_at',
label: '定位时间',
align: 'center',
width: "180"
},{
prop: 'orp',
label: 'ORP',
align: 'center'
},{
prop: 'oxygen',
label: '溶解氧',
align: 'center'
}, {
prop: 'ph',
label: 'PH',
align: 'center'
}, {
prop: 'shipbow',
label: '船艏测距仪',
align: 'center'
}, {
prop: 'temperature',
label: '温度',
align: 'center'
},{
prop: 'longitude',
label: '经度',
align: 'center',
width: "180"
}, {
prop: 'latitude',
label: '纬度',
align: 'center',
width: "180"
}],
//
speedArr: {
xArr: [],
legendArr: [],
series: [{
name: '',
type: 'line',
stack: 'Total',
data: []
}]
}
}
},
mounted() {
this.$store.dispatch('app/toggleSideBar')
//
this.boatEquipment = this.$route.query.boatEquipment ? this.$route.query.boatEquipment : ""
this.boatPlate = this.$route.query.boatPlate ? this.$route.query.boatPlate : ""
this.boatName = this.$route.query.boatName ? this.$route.query.boatName : ""
this.boatBranch = this.$route.query.boatBranch ? this.$route.query.boatBranch : ""
console.log(this.boatBranch)
this.modelName = this.$route.query.modelName ? this.$route.query.modelName : "";
console.log(this.$route.query.type)
this.boatType = this.$route.query.type ? this.$route.query.type : "";
if (this.boatEquipment != "") {
if (this.boatType == "") this.getList();
}
},
watch: {
filterText(val) {
this.$refs.boatTree.filter(val);
}
},
created() {
this.getData()
this.getmapHeight()
this.chart2(7);
},
methods: {
//
filterNode(value, data) {
if (!value) return true;
return data.num.indexOf(value) !== -1;
},
loadMore() {
console.log("pointsArr", 1)
this.page.currentPage = this.page.currentPage + 1;
console.log("currentPage", this.page.currentPage)
this.tbdata = this.tbdata.concat(this.pointsArr.slice((this.page.currentPage - 1) * this.page.pageSize, this
.page.currentPage *
this.page.pageSize));
},
toGetWarn(str) {
if (!str) {
return "无"
}
if (str.indexOf(1) > -1) {
return "有";
} else {
return "无";
}
},
toGetStatus(str) {
if (Number(str) != 11) {
return "异常信号";
} else {
return "正常信号";
}
},
timeRange(sdate, edate) {
let start = this.$moment(sdate) //1242021-05-10 18:42:53
let end = this.$moment(edate) //2021-05-11 18:42:53
//let timeRange = [start, end];
return end.diff(start, 'minutes') // 1;
},
handleClick(tab, event) {
if (tab.name == "first") {
this.tbdata = [];
this.page.currentPage = 0;
this.list1 = this.pointsArr;
this.loadMore();
} else if (tab.name == "second") {
} else {
getStop({
page: this.paginations.page,
page_size: this.paginations.page_size,
start_time: this.start_time,
end_time: this.end_time,
equipment_number: this.boatEquipment
}).then(res => {
this.list2 = res.data;
}).catch(error => {
//reject(error)
})
}
},
// table
showMapBars() {
this.showMapBar = !this.showMapBar
this.barIcon = !this.showMapBar ? "el-icon-caret-top" : "el-icon-caret-bottom"
},
//
toputInSeaction(obj) {
if (obj.gps) {
var box = this.data[0].children.filter(item => {
return item.id == obj.section
})[0];
box.children.push(obj);
}
},
//
async getData() {
await listSection({
page: this.paginations.page,
page_size: this.paginations.page_size
}).then(res => {
this.data = res.data;
// for (var m of data) {
// m.text = ""
// this.toputInSeaction(m);
// }
})
},
//
getList(checkTime, callday) {
// this.pointsArr = [{
// longitude:"120.630041",
// latitude:'31.314108',
// },{
// longitude:"120.640773",
// latitude:'31.291506',
// },{
// longitude:"120.633048",
// latitude:'31.294151',
// },{
// longitude:"120.633073",
// latitude:'31.294158',
// },{
// longitude:"120.640076",
// latitude:'31.326990',
// },{
// longitude:"120.635291",
// latitude:'31.329283',
// },{
// longitude:"120.630042",
// latitude:'31.314108',
// },{
// longitude:"120.640774",
// latitude:'31.291506',
// },{
// longitude:"120.633049",
// latitude:'31.294151',
// },{
// longitude:"120.633079",
// latitude:'31.294158',
// },{
// longitude:"120.640071",
// latitude:'31.326990',
// },{
// longitude:"120.635299",
// latitude:'31.329283',
// }]
// return
if (!checkTime) {
this.getCurrentTime(callday)
}
getPlayBack({
page: this.paginations.page,
page_size: this.paginations.page_size,
start_time: this.start_time,
end_time: this.end_time,
equipment_number: this.boatEquipment,
status: this.status,
sort_name:'id',
sort_type:'ASC'
}).then(res => {
this.paginations.total = res.total
this.pointsArr = res.data
for (var m of res.data) {
// this.speedData.push(m.speed)
this.speedArr.series[0].data.push(m.speed / 10)
this.speedArr.xArr.push(m.created_at)
}
// this.$refs.lineChart.resize()
console.log(this.speedArr)
}).catch(error => {
//reject(error)
})
},
//
searchTime() {
this.start_time = this.starttime
this.end_time = this.endtime
this.getList(true)
},
// maps
getmapHeight(val) {
this.menuHeight = val
},
//
getNodeList(val) {
console.log("node", val)
if (!val.children) {
this.boatName = val.name
this.boatEquipment = val.gps
this.boatBranch = val.branch
this.boatPlate = val.plate
this.modelName = val.model ? val.model : ''
this.showMapTime = true
this.getCurrentTime()
this.getList()
}
},
//
getListTime(val, time) {
console.log("val", val)
this.boatName = val.data.name
this.boatEquipment = val.data.gps
this.boatPlate = val.data.plate
this.boatBranch = val.data.branch
this.modelName = val.data.model
this.getList(false, time)
},
//
changeCallDay(val) {
this.chart2(val)
},
//
getCurrentTime(callday) {
var _this = this;
let yy = new Date().getFullYear();
var mm =
new Date().getMonth() + 1 < 10 ?
"0" + (new Date().getMonth() + 1) :
new Date().getMonth() + 1;
var dd =
new Date().getDate() < 10 ?
"0" + new Date().getDate() :
new Date().getDate();
let hh = new Date().getHours();
let mf =
new Date().getMinutes() < 10 ?
"0" + new Date().getMinutes() :
new Date().getMinutes();
let ss =
new Date().getSeconds() < 10 ?
"0" + new Date().getSeconds() :
new Date().getSeconds();
if (callday) {
this.start_time = callday + " 00:00:00"
this.end_time = callday + " " + hh + ":" + mf + ":" + ss
return
}
this.start_time = yy + "-" + mm + "-" + dd + " 00:00:00"
this.end_time = yy + "-" + mm + "-" + dd + " " + hh + ":" + mf + ":" + ss
},
//
getDay(day) {
var today = new Date()
var targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day
today.setTime(targetday_milliseconds); //
var tYear = today.getFullYear()
var tMonth = today.getMonth()
var tDate = today.getDate()
tMonth = this.doHandleMonth(tMonth + 1)
tDate = this.doHandleMonth(tDate)
// console.log(tYear + "-" + tMonth + "-" + tDate)
return tYear + "-" + tMonth + "-" + tDate
},
doHandleMonth(month) {
var m = month
if (month.toString().length == 1) {
m = "0" + month
}
return m;
},
chart2(datas) {
this.lastdata = []
for (var i = 0; i < datas; i++) {
this.lastdata.push({
date: this.getDay(-i)
})
}
}
}
}
</script>
<style scoped>
.mapwraper {
position: relative;
display: flex;
justify-content: space-between;
}
.treewrap {
height: 60%;
overflow: hidden;
}
.treeInput{
margin: 10px 0;
}
.treewrap .el-tree {
height: calc(100% - 60px);
overflow: auto;
}
.leftMenu {
width: 25%;
background: #fff;
margin: 0 1%;
padding: 15px 20px;
overflow: auto;
position: relative;
}
.leftbottom {
position: absolute;
height: 30%;
width: 100%;
bottom: 0;
left: 0;
padding: 15px 20px;
margin-top: 20px;
border-top: 1px solid #ddd;
padding-top: 20px
}
.searchmap {
margin-top: 20px;
border-top: 1px solid #ddd;
padding-top: 20px;
padding-bottom: 20px;
}
.maptime {
position: absolute;
left: 10px;
top: 10px;
background: #fff;
padding: 20px;
z-index: 1000;
}
.el-icon-close {
position: absolute;
top: 3px;
right: 3px;
font-size: 20px;
cursor: pointer;
}
.el-icon-plus {
font-size: 20px;
cursor: pointer;
}
.popper .el-icon-rank {
cursor: pointer;
}
.mapbar {
position: absolute;
bottom: 0;
left: 0;
z-index: 1001;
width: 100%;
}
/deep/ .el-tabs--bottom.el-tabs--border-card .el-tabs__header.is-bottom {
margin-top: 0
}
/deep/ .el-tabs--border-card>.el-tabs__content {
padding: 0
}
</style>

@ -0,0 +1,24 @@
<template>
<div class="container">
<div style="padding: 0px 20px">
<el-image
style="width: 100%"
:src="require('/src/assets/chart.png')"
fit="fill"></el-image>
<!-- <div ref="lxHeader">
<lx-header icon="md-apps" text="数据统计" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
<div slot="content"></div>
<slot>
</slot>
</lx-header>
</div> -->
</div>
</div>
</template>
<script>
</script>
<style>
</style>

@ -0,0 +1,24 @@
<template>
<div class="container">
<div style="padding: 0px 20px">
<el-image
style="width: 100%"
:src="require('/src/assets/warning.png')"
fit="fill"></el-image>
<!-- <div ref="lxHeader">
<lx-header icon="md-apps" text="系统预警" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
<div slot="content"></div>
<slot>
</slot>
</lx-header>
</div> -->
</div>
</div>
</template>
<script>
</script>
<style>
</style>

@ -0,0 +1,24 @@
<template>
<div class="container">
<div style="padding: 0px 20px">
<el-image
style="width: 100%"
:src="require('/src/assets/monitor.png')"
fit="fill"></el-image>
<!-- <div ref="lxHeader">
<lx-header icon="md-apps" text="环境监控" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
<div slot="content"></div>
<slot>
</slot>
</lx-header>
</div> -->
</div>
</div>
</template>
<script>
</script>
<style>
</style>

@ -27,7 +27,7 @@ module.exports = {
* Detail: https://cli.vuejs.org/config/#publicpath
*/
publicPath: '/admin/',
outputDir: '/Users/mac/Documents/朗业/2023/w-河道物资/hd-wuziguanli-test/public/admin',
outputDir: '/Users/mac/Documents/朗业/2025/h-苏州河道处/y-应急保障/hd-wuziguanli-test/public/admin',
assetsDir: 'static',
css: {
loaderOptions: { // 向 CSS 相关的 loader 传递选项

Loading…
Cancel
Save