ZaiZai 2 rokov pred
rodič
commit
4f61225130

+ 115 - 0
src/components/echarts/BarLabel.vue

@@ -0,0 +1,115 @@
+<template>
+    <echartsBase :option="setOption"/>
+</template>
+
+<script setup>
+import echartsBase from './index.vue'
+import { nextTick, onMounted, ref, watch } from 'vue'
+
+const props = defineProps({
+    color: {
+        type: Array,
+        default: () => ([])
+    },
+    datas: {
+        type: Array,
+        default: () => ([])
+    },
+    lables: {
+        type: Array,
+        default: () => ([])
+    },
+    isMonth: {
+        type: Boolean,
+        default: false
+    },
+})
+
+//初始变量
+const setOption = ref({})
+const colors = ref(props.color)
+const datas = ref(props.datas)
+const isMonths = ref(props.isMonth)
+const xAxis = ref(props.lables)
+
+
+watch(() => [
+    props.color,
+    props.isMonth,
+    props.lables,
+], ([color, isMonth, lables]) => {
+    colors.value = color
+    isMonths.value = isMonth
+    xAxis.value = lables
+    setOptions()
+})
+
+
+//深度监听数据变化
+watch(() => [
+    props.datas
+], ([data]) => {
+    datas.value = data
+    setDataFormat()
+}, { deep: true })
+
+//处理数据
+const setDataFormat = () => {
+    let series = [], lables = xAxis.value, data = datas.value;
+    let isLables = lables.length > 0
+    //处理数据
+    for (let i = 0; i < data.length; i++) {
+        if (data[i].name) {
+            if (!isLables) {
+                lables.push(data[i].name)
+            }
+            series.push({
+                name: data[i].name,
+                type: 'bar',
+                data: data[i].value
+            })
+        }
+    }
+    setOptions(lables, series)
+}
+
+//设置图表
+const setOptions = (lables = [], series = []) => {
+    setOption.value = {
+        color: colors.value,
+        tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+                type: 'shadow'
+            }
+        },
+        grid: {
+            top: '50px',
+            left: '0',
+            right: '4px',
+            bottom: '0',
+            containLabel: true
+        },
+        xAxis: [
+            {
+                type: 'category',
+                data: lables,
+            }
+        ],
+        yAxis: [{
+            type: 'value',
+            axisLabel: {
+                formatter: '{value}'
+            },
+        }],
+        series: series
+    }
+}
+
+//渲染完成
+onMounted(() => {
+    nextTick(() => {
+        setDataFormat()
+    })
+})
+</script>

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

@@ -0,0 +1,98 @@
+<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%;
+    overflow: hidden;
+    position: relative;
+    .hac-echarts {
+        position: absolute;
+        bottom: 0;
+        left: 0;
+        right: 0;
+        z-index: 2;
+        width: 100%;
+        height: 100%;
+    }
+}
+</style>

+ 148 - 0
src/components/echarts/stackEcharts.vue

@@ -0,0 +1,148 @@
+<template>
+    <echartsBase :option="setOption"/>
+</template>
+
+<script setup>
+import echartsBase from './index.vue'
+import { nextTick, onMounted, ref, watch } from 'vue'
+
+const props = defineProps({
+    color: {
+        type: Array,
+        default: () => ([])
+    },
+    datas: {
+        type: Array,
+        default: () => ([])
+    },
+    lables: {
+        type: Array,
+        default: () => ([])
+    },
+    isMonth: {
+        type: Boolean,
+        default: false
+    },
+})
+
+//初始变量
+const setOption = ref({})
+const colors = ref(props.color)
+const datas = ref(props.datas)
+const isMonths = ref(props.isMonth)
+const xAxis = ref(props.lables)
+
+
+watch(() => [
+    props.color,
+    props.isMonth,
+    props.lables,
+], ([color, isMonth, lables]) => {
+    colors.value = color
+    isMonths.value = isMonth
+    xAxis.value = lables
+    setOptions()
+})
+
+
+//深度监听数据变化
+watch(() => [
+    props.datas
+], ([data]) => {
+    datas.value = data
+    setDataFormat()
+}, { deep: true })
+
+//处理数据
+const setDataFormat = () => {
+    let series = [], lables = xAxis.value, data = datas.value;
+    let isLables = lables.length > 0
+    //处理数据
+    for (let i = 0; i < data.length; i++) {
+        if (data[i].name) {
+            if (!isLables) {
+                lables.push(data[i].name)
+            }
+            series.push({
+                name: data[i].name,
+                type: 'bar',
+                data: data[i].value
+            })
+        }
+    }
+    setOptions(lables, series)
+}
+
+//设置图表
+const setOptions = (lables = [], series = []) => {
+    setOption.value = {
+        color: colors.value,
+        tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+                type: 'shadow'
+            }
+        },
+        legend: {
+            data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
+        },
+        grid: {
+            top: '50px',
+            left: '0',
+            right: '4px',
+            bottom: '0',
+            containLabel: true
+        },
+        xAxis: {
+            type: 'category',
+            boundaryGap: false,
+            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+        },
+        yAxis: [{
+            type: 'value',
+            axisLabel: {
+                formatter: '{value}'
+            },
+        }],
+        series: [
+            {
+                name: 'Email',
+                type: 'line',
+                stack: 'Total',
+                data: [120, 132, 101, 134, 90, 230, 210]
+            },
+            {
+                name: 'Union Ads',
+                type: 'line',
+                stack: 'Total',
+                data: [220, 182, 191, 234, 290, 330, 310]
+            },
+            {
+                name: 'Video Ads',
+                type: 'line',
+                stack: 'Total',
+                data: [150, 232, 201, 154, 190, 330, 410]
+            },
+            {
+                name: 'Direct',
+                type: 'line',
+                stack: 'Total',
+                data: [320, 332, 301, 334, 390, 330, 320]
+            },
+            {
+                name: 'Search Engine',
+                type: 'line',
+                stack: 'Total',
+                data: [820, 932, 901, 934, 1290, 1330, 1320]
+            }
+        ]
+    }
+}
+
+//渲染完成
+onMounted(() => {
+    nextTick(() => {
+        setDataFormat()
+    })
+})
+</script>

