Compare commits

..

2 Commits

Author SHA1 Message Date
c75308b390 内容修改 2024-07-27 10:20:09 +08:00
23ea8a9c71 地图修改 2024-07-24 18:00:08 +08:00
11 changed files with 982 additions and 730 deletions

View File

@ -6,7 +6,7 @@ ENV = 'development'
# 共享电动车管理系统/开发环境 # 共享电动车管理系统/开发环境
# VUE_APP_BASE_API = 'https://dche.ccttiot.com/prod-api' # VUE_APP_BASE_API = 'https://dche.ccttiot.com/prod-api'
VUE_APP_BASE_API = 'http://localhost:8080' VUE_APP_BASE_API = 'http://192.168.2.189:8080'
# 路由懒加载 # 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true VUE_CLI_BABEL_TRANSPILE_MODULES = true

View File

@ -25,4 +25,18 @@ export default {
#app .theme-picker { #app .theme-picker {
display: none; display: none;
} }
</style>
<style lang="scss" >
.el-select {
.el-input__inner{
color: red;
}
}
.el-input{
.el-input__inner{
color: red;
}
}
</style> </style>

View File

@ -54,6 +54,14 @@ export function updateArea(data) {
data: data data: data
}) })
} }
// 修改导览
export function putguide(data) {
return request({
url: '/system/area/guide',
method: 'put',
data: data
})
}
// 修改运营区 // 修改运营区
export function updateArea2(data) { export function updateArea2(data) {
return request({ return request({

View File

@ -100,6 +100,39 @@ export default {
trajectory() { trajectory() {
this.line = JSON.parse(this.tripRouteStr) this.line = JSON.parse(this.tripRouteStr)
console.log("this.line================" + this.line) console.log("this.line================" + this.line)
let abb;
try {
abb = JSON.parse(this.tripRouteStr);
} catch (error) {
console.error("Error parsing tripRouteStr:", error);
return;
}
let latitude = parseFloat(abb[0][1]);
let longitude = parseFloat(abb[0][0]);
let latitude1 = parseFloat(abb[abb.length - 1][1]);
let longitude1 = parseFloat( abb[abb.length - 1][0]);
this.marker = new AMap.Marker({
map: this.map,
position: [longitude, latitude],
icon: new AMap.Icon({
size: new AMap.Size(25, 38), //
image: "https://lxnapi.ccttiot.com/bike/img/static/u06paUGiHLvL08Pw7BGr",
imageSize: new AMap.Size(25, 38) //
}),
offset: new AMap.Pixel(-12.5, -19.5),
});
this.marker = new AMap.Marker({
map: this.map,
position: [longitude1, latitude1],
icon: new AMap.Icon({
size: new AMap.Size(25, 38), //
image: "https://lxnapi.ccttiot.com/bike/img/static/uwpAj9vYtPRmhtTOtflx",
imageSize: new AMap.Size(25, 38) //
}),
offset: new AMap.Pixel(-12.5, -19.5),
});
// console.log(latitude,longitude,'longitudelongitudelongitude');
let line = this.line; let line = this.line;
this.marker = new AMap.Marker({ this.marker = new AMap.Marker({
map: this.map, map: this.map,

View File

@ -2,7 +2,7 @@
<div class="container"> <div class="container">
<div class="input-card-right"> <div class="input-card-right">
<div class="img"> <div class="img">
<image-upload v-model="picture" /> <image-upload :limit="1" :isShowTip="false" v-model="picture" />
</div> </div>
<el-button :style="topRightCoord ? buttonStyleActive : buttonStyleInactive" @click="setClickType('topRight')"> <el-button :style="topRightCoord ? buttonStyleActive : buttonStyleInactive" @click="setClickType('topRight')">
@ -16,6 +16,10 @@
<el-button @click="generateMap" :disabled="!canGenerateMap"> <el-button @click="generateMap" :disabled="!canGenerateMap">
生成导览地图 生成导览地图
</el-button> </el-button>
<el-button @click="saveMap" :disabled="!canSaveMap">
保存
</el-button>
</div> </div>
<div id="amap-container" class="map-container"></div> <div id="amap-container" class="map-container"></div>
@ -25,15 +29,16 @@
<div v-if="bottomLeftCoord">左下角: {{ bottomLeftCoord }}</div> <div v-if="bottomLeftCoord">左下角: {{ bottomLeftCoord }}</div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import AMapLoader from "@amap/amap-jsapi-loader"; import AMapLoader from "@amap/amap-jsapi-loader";
import globalConfig from '@/utils/config/globalConfig'; import globalConfig from '@/utils/config/globalConfig';
import {getArea, optionselect as getAreaOptionselect} from "@/api/system/area"; import { getArea, putguide } from "@/api/system/area";
export default { export default {
name: "NewPage", name: "NewPage",
data() { data() {
return { return {
map: null, map: null,
@ -44,17 +49,31 @@ export default {
picture: '', picture: '',
buttonStyleActive: 'background-color: #409EFF; color: white;', buttonStyleActive: 'background-color: #409EFF; color: white;',
buttonStyleInactive: 'background-color: #fff; color: #409EFF;', buttonStyleInactive: 'background-color: #fff; color: #409EFF;',
areaLon: null,
areaLat: null,
queryParams: {
pageNum: 1,
pageSize: 10,
parkingName: null,
areaId: null,
type: "2"
},
// id
defaultAreaId: "",
isMapGenerated: false,
}; };
}, },
computed: { computed: {
canGenerateMap() { canGenerateMap() {
return this.picture && this.topRightCoord && this.bottomLeftCoord; return this.picture && this.topRightCoord && this.bottomLeftCoord;
},
canSaveMap() {
return this.isMapGenerated;
} }
}, },
created() { created() {
const areaId = this.$route.params && this.$route.params.areaId; const areaId = this.$route.params && this.$route.params.areaId;
this.getArea(areaId); this.getArea(areaId);
// this.getAreaList();
}, },
mounted() { mounted() {
this.initMap(); this.initMap();
@ -67,7 +86,6 @@ export default {
this.areaLon = response.data.longitude; this.areaLon = response.data.longitude;
this.areaLat = response.data.latitude; this.areaLat = response.data.latitude;
this.defaultAreaId = response.data.areaId; this.defaultAreaId = response.data.areaId;
this.getList();
}); });
}, },
initMap() { initMap() {
@ -84,6 +102,7 @@ export default {
this.map = new AMap.Map("amap-container", { this.map = new AMap.Map("amap-container", {
viewMode: "3D", viewMode: "3D",
zoom: 13, zoom: 13,
center: [this.areaLon, this.areaLat], //
}); });
this.map.setFitView(); this.map.setFitView();
this.map.on('click', this.handleMapClick); this.map.on('click', this.handleMapClick);
@ -93,33 +112,49 @@ export default {
}, },
setClickType(type) { setClickType(type) {
this.clickType = type; this.clickType = type;
//
if (type === 'topRight' && this.topRightCoord) {
this.clearMarker('topRight');
this.topRightCoord = null;
} else if (type === 'bottomLeft' && this.bottomLeftCoord) {
this.clearMarker('bottomLeft');
this.bottomLeftCoord = null;
}
}, },
handleMapClick(event) { handleMapClick(event) {
const lnglat = event.lnglat; const lnglat = event.lnglat;
//
if (this.clickType === 'topRight') { if (this.clickType === 'topRight') {
this.topRightCoord = lnglat; this.topRightCoord = lnglat;
this.addMarker(lnglat, 'topRight');
} else if (this.clickType === 'bottomLeft') { } else if (this.clickType === 'bottomLeft') {
this.bottomLeftCoord = lnglat; this.bottomLeftCoord = lnglat;
this.addMarker(lnglat, 'bottomLeft');
} }
//
const marker = new AMap.Marker({
position: lnglat,
});
this.map.add(marker);
this.markers.push(marker);
// //
this.clickType = null; this.clickType = null;
}, },
clearMarkers() { addMarker(lnglat, type) {
this.markers.forEach(marker => { //
this.map.remove(marker); this.clearMarker(type);
//
const marker = new AMap.Marker({
position: lnglat,
});
this.map.add(marker);
this.markers.push({ marker, type });
},
clearMarker(type) {
this.markers = this.markers.filter(({ marker, type: markerType }) => {
if (markerType === type) {
this.map.remove(marker);
return false;
}
return true;
}); });
this.markers = [];
this.topRightCoord = null;
this.bottomLeftCoord = null;
}, },
generateMap() { generateMap() {
if (!this.canGenerateMap) { if (!this.canGenerateMap) {
@ -136,14 +171,20 @@ export default {
const topRight = lnglatToFixed(this.topRightCoord); const topRight = lnglatToFixed(this.topRightCoord);
const bottomLeft = lnglatToFixed(this.bottomLeftCoord); const bottomLeft = lnglatToFixed(this.bottomLeftCoord);
console.log('Top Right:', topRight);
console.log('Bottom Left:', bottomLeft);
// //
const bounds = new AMap.Bounds([bottomLeft.lng, bottomLeft.lat], [topRight.lng, topRight.lat]); const bounds = new AMap.Bounds([bottomLeft.lng, bottomLeft.lat], [topRight.lng, topRight.lat]);
console.log('Bounds:', bounds);
// //
const imageLayer = new AMap.ImageLayer({ const imageLayer = new AMap.ImageLayer({
url: this.picture, url: this.picture,
bounds: bounds, bounds: bounds,
zooms: [15, 20] zooms: [15, 20],
zIndex: 999 // zIndex
}); });
// //
@ -155,6 +196,34 @@ export default {
// //
this.map.add(imageLayer); this.map.add(imageLayer);
//
this.isMapGenerated = true;
},
saveMap() {
if (!this.canSaveMap) {
this.$message.error('请先生成导览地图');
return;
}
//
const formatLngLat = (lnglat) => `${lnglat.lng},${lnglat.lat}`;
//
const mapData = {
guideMap: this.picture,
upperRight: formatLngLat(this.topRightCoord),
lowerLeft: formatLngLat(this.bottomLeftCoord),
areaId: this.defaultAreaId
};
putguide(mapData).then(response => {
//
});
// mapData
console.log('保存地图数据:', mapData);
this.$message.success('地图数据已保存');
} }
}, },
}; };
@ -172,11 +241,14 @@ export default {
} }
.input-card-right { .input-card-right {
position: fixed;
top: 100px;
left: 230px;
z-index: 100;
width: 100%; width: 100%;
display: flex; display: flex;
flex-wrap: nowrap; flex-wrap: nowrap;
align-items: flex-end; align-items: flex-end;
// justify-content: center;
margin-bottom: 10px; margin-bottom: 10px;
} }

View File

@ -1,13 +1,16 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="运营商" prop="deptId" v-if="userName == 'admin'"> <el-form-item label="运营商" prop="deptId" v-if="userName == 'admin'">
<el-select v-model="queryParams.deptId" placeholder="请选择运营商" clearable> <el-select v-model="queryParams.deptId" placeholder="请选择运营商" clearable :popper-append-to-body="false">
<el-option <el-option
v-for="item in deptOptions" v-for="item in deptOptions"
:key="item.deptId" :key="item.deptId"
:label="item.deptName" :label="item.deptName"
:value="item.deptId" :value="item.deptId"
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -1071,7 +1074,18 @@ export default {
} }
}; };
</script> </script>
<style> <style lang="scss">
.el-select {
.el-input__inner{
color: red;
}
}
.el-input{
.el-input__inner{
color: red;
}
}
.nav-container { .nav-container {
display: flex; display: flex;
justify-content: center; justify-content: center;

View File

@ -368,3 +368,16 @@ export default {
} }
}; };
</script> </script>
<style lang="scss" >
.el-select {
.el-input__inner{
color: red;
}
}
.el-input{
.el-input__inner{
color: red;
}
}
</style>

View File

@ -38,12 +38,8 @@
<div class="area-options" v-if="userName == 'admin'"> <div class="area-options" v-if="userName == 'admin'">
<span>切换运营区</span> <span>切换运营区</span>
<el-select v-model="areaId" placeholder="请选择运营区" clearable @change="handleAreaChange"> <el-select v-model="areaId" placeholder="请选择运营区" clearable @change="handleAreaChange">
<el-option <el-option v-for="item in areaOptions" :key="item.areaId" :label="item.areaName"
v-for="item in areaOptions" :value="item.areaId"></el-option>
:key="item.areaId"
:label="item.areaName"
:value="item.areaId"
></el-option>
</el-select> </el-select>
</div> </div>
<div class="input-card"> <div class="input-card">
@ -67,10 +63,7 @@
<el-col :span="8"> <el-col :span="8">
<el-form-item label="二维码:"> <el-form-item label="二维码:">
<template> <template>
<el-popover <el-popover placement="top" width="180" trigger="hover">
placement="top"
width="180"
trigger="hover">
<div class="qr-code-box"> <div class="qr-code-box">
<qr-code :text="form.qrText" :width="150" :height="150" /> <qr-code :text="form.qrText" :width="150" :height="150" />
</div> </div>
@ -78,12 +71,14 @@
</el-popover> </el-popover>
</template> </template>
</el-form-item> </el-form-item>
<el-form-item label="网络状态:" style="color: #ffcc00;font-weight: 700">{{ form.onlineStatus == 1 ? '在线' : '离线' }}</el-form-item> <el-form-item label="网络状态:" style="color: #ffcc00;font-weight: 700">{{ form.onlineStatus == 1 ? '在线' : '离线'
}}</el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<div class="nav-container"> <div class="nav-container">
<el-menu :default-active="activeIndex" class="el-menu-demo nav-menu" mode="horizontal" @select="handleSelect"> <el-menu :default-active="activeIndex" class="el-menu-demo nav-menu" mode="horizontal"
@select="handleSelect">
<el-menu-item index="1">使用记录</el-menu-item> <el-menu-item index="1">使用记录</el-menu-item>
<el-menu-item index="2">维修记录</el-menu-item> <el-menu-item index="2">维修记录</el-menu-item>
<el-menu-item index="3">换电记录</el-menu-item> <el-menu-item index="3">换电记录</el-menu-item>
@ -410,26 +405,43 @@
} }
}, },
generateInfoContent(data) { generateInfoContent(data) {
let content = `<div><table class="info-table"> let content = `<div style="max-hight: 500px; overflow-y: auto;">
<table class="info-table">
<thead> <thead>
<tr> <tr>
<th>SN</th> <th>SN</th>
<th>车牌号</th> <th>车牌号</th>
<th>状态</th> <th>状态</th>
<th>操作</th> <th>操作</th>
<th>SN</th>
<th>车牌号</th>
<th>状态</th>
<th>操作</th>
</tr> </tr>
</thead> </thead>
<tbody>`; <tbody>`;
data.forEach(item => {
content += `<tr> for (let i = 0; i < data.length; i += 2) {
<td>${item.sn}</td> content += `<tr>`;
<td>${item.vehicleNum}</td> content += generateRowContent(data[i]);
<td>${formatVehicleStatus(item.status)}</td> if (i + 1 < data.length) {
<td><button class="detail-btn" data-device-id="${item.deviceId}">详情</button></td> content += generateRowContent(data[i + 1]);
</tr>`; } else {
}); content += `<td colspan="4"></td>`;
}
content += `</tr>`;
}
content += `</tbody> content += `</tbody>
</table></div>`; </table></div>`;
function generateRowContent(item) {
return `<td>${item.sn}</td>
<td>${item.vehicleNum}</td>
<td>${formatVehicleStatus(item.status)}</td>
<td><button class="detail-btn" data-device-id="${item.deviceId}">详情</button></td>`;
}
function formatVehicleStatus(status) { function formatVehicleStatus(status) {
switch (status) { switch (status) {
case '7': case '7':
@ -452,10 +464,12 @@
return '未知状态'; return '未知状态';
} }
} }
return content; return content;
}, },
handleInfoWindowClick(event) { handleInfoWindowClick(event) {
console.log("点击详情按钮====", event) console.log("点击详情按钮====", event)
const button = event.target.closest('.detail-btn'); const button = event.target.closest('.detail-btn');
if (button) { if (button) {
const deviceId = button.getAttribute('data-device-id'); const deviceId = button.getAttribute('data-device-id');
@ -709,6 +723,42 @@
width: 100%; width: 100%;
height: 850px; height: 850px;
} }
.info-table {
width: 100%;
border-collapse: collapse;
}
.info-table th,
.info-table td {
border: 1px solid #ddd;
padding: 8px;
}
.info-table thead {
background-color: #f4f4f4;
}
.info-table tbody tr:nth-child(even) {
background-color: #f9f9f9;
}
.info-table tbody tr:hover {
background-color: #f1f1f1;
}
/* Scrollbar styles for WebKit browsers (Chrome, Safari) */
.info-table::-webkit-scrollbar {
width: 8px;
}
.info-table::-webkit-scrollbar-thumb {
background-color: #888;
border-radius: 4px;
}
.info-table::-webkit-scrollbar-thumb:hover {
background-color: #555;
}
.container { .container {
position: relative; position: relative;
border: 1px solid rgb(204, 204, 204); border: 1px solid rgb(204, 204, 204);
@ -719,17 +769,22 @@
right: 15px; right: 15px;
} }
} }
.tips { .tips {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
position: absolute; position: absolute;
top: 15px; top: 15px;
left: 15px; left: 15px;
.tip-item { .tip-item {
display: flex; display: flex;
align-items: center; /* 垂直居中 */ align-items: center;
margin-bottom: 10px; /* 可以根据需要调整间距 */ /* 垂直居中 */
margin-bottom: 10px;
/* 可以根据需要调整间距 */
color: #38383b; color: #38383b;
.span-class { .span-class {
background-color: rgba(255, 255, 255, 0.5); background-color: rgba(255, 255, 255, 0.5);
padding: 3px 5px; padding: 3px 5px;
@ -738,19 +793,24 @@
font-size: 13px; font-size: 13px;
} }
} }
img { img {
width: 25px; width: 25px;
padding-top: 5px; padding-top: 5px;
height: auto; /* 保持图片高度自适应 */ height: auto;
margin-right: 10px; /* 图片与文字间距,根据需要调整 */ /* 保持图片高度自适应 */
margin-right: 10px;
/* 图片与文字间距,根据需要调整 */
} }
} }
.area-options { .area-options {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
position: absolute; position: absolute;
top: 15px; top: 15px;
right: 15px; right: 15px;
span { span {
display: flex; display: flex;
align-items: center; align-items: center;
@ -768,9 +828,11 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
.apiary-marker-img { .apiary-marker-img {
width: 25px; width: 25px;
} }
.apiary-marker-name { .apiary-marker-name {
background-color: #1890ff; background-color: #1890ff;
border: none; border: none;
@ -780,6 +842,7 @@
padding: 5px; padding: 5px;
} }
} }
.detail-btn { .detail-btn {
background: none; background: none;
border: none; border: none;
@ -819,5 +882,4 @@
.el-dialog:not(.is-fullscreen) { .el-dialog:not(.is-fullscreen) {
margin-top: 6vh !important; margin-top: 6vh !important;
} }
</style> </style>

View File

@ -313,3 +313,16 @@ export default {
} }
}; };
</script> </script>
<style lang="scss" >
.el-select {
.el-input__inner{
color: red;
}
}
.el-input{
.el-input__inner{
color: red;
}
}
</style>

View File

@ -518,7 +518,19 @@ export default {
} }
}; };
</script> </script>
<style>
<style lang="scss">
.el-select {
.el-input__inner{
color: red;
}
}
.el-input{
.el-input__inner{
color: red;
}
}
.amoun-tips{ .amoun-tips{
color: red; color: red;
font-size: 12px; font-size: 12px;

View File

@ -490,7 +490,18 @@ export default {
} }
}; };
</script> </script>
<style> <style lang="scss">
.el-select {
.el-input__inner{
color: red;
}
}
.el-input{
.el-input__inner{
color: red;
}
}
.amoun-tips{ .amoun-tips{
color: red; color: red;
font-size: 12px; font-size: 12px;