Переглянути джерело

优化图表和开发报表页面

ZaiZai 2 роки тому
батько
коміт
49fb8ccbd1

+ 1 - 1
package.json

@@ -13,7 +13,7 @@
         "dayjs": "^1.11.7",
         "echarts": "^5.4.2",
         "element-plus": "2.3.4",
-        "hc-vue3-ui": "^1.0.4",
+        "hc-vue3-ui": "^1.0.5",
         "js-base64": "^3.7.5",
         "js-cookie": "^3.0.5",
         "js-fast-way": "^0.1.0",

+ 135 - 0
src/components/echarts/AreaStack.vue

@@ -0,0 +1,135 @@
+<template>
+    <echartsBase :option="setOption"/>
+</template>
+
+<script setup>
+import echartsBase from './index.vue'
+import { nextTick, onMounted, ref, watch } from 'vue'
+
+const props = defineProps({
+    title: {
+        type: String,
+        default: '管理费已支出与剩余预算曲线图'
+    },
+    color: {
+        type: Array,
+        default: () => (['#4095E5', '#C25750'])
+    },
+    unit: {
+        type: String,
+        default: '元'
+    },
+    datas: {
+        type: Array,
+        default: () => ([])
+    }
+})
+
+//初始变量
+const setOption = ref({})
+const titles = ref(props.title)
+const colors = ref(props.color)
+const units = ref(props.unit)
+const datas = ref(props.datas)
+
+//创建月份
+const monthData = ref([])
+for (let i = 1; i < 13; i++) {
+    monthData.value = [...monthData.value, i + '月']
+}
+
+watch(() => [
+    props.title,
+    props.color,
+    props.unit,
+], ([title, color, unit]) => {
+    titles.value = title
+    colors.value = color
+    units.value = unit
+    setOptions()
+})
+
+//深度监听数据变化
+watch(() => [
+    props.datas,
+], ([data]) => {
+    datas.value = data
+    setDataFormat()
+}, { deep: true })
+
+
+//处理数据
+const setDataFormat = () => {
+    const data = datas.value
+    let legend = [], series = [];
+    for (let i = 0; i < data.length; i++) {
+        if (data[i].name) {
+            legend.push(data[i].name)
+            series.push({
+                name: data[i].name,
+                type: 'line',
+                stack: 'Total',
+                areaStyle: {},
+                data: data[i].value
+            })
+        }
+    }
+    setOptions(legend, series)
+}
+
+
+//设置图表
+const setOptions = (legend = [], series = []) => {
+    setOption.value = {
+        color: colors.value,
+        title: {
+            text: titles.value,
+            left: 'center',
+            bottom: '0',
+            textStyle: {
+                color: '#B3B3B3',
+                fontSize: 14,
+            }
+        },
+        tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+                type: 'cross',
+            }
+        },
+        legend: {
+            data: legend
+        },
+        grid: {
+            top: '40px',
+            left: '0',
+            right: '10px',
+            bottom: titles.value ? '40px' : '0',
+            containLabel: true
+        },
+        xAxis: [
+            {
+                type: 'category',
+                boundaryGap: false,
+                data: monthData.value
+            }
+        ],
+        yAxis: [
+            {
+                type: 'value',
+                axisLabel: {
+                    formatter: '{value}' + units.value
+                },
+            }
+        ],
+        series: series
+    }
+}
+
+//渲染完成
+onMounted(() => {
+    nextTick(() => {
+        setDataFormat()
+    })
+})
+</script>

+ 107 - 0
src/components/echarts/BarLabelChart.vue

