页面布局完成

This commit is contained in:
zengmingjie 2025-06-19 23:41:07 +08:00
parent 9898cd5bde
commit 7e19706ab9
15 changed files with 199 additions and 430 deletions

View File

@ -29,7 +29,7 @@ body {
// 滚动条样式
::-webkit-scrollbar {
width: 5px;
width: 0px;
height: 3px;
background-color: transparent;
}
@ -117,108 +117,11 @@ body {
height: 40px;
display: flex;
align-items: center;
margin-right: 40px;
margin-right: 20px;
margin-top: 10px;
.menuItem {
width: 305px;
display: flex;
align-items: center;
justify-content: space-between;
margin-right: 10px;
.menuFor {
width: 41px;
height: 41px;
text-align: center;
margin: 0 auto;
.itemIcon {
width: 100%;
height: 100%;
margin-right: 10px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
}
}
.menuItemQuanping {
width: 10%;
margin-right: 20px;
.menuFor {
text-align: center;
margin: 0 auto;
.itemIcon {
width: 24px;
height: 24px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
}
}
.user {
width: 15%;
height: 100%;
margin-right: 30px;
.el-dropdown {
cursor: pointer;
height: 100%;
img {
width: 32px;
height: 32px;
margin-top: 5px;
}
}
}
.time {
width: 93px;
height: 36px;
.top {
width: 100%;
height: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
.time_date {
width: 50px;
text-align: center;
color: #fff;
}
span {
border: 0.2px solid #000;
background-color: #000;
}
.weather {
width: 50%;
display: flex;
align-items: center;
color: #fff;
border-left: 1px solid #ccc;
margin-left: 5px;
padding-left: 5px;
img {
width: 10px;
height: 10px;
}
.weather_text {
font-size: 12px;
margin-left: 2px;
}
}
}
.date {
width: 100%;
height: 50%;
text-align: center;
font-size: 20px;
color: #fff;
letter-spacing: 1px;
}
}
color: #61ff3a;
justify-content: space-between;
font-size: 1vw;
}
}
.left-sidebar {
@ -227,7 +130,6 @@ body {
position: absolute;
top: 60px;
left: 0;
pointer-events: auto;
padding: 0;
margin: 0;
padding: 0 40px;
@ -266,8 +168,9 @@ body {
}
.drone-list {
width: 100%;
height: calc(100% - 200px);
height: calc(100% - 140px);
margin-top: 25px;
pointer-events: none;
.title {
width: 100%;
height: 40px;
@ -279,9 +182,9 @@ body {
margin: 0;
overflow: auto;
margin-top: 10px;
li {
width: 95%;
border-bottom: 1px dashed #ccc;
padding: 5px;
color: #0144ef;
margin-left: 2%;
@ -295,6 +198,7 @@ body {
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
pointer-events: auto;
.top {
width: 98%;
height: 50%;
@ -341,11 +245,11 @@ body {
width: 50%;
.color-ef {
color: #0144ef;
font-size: 14px;
font-size: 1.09vw;
}
.text-fff {
color: #000;
font-size: 12px;
font-size: 1.09vw;
}
}
}
@ -358,6 +262,7 @@ body {
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
pointer-events: auto;
.top {
width: 98%;
height: 30px;
@ -537,13 +442,51 @@ body {
}
}
.navigation-content {
width: 140px;
height: 244px;
width: 100px;
height: 200px;
background: url(../img/uavBackfff-big.png);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
margin-left: 9px;
padding: 20px;
pointer-events: auto;
.navigation-content-text {
text-align: left;
margin-bottom: 5px;
font-size: 1.09vw;
.color-ef-fw {
color: #0144ef;
font-size: 1.09vw;
font-weight: 600;
}
.text-fff {
color: #000;
font-size: 1.09vw;
}
}
.navigation-content-qrcode {
width: 80px;
height: 80px;
background-color: red;
margin: 0 auto;
margin-top: 5px;
margin-bottom: 5px;
}
}
.navigation-content-btn {
width: 100%;
.btns {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: space-around;
.el-button--primary {
background-color: #0144ef;
border-color: #0144ef;
}
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/assets/img/mute.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 B

BIN
src/assets/img/query.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
src/assets/img/refresh.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 B

BIN
src/assets/img/setup.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
src/assets/img/sound.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1007 B

BIN
src/assets/img/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -127,7 +127,30 @@
</div>
</div>
</div>
<div class="navigation-content" v-if="!drone.detailsShow"></div>
<div class="navigation-content" v-if="!drone.detailsShow">
<div class="navigation-content-text">
<span class="color-ef">距飞手</span>
<span class="text-fff">{{ drone.height || 0 }}</span>
</div>
<div class="navigation-content-text">
<span class="color-ef">距我</span>
<span class="text-fff">{{ drone.height || 0 }}</span>
</div>
<div class="navigation-content-qrcode"></div>
<div class="navigation-content-text">
<span class="text-fff">跳转到导航系统</span>
</div>
<div class="navigation-content-btn">
<div class="btns">
<div class="btn-trust">
<el-button type="primary"></el-button>
</div>
<div class="btn-navigation">
<el-button type="primary"></el-button>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
@ -252,7 +275,9 @@ export default {
showAudioPrompt: false
};
},
mounted() {},
mounted() {
this.startTracking();
},
watch: {
homeData: {
handler(newVal) {
@ -333,6 +358,38 @@ export default {
}
},
methods: {
startTracking() {
if (!navigator.geolocation) {
console.error("您的浏览器不支持地理位置功能");
return;
}
this.loading = true;
// 使 watchPosition
this.watchId = navigator.geolocation.watchPosition(
this.handleSuccess,
this.handleError,
{
enableHighAccuracy: true, //
timeout: 5000, // 5
maximumAge: 0 // 使
}
);
this.isTracking = true;
}, //
handleSuccess(position) {
this.loading = false;
this.latitude = position.coords.latitude;
this.longitude = position.coords.longitude;
this.lastUpdated = new Date().toLocaleString();
console.log(position, "this.watchId");
},
//
handleError(error) {
this.loading = false;
this.error = this.getErrorMessage(error.code);
},
enableAudio() {
this.iswarning = true;
const media = this.$refs.uavAudio;

View File

@ -11,122 +11,18 @@
<!-- <img src="@/assets/img/title.svg" alt="" /> -->
</div>
</div>
<!-- <div class="header-menu">
<div class="menuItem" v-if="isAdmins">
<div
class="menuFor"
v-for="(item, index) in menuList"
:key="index"
@click="handleMenuClick(item)"
>
<div class="itemIcon">
<el-tooltip
class="item"
effect="dark"
:content="item.name"
placement="bottom"
>
<img
:src="activeId === item.id ? item.iconActive : item.icon"
:alt="item.name"
/>
</el-tooltip>
</div>
</div>
</div>
<div class="menuItemQuanping">
<div
class="menuFor"
v-for="(item, index) in quanping"
:key="index"
@click="handlefdClick(item)"
>
<div class="itemIcon">
<el-tooltip
class="item"
effect="dark"
:content="item.name"
placement="bottom"
>
<img :src="item.icon" :alt="item.name" />
</el-tooltip>
</div>
</div>
</div>
<div class="user">
<el-dropdown trigger="click">
<img :size="30" src="@/assets/img/menu/iconUser.png" />
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="passClick">
修改密码
</el-dropdown-item>
<el-dropdown-item @click.native="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<div class="time">
<div class="top">
<div class="time_date">{{ currentTime }}</div>
<div class="weather">
<img src="@/assets/img/menu/tianqi.png" alt="" />
<div class="weather_text">
{{ homeView.weather?.now.temperature + "°C" }}
</div>
</div>
</div>
<div class="date">{{ currentDate }}</div>
</div>
</div> -->
<el-dialog
:title="title"
:visible.sync="showDialog"
:before-close="handleClose"
append-to-body
>
<!-- 对话框组件 -->
<component :is="currentDialog"></component>
</el-dialog>
<el-dialog
:title="titleDialog"
:visible.sync="dialog"
:before-close="handleClose"
append-to-body
class="el-dialog-center"
>
<my-form
:formNewList="formDrawerList"
:fromItem="fromItem"
dialogImageUrl
@determine="determine"
@handleClose="handleClose"
labelWidth="120px"
>
</my-form>
</el-dialog>
<div class="header-menu">
<span>{{ leftText }}</span>
<span style="width: 20px"> | </span>
<span>{{ rightText }}</span>
</div>
</div>
</template>
<script>
//
import PermissionDialog from "../../menuData/PermissionDialog.vue"; // ID: 1
import DeviceDialog from "../../menuData/DeviceDialog.vue"; // ID: 2
import LogDialog from "../../menuData/LogDialog.vue"; // ID: 3
import AlertDialog from "../../menuData/AlertDialog.vue"; // ID: 5
import PositionDialog from "../../menuData/PositionDialog.vue"; // ID: 6
import AnalysisDialog from "../../menuData/AnalysisDialog.vue"; // ID: 7
import WhitListDialog from "../../menuData/WhitListDialog.vue"; // ID: 8
import { userUpdatepwd } from "@/api/user.js";
export default {
name: "header-top",
components: {
PermissionDialog,
DeviceDialog,
LogDialog,
AlertDialog,
PositionDialog,
AnalysisDialog,
WhitListDialog
},
components: {},
props: {
homeData: {
type: Object,
@ -135,105 +31,19 @@ export default {
},
data() {
return {
menuList: [
{
id: 1,
name: "人员",
icon: require("@/assets/img/menu/xitongquanxian.png"),
iconActive: require("@/assets/img/menu/xitongquanxian-hove.png")
},
{
id: 2,
name: "设备",
icon: require("@/assets/img/menu/shebei.png"),
iconActive: require("@/assets/img/menu/shebei-hove.png")
},
{
id: 3,
name: "日志",
icon: require("@/assets/img/menu/rizhi.png"),
iconActive: require("@/assets/img/menu/rizhi-hove.png")
},
{
id: 4,
name: "首页",
icon: require("@/assets/img/menu/tongji.png"),
iconActive: require("@/assets/img/menu/tongji-hove.png")
},
{
id: 5,
name: "预警",
icon: require("@/assets/img/menu/yujing.png"),
iconActive: require("@/assets/img/menu/yujing-hove.png")
},
{
id: 6,
name: "防区",
icon: require("@/assets/img/menu/zhendi.png"),
iconActive: require("@/assets/img/menu/zhendi-hove.png")
},
{
id: 7,
name: "统计分析",
icon: require("@/assets/img/menu/tjfx.png"),
iconActive: require("@/assets/img/menu/tjfx-hove.png")
},
{
id: 8,
name: "白名单",
icon: require("@/assets/img/menu/bmd.png"),
iconActive: require("@/assets/img/menu/bmd-hove.png")
}
],
quanping: [
{
id: 8,
name: "全屏",
icon: require("@/assets/img/menu/quanping.png"),
iconActive: require("@/assets/img/menu/quanping.png")
}
],
activeId: 4,
currentTime: "",
currentDate: "",
currentDialog: "",
showDialog: false,
title: "",
titleDialog: "",
homeView: {
weather: {
now: {
temperature: 0
}
}
},
formDrawerList: [
{
label: "原密码",
type: "input",
model: "oldPwd",
rules: [{ required: true, message: "请输入原密码" }],
showPassword: true
},
{
label: "新密码",
type: "input",
model: "newPwd",
rules: [{ required: true, message: "请输入新密码" }],
showPassword: true
}
],
fromItem: {},
dialog: false,
isAdmins: false
isAdmins: false,
leftText: "平台已连接",
rightText: "定位正常"
};
},
created() {},
watch: {
homeData: {
handler(newVal) {
this.homeView = newVal;
},
handler(newVal) {},
deep: true
}
},
@ -247,99 +57,6 @@ export default {
const now = new Date();
this.currentTime = now.toLocaleTimeString(); //
this.currentDate = now.toLocaleDateString(); //
},
passClick() {
this.fromItem = {};
this.titleDialog = "修改密码";
//
this.dialog = true;
console.log("修改密码");
},
logout() {
// 退
localStorage.removeItem("setToken");
localStorage.removeItem("userId");
localStorage.removeItem("userName");
localStorage.removeItem("isAdmin");
this.$router.push("/login");
},
//
determine(value) {
let params = {};
params = value;
params.id = localStorage.getItem("userId");
userUpdatepwd(params).then((res) => {
if (res.code === 0) {
this.$message.success("修改成功");
}
});
this.dialog = false;
},
handlefdClick(value) {
if (document.fullscreenElement) {
document
.exitFullscreen()
.then(() => {
console.log("退出全屏模式");
})
.catch((err) => {
console.error(`退出全屏模式失败: ${err.message}`);
});
} else {
document.documentElement
.requestFullscreen()
.then(() => {
console.log("进入全屏模式");
})
.catch((err) => {
console.error(`进入全屏模式失败: ${err.message}`);
});
}
},
handleMenuClick(value) {
this.activeId = value.id; // ID
this.title = value.name; //
// ID
switch (value.id) {
case 1:
this.currentDialog = "PermissionDialog";
this.showDialog = true;
break;
case 2:
this.currentDialog = "DeviceDialog";
this.showDialog = true;
break;
case 3:
this.currentDialog = "LogDialog";
this.showDialog = true;
break;
case 4:
this.showDialog = false;
break;
case 5:
this.currentDialog = "AlertDialog";
this.showDialog = true;
break;
case 6:
this.currentDialog = "PositionDialog";
this.showDialog = true;
break;
case 7:
this.currentDialog = "AnalysisDialog";
this.showDialog = true;
break;
case 8:
this.currentDialog = "WhitListDialog";
this.showDialog = true;
break;
}
},
handleClose() {
// ID
this.activeId = 4;
this.showDialog = false;
this.dialog = false;
}
}
};

View File

@ -3,24 +3,24 @@
<div class="app-container">
<headerTop :homeData="homeView" />
<LeftSidebar :homeData="homeView" :signaData="signaList" />
<RightSidebar :homeData="homeView" />
<Footer />
<!-- <RightSidebar :homeData="homeView" /> -->
<!-- <Footer /> -->
</div>
</template>
<script>
import headerTop from "./headerTop/index.vue";
import LeftSidebar from "./LeftSidebar/index.vue";
import RightSidebar from "./RightSidebar/index.vue";
import Footer from "./Footer/index.vue";
// import RightSidebar from "./RightSidebar/index.vue";
// import Footer from "./Footer/index.vue";
export default {
name: "App",
components: {
headerTop,
LeftSidebar,
RightSidebar,
Footer
LeftSidebar
// RightSidebar
// Footer
},
props: {
homeData: {

View File

@ -31,9 +31,9 @@ export default {
},
mounted() {
this.initHomeData();
this.timeInterval = setInterval(() => {
this.initHomeData();
}, 2000);
// this.timeInterval = setInterval(() => {
// this.initHomeData();
// }, 2000);
},
methods: {
initHomeData() {

View File

@ -1,9 +1,24 @@
<template>
<div class="HomeMap">
<div class="zoom-level">当前缩放等级: {{ zoomLevel }}</div>
<div class="zoom-level" @click="soundAndMenu">
<img :src="zoomLevelImage" alt="" />
</div>
<div id="map" ref="olMap" class="map-container"></div>
<div class="pointingNorth" @click="mapNorth">
<img src="@/assets/img/menu/zhibeizhen.png" alt="指北" />
<img src="@/assets/img/user.png" alt="" />
<img src="@/assets/img/setup.png" alt="" />
<img src="@/assets/img/query.png" alt="" />
</div>
<div class="configuration">
<div class="refresh">
<img src="@/assets/img/refresh.png" alt="" />
</div>
<div class="refresh">
<img src="@/assets/img/icon_postions.png" alt="" />
</div>
<div class="refresh">
<img src="@/assets/img/icon_model.png" alt="" />
</div>
</div>
</div>
</template>
@ -21,7 +36,8 @@ export default {
data() {
return {
map: null,
zoomLevel: null
zoomLevel: null,
isZoomedIn: false
};
},
created() {
@ -32,9 +48,17 @@ export default {
this.initMap();
},
computed: {
...mapGetters(["statePage", "cityCode"])
...mapGetters(["statePage", "cityCode"]),
zoomLevelImage() {
return this.isZoomedIn
? require("@/assets/img/sound.png")
: require("@/assets/img/mute.png");
}
},
methods: {
soundAndMenu() {
this.isZoomedIn = !this.isZoomedIn;
},
initMap() {
// OpenLayers
@ -118,13 +142,37 @@ export default {
.zoom-level {
position: absolute;
bottom: 0.8%;
left: 1%;
top: 60px;
right: 40px;
z-index: 1000;
color: #fff;
background: rgba(0, 0, 0, 0.5);
padding: 5px;
border-radius: 3px;
img {
width: 48px;
height: 48px;
}
}
.configuration {
position: absolute;
bottom: 32px;
right: 40px;
z-index: 1000;
color: #fff;
width: 29px;
height: 174px;
background-color: rgba(209, 242, 255, 0.9);
padding: 19px 8px;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
.refresh {
width: 32px;
height: 32px;
img {
width: 32px;
height: 32px;
}
}
}
.map-container {
@ -133,15 +181,19 @@ export default {
}
.pointingNorth {
width: 236px;
height: 52px;
position: absolute;
bottom: 5%;
right: 25%;
cursor: pointer;
bottom: 37px;
left: 50%;
transform: translateX(-50%);
z-index: 1000;
display: flex;
align-items: center;
justify-content: space-between;
img {
width: 35px;
height: 35px;
width: 52px;
height: 52px;
}
}
}

View File

@ -18,7 +18,7 @@ module.exports = defineConfig({
productionSourceMap: false,
transpileDependencies: true,
devServer: {
host: "127.0.0.1",
host: "192.168.1.9",
port: 9997,
open: true,
proxy: {}