This commit is contained in:
zmj 2023-12-14 20:08:53 +08:00
parent 9c7ea2527d
commit 141717d414
30 changed files with 2444 additions and 1622 deletions

View File

@ -10,5 +10,6 @@
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<!-- <script src="/public/jessibuca.js"></script> -->
</body>
</html>

39
package-lock.json generated
View File

@ -14,6 +14,7 @@
"axios": "^1.6.2",
"echarts": "^5.4.3",
"echarts-gl": "^2.0.9",
"flv.js": "^1.6.2",
"postcss-pxtorem": "^5.1.1",
"vue": "^3.3.8",
"vue-router": "^4.2.5"
@ -1279,6 +1280,11 @@
"dev": true,
"peer": true
},
"node_modules/es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmmirror.com/es6-promise/-/es6-promise-4.2.8.tgz",
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
},
"node_modules/esbuild": {
"version": "0.19.7",
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.19.7.tgz",
@ -1414,6 +1420,15 @@
"node": ">=8"
}
},
"node_modules/flv.js": {
"version": "1.6.2",
"resolved": "https://registry.npmmirror.com/flv.js/-/flv.js-1.6.2.tgz",
"integrity": "sha512-xre4gUbX1MPtgQRKj2pxJENp/RnaHaxYvy3YToVVCrSmAWUu85b9mug6pTXF6zakUjNP2lFWZ1rkSX7gxhB/2A==",
"dependencies": {
"es6-promise": "^4.2.8",
"webworkify-webpack": "^2.1.5"
}
},
"node_modules/follow-redirects": {
"version": "1.15.3",
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.3.tgz",
@ -2144,6 +2159,11 @@
"node": ">=10.13.0"
}
},
"node_modules/webworkify-webpack": {
"version": "2.1.5",
"resolved": "https://registry.npmmirror.com/webworkify-webpack/-/webworkify-webpack-2.1.5.tgz",
"integrity": "sha512-2akF8FIyUvbiBBdD+RoHpoTbHMQF2HwjcxfDvgztAX5YwbZNyrtfUMgvfgFVsgDhDPVTlkbb5vyasqDHfIDPQw=="
},
"node_modules/zrender": {
"version": "5.4.4",
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.4.4.tgz",
@ -3062,6 +3082,11 @@
"dev": true,
"peer": true
},
"es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmmirror.com/es6-promise/-/es6-promise-4.2.8.tgz",
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
},
"esbuild": {
"version": "0.19.7",
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.19.7.tgz",
@ -3171,6 +3196,15 @@
"to-regex-range": "^5.0.1"
}
},
"flv.js": {
"version": "1.6.2",
"resolved": "https://registry.npmmirror.com/flv.js/-/flv.js-1.6.2.tgz",
"integrity": "sha512-xre4gUbX1MPtgQRKj2pxJENp/RnaHaxYvy3YToVVCrSmAWUu85b9mug6pTXF6zakUjNP2lFWZ1rkSX7gxhB/2A==",
"requires": {
"es6-promise": "^4.2.8",
"webworkify-webpack": "^2.1.5"
}
},
"follow-redirects": {
"version": "1.15.3",
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.3.tgz",
@ -3675,6 +3709,11 @@
"dev": true,
"peer": true
},
"webworkify-webpack": {
"version": "2.1.5",
"resolved": "https://registry.npmmirror.com/webworkify-webpack/-/webworkify-webpack-2.1.5.tgz",
"integrity": "sha512-2akF8FIyUvbiBBdD+RoHpoTbHMQF2HwjcxfDvgztAX5YwbZNyrtfUMgvfgFVsgDhDPVTlkbb5vyasqDHfIDPQw=="
},
"zrender": {
"version": "5.4.4",
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.4.4.tgz",

View File

@ -15,6 +15,7 @@
"axios": "^1.6.2",
"echarts": "^5.4.3",
"echarts-gl": "^2.0.9",
"flv.js": "^1.6.2",
"postcss-pxtorem": "^5.1.1",
"vue": "^3.3.8",
"vue-router": "^4.2.5"

1
public/decoder.js Normal file

File diff suppressed because one or more lines are too long

BIN
public/decoder.wasm Normal file

Binary file not shown.

1
public/jessibuca.js Normal file

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 496 B

After

Width:  |  Height:  |  Size: 496 B

View File

@ -1,19 +1,16 @@
<script setup lang="ts">
// @ts-ignore
import Header from "@/components/Header.vue"
import Login from "@/components/login.vue"
import Login from "@/view/login.vue"
let Token =localStorage.getItem('TOKEN')
</script>
<template>
<!-- <div>sadas</div> -->
<div class="main-box" v-if="Token">
<Header></Header>
<!-- <div class="main-box" > -->
<router-view></router-view>
</div>
<div v-else class="login-box">
<Login></Login>
</div>
<!-- </div> -->
<div>
@ -31,20 +28,8 @@ let Token =localStorage.getItem('TOKEN')
padding: 0;
}
.main-box {
width: 100vw;
height: 100vh;
background-image: url('/static/index/bg.png');
background-size: 100% 100%;
overflow: hidden;
}
.login-box{
width: 100vw;
height: 100vh;
background-image: url('/static/login/bg.png');
background-size: 100% 100%;
overflow: hidden;
}
.color-font {
font-family: FZCYJ;
color: #E5EFFF;

View File

@ -1,297 +0,0 @@
<template>
<div style="width: 45vw;height: 50vh;" id="myChart"></div>
<div style="width: 45vw;height: 50vh;" id="chart2"></div>
<img src="/static/index/aa.png" id="img" style="opacity: 0;" alt="">
</template>
<script setup>
import { ref, onMounted } from "vue"
import axios from "axios";
import * as echarts from 'echarts';
import "echarts-gl"
const initData = (data) => {
var data3d = data.map(el => {
return {
name: el.properties.name,
value:el.properties.center,
label: {
normal: {
show: true,
position: 'right',
formatter: '{b}',
color: 'white',
fontWeight: "bold",
fontSize: 18
}
},
itemStyle: {
normal: {
color: '#FFB923'
}
},
}
});
return data3d
}
onMounted(() => {
const u = 'https:\/\/ceshi-worker-task.lihaink.cn\/uploads\/images\/20231129\/202311291816106120a4034.png'
axios.get('https://geo.datav.aliyun.com/areas_v3/bound/510000_full.json')
.then(function (response) {
let dot=document.getElementById('img')
let mapJson = response.data
let chartOption= {
geo: {
backgroundColor: {
color: {
image: dot, // HTMLImageElement, HTMLCanvasElement
repeat: 'repeat' // 'repeat-x', 'repeat-y', 'no-repeat'
}
},
show: true,
map: `lz`,
left: '0',
top: `0%`,
right: '8%',
bottom: '0',
itemStyle: {
// normal: {
// areaColor: `rgba(115, 219, 249, 0)`,
// borderwidth: 3,
// borderColor: `#37C1FD`,
// shadowBlur: 20,
// shadowOffsetY: 4,
// shadowOffsetX: 4,
// shadowColor: `#ddd`
// },
areaColor: {
image: dot,
repeat: 'repeat'
},
}
},
series: [
{
type: `effectScatter`,
coordinateSystem: `geo`,
rippleEffect: { //
period: 4, //
brushType: `stroke`, // stroke, fill
scale: 8 //
},
itemStyle: {
// normal: {
// color: `orange`,
// shadowBlur: 2
// },
},
symbolSize: 8,
data: [
{ name: `三亚市`, value: [ 104.065735, 30.659462] },
{ name: `五指山市`, value: [104.773447,29.352765] }
//[109.508268, 18.247872, ``],
//[109.516662, 18.776921, ``]
]
}
]
}
echarts.registerMap(`lz`, mapJson)
// const myChart2 = document.getElementById('chart2')
// const bg = echarts.init(myChart2);
// bg.setOption(chartOption)
const canvas = document.createElement(`canvas`)
let bg = echarts.init(canvas, null, {
width: 1024,
height: 1024
})
bg.setOption(chartOption)
const myChart = document.getElementById('myChart')
const charts = echarts.init(myChart);
let option = {
// geo3D: {
// map: ``,
// viewControl: {
// autoRotate: false,
// distance: 180
// },
// shading: `color`,
// boundingCoords: [
// [-180, 90],
// [180, -90]
// ],
// colorMaterial: {
// detailTexture: this.bg, //
// textureTiling: 1 // 1
// },
// //
// groundPlane: {
// show: false
// }
// },
geo3D: {
map: "luzhou",
shading: `color`,
//
roam: true,
itemStyle: {
// color: "#014281",
opacity: 0.9,
borderWidth: 0.4,
borderColor: "#000",
normal: {
areaColor: 'red',
borderWidth: 4, //
// borderColor: '#f8911b',
},
emphasis: {
show: false,
// areaColor: '#01215c'
}
// areaColor: '#fff'
},
viewControl: {
autoRotate: true,
autoRotateAfterStill: 3,
distance: 90,
minAlpha: 5, // alpha [ default: 5 ]
maxAlpha: 90, // alpha [ default: 90 ]
minBeta: -360, // beta [ default: -80 ]
maxBeta: 360, // beta [ default: 80 ]
animation: true, // [ default: true ]
animationDurationUpdate: 1000, // [ default: 1000 ]
animationEasingUpdate: "cubicInOut" // [ default: cubicInOut ]
},
emphasis: {
disabled: true, //
label: {
//
show: true,
},
itemStyle: {
color:
"#B17049" //
}
},
label: {
show: false,
// position: "bottom",
color: "white", //
fontSize: 14,
lineHeight: 16,
// textStyle: {
// color: "#fff", //
// fontSize: 12,
// opacity: 1,
// backgroundColor: "red",
// },
},
shading: "color",
light: {
//
main: {
// color: "#fff", //
intensity: 0.8, //
shadowQuality: 'high', //
shadow: true, //
shadowQuality: "medium", // ultra //
alpha: 55,
beta: 10
},
ambient: {
intensity: 0.7
}
},
colorMaterial: {
detailTexture: bg, //
textureTiling: 1 // 1
},
},
series: [
{
type: "scatter3D",
coordinateSystem: "geo3D",
data: initData(mapJson.features),
// symbol: "circle",
symbolSize: 20,
// itemStyle: {
// color: "transparent",
// },
label: {
show: true,
position: "top",
distance: -10,
formatter(params) {
return "2";
},
textStyle: {
// color: "transparent",
padding: [15, 20],
backgroundColor: {
image: '/static/index/aa.png',
},
// backgroundColor:""
},
},
emphasis: {
label: {
show: true,
textStyle: {
backgroundColor: {
// image: '/static/index/aa.png',
},
},
},
},
},
],
};
// option.geo.map
echarts.registerMap("luzhou", mapJson)
charts.setOption(option);
})
})
</script>

View File

@ -1,8 +1,11 @@
import axios from "axios";
// 创建axios 实例
const instacne = axios.create({
baseURL: "https://ceshi-worker-task.lihaink.cn",
baseURL: "http://ceshi-suyuan.lihaink.cn/",
timeout: 30000,
});
@ -10,6 +13,7 @@ const instacne = axios.create({
instacne.interceptors.request.use(
(config) => {
// 在发送请求之前做什么
return config;
},
@ -21,8 +25,8 @@ instacne.interceptors.request.use(
// 响应拦截
instacne.interceptors.response.use(
(res) => {
// 对响应的数据做什么
return res;
return res.data;
},
(err) => {
return Promise.reject(err);
@ -32,9 +36,12 @@ instacne.interceptors.response.use(
export function getConfig(parms) {
return instacne.post('/adminapi/login/account', parms)
export function deviceAlarmCountApi(params) {
return instacne.get('/api/dataview.device/deviceAlarmCount', { params })
}
//
//api/dataview/merchant?mer_id=36&areaCode=510524&streetCode=510524100
// }

View File

@ -5,7 +5,7 @@
<div class="right">
<div class="rigth-li" @click="choseArea = true"> <img style="width: 1VW;height:1VW;margin-right: 0.5vw;"
:src="u('DW')" alt=""> 泸县
:src="u('DW')" alt=""> {{ area|| '泸县' }}
</div>
<areaList :choseArea="choseArea" @offAreaList="offAreaList"></areaList>
<div class="right-line">
@ -42,23 +42,22 @@ const router = useRouter()
const route = useRoute()
//
const show = reactive([false, true, true, true, true])
//
const choseArea = ref(false)
//
const offAreaList = () => {
const offAreaList = (item) => {
area.value=item.name
// console.log(item)
choseArea.value = false
}
const out = () => {
//@ts-ignore
// window.open("about:blank", "_top").close()
localStorage.removeItem('TOKEN')
router.replace('/')
router.replace('/login')
}
const area=ref('')
const updateTime = () => {
var date = new Date();
var hours = date.getHours();
@ -109,40 +108,7 @@ onMounted(() => {
margin-right: 30px;
position: relative;
.address {
left: 1vw;
top: 18px;
position: absolute;
width: 8vw;
height: 18vh;
background-color: #001E32;
color: #C7DBE3;
z-index: 9999;
overflow-y: auto;
box-sizing: border-box;
padding: 5px;
.address-li {
padding: 2px 5px;
cursor: pointer;
border-bottom: 0.1px solid #0E293C;
}
}
.address::-webkit-scrollbar {
width: 10px;
background-color: #153041;
}
.address::-webkit-scrollbar-track {
background-color: #153041;
}
::-webkit-scrollbar-thumb {
background-color: #4AB9D0;
border-radius: 5px;
}
.rigth-li {
height: 15px;

View File

@ -0,0 +1,387 @@
<template>
<div class="rot" >
<div class="container-shell">
<div class="option" style="display: none;">
<input
style="width: 50px"
type="number"
ref="buffer"
value="0.2"
@change="changeBuffer"
/>
<input
type="checkbox"
v-model="useMSE"
ref="vod"
@change="restartPlay('mse')"
/><span>MediaSource</span>
<input
type="checkbox"
v-model="useWCS"
ref="vod"
@change="restartPlay('wcs')"
/><span>webcodecs</span>
</div>
<div id="container" ref="container"></div>
<div class="input" style="display: none;">
<div>输入URL</div>
<input
type="input"
autocomplete="on"
ref="playUrl"
:value="url"
/>
<button v-if="!playing" @click="play">播放</button>
<button v-else @click="pause">停止</button>
</div>
</div>
</div>
</template>
<script>
// http://192.168.1.27/live/test.live.flv?secret=gqig2yFKkDpIMic1uWZY1L5MsIo0eflm
export default {
name: "DemoPlayer",
props: {
url:String
},
data() {
return {
jessibuca: null,
version: '',
wasm: false,
vc: "ff",
playing: false,
quieting: true,
loaded: false, // mute
showOperateBtns: false,
showBandwidth: false,
err: "",
speed: 0,
performance: "",
volume: 1,
rotate: 0,
useWCS: false,
useMSE: true,
useOffscreen: false,
recording: false,
recordType: 'webm',
scale: 0
};
},
mounted() {
this.create();
window.onerror = (msg) => (this.err = msg);
setTimeout( ()=>{
this.play()
},2000 )
},
unmounted() {
this.jessibuca.destroy();
},
methods: {
create(options) {
options = options || {};
this.jessibuca = new window.Jessibuca(
Object.assign(
{
container: this.$refs.container,
videoBuffer: Number(this.$refs.buffer.value), //
isResize: false,
useWCS: this.useWCS,
useMSE: this.useMSE,
text: "",
// background: "bg.jpg",
loadingText: "疯狂加载中...",
// hasAudio:false,
debug: true,
supportDblclickFullscreen: true,
showBandwidth: this.showBandwidth, //
operateBtns: {
fullscreen: this.showOperateBtns,
screenshot: this.showOperateBtns,
play: this.showOperateBtns,
audio: this.showOperateBtns,
},
vod: this.vod,
forceNoOffscreen: !this.useOffscreen,
isNotMute: true,
timeout: 10
},
options
)
);
var _this = this;
this.jessibuca.on("load", function () {
console.log("on load");
});
this.jessibuca.on("log", function (msg) {
console.log("on log", msg);
});
this.jessibuca.on("record", function (msg) {
console.log("on record:", msg);
});
this.jessibuca.on("pause", function () {
console.log("on pause");
_this.playing = false;
});
this.jessibuca.on("play", function () {
console.log("on play");
_this.playing = true;
});
this.jessibuca.on("fullscreen", function (msg) {
console.log("on fullscreen", msg);
});
this.jessibuca.on("mute", function (msg) {
console.log("on mute", msg);
_this.quieting = msg;
});
this.jessibuca.on("mute", function (msg) {
console.log("on mute2", msg);
});
this.jessibuca.on("audioInfo", function (msg) {
console.log("audioInfo", msg);
});
// this.jessibuca.on("bps", function (bps) {
// // console.log('bps', bps);
// });
// let _ts = 0;
// this.jessibuca.on("timeUpdate", function (ts) {
// console.log('timeUpdate,old,new,timestamp', _ts, ts, ts - _ts);
// _ts = ts;
// });
this.jessibuca.on("videoInfo", function (info) {
console.log("videoInfo", info);
});
this.jessibuca.on("error", function (error) {
console.log("error", error);
});
this.jessibuca.on("timeout", function () {
console.log("timeout");
});
this.jessibuca.on('start', function () {
console.log('frame start');
})
this.jessibuca.on("performance", function (performance) {
var show = "卡顿";
if (performance === 2) {
show = "非常流畅";
} else if (performance === 1) {
show = "流畅";
}
_this.performance = show;
});
this.jessibuca.on('buffer', function (buffer) {
console.log('buffer', buffer);
})
this.jessibuca.on('stats', function (stats) {
console.log('stats', stats);
})
this.jessibuca.on('kBps', function (kBps) {
console.log('kBps', kBps);
});
this.jessibuca.on("play", () => {
this.playing = true;
this.loaded = true;
this.quieting = this.jessibuca.isMute();
});
this.jessibuca.on('recordingTimestamp', (ts) => {
console.log('recordingTimestamp', ts);
})
// console.log(this.jessibuca);
},
play() {
// this.jessibuca.onPlay = () => (this.playing = true);
if (this.$refs.playUrl.value) {
this.jessibuca.play(this.$refs.playUrl.value);
}
},
mute() {
this.jessibuca.mute();
},
cancelMute() {
this.jessibuca.cancelMute();
},
pause() {
this.jessibuca.pause();
this.playing = false;
this.err = "";
this.performance = "";
},
volumeChange() {
this.jessibuca.setVolume(this.volume);
},
rotateChange() {
this.jessibuca.setRotate(this.rotate);
},
destroy() {
if (this.jessibuca) {
this.jessibuca.destroy();
}
this.create();
this.playing = false;
this.loaded = false;
this.performance = "";
},
fullscreen() {
this.jessibuca.setFullscreen(true);
},
clearView() {
this.jessibuca.clearView();
},
startRecord() {
const time = new Date().getTime();
this.jessibuca.startRecord(time, this.recordType);
},
stopAndSaveRecord() {
this.jessibuca.stopRecordAndSave();
},
screenShot() {
this.jessibuca.screenshot();
},
restartPlay(type) {
if (type === 'mse') {
this.useWCS = false;
this.useOffscreen = false;
} else if (type === 'wcs') {
this.useMSE = false
} else if (type === 'offscreen') {
this.useMSE = false
}
this.destroy();
setTimeout(() => {
this.play();
}, 100)
},
changeBuffer() {
this.jessibuca.setBufferTime(Number(this.$refs.buffer.value));
},
scaleChange() {
this.jessibuca.setScaleMode(this.scale);
},
},
};
</script>
<style>
.root {
display: flex;
place-content: center;
margin-top: 3rem;
}
.container-shell {
position: relative;
backdrop-filter: blur(5px);
/* background: hsla(0, 0%, 50%, 0.5);
padding: 30px 4px 10px 4px; */
/* border: 2px solid black; */
width: auto;
position: relative;
border-radius: 5px;
/* box-shadow: 0 10px 20px; */
}
.container-shell-title {
position: absolute;
color: darkgray;
top: 4px;
left: 10px;
text-shadow: 1px 1px black;
}
.tag-version {
}
#container {
background: rgba(13, 14, 27, 0.7);
width: 100%;
height: 300px;
}
.input {
display: flex;
align-items: center;
margin-top: 10px;
color: white;
place-content: stretch;
}
.input2 {
bottom: 0px;
}
.input input[type='input'] {
flex: auto;
}
.err {
position: absolute;
top: 40px;
left: 10px;
color: red;
}
.option {
position: absolute;
top: 4px;
right: 10px;
display: flex;
place-content: center;
font-size: 12px;
}
.option span {
color: white;
}
.page {
background: url(/bg.jpg);
background-repeat: no-repeat;
background-position: top;
}
@media (max-width: 720px) {
#container {
width: 90vw;
height: 52.7vw;
}
}
</style>

6
src/components/Toast.vue Normal file
View File

@ -0,0 +1,6 @@
<template>
<div>
登录成功
</div>
</template>

View File

@ -1,7 +1,8 @@
<template>
<Transition>
<div class="address" v-if="props.choseArea">
<div class="address-li" @click="choseTownFn(1)" v-for="( item, index ) in 10 ">泸县</div>
<div class="address-li" @click="choseTownFn({name:'泸县'})"> 泸县</div>
<div class="address-li" @click="choseTownFn(item)" v-for="( item, index ) in areaList ">{{ item.name }}</div>
</div>
</Transition>
</template>
@ -9,19 +10,36 @@
<script setup>
import { defineProps, defineEmits } from "vue"
import { useRouter } from 'vue-router'
import {reactive} from "vue"
import axios from "axios"
const router = useRouter()
const emit = defineEmits(['offAreaList'])
const props = defineProps({
choseArea: Boolean,
})
const areaList=reactive([])
//
const choseTownFn = (id) => {
const choseTownFn = (item) => {
props.choseArea = false
emit('offAreaList')
emit('offAreaList',item)
// router.replace('/townDetail?id=' + id)
}
axios.get(`https://crmeb-test.shop.lihaink.cn/api/city/get_street?area_code=${510524}`)
.then(function (response) {
response.data.data.forEach(item => {
areaList.push(item)
})
})
.catch(function (error) {
//
})
.finally(function () {
//
});
</script>
<style lang="scss" scoped>
@ -31,7 +49,7 @@ const choseTownFn = (id) => {
position: absolute;
width: 8vw;
height: 18vh;
background-color: #001E32;
background-color: #092049;
color: #C7DBE3;
z-index: 9999;
overflow-y: auto;
@ -42,13 +60,13 @@ const choseTownFn = (id) => {
padding: 2px 5px;
cursor: pointer;
border-bottom: 0.1px solid #0E293C;
border-bottom: 0.1px solid #24A4F8;
}
}
.address::-webkit-scrollbar {
width: 10px;
background-color: #153041;
background-color: #1581DC;
}
.address::-webkit-scrollbar-track {
@ -56,7 +74,7 @@ const choseTownFn = (id) => {
}
::-webkit-scrollbar-thumb {
background-color: #4AB9D0;
background-color: #1581DC;
border-radius: 5px;
}
</style>

View File

@ -48,6 +48,7 @@ import iconbg from '/static/index/mapicon.png'
import geoJson from "/static/jsonData/xuantan.js"
const u = 'https:\/\/ceshi-worker-task.lihaink.cn\/uploads\/images\/20231129\/202311291816106120a4034.png'
const icon = "https:\/\/ceshi-worker-task.lihaink.cn\/uploads\/images\/20231204\/202312041608529c9e21252.png"
const lx="https:\/\/ceshi-worker-task.lihaink.cn\/uploads\/images\/20231205\/20231205092709cfe148712.png"
const pointerFn = () => {
@ -56,14 +57,13 @@ const pointerFn = () => {
geoJson.center.forEach((item, index) => {
list.push({
coord: item,
symbol: ('image://' + icon),//
symbol: index==geoJson.center.length-1?('image://'+lx): ('image://' + icon),//
symbolSize: [100, 30], //
symbolOffset: ['50%', '-50%'],
value: geoJson.features[index].properties.name,
value: geoJson.features[index]?.properties.name||'泸县',
animation: true,
label: {
show: true,
@ -89,7 +89,7 @@ onMounted(() => {
aspectScale: 1,
zoom: 1.2,
layoutCenter: ["50%", "51%"],
layoutSize: "100%",
layoutSize: "110%",
roam: false,
label:{
emphasis:{
@ -144,7 +144,7 @@ onMounted(() => {
aspectScale: 1,
zoom: 1.2,
layoutCenter: ["50%", "51%"],
layoutSize: "100%",
layoutSize: "110%",
roam: false,
silent: true,
@ -169,7 +169,7 @@ onMounted(() => {
aspectScale: 1,
zoom: 1.2,
layoutCenter: ["50%", "52%"],
layoutSize: "100%",
layoutSize: "110%",
roam: false,
silent: true,
@ -194,7 +194,7 @@ onMounted(() => {
aspectScale: 1,
zoom: 1.2,
layoutCenter: ["50%", "53%"],
layoutSize: "100%",
layoutSize: "110%",
roam: false,
silent: true,
@ -218,7 +218,7 @@ onMounted(() => {
aspectScale: 1,
zoom: 1.2,
layoutCenter: ["50%", "54%"],
layoutSize: "100%",
layoutSize: "110%",
roam: false,
silent: true,
@ -266,10 +266,10 @@ onMounted(() => {
}
let finalData = []
Object.keys(data).map((i, index) => {
let child = data[i].map((row) => ({
let child = data[i].map((row,index) => ({
value: row,
itemStyle: {
color: '#FFB922',
color:index==geoJson.center.length-1?'#FEB821':'#F0733A',
},
}))

View File

@ -0,0 +1,12 @@
<template>
<iframe
id="inlineFrameExample"
title="Inline Frame Example"
width="500"
height="400"
src="http://localhost:3000/player.html">
</iframe>
</template>

View File

@ -0,0 +1,87 @@
<template>
<div>监控设备总数: <span class="num color-font">1528</span> </div>
<div class="cont">
<div style="display: flex;justify-content: space-between;align-items: center;margin-top: 3vh;">
<img src="/static/index/JYZ.png" style="width: 2.8vw; height: 4vw;" alt="">
<div class="circle">
<img src="/static/detail/bk.png" class="act-img" alt="">
<div style="width: 110px;height: 110px;" class="online" id="online"></div>
</div>
<div class="circle">
<img src="/static/detail/bk.png" class="act-img" alt="">
<div style="width: 110px;height: 110px;" class="online" id="offline"></div>
</div>
<img src="/static/index/JTY.png" style="width: 2.8vw; height: 4vw;" alt="">
</div>
<div class="eqNum">
<div>
<img src="/static/index/Q.png" alt="" style="transform: translateY(2px);"> 在线设备统计<span
class="num color-font" style="margin-left: 10px;">1418</span>
</div>
<div>
<img src="/static/index/Q.png" style="transform: translateY(2px);"> 离线设备统计<span class="num color-font"
style="margin-left: 10px;">1418</span>
</div>
</div>
</div>
</template>
<style lang="scss">
.num {
font-size: 20px;
}
.cont {
height: 70%;
.eqNum {
margin-top: 2vh;
display: flex;
justify-content: space-around;
font-size: 11px;
background-image: url('/static/index/BTBG.png');
background-size: 100% 100%;
// text-align: ;
}
.circle {
width: 120px;
height: 120px;
position: relative;
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.act-img {
position: absolute;
width: 100%;
height: 100%;
animation: spin 2s linear infinite;
left: -0%;
top: 0%;
}
}
.online {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
</style>

View File

@ -0,0 +1,65 @@
<template>
<warnDetail v-if="showWarnDeatil" @off="showWarnDeatil = false"></warnDetail>
<scrollTable @click="hdClick3" :config="config3" style="width:100%;height:100%" v-if="config3.data.length"></scrollTable>
</template>
<script setup>
import warnDetail from "@/components/warnDetail.vue"
import scrollTable from "@/components/scrollTable.vue"
import { ref, reactive,onMounted } from "vue"
import {deviceAlarmCountApi} from "@/api.js"
const showWarnDeatil = ref(false)
const hdClick3 = (e) => {
if (e.ceil) {
if (e.columnIndex == 3) {
// showWarnPop.value = true
showWarnDeatil.value = true
}
}
}
const alignFn = (num) => {
let arr = []
for (let i = 0; i < num; i++) {
arr.push('center')
}
return arr
}
const config3 = reactive({
header: ['设备名称', '设备编号', '告警时间', '操作',],
headerBGC: "#092757",
oddRowBGC: "#0C2045",
headerStyle: "background-image: url('/static/index/SBGJBG.png');font-family: FZCYJ;background-size: 100% 100%;",
align: alignFn(4),
data: [
// ['11', '12', '13', `<span style="color:#2562AD"> </span>`,],
// ['11', '12', '13', `<span style="color:#2562AD"> </span>`,],
// ['11', '12', '13', `<span style="color:#2562AD"> </span>`,],
// ['11', '12', '13', `<span style="color:#2562AD"> </span>`,],
// ['11', '12', '13', `<span style="color:#2562AD"> </span>`,],
// ['11', '12', '13', `<span style="color:#2562AD"> </span>`,],
// ['11', '12', '13', `<span style="color:#2562AD"> </span>`,],
]
})
onMounted( ()=>{
deviceAlarmCountApi(
{
areaCode:510521,
streetCode:510521100
}
).then(res=>{
console.log(res.data)
res.data.list.forEach(item => {
config3.data.push(
[item.device_name, item.device_code, item.update_time, `<span style="color:#2562AD"> 详情 </span>`,],
)
});
})
} )
</script>

View File

@ -0,0 +1 @@
export const VERSION = '#VERSION#'

View File

@ -1,114 +0,0 @@
<template>
<div class="form">
<div class="content">
<div style="position: relative;margin-bottom: 3VH;">
<input class="ipt" type="text" placeholder="请输入账号" v-model="account">
<img src="/static/login/ZH.png" alt="" class="accont-icon">
<div style="color: red;" v-show="isAccount">请输入账号</div>
</div>
<div style="position: relative;margin-bottom: 3VH;">
<input class="ipt" placeholder="请输入密码" :type="show ? 'text' : 'password'" v-model="password">
<div style="color: red;" v-show="isPassword">请输入密码</div>
<img src="/static/login/MM.png" alt="" class="accont-icon">
<img src="/static/login/KJ.png" v-if="show" alt="" @click="show = false" class="show">
<img src="/static/login/BKH.png" v-else alt="" @click="show = true" class="show">
</div>
<img src="/static/login/DL.png" class="btn" alt="" @click="submit">
</div>
</div>
</template>
<style lang="scss" scoped>
.form {
width: 35vw;
height: 45vh;
position: absolute;
top: 25vh;
right: 10vw;
box-sizing: border-box;
background: url("/static/login/DLBG.png");
background-size: 100% 100%;
.content {
position: absolute;
top: 13vh;
// background-color: red;
left: 10vw;
.ipt {
border: 1px solid #194FA3;
padding: 1vh 2vw;
background-color: #123266;
width: 13VW;
outline: none;
-webkit-user-select: auto;
caret-color: #fff;
color: white;
}
input[type="password"]::-ms-reveal {
display: none
}
.btn {
width: 7vw;
cursor: pointer;
margin-left: 50%;
transform: translateX(-50%);
}
.accont-icon {
width: 0.8vw;
position: absolute;
left: 1vh;
top: .8vh;
}
.show {
position: absolute;
top: 10px;
right: 10px;
width: 1vw;
cursor: pointer;
}
}
}
</style>
<script setup>
import { ref, reactive } from "vue"
import { useRouter } from "vue-router";
const router =useRouter()
const show = ref(false)
const account = ref('')
const password = ref('')
const isAccount = ref(false)
const isPassword = ref(false)
const submit = () => {
if (!account.value) {
isAccount.value = true;
return
}
else isAccount.value = false;
if (!password.value)
{ isPassword.value = true;
return}
else isPassword.value = false;
localStorage.setItem("TOKEN",15455465465465)
router.replace('/index')
// alert(isAccount.value)
}
</script>

372
src/components/videoFlv.vue Normal file
View File

@ -0,0 +1,372 @@
<template>
<div class="container-shell">
<div class="option" style="display: none">
<input
style="width: 50px"
type="number"
ref="buffer"
value="0.2"
@change="changeBuffer"
/>
<input
type="checkbox"
v-model="useMSE"
ref="vod"
@change="restartPlay('mse')"
/><span>MediaSource</span>
<input
type="checkbox"
v-model="useWCS"
ref="vod"
@change="restartPlay('wcs')"
/><span>webcodecs</span>
</div>
<div id="container" ref="container"></div>
<div class="input" style="display: none">
<div>输入URL</div>
<input
type="input"
autocomplete="on"
ref="playUrl"
value="http://192.168.1.27/live/test.live.flv?secret=gqig2yfkkdpimic1uwzy1l5msio0eflm"
/>
<button v-if="!playing" @click="play">播放</button>
<button v-else @click="pause">停止</button>
</div>
</div>
</template>
<script>
export default {
name: "DemoPlayer",
props: {},
data () {
return {
jessibuca: null,
version: '',
wasm: false,
vc: "ff",
playing: false,
quieting: true,
loaded: false, // mute
showOperateBtns: false,
showBandwidth: false,
err: "",
speed: 0,
performance: "",
volume: 1,
rotate: 0,
useWCS: false,
useMSE: true,
useOffscreen: false,
recording: false,
recordType: 'webm',
scale: 0
};
},
mounted () {
this.create();
window.onerror = (msg) => (this.err = msg);
setTimeout(() => {
this.play()
}, 2000)
},
unmounted () {
this.jessibuca.destroy();
},
methods: {
create (options) {
options = options || {};
this.jessibuca = new window.Jessibuca(
Object.assign(
{
container: this.$refs.container,
videoBuffer: Number(this.$refs.buffer.value), //
isResize: false,
useWCS: this.useWCS,
useMSE: this.useMSE,
text: "",
// background: "bg.jpg",
loadingText: "疯狂加载中...",
// hasAudio:false,
debug: true,
supportDblclickFullscreen: true,
showBandwidth: this.showBandwidth, //
operateBtns: {
fullscreen: this.showOperateBtns,
screenshot: this.showOperateBtns,
play: this.showOperateBtns,
audio: this.showOperateBtns,
},
vod: this.vod,
forceNoOffscreen: !this.useOffscreen,
isNotMute: true,
timeout: 10
},
options
)
);
var _this = this;
this.jessibuca.on("load", function () {
console.log("on load");
});
this.jessibuca.on("log", function (msg) {
console.log("on log", msg);
});
this.jessibuca.on("record", function (msg) {
console.log("on record:", msg);
});
this.jessibuca.on("pause", function () {
console.log("on pause");
_this.playing = false;
});
this.jessibuca.on("play", function () {
console.log("on play");
_this.playing = true;
});
this.jessibuca.on("fullscreen", function (msg) {
console.log("on fullscreen", msg);
});
this.jessibuca.on("mute", function (msg) {
console.log("on mute", msg);
_this.quieting = msg;
});
this.jessibuca.on("mute", function (msg) {
console.log("on mute2", msg);
});
this.jessibuca.on("audioInfo", function (msg) {
console.log("audioInfo", msg);
});
// this.jessibuca.on("bps", function (bps) {
// // console.log('bps', bps);
// });
// let _ts = 0;
// this.jessibuca.on("timeUpdate", function (ts) {
// console.log('timeUpdate,old,new,timestamp', _ts, ts, ts - _ts);
// _ts = ts;
// });
this.jessibuca.on("videoInfo", function (info) {
console.log("videoInfo", info);
});
this.jessibuca.on("error", function (error) {
console.log("error", error);
});
this.jessibuca.on("timeout", function () {
console.log("timeout");
});
this.jessibuca.on('start', function () {
console.log('frame start');
})
this.jessibuca.on("performance", function (performance) {
var show = "卡顿";
if (performance === 2) {
show = "非常流畅";
} else if (performance === 1) {
show = "流畅";
}
_this.performance = show;
});
this.jessibuca.on('buffer', function (buffer) {
console.log('buffer', buffer);
})
this.jessibuca.on('stats', function (stats) {
console.log('stats', stats);
})
this.jessibuca.on('kBps', function (kBps) {
console.log('kBps', kBps);
});
this.jessibuca.on("play", () => {
this.playing = true;
this.loaded = true;
this.quieting = this.jessibuca.isMute();
});
this.jessibuca.on('recordingTimestamp', (ts) => {
console.log('recordingTimestamp', ts);
})
// console.log(this.jessibuca);
},
play () {
// this.jessibuca.onPlay = () => (this.playing = true);
if (this.$refs.playUrl.value) {
this.jessibuca.play(this.$refs.playUrl.value);
}
},
mute () {
this.jessibuca.mute();
},
cancelMute () {
this.jessibuca.cancelMute();
},
pause () {
this.jessibuca.pause();
this.playing = false;
this.err = "";
this.performance = "";
},
volumeChange () {
this.jessibuca.setVolume(this.volume);
},
rotateChange () {
this.jessibuca.setRotate(this.rotate);
},
destroy () {
if (this.jessibuca) {
this.jessibuca.destroy();
}
this.create();
this.playing = false;
this.loaded = false;
this.performance = "";
},
fullscreen () {
this.jessibuca.setFullscreen(true);
},
clearView () {
this.jessibuca.clearView();
},
startRecord () {
const time = new Date().getTime();
this.jessibuca.startRecord(time, this.recordType);
},
stopAndSaveRecord () {
this.jessibuca.stopRecordAndSave();
},
screenShot () {
this.jessibuca.screenshot();
},
restartPlay (type) {
if (type === 'mse') {
this.useWCS = false;
this.useOffscreen = false;
} else if (type === 'wcs') {
this.useMSE = false
} else if (type === 'offscreen') {
this.useMSE = false
}
this.destroy();
setTimeout(() => {
this.play();
}, 100)
},
changeBuffer () {
this.jessibuca.setBufferTime(Number(this.$refs.buffer.value));
},
scaleChange () {
this.jessibuca.setScaleMode(this.scale);
},
},
};
</script>
<style>
.container-shell {
height: 100%;
width: 100%;
backdrop-filter: blur(5px);
/* background: hsla(0, 0%, 50%, 0.5);
padding: 30px 4px 10px 4px; */
/* border: 2px solid black; */
width: auto;
position: relative;
border-radius: 5px;
/* box-shadow: 0 10px 20px; */
}
.container-shell-title {
position: absolute;
color: darkgray;
top: 4px;
left: 10px;
text-shadow: 1px 1px black;
}
.tag-version {
}
#container {
background: rgba(13, 14, 27, 0.7);
width: 100%;
height: 100%;
}
.input {
display: flex;
align-items: center;
margin-top: 10px;
color: white;
place-content: stretch;
}
.input2 {
bottom: 0px;
}
.input input[type="input"] {
flex: auto;
}
.err {
position: absolute;
top: 40px;
left: 10px;
color: red;
}
.option {
position: absolute;
top: 4px;
right: 10px;
display: flex;
place-content: center;
font-size: 12px;
}
.option span {
color: white;
}
.page {
background: url(/bg.jpg);
background-repeat: no-repeat;
background-position: top;
}
/* @media (max-width: 720px) {
#container {
width: 90vw;
height: 52.7vw;
}
} */
</style>

View File

@ -2,7 +2,11 @@ import { createApp } from 'vue'
import App from './App.vue'
import dataV from '@jiaminghi/data-view'
import router from "./router";
import 'amfe-flexible'
import "/public/jessibuca.js"
const app = createApp(App)
app.use(router)
app.use(dataV)

View File

@ -3,23 +3,25 @@ import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{
path: '/',
name: 'login',
component: () => import('@/components/login.vue'),
},
{
path: '/index',
name: 'index',
component: () => import('@/view/index.vue'),
redirect: "/home",
children: [
{
path: '/home',
component: () => import('@/view/home.vue'),
}, {
path: '/detail',
component: () => import('@/view/detail.vue'),
}
]
},
{
path: '/detail',
name: 'detail',
component: () => import('@/view/detail.vue'),
},
path: '/login',
name: 'login',
component: () => import('@/view/login.vue'),
}
]
const router = createRouter({
@ -27,4 +29,26 @@ const router = createRouter({
routes
})
router.beforeEach(async (to, from, next) => {
// let token = localStorage.getItem("TOKEN")
// if (to.name == "login" && token) {
// next("/")
// return
// }
// if (to.name != "login" && !token) {
// next("/login") //跳转
// return
// }
next() //放行
})
// 把这段代码直接粘贴到router/index.js中的Vue.use(VueRouter)之前
// const originalPush = VueRouter.prototype.push;
// VueRouter.prototype.push = function (location) {
// return originalPush.call(this, location).catch(err => { })
// };
export default router

View File

@ -1,8 +1,6 @@
<template>
<div class="box">
<div class="l">
<div class="top">
<div style="display: flex;justify-content: space-between;align-items: center;">
<span>种植总面积</span>
@ -34,7 +32,7 @@
<div class="c">
<div class="top">
<div style="display: flex;justify-content: space-between;">
<div class=" c-top-tits"><span class="color-font" @click="router.push('/index')">返回首页</span></div>
<div class=" c-top-tits"><span class="color-font" @click="router.push('/')">返回首页</span></div>
<div class=" c-top-tits"><span class="color-font">同谭政地块</span> </div>

479
src/view/home.vue Normal file
View File

@ -0,0 +1,479 @@
<template>
<div class="box">
<div class="l">
<div class="top">
<!-- <warnDetail v-if="showWarnDeatil" @off="showWarnDeatil = false"></warnDetail>
<scrollTable @click="hdClick3" :config="config3" style="width:100%;height:100%"></scrollTable> -->
<leftTop></leftTop>
</div>
<div class="center top">
<div>监控设备总数: <span class="num color-font">1528</span> </div>
<div class="cont">
<div style="display: flex;justify-content: space-between;align-items: center;margin-top: 3vh;">
<img src="/static/index/JYZ.png" style="width: 2.8vw; height: 4vw;" alt="">
<div class="circle">
<img src="/static/detail/bk.png" class="act-img" alt="">
<div style="width: 110px;height: 110px;" class="online" id="online"></div>
</div>
<div class="circle">
<img src="/static/detail/bk.png" class="act-img" alt="">
<div style="width: 110px;height: 110px;" class="online" id="offline"></div>
</div>
<img src="/static/index/JTY.png" style="width: 2.8vw; height: 4vw;" alt="">
</div>
<div class="eqNum">
<div>
<img src="/static/index/Q.png" alt="" style="transform: translateY(2px);"> 在线设备统计<span
class="num color-font" style="margin-left: 10px;">1418</span>
</div>
<div>
<img src="/static/index/Q.png" style="transform: translateY(2px);"> 离线设备统计<span
class="num color-font" style="margin-left: 10px;">1418</span>
</div>
</div>
</div>
</div>
<div class="bottom top">
<scrollTable :config="config2" style="width:100%;height:100%"></scrollTable>
</div>
</div>
<div class="c">
<div class="top">
<div class="c-top-tit">
<div class="c-top-li">种植面积 <span class="color-font"
style="font-size: 18px;margin-left: 1vw; ">45454</span> m</div>
<div class="c-top-li">种植种类 <span class="color-font"
style="font-size: 18px;margin-left: 1vw; ">45454</span> </div>
<div class="c-top-li">地块数量 <span class="color-font"
style="font-size: 18px;margin-left: 1vw; ">45454</span> </div>
</div>
<div class="map">
<areaMap></areaMap>
</div>
</div>
<div class="bottom">
<warnPop v-if="showWarnPop" ref="ChildsDom" @off="showWarnPop = false"></warnPop>
<scrollTable :config="config" @click="hdClick" style="width:100%;height:100%"></scrollTable>
</div>
</div>
<div class="r">
<div class="top">
<div class="content" id="eq">
<div class="eq" v-for="item in 10" :key="item">
<img :src="u" style="width:8vw;height: 100%;border-radius: 1vh;" alt="">
<div
style="display: flex;flex-direction: column;justify-content: space-between;margin-left: 1vw;color: #CAD5E5;">
<div style="display: flex;align-items: center;">
<img src="/static/index/MC.png" style="width:1.7vw;height: 1.5vw;margin-right: 5px; "
alt="">
张伟
</div>
<div style="display: flex;align-items: center;">
<img src="/static/index/JS.png" style="width:1.7vw;height: 1.5vw;margin-right: 5px; "
alt="">
这是一名后端开发
</div>
</div>
</div>
</div>
</div>
<div class="bottom">
<div style="height: 35%;">
<div class="lands">
<div class="land" v-for="(item, index) in 16" @click="test" :key="index">地块</div>
</div>
</div>
<div class="video" style="height: 65%;">
<div class="video-tit"> 实时监测影像 </div>
<!-- <JessibucaDemo style="height: 80%;" :url="a"></JessibucaDemo> -->
</div>
</div>
</div>
</div>
</template>
<script setup>
// import flvjs from "flv.js"
import { ref, reactive, onMounted } from "vue"
import leftTop from "@/components/index/leftTop.vue"
import scrollTable from "@/components/scrollTable.vue"
import options from "./option"
import * as echarts from 'echarts';
import warnPop from "@/components/warnPop.vue"
import JessibucaDemo from "@/components/videoFlv.vue"
import { useRouter } from "vue-router";
import areaMap from "@/components/areaMap.vue"
const a=ref( 'http://192.168.1.27/live/test.live.flv?secret=gqig2yFKkDpIMic1uWZY1L5MsIo0eflm')
const router = useRouter()
const u = ref('https:\/\/ceshi-worker-task.lihaink.cn\/uploads\/images\/20231129\/202311291816106120a4034.png')
const alignFn = (num) => {
let arr = []
for (let i = 0; i < num; i++) {
arr.push('center')
}
return arr
}
const config = reactive({
header: ['地块名称', '土壤温度', '土壤湿度', '土壤PH值', '土壤氮磷钾', '风速', '环境温度', '环境湿度', '二氧化碳', '历史预警数据'],
headerBGC: "#092757",
headerStyle: "background-image: url('/static/index/tableHead.png');font-family: FZCYJ;background-size: 100% 100%;",
oddRowBGC: "#0C2045",
align: alignFn(10),
data: [
['行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', `<span style='color:#2562AD' > 查看<span>`],
['行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', `<span style='color:#2562AD' > 查看<span>`],
['行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', `<span style='color:#2562AD' > 查看<span>`],
['行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', `<span style='color:#2562AD' > 查看<span>`],
['行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', `<span style='color:#2562AD' > 查看<span>`],
['行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', `<span style='color:#2562AD' > 查看<span>`],
['行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', `<span style='color:#2562AD' > 查看<span>`],
]
})
const config2 = reactive({
header: ['产品名称', '溯源码', '产品名称', '溯源码',],
headerBGC: "#092757",
oddRowBGC: "#0C2045",
headerStyle: "background:#0E316B",
align: alignFn(4),
data: [
['行1列1', '行1列2', '行1列3', '行1列1',],
['行1列1', '行1列2', '行1列3', '行1列1',],
['行1列1', '行1列2', '行1列3', '行1列1',],
['行1列1', '行1列2', '行1列3', '行1列1',],
['行1列1', '行1列2', '行1列3', '行1列1',],
['行1列1', '行1列2', '行1列3', '行1列1',],
['行1列1', '行1列2', '行1列3', '行1列1',],
]
})
const config3 = reactive({
header: ['设备名称', '设备编号', '告警时间', '操作',],
headerBGC: "#092757",
oddRowBGC: "#0C2045",
headerStyle: "background-image: url('/static/index/SBGJBG.png');font-family: FZCYJ;background-size: 100% 100%;",
align: alignFn(4),
data: [
['行1列1', '行1列2', '行1列3', `<span style="color:#2562AD"> 详情 </span>`,],
['行1列1', '行1列2', '行1列3', `<span style="color:#2562AD"> 详情 </span>`,],
['行1列1', '行1列2', '行1列3', `<span style="color:#2562AD"> 详情 </span>`,],
['行1列1', '行1列2', '行1列3', `<span style="color:#2562AD"> 详情 </span>`,],
['行1列1', '行1列2', '行1列3', `<span style="color:#2562AD"> 详情 </span>`,],
['行1列1', '行1列2', '行1列3', `<span style="color:#2562AD"> 详情 </span>`,],
['行1列1', '行1列2', '行1列3', `<span style="color:#2562AD"> 详情 </span>`,],
]
})
//
const initCharts = (tag, option) => {
var chartDom = document.getElementById(tag);
var myChart = echarts.init(chartDom);
myChart.setOption(option);
}
const ChildsDom = ref(null);
const showWarnPop = ref(false)
const hdClick = (e) => {
// console.log(e)
if (e.ceil) {
if (e.columnIndex == 9) {
showWarnPop.value = true
}
}
}
const showWarnDeatil = ref(false)
const hdClick3 = (e) => {
if (e.ceil) {
if (e.columnIndex == 3) {
// showWarnPop.value = true
showWarnDeatil.value = true
}
}
}
const test = () => {
router.replace('/detail')
}
const scrollTableFn = () => {
const tag = document.getElementById('eq')
const height = tag.scrollHeight
setInterval(() => {
tag.scrollTop += 1
if ((tag.scrollTop + tag.clientHeight) >= height - 50) {
tag.scrollTop = 0
}
}, 50)
}
onMounted(() => {
document.getElementById("online").removeAttribute('_echarts_instance_');
document.getElementById("offline").removeAttribute('_echarts_instance_');
scrollTableFn()
initCharts('online', options.onLine)
initCharts('offline', options.offLine)
// liveFn()
})
</script>
<style lang="scss">
.box {
width: 100vw;
height: 93vh;
margin-top: 1vh;
display: flex;
justify-content: space-between;
.l {
width: 25vw;
height: 93vh;
.top {
width: 25vw;
height: 30vh;
background-size: 100% 100%;
// background-color: pink;
background-image: url('/static/index/SBGJTJ.png');
margin-top: 1vh;
box-sizing: border-box;
padding: 6vh 2vh 1vh 2vh;
color: white;
font-size: 14px;
position: relative;
}
.center {
background-image: url('/static/index/JCSBSLTJ.png');
.num {
font-size: 20px;
// font-family: FZCYJ;
// color: #E5EFFF;
// background: linear-gradient(to bottom, #DAE8FE 30%, #53A0FF 100%);
// -webkit-background-clip: text;
// -webkit-text-fill-color: transparent;
// margin-left: 30px;
}
.cont {
height: 70%;
.eqNum {
margin-top: 2vh;
display: flex;
justify-content: space-around;
font-size: 11px;
background-image: url('/static/index/BTBG.png');
background-size: 100% 100%;
// text-align: ;
}
.circle {
width: 120px;
height: 120px;
position: relative;
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.act-img {
position: absolute;
width: 100%;
height: 100%;
animation: spin 2s linear infinite;
left: -0%;
top: 0%;
}
}
.online {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
}
.bottom {
background-image: url('/static/index/SYCPTJ.png');
}
}
.c {
width: 49vw;
height: 93vh;
.top {
margin-top: 1vh;
width: 49vw;
height: 61vh;
// background-color: RED;
background-image: url('/static/index/ZBK.png');
background-size: 100% 100%;
box-sizing: border-box;
padding: 2vh 2vw;
.c-top-tit {
display: flex;
color: white;
justify-content: space-between;
font-size: 12px;
line-height: 2vh;
.c-top-li {
padding: 2vh 3vw;
// background-color: #fff;
background-image: url('/static/index/DBTC.png');
background-size: 100% 100%;
}
}
.map {
width: 100%;
height: 50vh;
// background-color: #fff;
// border: 1px solid red;
}
}
.bottom {
width: 49vw;
height: 30vh;
margin-top: 1vh;
background-image: url('/static/index/ZNYJ.png');
background-size: 100% 100%;
box-sizing: border-box;
padding: 6vh 1vh 1vh 2vh;
position: relative;
}
}
.r {
width: 25vw;
height: 93vh;
.bottom {
width: 25vw;
box-sizing: border-box;
padding-top: 6vh;
padding: 6vh 1vh 0;
height: 61vh;
background-size: 100% 100%;
background-image: url('/static/index/MQ.png');
margin-top: 1vh;
.lands {
display: flex;
// justify-content: ;
flex-wrap: wrap;
height: 100%;
justify-content: space-between;
font-size: 14px;
.land {
width: 5vw;
height: 3vh;
// background-color: #fff;
background-image: url('/static/index/DK.png');
background-size: 100% 100%;
color: white;
text-align: center;
line-height: 3vh;
}
}
.video {
.video-tit {
color: white;
width: 110px;
text-align: center;
line-height: 30px;
height: 30px;
background-image: url('/static/index/JKBT.png');
background-size: cover;
font-size: 15px;
margin-bottom: 3vh;
}
}
}
.top {
width: 25vw;
height: 30vh;
padding: 2vh;
box-sizing: border-box;
background-size: 100% 100%;
background-image: url('/static/index/YJCP.png');
margin-top: 1vh;
padding-top: 6vh;
.content {
width: 100%;
height: 100%;
transition: 1s;
// background-color: #fff;
overflow-y: auto;
font-size: 14px;
.eq {
width: 100%;
height: 10vh;
// background-color: #fff;
margin-bottom: 1vh;
background-color: #092049;
box-sizing: border-box;
padding: 1vh;
display: flex;
}
}
.content::-webkit-scrollbar {
width: 10px;
background-color: #153041;
}
.content::-webkit-scrollbar-track {
background-color: #153041;
}
::-webkit-scrollbar-thumb {
background-color: #1581DC;
border-radius: 5px;
}
}
}
}
</style>

View File

@ -1,474 +1,32 @@
<template>
<div class="box">
<div class="l">
<div class="top">
<warnDetail v-if="showWarnDeatil" @off="showWarnDeatil = false"></warnDetail>
<scrollTable @click="hdClick3" :config="config3" style="width:100%;height:100%"></scrollTable>
</div>
<div class="center top">
<div>监控设备总数: <span class="num color-font">1528</span> </div>
<div class="cont">
<div style="display: flex;justify-content: space-between;align-items: center;margin-top: 3vh;">
<img src="/static/index/JYZ.png" style="width: 2.8vw; height: 4vw;" alt="">
<div class="circle">
<img src="/static/detail/bk.png" class="act-img" alt="">
<div style="width: 110px;height: 110px;" class="online" id="online"></div>
</div>
<div class="circle">
<img src="/static/detail/bk.png" class="act-img" alt="">
<div style="width: 110px;height: 110px;" class="online" id="offline"></div>
</div>
<img src="/static/index/JTY.png" style="width: 2.8vw; height: 4vw;" alt="">
</div>
<div class="eqNum">
<div>
<img src="/static/index/Q.png" alt="" style="transform: translateY(2px);"> 在线设备统计<span
class="num color-font" style="margin-left: 10px;">1418</span>
</div>
<div>
<img src="/static/index/Q.png" style="transform: translateY(2px);"> 离线设备统计<span
class="num color-font" style="margin-left: 10px;">1418</span>
</div>
</div>
</div>
</div>
<div class="bottom top">
<scrollTable :config="config2" style="width:100%;height:100%"></scrollTable>
</div>
</div>
<div class="c">
<div class="top">
<div class="c-top-tit">
<div class="c-top-li">种植面积 <span class="color-font"
style="font-size: 18px;margin-left: 1vw; ">45454</span> m</div>
<div class="c-top-li">种植种类 <span class="color-font"
style="font-size: 18px;margin-left: 1vw; ">45454</span> </div>
<div class="c-top-li">地块数量 <span class="color-font"
style="font-size: 18px;margin-left: 1vw; ">45454</span> </div>
</div>
<div class="map">
<areaMap></areaMap>
</div>
</div>
<div class="bottom">
<warnPop v-if="showWarnPop" ref="ChildsDom" @off="showWarnPop = false"></warnPop>
<scrollTable :config="config" @click="hdClick" style="width:100%;height:100%"></scrollTable>
</div>
</div>
<div class="r">
<div class="top">
<div class="content" id="eq">
<div class="eq" v-for="item in 10" :key="item">
<img :src="u" style="width:8vw;height: 100%;border-radius: 1vh;" alt="">
<div
style="display: flex;flex-direction: column;justify-content: space-between;margin-left: 1vw;color: #CAD5E5;">
<div style="display: flex;align-items: center;">
<img src="/static/index/MC.png" style="width:1.7vw;height: 1.5vw;margin-right: 5px; "
alt="">
张伟
</div>
<div style="display: flex;align-items: center;">
<img src="/static/index/JS.png" style="width:1.7vw;height: 1.5vw;margin-right: 5px; "
alt="">
这是一名后端开发
</div>
</div>
</div>
</div>
</div>
<div class="bottom">
<div style="height: 35%;">
<div class="lands">
<div class="land" v-for="(item, index) in 16" @click="test" :key="index">地块</div>
</div>
</div>
<div class="video" style="height: 65%;">
<div class="video-tit"> 实时监测影像 </div>
<video style="margin-top: 1vh;width: 100%;height: 100%;" autoplay muted
src="http://192.168.1.27/live/test.live.mp4?secret=gqig2yFKkDpIMic1uWZY1L5MsIo0eflm">
</video>
</div>
</div>
</div>
</div>
<div class="main-box">
<Header></Header>
<router-view></router-view>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from "vue"
import scrollTable from "@/components/scrollTable.vue"
import options from "./option"
import * as echarts from 'echarts';
import warnPop from "@/components/warnPop.vue"
import warnDetail from "@/components/warnDetail.vue"
import { useRouter } from "vue-router";
import areaMap from "@/components/areaMap.vue"
const router = useRouter()
import Header from "@/components/Header.vue"
const u = ref('https:\/\/ceshi-worker-task.lihaink.cn\/uploads\/images\/20231129\/202311291816106120a4034.png')
const alignFn = (num) => {
let arr = []
for (let i = 0; i < num; i++) {
arr.push('center')
}
return arr
}
const config = reactive({
header: ['地块名称', '土壤温度', '土壤湿度', '土壤PH值', '土壤氮磷钾', '风速', '环境温度', '环境湿度', '二氧化碳', '历史预警数据'],
headerBGC: "#092757",
headerStyle: "background-image: url('/static/index/tableHead.png');font-family: FZCYJ;background-size: 100% 100%;",
oddRowBGC: "#0C2045",
align: alignFn(10),
data: [
['行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', `<span style='color:#2562AD' > 查看<span>`],
['行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', `<span style='color:#2562AD' > 查看<span>`],
['行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', `<span style='color:#2562AD' > 查看<span>`],
['行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', `<span style='color:#2562AD' > 查看<span>`],
['行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', `<span style='color:#2562AD' > 查看<span>`],
['行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', `<span style='color:#2562AD' > 查看<span>`],
['行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', '行1列1', '行1列2', '行1列3', `<span style='color:#2562AD' > 查看<span>`],
]
})
const config2 = reactive({
header: ['产品名称', '溯源码', '产品名称', '溯源码',],
headerBGC: "#092757",
oddRowBGC: "#0C2045",
headerStyle: "background:#0E316B",
align: alignFn(4),
data: [
['行1列1', '行1列2', '行1列3', '行1列1',],
['行1列1', '行1列2', '行1列3', '行1列1',],
['行1列1', '行1列2', '行1列3', '行1列1',],
['行1列1', '行1列2', '行1列3', '行1列1',],
['行1列1', '行1列2', '行1列3', '行1列1',],
['行1列1', '行1列2', '行1列3', '行1列1',],
['行1列1', '行1列2', '行1列3', '行1列1',],
]
})
const config3 = reactive({
header: ['产品名称', '溯源码', '产品名称', '溯源码',],
headerBGC: "#092757",
oddRowBGC: "#0C2045",
headerStyle: "background-image: url('/static/index/SBGJBG.png');font-family: FZCYJ;background-size: 100% 100%;",
align: alignFn(4),
data: [
['行1列1', '行1列2', '行1列3', `<span style="color:#2562AD"> 详情 </span>`,],
['行1列1', '行1列2', '行1列3', `<span style="color:#2562AD"> 详情 </span>`,],
['行1列1', '行1列2', '行1列3', `<span style="color:#2562AD"> 详情 </span>`,],
['行1列1', '行1列2', '行1列3', `<span style="color:#2562AD"> 详情 </span>`,],
['行1列1', '行1列2', '行1列3', `<span style="color:#2562AD"> 详情 </span>`,],
['行1列1', '行1列2', '行1列3', `<span style="color:#2562AD"> 详情 </span>`,],
['行1列1', '行1列2', '行1列3', `<span style="color:#2562AD"> 详情 </span>`,],
]
})
//
const initCharts = (tag, option) => {
var chartDom = document.getElementById(tag);
var myChart = echarts.init(chartDom);
myChart.setOption(option);
}
const ChildsDom = ref(null);
const showWarnPop = ref(false)
const hdClick = (e) => {
// console.log(e)
if (e.ceil) {
if (e.columnIndex == 9) {
showWarnPop.value = true
}
}
}
const showWarnDeatil = ref(false)
const hdClick3 = (e) => {
if (e.ceil) {
if (e.columnIndex == 3) {
// showWarnPop.value = true
showWarnDeatil.value = true
}
}
}
const test = () => {
router.replace('/detail')
}
const scrollTableFn = () => {
const tag = document.getElementById('eq')
const height = tag.scrollHeight
setInterval(() => {
tag.scrollTop += 1
if ((tag.scrollTop + tag.clientHeight) >= height - 50) {
tag.scrollTop = 0
}
}, 50)
}
onMounted(() => {
document.getElementById("online").removeAttribute('_echarts_instance_');
document.getElementById("offline").removeAttribute('_echarts_instance_');
scrollTableFn()
initCharts('online', options.onLine)
initCharts('offline', options.offLine)
})
</script>
<style lang="scss">
.box {
width: 100vw;
height: 93vh;
margin-top: 1vh;
display: flex;
justify-content: space-between;
.l {
width: 25vw;
height: 93vh;
.top {
width: 25vw;
height: 30vh;
background-size: 100% 100%;
// background-color: pink;
background-image: url('/static/index/SBGJTJ.png');
margin-top: 1vh;
box-sizing: border-box;
padding: 6vh 2vh 1vh 2vh;
color: white;
font-size: 14px;
position: relative;
}
.center {
background-image: url('/static/index/JCSBSLTJ.png');
.num {
font-size: 20px;
// font-family: FZCYJ;
// color: #E5EFFF;
// background: linear-gradient(to bottom, #DAE8FE 30%, #53A0FF 100%);
// -webkit-background-clip: text;
// -webkit-text-fill-color: transparent;
// margin-left: 30px;
}
.cont {
height: 70%;
.eqNum {
margin-top: 2vh;
display: flex;
justify-content: space-around;
font-size: 11px;
background-image: url('/static/index/BTBG.png');
background-size: 100% 100%;
// text-align: ;
}
.circle {
width: 120px;
height: 120px;
position: relative;
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.act-img {
position: absolute;
width: 100%;
height: 100%;
animation: spin 2s linear infinite;
left: -0%;
top: 0%;
}
}
.online {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
}
.bottom {
background-image: url('/static/index/SYCPTJ.png');
}
}
.c {
width: 49vw;
height: 93vh;
.top {
margin-top: 1vh;
width: 49vw;
height: 61vh;
// background-color: RED;
background-image: url('/static/index/ZBK.png');
background-size: 100% 100%;
box-sizing: border-box;
padding: 2vh 2vw;
.c-top-tit {
display: flex;
color: white;
justify-content: space-between;
font-size: 12px;
line-height: 2vh;
.c-top-li {
padding: 2vh 3vw;
// background-color: #fff;
background-image: url('/static/index/DBTC.png');
background-size: 100% 100%;
}
}
.map {
width: 100%;
height: 50vh;
// background-color: #fff;
// border: 1px solid red;
}
}
.bottom {
width: 49vw;
height: 30vh;
margin-top: 1vh;
background-image: url('/static/index/ZNYJ.png');
background-size: 100% 100%;
box-sizing: border-box;
padding: 6vh 1vh 1vh 2vh;
position: relative;
}
}
.r {
width: 25vw;
height: 93vh;
.bottom {
width: 25vw;
box-sizing: border-box;
padding-top: 6vh;
padding: 6vh 1vh 0;
height: 61vh;
background-size: 100% 100%;
background-image: url('/static/index/MQ.png');
margin-top: 1vh;
.lands {
display: flex;
// justify-content: ;
flex-wrap: wrap;
height: 100%;
justify-content: space-between;
font-size: 14px;
.land {
width: 5vw;
height: 3vh;
// background-color: #fff;
background-image: url('/static/index/DK.png');
background-size: 100% 100%;
color: white;
text-align: center;
line-height: 3vh;
}
}
.video {
.video-tit {
color: white;
width: 110px;
text-align: center;
line-height: 30px;
height: 30px;
background-image: url('/static/index/JKBT.png');
background-size: cover;
font-size: 15px;
}
}
}
.top {
width: 25vw;
height: 30vh;
padding: 2vh;
box-sizing: border-box;
background-size: 100% 100%;
background-image: url('/static/index/YJCP.png');
margin-top: 1vh;
padding-top: 6vh;
.content {
width: 100%;
height: 100%;
transition: 1s;
// background-color: #fff;
overflow-y: auto;
font-size: 14px;
.eq {
width: 100%;
height: 10vh;
// background-color: #fff;
margin-bottom: 1vh;
background-color: #092049;
box-sizing: border-box;
padding: 1vh;
display: flex;
}
}
.content::-webkit-scrollbar {
width: 10px;
background-color: #153041;
}
.content::-webkit-scrollbar-track {
background-color: #153041;
}
::-webkit-scrollbar-thumb {
background-color: #1581DC;
border-radius: 5px;
}
}
}
.main-box {
width: 100vw;
height: 100vh;
background-image: url('/static/index/bg.png');
background-size: 100% 100%;
overflow: hidden;
color: white;
}
</style>

146
src/view/login.vue Normal file
View File

@ -0,0 +1,146 @@
<template>
<div class="login-box">
<div class="form">
<div class="content">
<div style="position: relative;margin-bottom: 3VH;">
<img src="/static/login/ZH.png" alt="" class="accont-icon">
<input class="ipt" type="text" placeholder="请输入账号" v-model="account">
<div style="color: red;" v-show="isAccount">请输入账号</div>
</div>
<div style="position: relative;margin-bottom: 3VH;">
<img src="/static/login/MM.png" alt="" class="accont-icon" style="">
<input class="ipt" placeholder="请输入密码" :type="show ? 'text' : 'password'" v-model="password">
<div style="color: red;" v-show="isPassword">请输入密码</div>
<img src="/static/login/KJ.png" v-if="show" alt="" @click="show = false" class="show">
<img src="/static/login/BKH.png" v-else @click="show = true" class="show">
</div>
<div style="background-color: red;position: relative;">
<img src="/static/login/DL.png" class="btn" alt="" @click="submit">
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.login-box {
width: 100vw;
height: 100vh;
background-image: url('/static/login/bg.png');
background-size: 100% 100%;
overflow: hidden;
}
.form {
width: 35vw;
height: 45vh;
position: absolute;
top: 25vh;
right: 10vw;
box-sizing: border-box;
background: url("/static/login/DLBG.png");
background-size: 100% 100%;
.content {
position: absolute;
top: 13vh;
// background-color: red;
left: 10vw;
.ipt {
border: 1px solid #194FA3;
padding: 1vh 2vw;
background-color: #123266;
width: 13VW;
outline: none;
-webkit-user-select: auto;
caret-color: #fff;
color: white;
}
input[type="password"]::-ms-reveal {
display: none
}
.btn {
width: 7vw;
cursor: pointer;
// margin: 0 auto;
position: absolute;
background-color: #fff;
left: 50%;
transform: translateX(-50%);
}
.accont-icon {
width: 0.8vw;
position: absolute;
top: 50%;
transform: translateY(-50%);
left: .5vw;
}
.show {
position: absolute;
top: 50%;
transform: translateY(-50%);
right: .5vw;
width: 1vw;
cursor: pointer;
}
}
}
</style>
<script setup>
import { ref, reactive } from "vue"
import { useRouter } from "vue-router";
import { loginAPI } from "@/api.js"
const router = useRouter()
const show = ref(false)
const account = ref('')
const password = ref('')
const isAccount = ref(false)
const isPassword = ref(false)
const submit = () => {
if (!account.value) {
isAccount.value = true;
return
}
else isAccount.value = false;
if (!password.value) {
isPassword.value = true;
return
}
else isPassword.value = false;
router.replace('/')
return
loginAPI({
account: account.value,
password: password.value
}).then(res => {
localStorage.setItem("TOKEN", res.token)
if (res.role_type == 0) {
router.replace('/')
}
else if (res.role_type == 1) {
router.replace('/detail')
}
})
return
// alert(isAccount.value)
}
</script>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,55 @@
// vite.config.js
import { defineConfig } from "file:///D:/books/apps/LiHai/plantScreen/node_modules/vite/dist/node/index.js";
import vue from "file:///D:/books/apps/LiHai/plantScreen/node_modules/@vitejs/plugin-vue/dist/index.mjs";
import path from "path";
import postCssPxToRem from "file:///D:/books/apps/LiHai/plantScreen/node_modules/postcss-pxtorem/index.js";
var __vite_injected_original_dirname = "D:\\books\\apps\\LiHai\\plantScreen";
var vite_config_default = defineConfig({
plugins: [vue()],
server: {
// ← ← ← ← ← ←
host: "0.0.0.0"
// ← 新增内容 ←
},
resolve: {
//别名配置引用src路径下的东西可以通过@如import Layout from '@/layout/index.vue'
alias: {
"@": path.resolve(__vite_injected_original_dirname, "src")
}
},
css: {
postcss: {
plugins: [
postCssPxToRem({
rootValue: 192,
propList: ["*"]
})
]
}
},
optimizeDeps: {
// 开发时 解决这些commonjs包转成esm包
include: [
"@jiaminghi/c-render",
"@jiaminghi/c-render/lib/plugin/util",
"@jiaminghi/charts/lib/util/index",
"@jiaminghi/charts/lib/util",
"@jiaminghi/charts/lib/extend/index",
"@jiaminghi/charts",
"@jiaminghi/color"
]
},
build: {
// 打包时需要另外处理的commonjs规范的包
commonjsOptions: {
include: [
/node_modules/
// 必须包含
]
}
}
});
export {
vite_config_default as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJEOlxcXFxib29rc1xcXFxhcHBzXFxcXExpSGFpXFxcXHBsYW50U2NyZWVuXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCJEOlxcXFxib29rc1xcXFxhcHBzXFxcXExpSGFpXFxcXHBsYW50U2NyZWVuXFxcXHZpdGUuY29uZmlnLmpzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9EOi9ib29rcy9hcHBzL0xpSGFpL3BsYW50U2NyZWVuL3ZpdGUuY29uZmlnLmpzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcclxuaW1wb3J0IHZ1ZSBmcm9tICdAdml0ZWpzL3BsdWdpbi12dWUnXHJcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXHJcbmltcG9ydCBwb3N0Q3NzUHhUb1JlbSBmcm9tICdwb3N0Y3NzLXB4dG9yZW0nXHJcbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyh7XHJcbiAgcGx1Z2luczogW3Z1ZSgpXSxcclxuICBzZXJ2ZXI6IHtcdFx0XHRcdC8vIFx1MjE5MCBcdTIxOTAgXHUyMTkwIFx1MjE5MCBcdTIxOTAgXHUyMTkwXHJcbiAgICBob3N0OiAnMC4wLjAuMCdcdC8vIFx1MjE5MCBcdTY1QjBcdTU4OUVcdTUxODVcdTVCQjkgXHUyMTkwXHJcbiAgfSxcclxuICByZXNvbHZlOiB7XHJcbiAgICAvL1x1NTIyQlx1NTQwRFx1OTE0RFx1N0Y2RVx1RkYwQ1x1NUYxNVx1NzUyOHNyY1x1OERFRlx1NUY4NFx1NEUwQlx1NzY4NFx1NEUxQ1x1ODk3Rlx1NTNFRlx1NEVFNVx1OTAxQVx1OEZDN0BcdTU5ODJcdUZGMUFpbXBvcnQgTGF5b3V0IGZyb20gJ0AvbGF5b3V0L2luZGV4LnZ1ZSdcclxuICAgIGFsaWFzOiB7XHJcbiAgICAgICdAJzogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJ3NyYycpXHJcbiAgICB9LFxyXG4gIH0sXHJcblxyXG4gIGNzczoge1xyXG4gICAgcG9zdGNzczoge1xyXG4gICAgICBwbHVnaW5zOiBbXHJcbiAgICAgICAgcG9zdENzc1B4VG9SZW0oe1xyXG4gICAgICAgICAgcm9vdFZhbHVlOiAxOTIsXHJcbiAgICAgICAgICBwcm9wTGlzdDogWycqJ10sXHJcbiAgICAgICAgfSlcclxuICAgICAgXVxyXG4gICAgfVxyXG4gIH0sXHJcblxyXG4gIG9wdGltaXplRGVwczoge1xyXG4gICAgLy8gXHU1RjAwXHU1M0QxXHU2NUY2IFx1ODlFM1x1NTFCM1x1OEZEOVx1NEU5QmNvbW1vbmpzXHU1MzA1XHU4RjZDXHU2MjEwZXNtXHU1MzA1XHJcbiAgICBpbmNsdWRlOiBbXHJcbiAgICAgIFwiQGppYW1pbmdoaS9jLXJlbmRlclwiLFxyXG4gICAgICBcIkBqaWFtaW5naGkvYy1yZW5kZXIvbGliL3BsdWdpbi91dGlsXCIsXHJcbiAgICAgIFwiQGppYW1pbmdoaS9jaGFydHMvbGliL3V0aWwvaW5kZXhcIixcclxuICAgICAgXCJAamlhbWluZ2hpL2NoYXJ0cy9saWIvdXRpbFwiLFxyXG4gICAgICBcIkBqaWFtaW5naGkvY2hhcnRzL2xpYi9leHRlbmQvaW5kZXhcIixcclxuICAgICAgXCJAamlhbWluZ2hpL2NoYXJ0c1wiLFxyXG4gICAgICBcIkBqaWFtaW5naGkvY29sb3JcIixcclxuICAgIF0sXHJcbiAgfSxcclxuICBidWlsZDoge1xyXG4gICAgLy8gXHU2MjUzXHU1MzA1XHU2NUY2XHU5NzAwXHU4OTgxXHU1M0U2XHU1OTE2XHU1OTA0XHU3NDA2XHU3Njg0Y29tbW9uanNcdTg5QzRcdTgzMDNcdTc2ODRcdTUzMDVcclxuICAgIGNvbW1vbmpzT3B0aW9uczoge1xyXG4gICAgICBpbmNsdWRlOiBbXHJcbiAgICAgICAgL25vZGVfbW9kdWxlcy8sIC8vIFx1NUZDNVx1OTg3Qlx1NTMwNVx1NTQyQlxyXG4gICAgICBdLFxyXG4gICAgfSxcclxuICB9XHJcblxyXG5cclxufSlcclxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUF5UixTQUFTLG9CQUFvQjtBQUN0VCxPQUFPLFNBQVM7QUFDaEIsT0FBTyxVQUFVO0FBQ2pCLE9BQU8sb0JBQW9CO0FBSDNCLElBQU0sbUNBQW1DO0FBSXpDLElBQU8sc0JBQVEsYUFBYTtBQUFBLEVBQzFCLFNBQVMsQ0FBQyxJQUFJLENBQUM7QUFBQSxFQUNmLFFBQVE7QUFBQTtBQUFBLElBQ04sTUFBTTtBQUFBO0FBQUEsRUFDUjtBQUFBLEVBQ0EsU0FBUztBQUFBO0FBQUEsSUFFUCxPQUFPO0FBQUEsTUFDTCxLQUFLLEtBQUssUUFBUSxrQ0FBVyxLQUFLO0FBQUEsSUFDcEM7QUFBQSxFQUNGO0FBQUEsRUFFQSxLQUFLO0FBQUEsSUFDSCxTQUFTO0FBQUEsTUFDUCxTQUFTO0FBQUEsUUFDUCxlQUFlO0FBQUEsVUFDYixXQUFXO0FBQUEsVUFDWCxVQUFVLENBQUMsR0FBRztBQUFBLFFBQ2hCLENBQUM7QUFBQSxNQUNIO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFBQSxFQUVBLGNBQWM7QUFBQTtBQUFBLElBRVosU0FBUztBQUFBLE1BQ1A7QUFBQSxNQUNBO0FBQUEsTUFDQTtBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsTUFDQTtBQUFBLE1BQ0E7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUFBLEVBQ0EsT0FBTztBQUFBO0FBQUEsSUFFTCxpQkFBaUI7QUFBQSxNQUNmLFNBQVM7QUFBQSxRQUNQO0FBQUE7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFHRixDQUFDOyIsCiAgIm5hbWVzIjogW10KfQo=

1308
yarn.lock

File diff suppressed because it is too large Load Diff