@@ -0,0 +1,107 @@
+<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: () => (['#5087EC', '#68BBC4'])
+    },
+    unit: {
+        type: String,
+        default: '元'
+    },
+    datas: {
+        type: Array,
+        default: () => ([])
+    },
+})
+
+//初始变量
+const setOption = ref({})
+const colors = ref(props.color)
+const units = ref(props.unit)
+const datas = ref(props.datas)
+
+watch(() => [
+    props.color,
+    props.unit,
+], ([color, unit]) => {
+    colors.value = color
+    units.value = unit
+    setOptions()
+})
+
+//深度监听数据变化
+watch(() => [
+    props.datas,
+], ([data]) => {
+    datas.value = data
+    setDataFormat()
+}, { deep: true })
+
+//处理数据
+const setDataFormat = () => {
+    let series = [], lables = [], data = datas.value;
+    //处理数据
+    for (let i = 0; i < data.length; i++) {
+        if (data[i].name) {
+            lables.push(data[i].name)
+            series.push(data[i].value)
+        }
+    }
+    setOptions(lables, series)
+}
+
+//设置图表
+const setOptions = (lables = [], series = []) => {
+    setOption.value = {
+        tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+                type: 'shadow'
+            }
+        },
+        grid: {
+            top: '20px',
+            left: '0',
+            right: '4px',
+            bottom: '0',
+            containLabel: true
+        },
+        xAxis: [
+            {
+                type: 'category',
+                data: lables,
+            }
+        ],
+        yAxis: [{
+            type: 'value',
+            axisLabel: {
+                formatter: '{value}' + units.value
+            },
+        }],
+        series: [
+            {
+                data: series,
+                type: 'bar',
+                showBackground: true,
+                backgroundStyle: {
+                    color: 'rgba(180, 180, 180, 0.2)'
+                }
+            }
+        ]
+    }
+}
+
+//渲染完成
+onMounted(() => {
+    nextTick(() => {
+        setDataFormat()
+    })
+})
+</script>

+ 78 - 101
src/components/echarts/BarLabelRotation.vue

@@ -1,76 +1,94 @@
 <template>
-    <div class="hac-echarts-box">
-        <div ref="echart" class="hac-echarts" :style="`width : ${chart?.clientWidth}px`"/>
-    </div>
+    <echartsBase :option="setOption"/>
 </template>
 
 <script setup>
-import * as echarts from 'echarts'
-import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
+import echartsBase from './index.vue'
+import { nextTick, onMounted, ref, watch } from 'vue'
+
 const props = defineProps({
+    color: {
+        type: Array,
+        default: () => ([])
+    },
+    unit: {
+        type: String,
+        default: ''
+    },
     datas: {
         type: Array,
         default: () => ([])
-    }
+    },
+    lables: {
+        type: Array,
+        default: () => ([])
+    },
+    isMonth: {
+        type: Boolean,
+        default: false
+    },
 })
 
 //初始变量
-let chart = null;
-const echart = ref(null)
+const setOption = ref({})
+const colors = ref(props.color)
+const units = ref(props.unit)
 const datas = ref(props.datas)
+const isMonths = ref(props.isMonth)
+const xAxis = ref(props.lables)
 
-//创建月份
-const monthData = ref([])
-for (let i = 1; i < 13; i++) {
-    monthData.value = [...monthData.value, i + '月']
-}
+watch(() => [
+    props.color,
+    props.unit,
+    props.isMonth,
+    props.lables
+], ([color, unit, isMonth, lables]) => {
+    colors.value = color
+    units.value = unit
+    isMonths.value = isMonth
+    xAxis.value = lables
+    setOptions()
+})
 
-//监听
+//深度监听数据变化
 watch(() => [
-    props.datas
+    props.datas,
 ], ([data]) => {
     datas.value = data
-    setDatas(data)
-})
-
-//初始化图表
-const initChart = () => {
-    chart = echarts.init(echart.value)
-    setDatas(props.datas)
-}
-
-//监听浏览器窗口变化
-const windowResize = () => {
-    window.addEventListener("resize", resizeEvent);
-}
-
-const resizeEvent = () => {
-    window.requestAnimationFrame(() => {
-        chart.resize();
-    })
-}
-
-const onResize = () => {
-    nextTick(() => {
-        chart.resize();
-    })
-}
+    setDataFormat()
+}, { deep: true })
 
