ZaiZai 2 rokov pred
rodič
commit
71d4216182

+ 1 - 0
.eslintrc.cjs

@@ -106,6 +106,7 @@ module.exports = {
         'vue/no-v-text-v-html-on-component': 'off',
         'vue/no-dupe-keys': 'off',
         'vue/no-use-v-if-with-v-for': 'off',
+        'vue/singleline-html-element-content-newline': 'off',
 
         // reactivity transform
         'vue/no-setup-props-destructure': 'off',

+ 99 - 0
src/components/echarts/index.vue

@@ -0,0 +1,99 @@
+<template>
+    <div class="hac-echarts-box">
+        <div ref="echart" class="hac-echarts" :style="`width : ${chart?.clientWidth}px`" />
+    </div>
+</template>
+
+<script setup>
+import * as echarts from 'echarts'
+import { getObjValue } from 'js-fast-way'
+import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
+const props = defineProps({
+    option: {
+        type: Object,
+        default: () => ({}),
+    },
+})
+
+//初始变量
+let chart = null
+const echart = ref(null)
+const options = ref(getObjValue(props.option))
+
+//深度监听
+watch(() => [
+    props.option,
+], ([option]) => {
+    options.value = getObjValue(option)
+    setOptions(options.value)
+}, { deep: true })
+
+//初始化图表
+const initChart = () => {
+    chart = echarts.init(echart.value)
+    setOptions(options.value)
+}
+
+//监听浏览器窗口变化
+const windowResize = () => {
+    window.addEventListener('resize', resizeEvent)
+}
+
+const resizeEvent = () => {
+    window.requestAnimationFrame(() => {
+        chart.resize()
+    })
+}
+
+//设置图表
+const setOptions = (option) => {
+    nextTick(() => {
+        chart.setOption(option)
+    })
+}
+
+//渲染完成
+onMounted(() => {
+    nextTick(() => {
+        initChart()
+        windowResize()
+    })
+})
+
+//被卸载
+onUnmounted(() => {
+    window.removeEventListener('resize', resizeEvent)
+    chart.dispose()
+    chart = null
+})
+
+const onResize = () => {
+    nextTick(() => {
+        chart.resize()
+    })
+}
+
+// 暴露出去
+defineExpose({
+    onResize,
+})
+</script>
+
+<style lang="scss" scoped>
+.hac-echarts-box {
+    display: block;
+    height: 100%;
+    width: 100%;
+    overflow: hidden;
+    position: relative;
+    .hac-echarts {
+        position: absolute;
+        bottom: 0;
+        left: 0;
+        right: 0;
+        z-index: 2;
+        width: 100%;
+        height: 100%;
+    }
+}
+</style>

+ 3 - 1
src/store/index.js

@@ -1,6 +1,6 @@
 import { defineStore } from 'pinia'
 import pinia from '~src/store/init'
-import appConfig from '~src/config/app'
+import appConfig from '~src/config/index'
 import { clearStoreAll, getStoreValue, setStoreValue } from '~src/utils/storage'
 import { removeRefreshToken, removeToken, setRefreshToken, setToken } from '~src/api/util/auth'
 
@@ -13,6 +13,8 @@ export const useAppStore = defineStore('main', {
         refreshToken: getStoreValue('refreshToken') || '',
         tenantId: getStoreValue('tenantId') || '',
         userInfo: getStoreValue('userInfo') || {},
+        //其他
+        isEchartSize: '',
     }),
     getters: {
         //系统信息

+ 111 - 0
src/views/home/components/echarts.vue

@@ -0,0 +1,111 @@
+<template>
+    <echartsBase ref="echart" :option="setOption" />
+</template>
+
+<script setup>
+import * as echarts from 'echarts'
+import echartsBase from '~com/echarts/index.vue'
+import { nextTick, onMounted, ref, watch } from 'vue'
+import { useAppStore } from '~src/store'
+const appStore = useAppStore()
+
+//渲染完成
+onMounted(() => {
+    nextTick(() => {
+        setOptions()
+    })
+})
+
+//监听
+watch(() => [
+    appStore.isEchartSize,
+], ([isSize]) => {
+    if (isSize) {
+        echart.value?.onResize()
+    }
+})
+
+//图表配置
+const echart = ref(null)
+const setOption = ref({})
+const setOptions = () => {
+    let base = +new Date(1968, 9, 3)
+    let oneDay = 24 * 3600 * 1000
+    let date = []
+    let data = [Math.random() * 300]
+    for (let i = 1; i < 100; i++) {
+        let now = new Date((base += oneDay))
+        date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'))
+        data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1]))
+    }
+    setOption.value = {
+        tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+                type: 'cross',
+                label: {
+                    backgroundColor: '#6a7985',
+                },
+            },
+        },
+        toolbox: {
+            feature: {
+                dataZoom: {
+                    yAxisIndex: 'none',
+                },
+                saveAsImage: {},
+            },
+        },
+        legend: {
+            data: ['名称'],
+        },
+        //#09c
+        xAxis: {
+            type: 'category',
+            boundaryGap: false,
+            data: date,
+        },
+        yAxis: {
+            type: 'value',
+            boundaryGap: [0, '30%'],
+        },
+        dataZoom: [
+            {
+                type: 'inside',
+                start: 0,
+                end: data.length,
+            },
+            {
+                start: 0,
+                end:data.length,
+            },
+        ],
+        series: [
+            {
+                name: '名称',
+                type: 'line',
+                stack: 'Total',
+                emphasis: {
+                    focus: 'series',
+                },
+                itemStyle: {
+                    color: '#03C5C2',
+                },
+                areaStyle: {
+                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                        {
+                            offset: 0,
+                            color: 'rgba(3, 197, 194, 0.5)',
+                        },
+                        {
+                            offset: 1,
+                            color: 'transparent',
+                        },
+                    ]),
+                },
+                data: data,
+            },
+        ],
+    }
+}
+</script>

