MrShi
11 小时以前 90d0ebde46cb1e5ece1e78fbff5ca72733ea621e
screen/src/views/KeyCabinet.vue
@@ -18,35 +18,35 @@
                            <img src="../assets/images/ic_zongguige@2x.png" />
                            <div class="left_box_one_item_info">
                                <span>总柜格</span>
                                <span>24</span>
                                <span v-if="data">{{data.gridNum}}</span>
                            </div>
                        </div>
                        <div class="left_box_one_item">
                            <img src="../assets/images/ic_zaiwei@2x.png" />
                            <div class="left_box_one_item_info">
                                <span>在位</span>
                                <span>24</span>
                                <span v-if="data">{{data.onlineKeyNum}}</span>
                            </div>
                        </div>
                        <div class="left_box_one_item">
                            <img src="../assets/images/ic_lingyong@2x.png" />
                            <div class="left_box_one_item_info">
                                <span>领用</span>
                                <span>24</span>
                                <span v-if="data">{{data.outKeyNum}}</span>
                            </div>
                        </div>
                        <div class="left_box_one_item">
                            <img src="../assets/images/ic_kongxian@2x.png" />
                            <div class="left_box_one_item_info">
                                <span>空闲</span>
                                <span>24</span>
                                <span v-if="data">{{data.unBindGridNum}}</span>
                            </div>
                        </div>
                        <div class="left_box_one_item">
                            <img src="../assets/images/ic_weibao@2x.png" />
                            <div class="left_box_one_item_info">
                                <span>维保</span>
                                <span>24</span>
                                <span v-if="data">{{data.serviceKeyNum}}</span>
                            </div>
                        </div>
                    </div>
@@ -58,9 +58,9 @@
                                    <div>派车统计</div>
                                </div>
                                <div class="tabs">
                                    <div class="tab active">近7天</div>
                                    <div class="tab" :class="type1 === 0 ? 'active' : ''" @click="clickOneItem(0)">近7天</div>
                                    <div class="separate">&nbsp;|&nbsp;</div>
                                    <div class="tab">近15天</div>
                                    <div class="tab" :class="type1 === 1 ? 'active' : ''" @click="clickOneItem(1)">近15天</div>
                                </div>
                                <img src="@/assets/images/task/title@2x.png" class="bg" alt="" />
                            </div>
@@ -74,9 +74,9 @@
                                    <div>钥匙领取归还统计</div>
                                </div>
                                <div class="tabs">
                                    <div class="tab active">近7天</div>
                                    <div class="tab" :class="type2 === 0 ? 'active' : ''" @click="clickTwoItem(0)">近7天</div>
                                    <div class="separate">&nbsp;|&nbsp;</div>
                                    <div class="tab">近15天</div>
                                    <div class="tab" :class="type2 === 1 ? 'active' : ''" @click="clickTwoItem(1)">近15天</div>
                                </div>
                                <img src="@/assets/images/task/title@2x.png" class="bg" alt="" />
                            </div>
@@ -94,22 +94,50 @@
                                <img src="@/assets/images/ic_title@2x.png" class="icon" alt="" />
                                <div>钥匙取还记录</div>
                            </div>
                            <div class="search">
                                <div class="search-item" @click.stop="show = true">
                                    <div class="search-item-label">状态:</div>
                                    <div class="search-item-select">
                                        <span v-if="form.status === ''">全部</span>
                                        <span v-if="form.status === 0">未归还</span>
                                        <span v-if="form.status === 1">已归还</span>
                                        <span>▼</span>
                                        <div class="search-item-select-list" v-if="show">
                                            <div class="search-item-select-list-item" @click.stop="sele('')">全部</div>
                                            <div class="search-item-select-list-item" @click.stop="sele(0)">未归还</div>
                                            <div class="search-item-select-list-item" @click.stop="sele(1)">已归还</div>
                                        </div>
                                    </div>
                                </div>
                                <div class="search-item">
                                    <div class="search-item-input">
                                        <img src="@/assets/images/ic_search@2x.png" />
                                        <input v-model="form.carCode" type="text" @keypress="Enter" placeholder="搜索车牌号" />
                                    </div>
                                </div>
                            </div>
                            <img src="@/assets/images/task/title@2x.png" class="bg" alt="" />
                        </div>
                        <div class="list_wrap">
                            <div class="header line">
                                <span class="item">合同号</span>
                                <span class="item status">订单状态</span>
                                <span class="item">目的地</span>
                                <span class="item">任务下达时间</span>
                                <span class="item">车牌号</span>
                                <span class="item">领取人</span>
                                <span class="item">归还时间</span>
                                <span class="item">状态</span>
                                <span class="item">备注</span>
                            </div>
                            <div class="one-swiper list">
                                <div class="swiper-wrapper">
                                    <div class="line one-swiper-slide swiper-slide item" v-for="item in 8" :key="item">
                                        <span class="item">contractNumber</span>
                                        <span class="item status">statusDesc</span>
                                        <span class="item">receiveEnterprise</span>
                                        <span class="item">createDate</span>
                                    <div class="line one-swiper-slide swiper-slide item" v-for="(item, i) in data5" :key="i">
                                        <span class="item">{{item.carCode}}</span>
                                        <span class="item">{{item.memberName}}</span>
                                        <span class="item">{{item.returnDate || '-'}}</span>
                                        <span class="item">
                                            <span v-if="item.status === 0" style="color: #FEAF01;">未归还</span>
                                            <span v-else-if="item.status === 1" style="color: #28F0C4;">已归还</span>
                                            <span v-else>-</span>
                                        </span>
                                        <span class="item">{{item.remark || '-'}}</span>
                                    </div>
                                </div>
                            </div>