+ 174 - 3
src/views/count/index.vue

@@ -1,15 +1,186 @@
 <template>
-    <div>222</div>
+    <HcCard ui="hc-count-card-ui" bodyUi="hc-count-card">
+        <div class="hc-count-tree" id="hc-count-tree">
+            <el-scrollbar>
+                <HcTreeData :isMenu="false" @nodeTap="treeNodeTap"/>
+            </el-scrollbar>
+        </div>
+        <div class="hc-count-body" id="hc-count-body">
+            <el-scrollbar>
+                <div class="hc-count-echarts-1">
+                    <el-row :gutter="14">
+                        <el-col :span="10">
+                            <HcCardItem title="面积进度柱状图统计" style="height: 440px">
+                                <BarLabelEcharts :lables="planLables" :color="planColors" :datas="planDatas"/>
+                            </HcCardItem>
+                        </el-col>
+                        <el-col :span="14">
+                            <HcCardItem title="面积进度" style="height: 160px">
+                                <el-row :gutter="20" class="h-full">
+                                    <el-col :span="6">
+                                        <div class="hc-count-area-progress">
+                                            <div class="num">23123123.12</div>
+                                            <div class="text">已签协议面积(亩)</div>
+                                        </div>
+                                    </el-col>
+                                    <el-col :span="6">
+                                        <div class="hc-count-area-progress">
+                                            <div class="num">26.12%</div>
+                                            <div class="text">已签协议比例</div>
+                                        </div>
+                                    </el-col>
+                                    <el-col :span="6">
+                                        <div class="hc-count-area-progress">
+                                            <div class="num">23123.12</div>
+                                            <div class="text">已结算面积(亩)</div>
+                                        </div>
+                                    </el-col>
+                                    <el-col :span="6">
+                                        <div class="hc-count-area-progress">
+                                            <div class="num">26.36%</div>
+                                            <div class="text">已结算比例</div>
+                                        </div>
+                                    </el-col>
+                                </el-row>
+                            </HcCardItem>
+                            <HcCardItem title="金额进度" style="height: 266px; margin-top: 14px">
+                                <BarLabelEcharts :lables="planLables1" :color="planColors1" :datas="planDatas1"/>
+                            </HcCardItem>
+                        </el-col>
+                    </el-row>
+                </div>
+                <HcCardItem title="结算统计图(单位:元)" style="height: 440px; margin-top: 14px">
+                    <stackEcharts/>
+                </HcCardItem>
+            </el-scrollbar>
+        </div>
+    </HcCard>
 </template>
 
 <script setup>
+import {ref, onUnmounted, onMounted} from "vue";
+import BarLabelEcharts from "~com/echarts/BarLabel.vue";
+import stackEcharts from "~com/echarts/stackEcharts.vue";
+import split from "split.js";
 
+//树节点被点击
+const treeNodeTap = ({node, data}) => {
+
+}
+
+//渲染完成
+onMounted(() => {
+    setSplitDom()
+})
+
+// 初始化设置拖动分割线
+const splitvar = ref(null);
+const setSplitDom = () => {
+    try {
+        //配置参考: https://split.js.org/#/?direction=vertical&snapOffset=0
+        splitvar.value = split([
+            '#hc-count-tree',
+            '#hc-count-body'
+        ], {
+            sizes: [20, 80],
+            minSize: [200, 900],
+        });
+    } catch (e) {
+        setTimeout(() => {
+            setSplitDom()
+        }, 500)
+    }
+}
+
+//面积进度柱状图统计
+const planColors = ['#D97558', '#E4C476']
+const planLables = ref(['农用地', '建设用地', '未利用地'])
+const planDatas = ref([
+    {
+        name: '已签面积',
+        value: [1200, 132, 501]
+    },
+    {
+        name: '设计面积',
+        value: [120, 432, 1001]
+    }
+])
+
+//金额进度
+const planColors1 = ['#7F83F6', '#81B336', '#E99D43']
+const planLables1 = ref(['征地补偿', '专项设施', '青苗', '坟地补偿', '地上附着物'])
+const planDatas1 = ref([
+    {
+        name: '实际补助总金额',
+        value: [1200, 132, 501, 323, 654]
+    },
+    {
+        name: '设计补助总金额',
+        value: [120, 432, 1001, 111, 987]
+    },
+    {
+        name: '已结算总金额',
+        value: [120, 432, 1001, 323, 654]
+    }
+])
+
+//销毁
+onUnmounted(() => {
+    if (splitvar.value) {
+        splitvar.value.destroy()
+    }
+})
 </script>
 
 <style lang="scss" scoped>