+ 39 - 1
src/views/home/components/index.vue

@@ -29,10 +29,48 @@
             </div>
         </div>
     </div>
+    <div class="row_data_statistics">
+        <div class="statistics_item_container" style="padding-right: 8px;">
+            <div class="statistics_item blue">
+                <div class="left_text">
+                    <div class="number">暂无</div>
+                    <div class="text">本周最大值</div>
+                </div>
+                <div class="divider" />
+                <div class="right_text">
+                    <div>环比上周:暂无</div>
+                    <div>监测时间:暂无</div>
+                </div>
+            </div>
+        </div>
+        <div class="statistics_item_container" style="padding-left: 8px;">
+            <div class="statistics_item purple">
+                <div class="left_text">
+                    <div class="number">暂无</div>
+                    <div class="text">本周平均值</div>
+                </div>
+                <div class="divider" />
+                <div class="right_text">
+                    <div>环比上周:暂无</div>
+                    <div>最大变幅:暂无</div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="row_radio_group">
+        <el-radio-group v-model="change_type" size="large">
+            <el-radio label="echarts">图表</el-radio>
+            <el-radio label="table">表格</el-radio>
+        </el-radio-group>
+    </div>
+    <div class="data_container">
+        <baseEcharts />
+    </div>
 </template>
 
 <script setup>
 import { ref } from 'vue'
+import baseEcharts from './echarts.vue'
 
 //选项卡
 const tab_key = ref('1')
@@ -42,8 +80,8 @@ const tabTap = (val) => {
 
 //类型
 const typeId = ref('1')
-
 const dateTime = ref(null)
+const change_type = ref('echarts')
 </script>
 
 <style lang="scss">

+ 82 - 0
src/views/home/components/style.scss

@@ -55,3 +55,85 @@
         }
     }
 }
+.row_data_statistics {
+    display: flex;
+    flex-flow: row wrap;
+    width: 100%;
+    row-gap: 0;
+    margin-top: 14px;
+    .statistics_item_container {
+        width: 50%;
+        .statistics_item {
+            height: 80px;
+            width: 100%;
+            display: flex;
+            justify-content: space-around;
+            align-items: center;
+            &.blue {
+                background-color: rgba(0,153,204,.55);
+                border: 1px solid rgba(0,153,204,.65);
+            }
+            &.purple {
+                background-color: rgba(153,51,255,.55);
+                border: 1px solid rgba(153,51,255,.65);
+            }
+            .left_text {
+                color: hsla(0,0%,100%,.85);
+                text-align: center;
+                width: 50%;
+                .number {
+                    font-size: 1.2em;
+                    font-weight: 500;
+                    color: hsla(0,0%,100%,.85);
+                }
+                .text {
+                    font-size: 1em;
+                }
+            }
+            .divider {
+                position: relative;
+                display: inline-block;
+                margin: 0 8px;
+                vertical-align: middle;
+                border-top: 0;
+                border-left: 1px solid hsla(0,0%,100%,.3);
+                padding-left: 6px;
+                padding-right: 6px;
+                height: 60%;
+                top: -.06em;
+                color: rgba(0,0,0,.85);
+                font-size: 14px;
+                font-variant: tabular-nums;
+                line-height: 1.5715;
+                list-style: none;
+                font-feature-settings: "tnum","tnum";
+            }
+            .right_text {
+                width: 50%;
+                font-size: 1em;
+                color: hsla(0,0%,100%,.85);
+                line-height: 30px;
+            }
+        }
+    }
+}
+.row_radio_group {
+    position: relative;
+    margin: 14px 0;
+    .el-radio-group .el-radio {
+        height: 26px;
+        --el-radio-text-color: #09c;
+        --el-border: var(--el-border-width) var(--el-border-style) #09c;
+        --el-radio-input-border-color: #09c;
+        --el-radio-input-border-color-hover: #00fffc;
+        &.is-checked {
+            --el-color-primary: #00fffc;
+            --el-color-white: #09c;
+        }
+    }
+}
+.data_container {
+    position: relative;
+    width: 100%;
+    height: calc(100% - 200px);
+}

+ 8 - 0
src/views/home/index.vue

@@ -161,17 +161,25 @@
 <script setup>
 import { ref } from 'vue'
 import indexVue from './components/index.vue'
+import { useAppStore } from '~src/store'
+import { getRandom } from 'js-fast-way'
+
+const appStore = useAppStore()
 
 //全屏
 const isScreen = ref(false)
 const fullscreenTap = () => {
     isScreen.value = !isScreen.value
+    appStore.isEchartSize = getRandom()
 }
 
 // 侧边栏
 const isCollapse = ref(true)
 const collapseTap = () => {
     isCollapse.value = !isCollapse.value
+    setTimeout(() => {
+        appStore.isEchartSize = getRandom()
+    }, 200)
 }
 
 // 报警消息