@@ -140,42 +168,42 @@
                                        <span>钥匙告警分布</span>
                                    </div>
                                    <div class="row-title-right">
                                        <span class="ac">今日</span>
                                        <span :class="type3 === 0 ? 'ac' : ''" @click="clickThreeItem(0)">今日</span>
                                        &nbsp;|&nbsp;
                                        <span>本月</span>
                                        <span :class="type3 === 1 ? 'ac' : ''" @click="clickThreeItem(1)">本月</span>
                                        &nbsp;|&nbsp;
                                        <span>本年</span>
                                        <span :class="type3 === 2 ? 'ac' : ''" @click="clickThreeItem(2)">本年</span>
                                    </div>
                                </div>
                                <div class="car_static">
                                    <div class="echart_wrap">
                                        <div class="pie_text">
                                            <div class="fs30"><strong>30</strong></div>
                                            <div>入库总量</div>
                                            <div style="font-size: 15px; color: rgba(255,255,255,0.8); font-weight: 400;">入库总量</div>
                                        </div>
                                        <div class="echart1" id="echart1"></div>
                                    </div>
                                    <div class="list">
                                    <div class="list" v-if="fenbu">
                                        <div class="item1">
                                            <div class="line">
                                                <div class="icon"></div>
                                                <div class="icon" :style="{ background: `linear-gradient(270deg, ${colors[0].color1} 0%, ${colors[0].color2} 100%)` }"></div>
                                                <div class="text">酒精检测告警</div>
                                            </div>
                                            <div class="num">16次|55.0%</div>
                                            <div class="num">{{fenbu.alcoholNum}}次|{{fenbu.alcoholNumPct}}%</div>
                                        </div>
                                        <div class="item1">
                                            <div class="line">
                                                <div class="icon"></div>
                                                <div class="icon" :style="{ background: `linear-gradient(270deg, ${colors[1].color1} 0%, ${colors[1].color2} 100%)` }"></div>
                                                <div class="text">柜门未关告警</div>
                                            </div>
                                            <div class="num">12次|40.0%</div>
                                            <div class="num">{{fenbu.timeOutNum}}次|{{fenbu.timeOutNumPct}}%</div>
                                        </div>
                                        <div class="item1">
                                            <div class="line">
                                                <div class="icon"></div>
                                                <div class="icon" :style="{ background: `linear-gradient(270deg, ${colors[2].color1} 0%, ${colors[2].color2} 100%)` }"></div>
                                                <div class="text">超时未还告警</div>
                                            </div>
                                            <div class="num">2次|5.0%</div>
                                            <div class="num">{{fenbu.unCloseNum}}次|{{fenbu.unCloseNumPct}}%</div>
                                        </div>
                                    </div>
                                </div>
@@ -189,25 +217,25 @@
                                </div>
                                <div class="list1 three-swiper">
                                    <div class="swiper-wrapper">
                                        <div class="item three-swiper-slide swiper-slide" v-for="(item, i) in alarm">
                                        <div class="item three-swiper-slide swiper-slide" v-for="(item, i) in alarm" :key="i">
                                            <div class="icon">
                                                <div class="circle"></div>
                                                <div class="line"></div>
                                            </div>
                                            <div class="content">
                                                <div class="header">
                                                    <div class="time">07月07日 14:23:22</div>
                                                    <div class="time">操作人:唐嫣李</div>
                                                    <div class="time">{{item.createDate}}</div>
                                                    <div class="time">操作人:{{item.createUserName}}</div>
                                                </div>
                                                <div class="main">
                                                    <div class="left">
                                                        <div class="title">
                                                            <img class="xf" src="@/assets/images/FireFighting/ic_gaojing_red@2x.png" alt="">
                                                            <span>酒精检测超标</span>
                                                            <div class="data">
                                                                <img src="@/assets/images/ic_guihao@2x.png" />
                                                                <span>柜号:19</span>
                                                            </div>
                                                            <span>{{item.content}}</span>
<!--                                                            <div class="data">-->
<!--                                                                <img src="@/assets/images/ic_guihao@2x.png" />-->
<!--                                                                <span>柜号:19</span>-->
<!--                                                            </div>-->
                                                        </div>
                                                    </div>
                                                    <!-- <div class="status">处理中</div> -->
@@ -230,13 +258,20 @@
<script setup>
    import VScaleScreen from 'v-scale-screen'
    import {onMounted, ref} from 'vue'
    import {onMounted, ref, nextTick} from 'vue'
    import dayjs from 'dayjs'
    import * as echarts from 'echarts'
    import duration from 'dayjs/plugin/duration'
    import 'swiper/css/swiper.min.css'
    import Swiper from 'swiper'
    import {zxenergyDataList, zxloadCurve} from '@/api'
    import {
        getCabinetGridData,
        getCarUseStatistics,
        getKeyUseStatistics,
        getCabinetBoardWarningPage,
        getWarningRataData,
        getKeyUseRecord
    } from '@/api'
    dayjs.extend(duration)