-
+.hc-count-body .hc-count-echarts-1 {
+    position: relative;
+    overflow: hidden;
+}
 </style>
 
 <style lang="scss">
-
+.hc-count-card-ui {
+    background: white;
+    .el-card__body {
+        padding: 10px;
+    }
+}
+.hc-count-card {
+    display: flex;
+    .hc-count-tree {
+        position: relative;
+        margin-right: 5px;
+        height: 100%;
+    }
+    .hc-count-body {
+        position: relative;
+        margin-left: 5px;
+        height: 100%;
+        .hc-card-item-box {
+            background: #f5f5f5;
+            .hc-card-item-header {
+                color: #101010;
+            }
+        }
+    }
+    .hc-count-area-progress {
+        position: relative;
+        height: 100%;
+        background: #ffffff;
+        border-radius: 5px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        .num {
+            margin-bottom: 18px;
+            font-size: 20px;
+        }
+        .text {
+            position: absolute;
+            bottom: 10px;
+            font-size: 14px;
+        }
+    }
+}
 </style>

+ 113 - 3
src/views/count/map.vue

@@ -1,15 +1,125 @@
 <template>
-    <div>222</div>
+    <HcCard ui="hc-count-card-ui" bodyUi="hc-count-card">
+        <div class="hc-count-tree" id="hc-count-tree">
+            <el-scrollbar>
+                <HcTreeData :isMenu="false" @nodeTap="treeNodeTap"/>
+            </el-scrollbar>
+        </div>
+        <div class="hc-count-body" id="hc-count-body">
+            <HcCardItem class="hc-card-item-box info-card">
+                <div class="content">
+                    <div class="item">
+                        <span>户主:xxxxx</span>
+                        <span class="ml-20">宗地编号:xxxxx</span>
+                    </div>
+                    <div class="item">征地面积:xxxxx</div>
+                    <div class="item">征拆状态:xxxxx</div>
+                    <div class="item">结算金额:xxxxx</div>
+                </div>
+                <div class="btn">
+                    <el-button type="primary">查看协议书</el-button>
+                    <el-button type="primary">查看结算协议书</el-button>
+                </div>
+            </HcCardItem>
+            <div class="hc-count-map">
+                地图
+            </div>
+        </div>
+    </HcCard>
 </template>
 
 <script setup>
+import {ref, onUnmounted, onMounted} from "vue";
+import split from "split.js";
 
+//树节点被点击
+const treeNodeTap = ({node, data}) => {
+
+}
+
+//渲染完成
+onMounted(() => {
+    setSplitDom()
+})
+
+// 初始化设置拖动分割线
+const splitvar = ref(null);
+const setSplitDom = () => {
+    try {
+        //配置参考: https://split.js.org/#/?direction=vertical&snapOffset=0
+        splitvar.value = split([
+            '#hc-count-tree',
+            '#hc-count-body'
+        ], {
+            sizes: [20, 80],
+            minSize: [200, 900],
+        });
+    } catch (e) {
+        setTimeout(() => {
+            setSplitDom()
+        }, 500)
+    }
+}
+
+//销毁
+onUnmounted(() => {
+    if (splitvar.value) {
+        splitvar.value.destroy()
+    }
+})
 </script>
 
 <style lang="scss" scoped>
-
+.hc-count-card .hc-count-body .hc-card-item-box.info-card {
+    height: 130px;
+    margin-bottom: 24px;
+    .content {
+        flex: 1;
+        position: relative;
+        .item + .item {
+            margin-top: 10px;
+        }
+    }
+    .btn {
+        position: relative;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+    }
+}
+.hc-count-map {
+    position: relative;
+    height: calc(100% - 155px);
+}
 </style>
 
 <style lang="scss">
-
+.hc-count-card-ui {
+    background: white;
+    .el-card__body {
+        padding: 10px;
+    }
+}
+.hc-count-card {
+    display: flex;
+    .hc-count-tree {
+        position: relative;
+        margin-right: 5px;
+        height: 100%;
+    }
+    .hc-count-body {
+        position: relative;
+        margin-left: 5px;
+        height: 100%;
+        .hc-card-item-box {
+            background: #f5f5f5;
+            .hc-card-item-header {
+                color: #101010;
+            }
+            &.info-card .hc-card-item-body {
+                display: flex;
+            }
+        }
+    }
+}
 </style>