-//设置数据
-const setDatas = (data) => {
-    let AxisData = [], neiYeRatio = [], waiYeRatio = [];
+//处理数据
+const setDataFormat = () => {
+    let series = [], lables = [], data = datas.value;
+    if (isMonths.value) {
+        for (let i = 1; i < 13; i++) {
+            lables = [...lables, i + '月']
+        }
+    } else {
+        lables = xAxis.value
+    }
+    let isLables = lables.length > 0
+    //处理数据
     for (let i = 0; i < data.length; i++) {
-        AxisData.push(data[i].title)
-        neiYeRatio.push(data[i]?.neiYeRatio)
-        waiYeRatio.push(data[i]?.waiYeRatio)
+        if (data[i].name) {
+            if (!isLables) {
+                lables.push(data[i].name)
+            }
+            series.push({
+                name: data[i].name,
+                type: 'bar',
+                data: data[i].value
+            })
+        }
     }
-    setOptions(AxisData,neiYeRatio,waiYeRatio)
+    setOptions(lables, series)
 }
 
 //设置图表
-const setOptions = (AxisData,neiYeRatio,waiYeRatio) => {
-    chart.setOption({
-        color: ['#5087EC', '#68BBC4', '#58A55D'],
+const setOptions = (lables = [], series = []) => {
+    setOption.value = {
+        color: colors.value,
         tooltip: {
             trigger: 'axis',
             axisPointer: {
@@ -80,71 +98,30 @@ const setOptions = (AxisData,neiYeRatio,waiYeRatio) => {
         grid: {
             top: '20px',
             left: '0',
-            right: '0',
+            right: '4px',
             bottom: '0',
             containLabel: true
         },
         xAxis: [
             {
                 type: 'category',
-                data: monthData.value,
+                data: lables,
             }
         ],
-        yAxis: [{type: 'value'}],
-        series: [
-            {
-                name: '总计划',
-                type: 'bar',
-                data: [320, 332, 301, 334, 390]
+        yAxis: [{
+            type: 'value',
+            axisLabel: {
+                formatter: '{value}' + units.value
             },
-            {
-                name: '已完成',
-                type: 'bar',
-                data: [220, 182, 191, 234, 290]
-            },
-            {
-                name: '未完成',
-                type: 'bar',
-                data: [150, 232, 201, 154, 190]
-            }
-        ]
-    })
+        }],
+        series: series
+    }
 }
 
 //渲染完成
 onMounted(() => {
     nextTick(() => {
-        initChart()
-        windowResize()
+        setDataFormat()
     })
 })
-
-//被卸载
-onUnmounted(() => {
-    window.removeEventListener("resize",resizeEvent);
-    chart.dispose()
-    chart = null
-})
-
-// 暴露出去
-defineExpose({
-    onResize
-})
 </script>
-
-<style lang="scss" scoped>
-.hac-echarts-box {
-    height: 100%;
-    overflow: hidden;
-    position: relative;
-    .hac-echarts {
-        position: absolute;
-        bottom: 0;
-        left: 0;
-        right: 0;
-        z-index: 2;
-        width: 100%;
-        height: 100%;
-    }
-}
-</style>

+ 63 - 116
src/components/echarts/BorderRadius.vue

@@ -1,140 +1,87 @@
 <template>
-    <div class="hac-echarts-box">
-        <div ref="echart" class="hac-echarts" :style="`width : ${chart?.clientWidth}px`"/>
-    </div>
+    <echartsBase :option="setOption"/>
 </template>
 
 <script setup>
-import * as echarts from 'echarts'
-import {useAppStore} from "~src/store";
-import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
+import echartsBase from './index.vue'
+import { nextTick, onMounted, ref, watch } from 'vue'
+
 const props = defineProps({
-    ratio: {
-        type: [Number,String],
-        default: 0
+    color: {
+        type: Array,
+        default: () => (['#5087EC', '#68BBC4'])
+    },
+    datas: {
+        type: Array,
+        default: () => ([])
     }
 })
 
 //初始变量
-let chart = null;
-const echart = ref(null)
-const useAppState = useAppStore()
-const AppColor = ref(useAppState.getColor);
+const setOption = ref({})
+const colors = ref(props.color)
+const datas = ref(props.datas)
 
 watch(() => [
-    props.ratio
-], ([ratio]) => {
-    setOptions(ratio, 100 - ratio)
+    props.color
+], ([color]) => {
+    colors.value = color
+    setOptions()
 })
 
-//初始化图表
-const initChart = () => {
-    chart = echarts.init(echart.value)
-    setOptions(props.ratio, 100 - props.ratio)
-}
-
-//监听浏览器窗口变化
-const windowResize = () => {
-    window.addEventListener("resize", resizeEvent);
-}
-
-const resizeEvent = () => {
-    window.requestAnimationFrame(() => {
-        chart.resize();
-    })
-}
+//深度监听数据变化
+watch(() => [
+    props.datas,
+], ([data]) => {
+    datas.value = data
+    setOptions()
+}, { deep: true })
 
 //设置图表
-const setOptions = (val1,val2) => {
-    nextTick(() => {
-        chart.setOption({
-            tooltip: {
-                trigger: "item",
-                formatter: "{d}%"
-            },
-            legend: {
-                type: 'scroll',
-                orient: 'vertical',
-                left: '-7',
-            },
-            series: [
-                {
-                    name: 'Access From',
-                    type: 'pie',
-                    radius: ['80%', '50%'],
-                    center: ["76%", "50%"],
-                    avoidLabelOverlap: false,
-                    itemStyle: {
-                        borderRadius: 4,
-                        borderColor: '#fff',
-                        borderWidth: 1
-                    },
+const setOptions = () => {
+    setOption.value = {
+        color: colors.value,
+        tooltip: {
+            trigger: "item"
+        },
+        legend: {
+            type: 'scroll',
+            orient: 'vertical',
+            left: '-7',
+        },
+        series: [
+            {
+                type: 'pie',
+                radius: ['80%', '50%'],
+                center: ["76%", "50%"],
+                avoidLabelOverlap: false,
+                itemStyle: {
+                    borderRadius: 4,
+                    borderColor: '#fff',
+                    borderWidth: 1
+                },
+                label: {
+                    show: false,
+                    position: 'center'
+                },
+                emphasis: {
                     label: {
-                        show: false,
-                        position: 'center'
-                    },
-                    emphasis: {
-                        label: {
-                            show: true,
-                        }
-                    },
-                    labelLine: {
-                        show: false
-                    },
-                    data: [
-                        { value: 1048, name: '奉建路' },
-                        { value: 735, name: '西环线' },
-                        { value: 580, name: '陈油路' },
-                        { value: 484, name: '宝北路' }
-                    ]
-                }
-            ],
-        })
-    })
+                        show: true,
+                    }
+                },
+                labelLine: {
+                    show: false
+                },
+                data: datas.value
+            }
+        ],
+    }
 }
 
 //渲染完成
 onMounted(() => {
     nextTick(() => {
-        initChart()
-        windowResize()
+        setOptions()
     })
 })
-
-//被卸载
-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>

+ 104 - 0
src/components/echarts/PieSimple.vue

@@ -0,0 +1,104 @@
+<template>
+    <echartsBase :option="setOption"/>
+</template>
+
+<script setup>
+import { nextTick, onMounted, ref, watch } from 'vue'
+import echartsBase from './index.vue'
+
+const props = defineProps({
+    title: {
+        type: String,
+        default: '管理费用项目分摊占比情况'
+    },
+    color: {
+        type: Array,
+        default: () => (['#5087EC', '#68BBC4'])
+    },
+    unit: {
+        type: String,
+        default: '元'
+    },
+    datas: {
+        type: Array,
+        default: () => ([])
+    }
+})
+
+//初始变量
+const setOption = ref({})
+const titles = ref(props.title)
+const colors = ref(props.color)
+const units = ref(props.unit)
+const datas = ref(props.datas)
+
+watch(() => [
+    props.title,
+    props.color,
+    props.unit,
+], ([title, color, unit]) => {
+    titles.value = title
+    colors.value = color
+    units.value = unit
+    setOptions()
+})
+
+//深度监听数据变化
+watch(() => [
+    props.datas,
+], ([data]) => {
+    datas.value = data
+    setOptions()
+}, { deep: true })
+
+
+//设置图表
+const setOptions = () => {
+    setOption.value = {
+        color: colors.value,
+        title: {
+            text: titles.value,
+            left: 'center',
+            bottom: '0',
+            textStyle: {
+                color: '#B3B3B3',
+                fontSize: 14,
+            }
+        },
+        tooltip: {
+            trigger: 'item'
+        },
+        legend: {
+            top: 'top'
+        },
+        series: [
+            {
+                type: 'pie',
+                radius: '70%',
+                center: ["50%", "52%"],
+                label: {
+                    show: true,
+                    formatter(param) {
+                        return param.name + '\n' +  param.value + units.value;
+                    }
+                },
+                data: datas.value,
+                emphasis: {
+                    itemStyle: {
+                        shadowBlur: 10,
+                        shadowOffsetX: 0,
+                        shadowColor: 'rgba(0, 0, 0, 0.5)'
+                    }
+                }
+            }
+        ]
+    }
+}
+
+//渲染完成
+onMounted(() => {
+    nextTick(() => {
+        setOptions()
+    })
+})
+</script>

+ 57 - 110
src/components/echarts/SimpleChart.vue

@@ -1,136 +1,83 @@
 <template>
-    <div class="hac-echarts-box">
-        <div ref="echart" class="hac-echarts" :style="`width : ${chart?.clientWidth}px`"/>
-    </div>
+    <echartsBase :option="setOption"/>
 </template>
 
 <script setup>
-import * as echarts from 'echarts'
-import {useAppStore} from "~src/store";
+import echartsBase from './index.vue'
 import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
+
 const props = defineProps({
-    ratio: {
-        type: [Number,String],
-        default: 0
+    color: {
+        type: Array,
+        default: () => (['#5087EC', '#68BBC4'])
+    },
+    datas: {
+        type: Array,
+        default: () => ([])
     }
 })
 
 //初始变量
-let chart = null;
-const echart = ref(null)
-const useAppState = useAppStore()
-const AppColor = ref(useAppState.getColor);
+const setOption = ref({})
+const colors = ref(props.color)
+const datas = ref(props.datas)
 
 watch(() => [
-    props.ratio
-], ([ratio]) => {
-    setOptions(ratio, 100 - ratio)
+    props.color
+], ([color]) => {
+    colors.value = color
+    setOptions()
 })
 
-//初始化图表
-const initChart = () => {
-    chart = echarts.init(echart.value)
-    setOptions(props.ratio, 100 - props.ratio)
-}
-
-//监听浏览器窗口变化
-const windowResize = () => {
-    window.addEventListener("resize", resizeEvent);
-}
-
-const resizeEvent = () => {
-    window.requestAnimationFrame(() => {
-        chart.resize();
-    })
-}
+//深度监听数据变化
+watch(() => [
+    props.datas,
+], ([data]) => {
+    datas.value = data
+    setOptions()
+}, { deep: true })
 
 //设置图表
-const setOptions = (val1,val2) => {
-    nextTick(() => {
-        chart.setOption({
-            tooltip: {
-                trigger: "item",
-                formatter: "{d}%"
-            },
-            legend: {
-                type: 'scroll',
-                orient: 'vertical',
-                left: '-7',
-            },
-            series: [
-                {
-                    name: 'Access From',
-                    type: 'pie',
-                    radius: '80%',
-                    center: ["76%", "50%"],
-                    label: {
-                        show: false,
-                        position: "center",
-                    },
-                    labelLine: {
-                        show: false,
-                    },
-                    data: [
-                        { value: 1048, name: '奉建路' },
-                        { value: 735, name: '西环线' },
-                        { value: 580, name: '陈油路' },
-                        { value: 484, name: '宝北路' }
-                    ],
-                    emphasis: {
-                        itemStyle: {
-                            shadowBlur: 10,
-                            shadowOffsetX: 0,
-                            shadowColor: 'rgba(0, 0, 0, 0.5)'
-                        }
+const setOptions = () => {
+    setOption.value = {
+        color: colors.value,
+        tooltip: {
+            trigger: "item"
+        },
+        legend: {
+            type: 'scroll',
+            orient: 'vertical',
+            left: '-7',
+        },
+        series: [
+            {
+                type: 'pie',
+                radius: '80%',
+                center: ["76%", "50%"],
+                label: {
+                    show: false,
+                    position: "center",
+                },
+                labelLine: {
+                    show: false,
+                },
+                data: datas.value,
+                emphasis: {
+                    itemStyle: {
+                        shadowBlur: 10,
+                        shadowOffsetX: 0,
+                        shadowColor: 'rgba(0, 0, 0, 0.5)'
                     }
                 }
-            ]
-        })
-    })
+            }
+        ]
+    }
 }
 
 //渲染完成
 onMounted(() => {
     nextTick(() => {
-        initChart()
-        windowResize()
+        setOptions()
     })
 })
-
-//被卸载
-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>

+ 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>

+ 7 - 1
src/router/modules/base.js

@@ -54,6 +54,12 @@ export default [
                 name: 'home-budget-form',
                 meta: {title: '新增/编辑公司经营预算'},
                 component: () => import('~src/views/home/budget-form.vue')
+            },
+            {
+                path: '/home/budget-chart',
+                name: 'home-budget-chart',
+                meta: {title: '公司经营预算报表'},
+                component: () => import('~src/views/home/budget-chart.vue')
             }
         ],
     },
@@ -109,7 +115,7 @@ export default [
                 meta: {title: '组织架构管理'},
                 component: () => import('~src/views/system/organization.vue')
             },
-        
+
         ],
     },
     {

+ 2 - 1
src/router/modules/token.js

@@ -7,11 +7,12 @@ export default [
     'home-task-details',
     'home-budget',
     'home-budget-form',
+    'home-budget-chart',
     'user-index',
     'user-config',
     'system-user',
     'system-menu',
     'system-parameter',
     'system-organization',
-  
+
 ]

+ 38 - 3
src/views/home/admin.vue

@@ -138,7 +138,7 @@
                     <HcDropdown :cur="planTime" :datas="itemData"/>
                 </template>
                 <div class="hc-row-echarts-box" style="height: 260px">
-                    <BarLabelRotation/>
+                    <BarLabelRotation isMonth :datas="expendDatas"/>
                 </div>
             </HcCardItem>
 
@@ -187,7 +187,7 @@
                                         <HcDropdown :cur="planTime" :datas="itemData"/>
                                     </template>
                                     <div class="hac-card-item-body" style="height: 160px">
-                                        <BorderRadius/>
+                                        <BorderRadius :datas="expendStatisticsDatas"/>
                                     </div>
                                 </HcCardItem>
                             </el-col>
@@ -200,7 +200,7 @@
                                         <HcDropdown :cur="planTime" :datas="itemData"/>
                                     </template>
                                     <div class="hac-card-item-body" style="height: 160px">
-                                        <SimpleChart/>
+                                        <SimpleChart :datas="incomeStatisticsDatas"/>
                                     </div>
                                 </HcCardItem>
                             </el-col>
@@ -295,6 +295,41 @@ const options = [
     },
 ]
 
+//年度各项目支出对比
+const expendDatas = ref([
+    {
+        name: '奉建路',
+        value: [120, 132, 101, 134, 90, 230, 210, 210, 210, 210, 132, 101]
+    },
+    {
+        name: '西环线',
+        value: [120, 132, 101, 134, 90, 230, 210, 210, 210, 210, 132, 101]
+    },
+    {
+        name: '陈油路',
+        value: [120, 132, 101, 134, 90, 230, 210, 210, 210, 210, 132, 101]
+    },
+    {
+        name: '宝贝路',
+        value: [120, 132, 101, 134, 90, 230, 210, 210, 210, 210, 132, 101]
+    },
+])
+
+//各项目支出占比统计
+const expendStatisticsDatas = ref([
+    { value: 1048, name: '奉建路' },
+    { value: 735, name: '西环线' },
+    { value: 580, name: '陈油路' },
+    { value: 484, name: '宝北路' }
+])
+
+//各项目收入占比统计
+const incomeStatisticsDatas = ref([
+    { value: 1048, name: '奉建路' },
+    { value: 735, name: '西环线' },
+    { value: 580, name: '陈油路' },
+    { value: 484, name: '宝北路' }
+])
 </script>
 
 <style lang="scss" scoped>

+ 123 - 0
src/views/home/budget-chart.vue

@@ -0,0 +1,123 @@
+<template>
+    <HcCard scrollbar>
+        <template #header>
+            <div class="w-36">
+                <el-select v-model="annual" block clearable placeholder="选择年度" size="large">
+                    <el-option v-for="item in annuals" :label="item.name" :value="item.key"/>
+                </el-select>
+            </div>
+        </template>
+        <template #extra>
+            <el-button size="large" type="info" hc-btn @click="goBackClick">
+                <HcIcon name="arrow-go-back"/>
+                <span>返回列表</span>
+            </el-button>
+        </template>
+        <div class="hc-main-row">
+            <el-row :gutter="14">
+                <el-col :span="8">
+                    <HcCardItem body-ui="h-96-i">
+                        <BarLabelChart :datas="contractDatas"/>
+                    </HcCardItem>
+                </el-col>
+                <el-col :span="8">
+                    <HcCardItem body-ui="h-96-i">
+                        <BarLabelChart :datas="manageDatas"/>
+                    </HcCardItem>
+                </el-col>
+                <el-col :span="8">
+                    <HcCardItem body-ui="h-96-i">
+                        <BarLabelChart :datas="profitDatas"/>
+                    </HcCardItem>
+                </el-col>
+            </el-row>
+            <el-row :gutter="14" class="mt-4">
+                <el-col :span="12">
+                    <HcCardItem body-ui="h-96-i">
+                        <PieSimple :datas="pieSimpleDatas"/>
+                    </HcCardItem>
+                </el-col>
+                <el-col :span="12">
+                    <HcCardItem body-ui="h-96-i">
+                        <AreaStack :datas="areaStackDatas"/>
+                    </HcCardItem>
+                </el-col>
+            </el-row>
+        </div>
+    </HcCard>
+</template>
+
+<script setup>
+import {onActivated, ref} from "vue";
+import {useRouter} from 'vue-router'
+import BarLabelChart from "~com/echarts/BarLabelChart.vue";
+import PieSimple from "~com/echarts/PieSimple.vue";
+import AreaStack from "~com/echarts/AreaStack.vue";
+
+const router = useRouter()
+
+const annual = ref('2023')
+const annuals = ref([
+    {name: '2023年', key: '2023'},
+    {name: '2022年', key: '2022'},
+    {name: '2021年', key: '2021'}
+])
+
+//缓存页面被激活时
+onActivated(() => {
+
+})
+
+//合同指标、实际合同额
+const contractDatas = ref([
+    {name: '合同指标', value: 190000},
+    {name: '实际合同额', value: 8000}
+])
+
+//经营预算
+const manageDatas = ref([
+    {name: '经营预算', value: 120000},
+    {name: '实际支出', value: 80000}
+])
+
+//利润指标
+const profitDatas = ref([
+    {name: '利润指标', value: 90010},
+    {name: '实际利润', value: 38230}
+])
+
+//管理费用项目分摊
+const pieSimpleDatas = ref([
+    { value: 1048, name: '已分摊' },
+    { value: 735, name: '未分摊' },
+])
+
+//管理费用支出
+const areaStackDatas = ref([
+    {
+        name: '剩余预算',
+        value: [120, 132, 101, 134, 90, 230, 210, 210, 210, 210, 132, 101]
+    },
+    {
+        name: '已支出预警',
+        value: [220, 182, 191, 234, 290, 330, 310, 310, 310, 310, 182, 191]
+    }
+])
+
+//返回列表
+const goBackClick = () => {
+    router.back()
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>
+
+<style lang="scss">
+.hc-main-row {
+    .h-96-i {
+        height: 24rem !important;
+    }
+}
+</style>

+ 15 - 3
src/views/home/budget.vue

@@ -8,11 +8,11 @@
             </div>
         </template>
         <template #extra>
-            <el-button size="large" color="#7728F5" hc-btn>
+            <el-button size="large" color="#7728F5" hc-btn @click="toBudgetChartClick">
                 <HcIcon name="folder-chart"/>
                 <span>报表查看</span>
             </el-button>
-            <el-button size="large" type="primary" hc-btn>
+            <el-button size="large" type="primary" hc-btn @click="addRowClick">
                 <HcIcon name="add"/>
                 <span>新增经营预算</span>
             </el-button>
@@ -78,7 +78,7 @@ const getTableData = () => {
 }
 
 
-//编辑
+//编辑预算
 const editRowClick = (row) => {
     router.push({
         name: 'home-budget-form', query: {
@@ -87,6 +87,18 @@ const editRowClick = (row) => {
     })
 }
 
+//新增预算
+const addRowClick = () => {
+    router.push({
+        name: 'home-budget-form'
+    })
+}
+
+const toBudgetChartClick = () => {
+    router.push({
+        name: 'home-budget-chart'
+    })
+}
 </script>
 
 <style lang="scss" scoped>

+ 16 - 4
src/views/home/index.vue

@@ -155,7 +155,7 @@
                 </template>
                 <div class="hac-card-item-body">
                     <div class="hc-row-echarts-box">
-                        <BarLabelRotation/>
+                        <BarLabelRotation isMonth :datas="planDatas"/>
                     </div>
                 </div>
             </HcCardItem>
@@ -187,10 +187,22 @@ const tableData = ref([
 //选择日期时间
 const planTime = ref('2023年02月')
 const itemData = ref([{name: '2023年02月'}, {name: '2023年03月'}, {name: '2023年04月'}, {name: '2023年05月'}])
-const planTimeClick = (item) => {
-    planTime.value = item.name
-}
 
+//计划统计图
+const planDatas = ref([
+    {
+        name: '总计划',
+        value: [120, 132, 101, 134, 90, 230, 210, 210, 210, 210, 132, 101]
+    },
+    {
+        name: '已完成',
+        value: [120, 132, 101, 134, 90, 230, 210, 210, 210, 210, 132, 101]
+    },
+    {
+        name: '未完成',
+        value: [120, 132, 101, 134, 90, 230, 210, 210, 210, 210, 132, 101]
+    },
+])
 </script>
 
 <style lang="scss" scoped>

Різницю між файлами не показано, бо вона завелика
+ 533 - 465
yarn.lock


Деякі файли не було показано, через те що забагато файлів було змінено