@@ -252,21 +287,185 @@
    }, 1000)
    const colors = [
        {
            color1: '#007EC3',
            color2: '#53E3FF'
        },
        {
            color1: '#DC9804',
            color2: '#FFD802'
        },
        {
            color1: '#14A585',
            color2: '#51F9E4'
        }
    ]
    const data = ref(null)
    const data4 = ref([])
    let type1 = ref(0)
    const data2 = ref([])
    const alarm = ref([{},{},{},{},{},{},{},{}])
    let type2 = ref(0)
    let type3 = ref(0)
    const alarm = ref([])
    let fenbu = ref(null)
    const data5 = ref([])
    const dataList5 = ref([])
    let form = ref({
        status: '',
        carCode: ''
    })
    let show = ref(false)
    const claimRecord = ref([{},{},{},{},{},{},{},{}])
    const Enter = (e) => {
        if (e.key === 'Enter') {
            getKeyUseRecords()
        }
    }
    const sele = (val) => {
        form.value.status = val
        show.value = false
        getKeyUseRecords()
    }
    // 钥匙取还记录
    const getKeyUseRecords = () => {
        getKeyUseRecord({ carCode: form.value.carCode, status: form.value.status })
            .then(res => {
                if (res.code === 200) {
                    data5.value = res.data
                }
            })
    }
    // 计算百分比
    const calculatePercentage = (target, numbers) => {
        const total = numbers.reduce((sum, num) => sum + num, 0);
        if (total === 0) return 0;
        return ((target / total) * 100).toFixed(2);
    }
    // 钥匙告警分布
    const getWarningRataDatas = () => {
        getWarningRataData({
            type: type3.value
        }).then(res => {
            if (res.code === 200) {
                fenbu.value = {
                    ...res.data,
                    alcoholNumPct: calculatePercentage(res.data.alcoholNum,[res.data.alcoholNum + res.data.timeOutNum + res.data.unCloseNum]),
                    timeOutNumPct: calculatePercentage(res.data.timeOutNum,[res.data.alcoholNum + res.data.timeOutNum + res.data.unCloseNum]),
                    unCloseNumPct: calculatePercentage(res.data.unCloseNum,[res.data.alcoholNum + res.data.timeOutNum + res.data.unCloseNum])
                }
                dataList5.value = [res.data.alcoholNum, res.data.unCloseNum, res.data.timeOutNum]
                nextTick(() => {
                    initEchart1()
                })
            }
        })
    }
    // 告警明细
    const getCabinetBoardWarningPages = () => {
        getCabinetBoardWarningPage({
            capacity: 8,
            page: 1,
            model: {}
        }).then(res => {
            if (res.code === 200) {
                alarm.value = res.data.records
            }
        })
    }
    // 顶部数据
    const getZXData = () => {
        getCabinetGridData()
            .then(res => {
                if (res.code === 200) {
                    data.value = res.data
                }
            })
    }
    const clickOneItem = (type) => {
        type1.value = type
        getData4()
    }
    const clickTwoItem = (type) => {
        type2.value = type
        getData2()
    }
    const clickThreeItem = (type) => {
        type3.value = type
        getWarningRataDatas()
    }
    // 告警分布
    const initEchart1 = () => {
        const myChart = echarts.init(document.getElementById('echart1'))
        const option = {
            series: [
                {
                    type: 'pie',
                    radius: ['86%', '100%'],
                    label: {
                        show: false,
                        position: 'center'
                    },
                    tooltip: {
                        trigger: 'none'
                    },
                    emphasis: {
                        // 设置悬浮时样式为空
                        scale: false, // 关闭放大效果
                        itemStyle: {
                            shadowBlur: 0, // 阴影模糊度为 0
                            shadowOffsetX: 0,
                            shadowColor: 'rgba(0, 0, 0, 0)',
                        },
                    },
                    padAngle: 3,
                    itemStyle: {
                        borderRadius: 10,
                        color: function(params) {
                            // 使用不同的渐变色
                            let colorList = [
                                {offset: 0, color: colors[params.dataIndex].color1}, // 0% 处的颜色
                                {offset: 1, color: colors[params.dataIndex].color2} // 100% 处的颜色
                            ];
                            return new echarts.graphic.LinearGradient(0, 0, 0, 1, colorList);
                        }
                    },
                    // color: colors,
                    labelLine: {
                        show: false
                    },
                    data: dataList5.value
                }
            ]
        }
        myChart.setOption(option)
        window.addEventListener('resize', function () { // 执行
            myChart.resize()
        })
    }
    // 派车统计
    const getData4 = () => {
        zxloadCurve().then(res => {
            const result = res.data || []
            data4.value = result
        getCarUseStatistics({ type: type1.value }).then(res => {
            data4.value = res.data || []
            if (data4.value && data4.value.length > 0) {
                initLoadReal()
            }
        })
    }
    // 派车统计
    const initLoadReal = () => {
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.querySelector('.three_one_chat'))
@@ -284,7 +483,7 @@
                axisLabel: {
                    color: '#D2E0FF'
                },
                data: data4.value.map(i => i.timeData)
                data: data4.value.map(i => i.name)
            },
            yAxis: {
                type: 'value',
@@ -315,7 +514,7 @@
            },
            series: [
                {
                    data: data4.value.map(i => i.energy),
                    data: data4.value.map(i => i.num),
                    type: 'line',
                    areaStyle: {
                        normal: {
@@ -367,13 +566,17 @@
        })
    }
    // 钥匙领取归还统计
    const getData2 = () => {
        zxenergyDataList({ type: 0 }).then(res => {
        getKeyUseStatistics({ type: type2.value }).then(res => {
            data2.value = res.data || []
            if (data2.value && data2.value.length > 0) {
            initEnergy()
            }
        })
    }
    // 钥匙领取归还统计
    const initEnergy = () => {
        var myChart = echarts.init(document.querySelector('.three_two_chat'))
@@ -393,7 +596,7 @@
                axisLabel: {
                    color: '#D2E0FF'
                },
                data: data2.value.map(i => dayjs(i.timeData).format('M'))
                data: data2.value.map(i => i.name)
            },
            yAxis: {
                type: 'value',
@@ -415,7 +618,7 @@
            },
            series: [
                {
                    data: data2.value.map(i => i.energy),
                    data: data2.value.map(i => i.num),
                    type: 'bar',
                    barWidth: 10,
                    itemStyle: {
@@ -432,7 +635,7 @@
                    }
                },
                {
                    data: data2.value.map(i => i.energy),
                    data: data2.value.map(i => i.nextNum),
                    type: 'bar',
                    barWidth: 10,
                    itemStyle: {
@@ -468,7 +671,7 @@
            initialSlide: 0,
            direction: 'vertical', //竖直方向
            slidesPerView: 4,
            autoplay: autoplayFlag(claimRecord.value, 4, 6000),
            autoplay: autoplayFlag(data5.value, 4, 6000),
            observer: true, //修改swiper自己或子元素时,自动初始化swiper
        })
    }
@@ -486,30 +689,20 @@
    }
    onMounted(() => {
        // getData1()
        getKeyUseRecords()
        getWarningRataDatas()
        getCabinetBoardWarningPages()
        getZXData()
        getData2()
        // getData3()
        getData4()
        // getData5()
        // getData6()
        // getData7()
        //
        // setInterval(() => {
        //     getData1()
        //     getData2()
        //     getData3()
        //     getData4()
        //     getData5()
        //     getData6()
        //     getData7()
        // }, 1000 * 60)
        //
        // setTimeout(() => {
        //     loopFn2()
        //     loopFn5()
        //     loopFn7()
        //     loopFn6()
        // }, 12000)
        setInterval(() => {
            getKeyUseRecords()
            getWarningRataDatas()
            getCabinetBoardWarningPages()
            getZXData()
            getData2()
            getData4()
        }, 1000 * 60)
        setTimeout(() => {
            loopFn1()
            loopFn7()
@@ -883,15 +1076,13 @@
                                position: relative;
                                .pie_text {
                                    width: 100px;
                                    height: 100px;
                                    border: 1px dashed rgba(1, 217, 254, 0.7);
                                    width: 150px;
                                    height: 150px;
                                    border: 1px dashed #FFFFFF;
                                    border-radius: 50%;
                                    position: absolute;
                                    left: 50%;
                                    top: 50%;
                                    transform: translate(-50%, -50%);
                                    left: 25px;
                                    top: 25px;
                                    z-index: 999;
                                    display: flex;
                                    flex-direction: column;
@@ -900,19 +1091,20 @@
                                    font-size: 12px;
                                    .fs30 {
                                        font-weight: bold;
                                        font-size: 18px;
                                        margin-bottom: 4px;
                                        font-weight: 500;
                                        font-size: 32px;
                                        color: #FFFFFF;
                                    }
                                }
                            }
                            .echart1 {
                                width: 130px;
                                height: 130px;
                                width: 200px;
                                height: 200px;
                            }
                            .list {
                                width: 260px;
                                display: flex;
                                flex-direction: column;
@@ -931,7 +1123,6 @@
                                            height: 12px;
                                            border-radius: 50%;
                                            margin-right: 10px;
                                            background: linear-gradient(270deg, #29aeff 0%, #207ff7 100%);
                                        }
                                    }
@@ -1128,6 +1319,99 @@
        padding: 0 15px 0 13px;
        position: relative;
        .search {
            display: flex;
            align-items: center;
            .search-item {
                display: flex;
                align-items: center;
                margin-left: 10px;
                .search-item-label {
                    font-weight: 400;
                    font-size: 13px;
                    color: #D2E0FF;
                }
                .search-item-select {
                    width: 100px;
                    height: 27px;
                    background: rgba(0,148,235,0.1);
                    border-radius: 14px;
                    border: 1px solid #869CC9;
                    padding: 0 10px;
                    box-sizing: border-box;
                    display: flex;
                    align-items: center;
                    justify-content: space-between;
                    cursor: pointer;
                    position: relative;
                    .search-item-select-list {
                        width: 100%;
                        height: auto;
                        position: absolute;
                        bottom: -120px;
                        left: 0;
                        z-index: 9;
                        border-radius: 10px;
                        overflow: hidden;
                        background: rgba(0,86,255,0.05);
                        .search-item-select-list-item {
                            width: 100%;
                            height: 40px;
                            line-height: 40px;
                            text-align: center;
                            font-size: 13px;
                            font-weight: 400;
                            color: #D2E0FF;
                            &:hover {
                                background-color: #00A68E;
                            }
                        }
                    }
                    span {
                        &:nth-child(1) {
                            font-weight: 400;
                            font-size: 13px;
                            color: #D2E0FF;
                        }
                        &:nth-child(2) {
                            font-weight: 400;
                            font-size: 10px;
                            color: #D2E0FF;
                        }
                    }
                }
                .search-item-input {
                    width: 150px;
                    height: 27px;
                    background: rgba(0,148,235,0.1);
                    border-radius: 14px;
                    border: 1px solid #869CC9;
                    display: flex;
                    align-items: center;
                    padding: 0 10px;
                    box-sizing: border-box;
                    img {
                        flex-shrink: 0;
                        width: 14px;
                        height: 14px;
                        margin-right: 6px;
                    }
                    input {
                        flex: 1;
                        height: 100%;
                        font-weight: 400;
                        font-size: 13px;
                        color: #D2E0FF;
                        &::placeholder {
                            font-weight: 400;
                            font-size: 13px;
                            color: rgba(255,255,255,0.36);
                        }
                    }
                }
            }
        }
        .title {
            display: flex;
            align-items: center;