Commit 64b36e18 authored by honghuiliu's avatar honghuiliu 💬

Merge remote-tracking branch 'origin/master'

parents 940bbe80 4f3dac54
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -8,6 +8,10 @@
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<script src="./echarts.min.js">
</script>
<script src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=fklOeUwr7Y1amxhGFZL8lvE6QvIKpGNi&callback=initialize">
</script>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
......
......@@ -36,4 +36,5 @@
<glyph unicode="&#xe91a;" glyph-name="27" d="M0.030 448.294l416.786 416.786 77.706-77.706-416.786-416.786-77.706 77.706zM77.726 526.001l416.786-416.786-77.706-77.706-416.786 416.786 77.706 77.706zM153.7 494.854h868.951v-109.893h-868.951v109.893z" />
<glyph unicode="&#xe91b;" glyph-name="28" d="M1022.667 448.335l-416.786-416.786-77.706 77.706 416.786 416.786 77.706-77.706zM944.971 370.618l-416.786 416.786 77.706 77.706 416.786-416.786-77.706-77.706zM868.951 401.745h-868.951v109.893h868.951v-109.893z" />
<glyph unicode="&#xe91c;" glyph-name="29" horiz-adv-x="835" d="M417.31-64.008l-417.336 417.336 77.808 77.808 417.336-417.336-77.808-77.808zM339.501 13.801l417.336 417.336 77.808-77.808-417.336-417.336-77.808 77.808zM370.727 89.903v870.097h110.038v-870.097h-110.038z" />
<glyph unicode="&#xe91d;" glyph-name="30" d="M511.959 960c-282.712-0.046-511.878-229.241-511.878-511.959 0-282.747 229.212-511.959 511.959-511.959s511.959 229.212 511.959 511.959v0c-0.046 282.757-229.277 511.959-512.041 511.959v0zM511.959 799.376c108.073 0 195.684-87.611 195.684-195.684s-87.611-195.684-195.684-195.684c-108.073 0-195.684 87.611-195.684 195.684v0c0 108.073 87.611 195.684 195.684 195.684v0zM511.959 56.509c-0.016 0-0.035 0-0.054 0-123.032 0-232.755 56.985-304.214 146l-0.592 0.763c72.128 89.679 181.849 146.585 304.86 146.585s232.732-56.906 304.272-145.829l0.588-0.756c-72.021-89.777-181.719-146.763-304.728-146.763-0.046 0-0.093 0-0.139 0h0.007z" />
</font></defs></svg>
\ No newline at end of file
@font-face {
font-family: 'icomoon';
src: url('fonts/icomoon.eot?e6yl7u');
src: url('fonts/icomoon.eot?e6yl7u#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?e6yl7u') format('truetype'),
url('fonts/icomoon.woff?e6yl7u') format('woff'),
url('fonts/icomoon.svg?e6yl7u#icomoon') format('svg');
src: url('fonts/icomoon.eot?ecryv7');
src: url('fonts/icomoon.eot?ecryv7#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?ecryv7') format('truetype'),
url('fonts/icomoon.woff?ecryv7') format('woff'),
url('fonts/icomoon.svg?ecryv7#icomoon') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
......@@ -112,3 +112,6 @@
.icon-29:before {
content: "\e91c";
}
.icon-30:before {
content: "\e91d";
}
......@@ -3,12 +3,19 @@ import App from './App.vue'
import router from './router'
import { store } from '@/store'
import ElementPlus from 'element-plus'
import zhCn from 'element-plus/dist/locale/zh-cn'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import 'element-plus/dist/index.css'
import vue3PhotoPreview from 'vue3-photo-preview';
import 'vue3-photo-preview/dist/index.css';
const app = createApp(App);
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.use(vue3PhotoPreview);
app.use(store);
app.use(ElementPlus);
app.use(ElementPlus, {
locale: zhCn
});
app.use(router);
app.mount('#app');
......@@ -8,10 +8,7 @@ export const useStore = defineStore('app',{
},
info:{
username:'银河环卫工',
area:{
areaName:'青山湖街道'
}
username:'admin'
},
tabs:[
{
......
import axios from 'axios'
import { ref } from 'vue'
const weatherInfo = ref('');
const amapKey = '89e4bcbcfe9cbe7560782e22719d31a6';
export const useWeatherInfo = () => {
ip();
return weatherInfo
};
export const ip = async() => {
// key换成你自己的 https://console.amap.com/dev/index
if (amapKey === '') {
return false
}
const res = await axios.get('https://restapi.amap.com/v3/ip?key=' + amapKey)
if (res.data.adcode) {
getWeather(res.data.adcode)
}
};
const getWeather = async(code) => {
const response = await axios.get('https://restapi.amap.com/v3/weather/weatherInfo?key=' + amapKey + '&extensions=base&city=' + code)
if (response.data.status === '1') {
const s = response.data.lives[0];
// weatherInfo.value = s.city + ' 天气:' + s.weather + ' 温度:' + s.temperature + '摄氏度 风向:' + s.winddirection + ' 风力:' + s.windpower + '级 空气湿度:' + s.humidity
weatherInfo.value = s.weather
}
};
<template>
<div class="home">
<div class="top">
<div class="left">
<span class="time">{{time.split(' ')[0]}}</span>
<span class="date">{{time.split(' ')[1]}}</span>
</div>
<div class="right">
<div class="weather">
<img class="weather-logo" :src="weatherChange(weather)" alt="">
<span class="weather-text" >{{weather}}</span>
</div>
<div class="user">
<p class="icon-30 user-logo"></p>
<p class="user-name">{{user.username}}</p>
</div>
</div>
</div>
<div class="bottom">
<div class="body">
<div id="container"></div>
</div>
<div class="logo">@浙江丹靓环境工程有限公司</div>
<transition name="el-zoom-in-bottom">
<site-detail v-model="show" v-if="show" :site_id="site_id"></site-detail>
</transition>
</div>
</template>
<script>
import {reactive,toRefs,defineComponent,onMounted,computed} from 'vue'
import {reactive,toRefs,defineComponent,defineAsyncComponent,onMounted,computed,nextTick} from 'vue'
import {useRouter} from "vue-router"
import {ElMessage} from "element-plus"
import api from "@/api/methods/index"
import myPublic from "@/utils/public"
import {useStore} from '@/store/modules/app';
import { useWeatherInfo } from '@/utils/weather.js'
export default defineComponent({
name: "home",
setup(props, ctx) {
const router = useRouter();
const store = useStore();
const weather = useWeatherInfo();
const state = reactive({
count:100,
now:myPublic.dateFormat.format(Date.now(), 'YYYY-MM-DD'),
list:[]
map:null,
timer:null,
show:false,
site_id:'',
time:myPublic.dateFormat.format(Date.now(), 'HH:mm:ss YYYY年MM月DD日'),
list:[
{
longitude:119.779647,
latitude:30.24369,
name:'青山湖国家森林公园',
address:'浙江省杭州市临安区老圣园路北',
type:1
},
{
longitude:119.821796,
latitude:30.254114,
name:'青山湖街道',
address:'浙江省杭州市临安区',
type:1
},
{
longitude:119.790127,
latitude:30.255317,
name:'灵山',
address:'浙江省杭州市临安区',
type:2
},
{
longitude:119.852565,
latitude:30.2528,
name:'青山湖互通',
address:'浙江省杭州市临安区',
type:1
},
{
longitude:119.823904,
latitude:30.24808,
name:'青山中学',
address:'浙江省杭州市临安区',
type:1
},
]
});
const user = computed(()=>{
return store.info;
});
function initMap(){
state.map = new BMapGL.Map("container");
const point = new BMapGL.Point(119.779647,30.24369);
state.map.centerAndZoom(point, 15);
state.map.enableScrollWheelZoom(true); // 开启鼠标滚轮缩放
state.map.setMapStyleV2({
styleId: '4cb2a842cb0d5506df9020a9afc02a39'
});
getList();
}
function getList() {
for (let item of state.list) {
const marker = new BMapGL.Point(item.longitude, item.latitude);
mapShow(marker, item, function (i) {
});
}
}
function mapShow(coordinate, item, callBack) {
const now = Date.now();
let str = `<img src="${require("@/assets/img/e.png")}" />`;
str += `<p style="font-weight: 700">${item.name}${typeChange(item.type)}</p>`;
str += `<p>位置:${item.address}</p>`;
str += `<p id="${now}" style="color: #3396fb;cursor: pointer" onclick="">查看详情<span class="icon-4"></span></p>`;
const url = require(`@/assets/img/type-${item.type}.png`);
let myIcon = new BMapGL.Icon(url, new BMapGL.Size(51, 76), {
// 指定定位位置。
// 当标注显示在地图上时,其所指向的地理位置距离图标左上
// 角各偏移10像素和25像素。您可以看到在本例中该位置即是
// 图标中央下端的尖角位置。
anchor: new BMapGL.Size(25, 76),
// 设置图片偏移。
// 当您需要从一幅较大的图片中截取某部分作为标注图标时,您
// 需要指定大图的偏移位置,此做法与css sprites技术类似。
// imageOffset: new BMap.Size(0, 0 - 81) // 设置图片偏移
});
let marker = new BMapGL.Marker(coordinate, {icon: myIcon});
state.map.addOverlay(marker); // 将标注添加到地图中
const infoOpts = {
width : 235, // 信息窗口宽度
height: 210, // 信息窗口高度
title : '' , // 信息窗口标题
message:"",
offset:new BMapGL.Size(0, -50)
};
const infoWindow = new BMapGL.InfoWindow(str, infoOpts); // 创建信息窗口对象
marker.addEventListener("click", function(){
state.map.openInfoWindow(infoWindow, coordinate); //开启信息窗口
});
infoWindow.addEventListener("open", function(e){
//开启信息窗口
document.getElementById(now).addEventListener("click", ()=>seeDetail(item));
});
infoWindow.addEventListener("close", function(e){
//开启信息窗口
document.getElementById(now).removeEventListener("click", ()=>seeDetail(item));
});
callBack(marker);
}
function typeChange(type=1){
switch (type) {
case 1:
return `<span style="display: inline-flex;line-height:20px;color:#fff;background-color: #fb6104;border-radius: 16px;padding:0 10px;margin-left:10px;font-weight: normal;font-size: 12px">有动力</span>`;
case 2:
return `<span style="display: inline-flex;line-height:20px;color:#fff;background-color: #c7ab97;border-radius: 16px;padding:0 10px;margin-left:10px;font-weight: normal;font-size: 12px">无动力</span>`;
}
}
function weatherChange(w) {
if (w.indexOf('晴')>=0) {
return require('@/assets/img/晴.png')
}
if (w.indexOf('多云')>=0) {
return require('@/assets/img/多云.png')
}
if (w.indexOf('雪')>=0) {
return require('@/assets/img/雪.png')
}
if (w.indexOf('雨')>=0) {
return require('@/assets/img/雨.png')
}
if (w.indexOf('阴')>=0) {
return require('@/assets/img/阴.png')
}
}
function seeDetail(item){
state.show = true;
state.site_id = item.site_id||'12';
}
onMounted(()=>{
nextTick(()=>{
initMap();
state.timer = setInterval(() => {
state.time = myPublic.dateFormat.format(Date.now(), 'HH:mm:ss YYYY年MM月DD日');
}, 1000)
});
});
return {
...toRefs(state),
weather,
weatherChange,
user
};
},
beforeRouteLeave(to,from,next){
clearInterval(this.timer);
next();
},
components:{
siteDetail:defineAsyncComponent(()=>import("@/views/site-detail.vue"))
}
})
</script>
<style scoped lang="less">
.home{
position: relative;
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
.top{
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.card{
flex-shrink: 0;
display: flex;
justify-content: space-around;
background-color: #fff;
border-radius: .08rem;
box-shadow: 0 0 .2rem rgba(0,0,0,.3);
margin: .6rem .25rem 0 .25rem;
padding: .2rem .1rem;
.card-one{
position: relative;
flex: 1;
position: absolute;
top: 0;
left: 0;
width:100%;
height: 120px;
background: url('../assets/img/top.png') no-repeat center/cover;
z-index: 10;
display: flex;
justify-content: space-between;
.left{
display: inline-flex;
align-items: center;
flex-direction: column;
.box{
position: relative;
display: flex;
justify-content: center;
.badge{
position: absolute;
top: -5%;
left: 85%;
height: 80px;
color: #fff;
background-color: #ff5048;
padding:0 .01rem;
font-size: .14rem;
line-height: .24rem;
height:.24rem;
z-index: 1;
&:before{
content:'';
position: absolute;
top: 0;
left: -.11rem;
width: .12rem;
height: .24rem;
border-top-left-radius: 2em;
border-bottom-left-radius: 2em;
background-color: #ff5048;
z-index: 0;
}
&:after{
content:'';
position: absolute;
top: 0;
right: -.11rem;
width: .12rem;
height: .24rem;
border-top-right-radius: 2em;
border-bottom-right-radius: 2em;
background-color: #ff5048;
z-index: 0;
margin-left: 2%;
.time{
font-size: 24px;
margin-right: 15px;
}
}
.card-img{
width: .6rem;
height: .6rem;
.right{
display: inline-flex;
align-items: center;
height: 80px;
color: #fff;
margin-right: 2%;
.weather{
display: inline-flex;
align-items: center;
color: #fff;
.weather-logo{
margin-right: 10px;
}
.weather-text{
font-size: 16px;
}
.card-name{
margin-top: .1rem;
font-size: .16rem;
margin-right: 20px;
}
.user{
text-align: center;
.user-logo{
font-size: 18px;
}
}
.calendar{
flex-shrink: 0;
}
.list{
flex: 1;
background-color: #f2f5f7;
overflow-y: auto;
padding: .1rem .1rem 0 .1rem;
.list-one{
display: flex;
flex-direction: column;
border-radius: .04rem;
background-color: #fff;
margin-bottom:.1rem;
padding: .1rem;
.list-title{
width: 100%;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
color: #333;
margin-bottom:.1rem;
font-size: .18rem;
font-weight: bolder;
}
.list-bottom{
display: flex;
align-items: center;
overflow: hidden;
.icon{
width: fit-content;
display: flex;
color: #b2b2b2;
margin-right: .1rem;
overflow: hidden;
span{
.body{
flex: 1;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
color: #666666;
margin-left: .05rem;
font-size: .14rem;
}
}
}
&:active{
opacity: .8;
}
}
#container{
width: 100%;
height: 100%;
}
}
.bottom{
flex-shrink: 0;
height: .5rem;
.logo{
position: absolute;
bottom: 22px;
right: 24px;
color: #fff;
z-index: 10;
}
}
</style>
<template>
<div class="order-detail">
<div class="order-title">
<span>工单详情</span>
<el-icon class="close" :size="20" color="#333" @click="closeBox"><Close /></el-icon>
</div>
<div class="order-body">
<div class="row-one">
<span class="row-name">工单标题</span>
<span class="row-content">{{detail.title}}</span>
</div>
<div class="row-one">
<span class="row-name">巡检公厕单位</span>
<span class="row-content">{{detail.name}}</span>
</div>
<div class="row-one">
<span class="row-name">巡检类型</span>
<span class="row-content">{{typeChange(detail.type).text}}</span>
</div>
<div class="row-one baseline">
<span class="row-name">巡检内容</span>
<div class="row-content">
<template v-for="item in detail.content">
<div class="check-one">
<el-checkbox v-model="item.check" :label="item.title" size="large" :disabled="true"/>
</div>
</template>
</div>
</div>
<div class="row-one">
<span class="row-name">附件</span>
<div class="row-content">
<photo-provider>
<photo-consumer v-for="(url,index) in fileList" :key="url" :src="url">
<p v-if="url" class="img-one view-box" :style="`background-image:url('${url}')`">
</p>
</photo-consumer>
</photo-provider>
</div>
</div>
<div class="row-one">
<span class="row-name">异常描述</span>
<span class="row-content">{{detail.description}}</span>
</div>
<div class="row-one">
<span class="row-name">站点巡检人</span>
<span class="row-content">{{detail.staff}}</span>
</div>
<div class="row-one">
<span class="row-name">提交时间</span>
<span class="row-content">{{detail.create_time}}</span>
</div>
</div>
</div>
</template>
<script>
// @ is an alias to /src
import {reactive, toRefs, onMounted} from "vue"
import {ElMessage} from "element-plus"
import {Close} from "@element-plus/icons-vue"
import api from "@/api/methods/index"
export default {
name: 'order-detail',
emits: ['update:modelValue'],
props: {
modelValue: {
type: Boolean,
default: false
},
order_id: {
type: String,
default: ''
},
},
setup(props, {emit}) {
const state = reactive({
detail: {
title:'2022年6月22日公厕巡检工作',
type:1,
name:'三号路公共厕所【GC-004】',
staff:'罗小飞',
content:[
{
title:'检查格栅井',
check:true
},
{
title:'格栅井照片',
check:false
},
{
title:'检查调节池',
check:true
},
{
title:'检查厌氧池',
check:false
},
{
title:'检查缺氧池',
check:true
},
{
title:'检查好氧池',
check:true
},
{
title:'检查清水池',
check:true
},
{
title:'格栅污泥池',
check:false
},
{
title:'检查出水井',
check:true
},
{
title:'清水池照片',
check:true
},
{
title:'检查各井口及井盖',
check:false
},
{
title:'检查水泵系统',
check:true
},
{
title:'检查风机系统',
check:false
},
{
title:'检查加药系统',
check:true
},
{
title:'检查监控系统',
check:true
},
{
title:'检查设备房',
check:false
},
],
description:'泵站清淤很多、泵站清淤很多、泵站清淤很多、泵站清淤很多、泵站清淤很多、泵站清淤很多、\n' +
'泵站清淤很多。',
create_time:'2022-06-22 10:00'
},
typeList:[
{
name:'液位',
prop:'a1',
value:0,
unit:'m',
color:'#09a8ae',
create_time:'2022-09-01 10:00'
},
{
name:'调解池流量',
prop:'a2',
value:0,
unit:'m^3/h',
color:'#ff6b6b',
create_time:'2022-09-01 10:00'
},
{
name:'出水池流量',
prop:'a3',
value:0,
unit:'m^3/h',
color:'#946fd0',
create_time:'2022-09-01 10:00'
},
{
name:'厌氧池PH值',
prop:'a4',
value:0,
unit:'',
color:'#3396fb',
create_time:'2022-09-01 10:00'
},
{
name:'好氧池PH值',
prop:'a5',
value:0,
unit:'',
color:'#28ae09',
create_time:'2022-09-01 10:00'
},
{
name:'出水池PH值',
prop:'a6',
value:0,
unit:'',
color:'#ffc019',
create_time:'2022-09-01 10:00'
},
{
name:'好氧池DO值',
prop:'a7',
value:0,
unit:'mg/l',
color:'#f8893f',
create_time:'2022-09-01 10:00'
},
{
name:'MBR池DO值',
prop:'a8',
value:0,
unit:'mg/l',
color:'#eb509d',
create_time:'2022-09-01 10:00'
}
],
fileList:[
"https://wensi-zhanlang.oss-cn-hangzhou.aliyuncs.com/volunteer/2022-08-24/1661300843457_Wc5B4kFjCb.jpeg",
"https://wensi-zhanlang.oss-cn-hangzhou.aliyuncs.com/volunteer/2022-06-30/1656575865931_zwwirj2Kix.webp",
"https://wensi-zhanlang.oss-cn-hangzhou.aliyuncs.com/volunteer/2022-06-30/1656574020995_SnDzKQYTQR.webp"
]
});
function typeChange(type=1) {
switch (type) {
case 1:
return {text:'一体化设备',color:'#3396fb'};
case 2:
return {text:'玻璃钢',color:'#f78131'};
default:
return {text:'...',color:'#f78131'};
}
}
function getDetail(){
}
function closeBox(){
emit('update:modelValue',false)
}
onMounted(async () => {
getDetail();
});
return {
...toRefs(state),
Close,
closeBox,
typeChange
}
},
components:{
}
}
</script>
<style lang="less">
.order-detail {
position: absolute;
right: 0;
width: 800px;
height: 100%;
-webkit-user-select: none;
background-color: #fff;
display: flex;
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
box-shadow: 0 0 20px rgba(0,0,0,.2);
flex-direction: column;
overflow: hidden;
z-index: 12;
.order-title{
flex-shrink: 0;
display: flex;
align-items: center;
height: 60px;
justify-content: space-between;
padding: 0 20px 0 30px;
border-bottom: 1px solid #efefef;
.close{
cursor: pointer;
&:hover{
opacity: .8;
}
}
}
.order-body{
flex: 1;
padding: 10px 20px 10px 30px;
overflow-y: auto;
.row-one{
flex-shrink: 0;
display: flex;
align-items: center;
padding: 10px 0;
.row-name{
flex-shrink: 0;
width: 100px;
color: #666;
margin-right: 15px;
}
.row-content{
flex: 1;
min-height: 30px;
background-color: #f8f8f8;
border-radius: 6px;
color: #333;
display: flex;
flex-wrap: wrap;
align-items: center;
padding: 10px 20px;
.check-one{
width: 33.3%;
padding: 5px 0;
}
.img-one{
position: relative;
width:60px;
height:60px;
border-radius: 4px;
border:1px solid #f7f8fa;
margin-right: 10px;
margin-bottom:5px;
background-repeat:no-repeat;
background-size:cover;
background-position:center;
cursor: pointer;
}
}
}
.baseline{
align-items: baseline;
.row-content{
background-color: #fff;
}
}
}
}
</style>
<template>
<div class="site-detail">
<div class="detail-header">
<span class="detail-title">公厕点位详情【{{detail.name}}</span>
<span class="btn" @click="close">退出</span>
</div>
<div class="tabs">
<span class="tab-one" :class="{selected:tab==item.value}" v-for="(item,index) in tabs.filter(one=>one.show)" :key="index"
@click="tabActive(item)">{{item.name}}</span>
</div>
<div class="detail-body">
<div class="body-one base" v-if="tab=='base'">
<div class="poster">
<div class="blur-mask" :style="`background-image:url('${detail.poster[detail.index]}')`"></div>
<div class="banner">
<el-carousel :interval="5000" arrow="never" style="height: 480px;"
@change="(val)=>{detail.index=val}">
<el-carousel-item style="height: 480px;" v-for="item in detail.poster" :key="item">
<div class="banner-bg" :style="`background-image:url('${item}')`"></div>
</el-carousel-item>
</el-carousel>
</div>
</div>
<div class="info">
<p class="info-title">公厕点位基本信息</p>
<div class="info-content">
<div class="table">
<div class="table-left">
<div class="table-row">
<div class="table-header-cell cell">
点位名称
</div>
<div class="table-content-cell cell">
</div>
</div>
<div class="table-row">
<div class="table-header-cell cell">
公厕类型
</div>
<div class="table-content-cell cell">
</div>
</div>
<div class="table-row">
<div class="table-header-cell cell">
管理人员
</div>
<div class="table-content-cell cell">
</div>
</div>
<div class="table-row">
<div class="table-header-cell cell">
联系电话
</div>
<div class="table-content-cell cell">
</div>
</div>
<div class="table-row">
<div class="table-header-cell cell">
地址
</div>
<div class="table-content-cell cell">
</div>
</div>
</div>
<div class="table-right">
<div class="table-row">
<div class="table-header-cell cell">
液位
</div>
<div class="table-content-cell cell">
<div class="chart" ref="chart"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="body-one history" v-else-if="tab=='history'">
<div class="filter">
<div class="filter-one">
<p class="filter-name">类型筛选</p>
<div class="filter-content">
<el-select v-model="filter.type" class="m-2" placeholder="请选择类型" @change="()=>getList()">
<el-option
v-for="item in [{name:'全部类型',value:'',prop:''},...typeList]"
:key="item.prop"
:label="item.name"
:value="item.prop"
/>
</el-select>
</div>
</div>
<div class="filter-one">
<p class="filter-name">时间筛选</p>
<div class="filter-content">
<el-date-picker
v-model="filter.time"
type="datetimerange"
format="YYYY-MM-DD HH:mm"
value-format="YYYY-MM-DD HH:mm"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
:teleported="false"
:editable="true"
@change="()=>getList()"
/>
</div>
</div>
</div>
<div class="history-table">
<div class="table-header">
<div class="row">
<div class="cell flex_2">数据类型</div>
<div class="cell flex_3">数据结果</div>
<div class="cell">检测时间</div>
</div>
</div>
<div class="table-body">
<div class="row" v-for="(item,index) in typeList" :key="index">
<div class="cell flex_2">
<span class="point" :style="`background-color:${item.color}`"></span>
<span :style="`color:${item.color}`">{{item.name}}</span>
</div>
<div class="cell flex_3">{{item.value}} {{item.unit}}</div>
<div class="cell">{{item.create_time}}</div>
</div>
</div>
</div>
</div>
<div class="body-one monitor" v-else-if="tab=='monitor'">
</div>
<div class="body-one process" v-else-if="tab=='process'">
<div class="process-box">
<div class="process-table">
<div class="table-header">
<div class="row">
<div class="cell">数据类型</div>
<div class="cell">数据结果</div>
</div>
</div>
<div class="table-body">
<div class="row" v-for="(item,index) in typeList.slice(0,4)" :key="index">
<div class="cell">
<span class="value">{{item.name}}</span>
</div>
<div class="cell">{{item.value}} {{item.unit}}</div>
</div>
</div>
</div>
<div class="process-table">
<div class="table-header">
<div class="row">
<div class="cell flex_2">数据类型</div>
<div class="cell flex_3">数据结果</div>
</div>
</div>
<div class="table-body">
<div class="row" v-for="(item,index) in typeList.slice(4)" :key="index">
<div class="cell flex_2">
<span class="value">{{item.name}}</span>
</div>
<div class="cell flex_3">{{item.value}} {{item.unit}}</div>
</div>
</div>
</div>
</div>
<video class="video" src="~@/assets/process.mp4" autoplay loop></video>
</div>
<div class="body-one order" v-else-if="tab=='order'">
<div class="filter">
<div class="filter-one">
<p class="filter-name">类型筛选</p>
<div class="filter-content">
<el-select v-model="filter.type" class="m-2" placeholder="请选择类型" @change="()=>getList()">
<el-option
v-for="item in [{name:'全部类型',value:'',prop:''},...typeList]"
:key="item.prop"
:label="item.name"
:value="item.prop"
/>
</el-select>
</div>
</div>
<div class="filter-one">
<p class="filter-name">时间筛选</p>
<div class="filter-content">
<el-date-picker
v-model="filter.time"
type="datetimerange"
format="YYYY-MM-DD HH:mm"
value-format="YYYY-MM-DD HH:mm"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
:teleported="false"
:editable="true"
@change="()=>getList()"
/>
</div>
</div>
</div>
<div class="order-table">
<div class="table-header">
<div class="row">
<div class="cell">序号</div>
<div class="cell flex_2">巡检标题</div>
<div class="cell flex_2">巡检类型</div>
<div class="cell flex_2">提交人员</div>
<div class="cell flex_2">提交时间</div>
<div class="cell">操作</div>
</div>
</div>
<div class="table-body">
<div class="row" v-for="(item,index) in list.data" :key="index">
<div class="cell">{{index+1}}</div>
<div class="cell flex_2">{{item.title}}</div>
<div class="cell flex_2">
<span class="type" :style="{backgroundColor:typeChange(item.type).color}">{{typeChange(item.type).text}}</span>
</div>
<div class="cell flex_2">{{item.staff}}</div>
<div class="cell flex_2">{{item.create_time}}</div>
<div class="cell">
<span class="opt" @click="seeDetail(item)">查看</span>
</div>
</div>
</div>
<div class="pagination">
<el-pagination
v-model:currentPage="list.page"
v-model:page-size="list.pageSize"
:page-sizes="[10, 15, 20, 25]"
:small="small"
:disabled="disabled"
:background="background"
layout="sizes, prev, pager, next"
:total="list.total"
@size-change="()=>getOrderList(list.page)"
@current-change="()=>getOrderList()"
/>
</div>
</div>
</div>
</div>
<transition name="el-zoom-in-bottom">
<order-detail v-model="show" v-if="show" :order_id="order_id"></order-detail>
</transition>
</div>
</template>
<script>
// @ is an alias to /src
import {ref,reactive, toRefs, onMounted,nextTick,defineAsyncComponent} from "vue"
import {ElMessage} from "element-plus"
import api from "@/api/methods/index"
export default {
name: 'site-detail',
emits: ['update:modelValue'],
props: {
modelValue: {
type: Boolean,
default: false
},
site_id: {
type: String,
default: ''
},
},
setup(props, {emit}) {
const state = reactive({
show:false,
order_id:'',
detail: {
name: '三号路公共厕所GC-004',
poster: [
require("@/assets/img/banner-1.png"),
require("@/assets/img/banner-1.png"),
require("@/assets/img/banner-1.png"),
require("@/assets/img/banner-1.png"),
require("@/assets/img/banner-1.png"),
require("@/assets/img/banner-1.png"),
],
index: 0,
yewei:0.7,
type:1
},
tabs: [
{
name: '点位基本信息',
value: 'base',
show:true
},
{
name: '历史数据',
value: 'history',
show:true
},
{
name: '监控画面',
value: 'monitor',
show:true
},
{
name: '工艺流程',
value: 'process',
show:false
},
{
name: '巡检工单',
value: 'order',
show:true
},
],
tab: 'base',
myChart:null,
filter:{
type:'',
time:['','']
},
typeList:[
{
name:'液位',
prop:'a1',
value:0,
unit:'m',
color:'#09a8ae',
create_time:'2022-09-01 10:00'
},
{
name:'调解池流量',
prop:'a2',
value:0,
unit:'m^3/h',
color:'#ff6b6b',
create_time:'2022-09-01 10:00'
},
{
name:'出水池流量',
prop:'a3',
value:0,
unit:'m^3/h',
color:'#946fd0',
create_time:'2022-09-01 10:00'
},
{
name:'厌氧池PH值',
prop:'a4',
value:0,
unit:'',
color:'#3396fb',
create_time:'2022-09-01 10:00'
},
{
name:'好氧池PH值',
prop:'a5',
value:0,
unit:'',
color:'#28ae09',
create_time:'2022-09-01 10:00'
},
{
name:'出水池PH值',
prop:'a6',
value:0,
unit:'',
color:'#ffc019',
create_time:'2022-09-01 10:00'
},
{
name:'好氧池DO值',
prop:'a7',
value:0,
unit:'mg/l',
color:'#f8893f',
create_time:'2022-09-01 10:00'
},
{
name:'MBR池DO值',
prop:'a8',
value:0,
unit:'mg/l',
color:'#eb509d',
create_time:'2022-09-01 10:00'
}
],
list:{
page:1,
pageSize:15,
total:20,
data:[
{
title:'2022年6月22日公厕巡检工作',
type:1,
name:'三号路公共厕所【GC-004】',
staff:'罗小飞',
create_time:'2022-06-22 10:00'
},
{
title:'2022年6月21日公厕巡检工作',
type:1,
name:'三号路公共厕所【GC-004】',
staff:'罗小飞',
create_time:'2022-06-21 10:00'
},
{
title:'2022年6月20日公厕巡检工作',
type:1,
name:'三号路公共厕所【GC-004】',
staff:'罗小飞',
create_time:'2022-06-20 10:00'
},
{
title:'2022年6月19日公厕巡检工作',
type:2,
name:'三号路公共厕所【GC-004】',
staff:'罗小飞',
create_time:'2022-06-19 10:00'
},
{
title:'2022年6月18日公厕巡检工作',
type:1,
name:'三号路公共厕所【GC-004】',
staff:'罗小飞',
create_time:'2022-06-18 10:00'
},
{
title:'2022年6月17日公厕巡检工作',
type:1,
name:'三号路公共厕所【GC-004】',
staff:'罗小飞',
create_time:'2022-06-17 10:00'
},
{
title:'2022年6月16日公厕巡检工作',
type:2,
name:'三号路公共厕所【GC-004】',
staff:'罗小飞',
create_time:'2022-06-16 10:00'
},
{
title:'2022年6月14日公厕巡检工作',
type:1,
name:'三号路公共厕所【GC-004】',
staff:'罗小飞',
create_time:'2022-06-14 10:00'
},
{
title:'2022年6月13日公厕巡检工作',
type:1,
name:'三号路公共厕所【GC-004】',
staff:'罗小飞',
create_time:'2022-06-13 10:00'
},
]
}
});
const chart = ref(null);
function getDetail() {
if(state.detail.type==1){
state.tabs.find(one=>one.value=='process').show = true;
}
}
function typeChange(type=1) {
switch (type) {
case 1:
return {text:'一体化设备',color:'#3396fb'};
case 2:
return {text:'玻璃钢',color:'#f78131'};
default:
return {text:'...',color:'#f78131'};
}
}
function close() {
emit('update:modelValue', false);
}
function tabActive(item) {
if (state.tab != item.value) {
state.tab = item.value;
if(item.value=='history'){
getList();
}
if(item.value=='order'){
getOrderList();
}
}
}
function initGauge(){
state.myChart = echarts.init(chart.value);
let option = {
series: [
{
type: 'gauge',
progress: {
show: true,
width: 18,
itemStyle:{
color:'#3396fb',
}
},
pointer: {
icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z',
width: 4,
length: '60%',
offsetCenter: [0, '8%']
},
itemStyle:{
color:'#3396fb'
},
axisLine: {
lineStyle: {
width: 18
}
},
axisTick: {
show: true,
distance: 0,
},
splitLine: {
distance: 5,
length: 8,
lineStyle: {
width: 1,
color: '#999'
}
},
axisLabel: {
distance: 22,
color: '#999',
fontSize: 12
},
anchor: {
show: true,
showAbove: true,
size: 20,
itemStyle: {
borderWidth: 4,
borderColor: '#3396fb',
color:'#fff',
}
},
title: {
show: false
},
detail: {
valueAnimation: true,
fontSize: 24,
offsetCenter: [0, '70%'],
formatter(p){
return `{a|${p}m}\n{b|液位}`
},
rich: {
a: {
color: '#333',
lineHeight: 20,
fontSize:18
},
b: {
color: '#666',
lineHeight: 20,
fontSize:14
}
}
},
data: [
{
value: state.detail.yewei
}
],
radius:"95%",
startAngle:210,
endAngle:-30,
max:1
}
]
};
state.myChart.setOption(option);
}
function getList(){
}
function getOrderList(page=1){
let p = {
page:page,
pageSize:state.list.pageSize
};
state.list.page = page;
}
function seeDetail(item){
state.order_id = item.order_id;
state.show = true;
}
onMounted(async () => {
getDetail();
await nextTick(()=>{
initGauge();
})
});
return {
...toRefs(state),
chart,
close,
tabActive,
typeChange,
getList,
getOrderList,
seeDetail
}
},
components: {
orderDetail:defineAsyncComponent(()=>import("@/views/order-detail.vue"))
}
}
</script>
<style lang="less">
.site-detail {
position: absolute;
width: 100%;
height: 100%;
-webkit-user-select: none;
background-color: #fff;
display: flex;
flex-direction: column;
overflow: hidden;
z-index: 11;
.detail-header {
flex-shrink: 0;
height: 70px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #2d71e2;
color: #fff;
padding: 0 30px 0 20px;
.detail-title {
font-size: 20px;
}
.btn {
width: 80px;
line-height: 36px;
text-align: center;
background-color: #6c9ef1;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
&:hover {
opacity: .8;
}
}
}
.tabs {
flex-shrink: 0;
padding: 0 40px;
.tab-one {
display: inline-flex;
align-items: center;
height: 70px;
color: #666;
cursor: pointer;
padding: 0 10px;
margin-right: 10px;
&:hover{
position: relative;
color: #3396fb;
&:after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 5px;
background-color: #3396fb;
}
}
}
.selected {
position: relative;
color: #3396fb;
&:after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 5px;
background-color: #3396fb;
}
}
}
.detail-body {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
background-color: #ebedef;
padding: 20px;
.body-one {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
background-color: #fff;
padding: 20px;
border-radius: 6px;
}
.base{
.poster {
flex-shrink: 0;
position: relative;
overflow: hidden;
.banner {
position: relative;
height: 480px;
z-index: 3;
.banner-bg {
display: block;
width: 1140px;
height: 100%;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
margin: 0 auto;
}
}
.blur-mask {
position: absolute;
width: 100%;
display: block;
height: 480px;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
filter: blur(5px);
z-index: 2;
}
}
.info {
flex: 1;
display: flex;
flex-direction: column;
background-color: #fff;
padding-top: 10px;
overflow: hidden;
.info-title {
flex-shrink: 0;
font-weight: bolder;
padding: 15px 0;
}
.info-content{
flex: 1;
overflow-y: auto;
.table {
flex-shrink: 0;
display: flex;
.table-left, .table-right {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
border-top: 1px solid #dfdfdf;
border-left: 1px solid #dfdfdf;
.table-header-cell {
min-width: 120px;
max-width: 180px;
font-weight: bolder;
}
.table-content-cell {
flex: 1;
min-width: 120px;
}
}
.table-right {
border-left: none
}
.table-row {
height: 100%;
display: flex;
overflow: hidden;
&:nth-child(even) {
background-color: #f7f8f8;
}
}
.cell {
display: inline-flex;
align-items: center;
min-height: 45px;
border-right: 1px solid #dfdfdf;
border-bottom: 1px solid #dfdfdf;
padding: 0 14px;
}
.chart{
flex: 1;
height: 100%;
}
}
}
}
}
.history{
padding: 0;
.filter{
flex-shrink: 0;
display: flex;
border-bottom: 1px solid #efefef;
padding: 18px 30px;
.filter-one{
display: inline-flex;
align-items: center;
margin-right: 55px;
.filter-name{
color: #666;
margin-right: 20px;
}
}
}
.history-table{
flex: 1;
display: flex;
flex-direction: column;
padding:20px 20px;
overflow: hidden;
.table-header{
flex-shrink: 0;
width: 100%;
border-radius: 4px;
color: #fff;
background-color: #7d848b;
}
.table-body{
flex: 1;
overflow-y: auto;
}
.row{
height: 60px;
display: flex;
align-items: center;
padding: 0 20px 0 100px;
&:nth-child(even) {
background-color: #f7f8f8;
}
}
.cell{
flex: 1;
display: flex;
align-items: center;
}
.flex_2{
flex: 2;
}
.flex_3{
flex: 3;
}
.point{
width: 6px;
height: 6px;
border-radius: 50%;
margin-right: 10px;
}
}
}
.monitor{
}
.process{
position: relative;
.process-box{
position: relative;
left: 40px;
top: 70px;
display: flex;
width: 720px;
z-index: 2;
}
.process-table{
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
border-left: 1px solid #efefef;
border-top: 1px solid #efefef;
.table-header{
flex-shrink: 0;
width: 100%;
color: #fff;
background-color: #056f2f;
}
.table-body{
flex: 1;
}
.row{
height: 48px;
display: flex;
align-items: center;
&:nth-child(even) {
background-color: #f7f8f8;
}
}
.cell{
height: 100%;
flex: 1;
display: flex;
align-items: center;
border-bottom: 1px solid #efefef;
border-right: 1px solid #efefef;
padding: 0 10px 0 20px;
.value{
font-weight: bolder;
}
}
.flex_2{
flex: 2;
}
.flex_3{
flex: 3;
}
.point{
width: 6px;
height: 6px;
border-radius: 50%;
margin-right: 10px;
}
}
.video{
position: absolute;
left: 20px;
right: 20px;
top: 20px;
bottom: 20px;
object-fit: fill;
z-index: 1;
}
}
.order{
padding: 0;
.filter{
flex-shrink: 0;
display: flex;
border-bottom: 1px solid #efefef;
padding: 18px 30px;
.filter-one{
display: inline-flex;
align-items: center;
margin-right: 55px;
.filter-name{
color: #666;
margin-right: 20px;
}
}
}
.order-table{
flex: 1;
display: flex;
flex-direction: column;
padding:20px 20px;
overflow: hidden;
.table-header{
flex-shrink: 0;
width: 100%;
border-radius: 4px;
color: #fff;
background-color: #7d848b;
}
.table-body{
flex: 1;
overflow-y: auto;
}
.pagination{
margin:0 auto;
}
.row{
height: 60px;
display: flex;
align-items: center;
padding: 0 20px 0 100px;
&:nth-child(even) {
background-color: #f7f8f8;
}
}
.cell{
flex: 1;
display: flex;
align-items: center;
}
.flex_2{
flex: 2;
}
.flex_3{
flex: 3;
}
.point{
width: 6px;
height: 6px;
border-radius: 50%;
margin-right: 10px;
}
.type{
color: #fff;
border-radius: 4px;
padding:5px 5px;
font-size: 12px;
}
.opt{
color: #2c70e2;
cursor: pointer;
&:hover{
opacity: .8;
}
}
}
}
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment