Parcourir la source

Merge branch 'master' into 'master'

新增运营监测报表

See merge request lighter/vue-intergration-platform!28
huangshuhua il y a 2 ans
Parent
commit
8005bdda56

+ 19 - 1
src/api/reports/high-report.js

@@ -3,6 +3,15 @@ import { ElMessage, ElMessageBox } from 'element-plus'
 import { downloadExcel } from '@/utils/excel'
 
 // 查询菜单报表
+export function selectReportPortal(data) {
+    return request({
+        url: '/highReport/selectReportPortal',
+        method: 'post',
+        data,
+    })
+}
+
+// 查询单个菜单报表
 export function selectReportPortalMenu(data) {
     return request({
         url: '/highReport/selectReportPortalMenu',
@@ -44,4 +53,13 @@ export function exportReportPortalData(params) {
         }
     })
 
-}
+}
+
+// 查询菜单报表钻取分组数据
+export function selectReportGroup(data) {
+    return request({
+        url: '/highReport/selectReportGroup',
+        method: 'post',
+        data,
+    })
+}

+ 126 - 0
src/components/operate-monitoring/ReportFirstPage.vue

@@ -0,0 +1,126 @@
+<template>
+    <page-layer>
+        <template #header>
+            <div style="text-align: center">
+                统计日期:
+                <!-- <span v-if="reportFirst.kssj" style="color: #fc6c34;">
+                        {{ reportFirst.kssj }} 至 {{ reportFirst.jssj }}
+                    </span> -->
+                <span style="color: #fc6c34;">当前</span>
+                统计机构名称:<span style="color: #fc6c34;">长沙泰和医院</span>
+                指标名称: <span style="color: #fc6c34;">{{ reportInfo1.reportName }}</span>
+                统计结果描述: <span style="color: #fc6c34;">{{ reportInfo1.overview }}{{ reportInfo1.unit }}</span>
+            </div>
+        </template>
+        <template #aside>
+            <el-table :data="reportData" :height="tableHeight" highlight-current-row row-key="childKey" stripe border
+                @row-dblclick="reportSecondInfo">
+                <el-table-column prop="x" :label="x1Name" width="120"></el-table-column>
+                <el-table-column prop="y" :label="y1Name"></el-table-column>
+            </el-table>
+        </template>
+        <template #main>
+            <div style="width: 80%; height: 400px; margin-bottom: 5px;" id="firstPie"></div>
+            <div style="width: 80%; height: 400px" id="firstDst"></div>
+        </template>
+    </page-layer>
+    <el-dialog v-if="props.reportFirst.tableInfo.sndGroup !== 'patient'" :title="titleChart" v-model="sndDrawer"
+        fullscreen destroy-on-close>
+        <ReportSecondPage :reportSecond="reportSecond" />
+    </el-dialog>
+    <el-dialog v-else :title="titleChart" v-model="patientDrawer" width="80%" height="80%" top="40px" draggable destroy-on-close>
+        <ReportPatientPage :reportPatient="reportPatient" />
+    </el-dialog>
+</template>
+<script setup name="ReportFirst">
+import { ref } from "vue"
+import { useStore } from 'vuex'
+import { clone } from '@/utils/clone'
+import PageLayer from '@/layout/PageLayer.vue'
+import { highBarUtils, highPieUtils } from '@/utils/high-charts'
+import { selectReportGroup } from '@/api/reports/high-report'
+import ReportSecondPage from '@/components/operate-monitoring/ReportSecondPage.vue'
+import ReportPatientPage from '@/components/operate-monitoring/ReportPatientPage.vue'
+
+const storeU = useStore()
+const windowSize = storeU.state.app.windowSize
+const tableHeight = windowSize.h - 105
+const props = defineProps({
+    reportFirst: {
+        type: Object,
+        default: {}
+    }
+})
+nextTick(() => {
+    showFirstPst()
+})
+// 报表基本信息
+const reportInfo1 = ref({})
+// 报表展示值
+const reportData = ref({})
+// 表格展示信息
+const tableData = ref({})
+// 查询信息
+const param1 = ref({})
+
+const x1Name = ref('')
+const y1Name = ref('')
+
+reportData.value = props.reportFirst.data
+reportInfo1.value = props.reportFirst.row
+tableData.value = props.reportFirst.tableInfo
+param1.value = props.reportFirst.params
+
+const showFirstPst = () => {
+    let barTitle = reportInfo1.value.reportName
+    let yAxisName = '单位:' + reportInfo1.value.unit
+    let tipUnit = reportInfo1.value.unit
+    let xdata = []
+    let ydata = []
+    let pieData = []
+    x1Name.value = tableData.value.fstName
+    y1Name.value = reportInfo1.value.unit
+
+    reportData.value.forEach((item) => {
+        let pieInfo = {}
+        pieInfo.value = item.y
+        pieInfo.name = item.x
+        pieInfo.unit = reportInfo1.value.unit
+        xdata.push(item.x)
+        ydata.push(item.y)
+        pieData.push(pieInfo)
+    })
+
+    highBarUtils(firstDst, barTitle, xdata, ydata, barTitle, yAxisName, tipUnit, 1)
+    highPieUtils(firstPie, barTitle, pieData)
+}
+
+// 钻取的查询结果
+const sndDrawer = ref(false)
+const reportSecond = ref({})
+const patientDrawer = ref(false)
+const reportPatient = ref({})
+const titleChart = ref('')
+const reportSecondInfo = (row) => {
+    reportInfo1.value.fstName = row.x
+    reportInfo1.value.fstValue = row.y
+    let params = clone(param1.value)
+    params.fstName = row.x
+    // 下一级是病人,则走最后固定的病人明细展示页面
+    let sndGroup = tableData.value.sndGroup
+    if (sndGroup === 'patient') {
+        titleChart.value = reportInfo1.value.reportName
+        patientDrawer.value = true
+        reportPatient.value.row = reportInfo1.value
+        reportPatient.value.params = clone(params)
+    } else {
+        selectReportGroup(params).then((res) => {
+            reportSecond.value = res
+            titleChart.value = res.title
+            sndDrawer.value = true
+            reportSecond.value.row = reportInfo1.value
+            reportSecond.value.params = clone(params)
+        })
+    }
+}
+</script>

+ 75 - 0
src/components/operate-monitoring/ReportPatientPage.vue

@@ -0,0 +1,75 @@
+<template>
+    <page-layer>
+        <template #header>
+            <el-button type="primary" icon="Download" @click="exportData" style="margin-left: 2px">导出</el-button>
+        </template>
+        <template #main>
+            <xc-table :data="returnData" localPaging :height="105">
+                <el-table-column type="index" label="序号" align="center"></el-table-column>
+                <template v-for="col in returnData.tableDisplays">
+                    <el-table-column v-if="col.sortable" :prop="col.prop" :label="col.label" :width="col.width"
+                        :align="col.align" sortable show-overflow-tooltip>
+                    </el-table-column>
+                    <el-table-column v-else :prop="col.prop" :label="col.label" :width="col.width" :align="col.align"
+                        show-overflow-tooltip>
+                    </el-table-column>
+                </template>
+            </xc-table>
+        </template>
+    </page-layer>
+</template>
+<script setup name="ReportPatientPage">
+import PageLayer from '@/layout/PageLayer.vue'
+import { ref } from '@vue/reactivity'
+import { clone } from '@/utils/clone'
+import { selectReportPortalMenu, exportReportPortalData } from '@/api/reports/high-report'
+import XcTable from "@/components/xiao-chan/xc-table/XcTable"
+
+const props = defineProps({
+    reportPatient: {
+        type: Object,
+        default: {}
+    }
+})
+
+// 报表基本信息
+const reportPatient = ref({})
+// 查询信息
+const paramPatient = ref({})
+
+reportPatient.value = props.reportPatient.row
+paramPatient.value = props.reportPatient.params
+
+nextTick(() => {
+    query()
+})
+const returnData = ref({
+    currentPage: 1,
+    pageSize: 30,
+    total: 0,
+    data: []
+});
+
+const queryTerm = clone(paramPatient.value)
+const query = async () => {
+    selectReportPortalMenu(queryTerm)
+        .then((res) => {
+            returnData.value.tableDisplays = res.tableDisplays
+            returnData.value.data = res.dataList
+            returnData.value.total = returnData.value.data.length
+        });
+};
+const exportData = () => {
+    if (returnData.value.data.length <= 0) {
+        ElMessage({
+            message: '没有可以导出的数据!',
+            type: 'warning',
+            duration: 2500,
+            showClose: true,
+        })
+    }
+    // 导出excel表格标题
+    queryTerm.exportName = reportPatient.value.reportName;
+    exportReportPortalData(queryTerm)
+}
+</script>

+ 129 - 0
src/components/operate-monitoring/ReportSecondPage.vue

@@ -0,0 +1,129 @@
+<template>
+    <page-layer>
+        <template #header>
+            <div style="text-align: center">
+                统计日期:
+                <!-- <span v-if="reportFirst.kssj" style="color: #fc6c34;">
+                        {{ reportFirst.kssj }} 至 {{ reportFirst.jssj }}
+                    </span> -->
+                <span style="color: #fc6c34;">当前</span>
+                统计机构名称:<span style="color: #fc6c34;">长沙泰和医院</span>
+                指标名称: <span style="color: #fc6c34;">{{ reportInfo2.reportName }}</span>
+                统计结果描述: <span style="color: #fc6c34;">{{ reportInfo2.overview }}{{ reportInfo2.unit }}</span>
+                <span style="color: #3742fa;">&nbsp;{{ reportInfo2.fstName }}: </span>
+                <span style="color: #fc6c34;">{{ reportInfo2.fstValue }}{{ reportInfo2.unit }}</span>
+            </div>
+            <el-button type="primary" style="margin-left: 10px;">返回</el-button>
+        </template>
+        <template #aside>
+            <el-table :data="reportData" :height="tableHeight" highlight-current-row row-key="childKey" stripe border
+                @row-dblclick="reportThirdInfo">
+                <el-table-column prop="x" :label="x2Name" width="120"></el-table-column>
+                <el-table-column prop="y" :label="y2Name"></el-table-column>
+            </el-table>
+        </template>
+        <template #main>
+            <div style="width: 80%; height: 400px; margin-bottom: 5px;" id="secondPie"></div>
+            <div style="width: 80%; height: 400px" id="secondDst"></div>
+        </template>
+    </page-layer>
+    <el-dialog v-if="props.reportSecond.tableInfo.trdGroup !== 'patient'" :title="titleChart" v-model="thirdDrawer"
+        fullscreen destroy-on-close>
+        <ReportThirdPage :reportThird="reportThird" />
+    </el-dialog>
+    <el-dialog v-else :title="titleChart" v-model="patientDrawer" width="80%" height="80%" top="40px" draggable destroy-on-close>
+        <ReportPatientPage :reportPatient="reportPatient" />
+    </el-dialog>
+</template>
+<script setup name="ReportFirst">
+import { ref } from "vue"
+import { useStore } from 'vuex'
+import { clone } from '@/utils/clone'
+import PageLayer from '@/layout/PageLayer.vue'
+import { highBarUtils, highPieUtils } from '@/utils/high-charts'
+import { selectReportGroup } from '@/api/reports/high-report'
+import ReportThirdPage from '@/components/operate-monitoring/ReportThirdPage.vue'
+import ReportPatientPage from '@/components/operate-monitoring/ReportPatientPage.vue'
+
+const storeU = useStore()
+const windowSize = storeU.state.app.windowSize
+const tableHeight = windowSize.h - 105
+const props = defineProps({
+    reportSecond: {
+        type: Object,
+        default: {}
+    }
+})
+nextTick(() => {
+    showSecondPst()
+})
+// 报表基本信息
+const reportInfo2 = ref({})
+// 报表展示值
+const reportData = ref({})
+// 表格展示信息
+const tableData = ref({})
+// 查询信息
+const param2 = ref({})
+
+const x2Name = ref('')
+const y2Name = ref('')
+
+reportData.value = props.reportSecond.data
+reportInfo2.value = props.reportSecond.row
+tableData.value = props.reportSecond.tableInfo
+param2.value = props.reportSecond.params
+
+const showSecondPst = () => {
+    let barTitle = reportInfo2.value.reportName
+    let yAxisName = '单位:' + reportInfo2.value.unit
+    let tipUnit = reportInfo2.value.unit
+    let xdata = []
+    let ydata = []
+    let pieData = []
+    x2Name.value = tableData.value.sndName
+    y2Name.value = reportInfo2.value.unit
+
+    reportData.value.forEach((item) => {
+        let pieInfo = {}
+        pieInfo.value = item.y
+        pieInfo.name = item.x
+        pieInfo.unit = reportInfo2.value.unit
+        xdata.push(item.x)
+        ydata.push(item.y)
+        pieData.push(pieInfo)
+    })
+
+    highBarUtils(secondDst, barTitle, xdata, ydata, barTitle, yAxisName, tipUnit, 1)
+    highPieUtils(secondPie, barTitle, pieData)
+}
+
+// 钻取的查询结果
+const thirdDrawer = ref(false)
+const reportThird = ref({})
+const patientDrawer = ref(false)
+const reportPatient = ref({})
+const titleChart = ref('')
+const reportThirdInfo = (row) => {
+    reportInfo2.value.sndName = row.x
+    reportInfo2.value.sndValue = row.y
+    let params = clone(param2.value)
+    params.sndName =  row.x
+    // 下一级是病人,则走最后固定的病人明细展示页面
+    let trdGroup = tableData.value.trdGroup
+    if (trdGroup === 'patient') {
+        titleChart.value = reportInfo2.value.reportName
+        patientDrawer.value = true
+        reportPatient.value.row = reportInfo2.value
+        reportPatient.value.params = clone(params)
+    } else {
+        selectReportGroup(params).then((res) => {
+            reportThird.value = res
+            titleChart.value = res.title
+            thirdDrawer.value = true
+            reportThird.value.row = reportInfo2.value
+            reportThird.value.params = clone(params)
+        })
+    }
+}
+</script>

+ 102 - 0
src/components/operate-monitoring/ReportThirdPage.vue

@@ -0,0 +1,102 @@
+<template>
+    <page-layer>
+        <template #header>
+            <div style="text-align: center">
+                统计日期:
+                <!-- <span v-if="reportFirst.kssj" style="color: #fc6c34;">
+                        {{ reportFirst.kssj }} 至 {{ reportFirst.jssj }}
+                    </span> -->
+                <span style="color: #fc6c34;">当前</span>
+                统计机构名称:<span style="color: #fc6c34;">长沙泰和医院</span>
+                指标名称: <span style="color: #fc6c34;">{{ reportInfo3.reportName }}</span>
+                统计结果描述: <span style="color: #fc6c34;">{{ reportInfo3.overview }}{{ reportInfo3.unit }}</span>
+                <span style="color: #3742fa;">&nbsp;{{ reportInfo3.fstName }}: </span>
+                <span style="color: #fc6c34;">{{ reportInfo3.fstValue }}{{ reportInfo3.unit }}</span>
+                <span style="color: #3742fa;">&nbsp;{{ reportInfo3.sndName }}: </span>
+                <span style="color: #fc6c34;">{{ reportInfo3.sndValue }}{{ reportInfo3.unit }}</span>
+            </div>
+            <el-button type="primary" icon="Search" style="margin-left: 10px;">返回</el-button>
+        </template>
+        <template #aside>
+            <el-table :data="reportData" :height="tableHeight" highlight-current-row row-key="childKey" stripe border
+                @row-dblclick="dbClickPatient">
+                <el-table-column prop="x" :label="x3Name" width="120"></el-table-column>
+                <el-table-column prop="y" :label="y3Name"></el-table-column>
+            </el-table>
+        </template>
+        <template #main>
+            <div style="width: 80%; height: 400px; margin-bottom: 5px;" id="thirdPie"></div>
+            <div style="width: 80%; height: 400px" id="thirdDst"></div>
+        </template>
+    </page-layer>
+    <el-dialog :title="titleChart" v-model="patientDrawer" width="80%" height="80%" top="40px" draggable destroy-on-close>
+        <ReportPatientPage :reportPatient="reportPatient" />
+    </el-dialog>
+</template>
+<script setup name="ReportFirst">
+import { ref } from "vue"
+import { useStore } from 'vuex'
+import PageLayer from '@/layout/PageLayer.vue'
+import { highBarUtils, highPieUtils } from '@/utils/high-charts'
+import ReportPatientPage from '@/components/operate-monitoring/ReportPatientPage.vue'
+
+const storeU = useStore()
+const windowSize = storeU.state.app.windowSize
+const tableHeight = windowSize.h - 105
+const props = defineProps({
+    reportThird: {
+        type: Object,
+        default: {}
+    }
+})
+nextTick(() => {
+    showSecondPst()
+})
+// 报表基本信息
+const reportInfo3 = ref({})
+// 报表展示值
+const reportData = ref({})
+// 表格展示信息
+const tableData = ref({})
+
+const x3Name = ref('')
+const y3Name = ref('')
+
+reportData.value = props.reportThird.data
+reportInfo3.value = props.reportThird.row
+tableData.value = props.reportThird.tableInfo
+const showSecondPst = () => {
+    let barTitle = reportInfo3.value.reportName
+    let yAxisName = '单位:' + reportInfo3.value.unit
+    let tipUnit = reportInfo3.value.unit
+    let xdata = []
+    let ydata = []
+    let pieData = []
+    x3Name.value = tableData.value.trdName
+    y3Name.value = reportInfo3.value.unit
+
+    reportData.value.forEach((item) => {
+        let pieInfo = {}
+        pieInfo.value = item.y
+        pieInfo.name = item.x
+        pieInfo.unit = reportInfo3.value.unit
+        xdata.push(item.x)
+        ydata.push(item.y)
+        pieData.push(pieInfo)
+    })
+
+    highBarUtils(thirdDst, barTitle, xdata, ydata, barTitle, yAxisName, tipUnit, 1)
+    highPieUtils(thirdPie, barTitle, pieData)
+}
+
+// 钻取病人的查询结果(目前仅限钻取这一层之后必须是病人页)
+const patientDrawer = ref(false)
+const reportPatient = ref({})
+const titleChart = ref('')
+const dbClickPatient = (row) => {
+    reportInfo3.value.trdName = row.x
+    titleChart.value = reportInfo3.value.reportName
+    reportPatient.value.row = reportInfo3.value
+    patientDrawer.value = true
+}
+</script>

+ 45 - 0
src/router/modules/dashboard.js

@@ -699,6 +699,51 @@ const route = [
             },
         ],
     },
+
+    {
+        path: '/operateMonitoring',
+        component: Layout,
+        meta: {title: '运营监测'},
+        children: [
+            {
+                path: 'inpatient/inHospital',
+                component: createNameComponent(() => import('@/views/operate-monitoring/OperateMonitoring.vue')),
+                meta: {title: '在院运营监测'},
+                params: {
+                    reportType: "zy",
+                    menuId: "122",
+                    levelType: "2",
+                    type: "2",
+                }
+            },
+            {
+                path: 'inpatient/outHospital',
+                component: createNameComponent(() => import('@/views/operate-monitoring/OperateMonitoringDate.vue')),
+                meta: {title: '出院运营监测'},
+                params: {
+                    startTime: "",
+                    endTime: "",
+                    reportType: "cy",
+                    menuId: "123",
+                    levelType: "2",
+                    type: "2",
+                }
+            },
+            {
+                path: 'outpatient/outpatientDept',
+                component: createNameComponent(() => import('@/views/operate-monitoring/OperateMonitoringDate.vue')),
+                meta: {title: '门诊运营监测'},
+                params: {
+                    startTime: "",
+                    endTime: "",
+                    reportType: "mz",
+                    menuId: "124",
+                    levelType: "2",
+                    type: "2",
+                }
+            },
+        ],
+    },
 ]
 
 export default route

+ 240 - 0
src/utils/high-charts.js

@@ -0,0 +1,240 @@
+import * as echarts from 'echarts'
+
+/**
+ * 参数
+ * @param id 图渲染容器id
+ * @param name 图标题
+ * @param Xdata x轴数据
+ * @param Ydata y轴数据
+ * @param seriesName 图数据种类
+ * @param yAxisName y轴单位说明
+ * @param db x轴倍数,默认是1
+ * @param isDrillDown 是否开启数据钻取
+ */
+export function highBarUtils(id, name, Xdata, Ydata, seriesName, yAxisName, unit, db) {
+    // 验证 这个 是否被创建了
+    let linearBarDom = echarts.getInstanceByDom(id)
+    if (linearBarDom == null) {
+        linearBarDom = echarts.init(id)
+    }
+    if (db == null) {
+        db = 1
+    }
+
+    linearBarDom.setOption({
+        title: {
+            text: name,
+            x: 'center',
+            y: 'bottom',
+            textAlign: 'left',
+        },
+        xAxis: {
+            type: 'category',
+            data: Xdata,
+            axisLabel: {
+                color: '#bb3137',
+                fontSize: 16
+            }
+        },
+        yAxis: {
+            type: 'value',
+            name: yAxisName,
+            nameLocation: 'end',
+            axisLabel: {
+                show: true,
+                interval: 0,
+                formatter: function (value, index) {
+                    return value / db
+                }
+            }
+        },
+        legend: {
+            data: [
+                {
+                    name: seriesName,
+                    icon: 'rect',
+                }
+            ],
+            top: "0%"
+        },
+        tooltip: {
+            trigger: 'axis',
+            confine: true,
+            formatter: function (param) {
+                let relVal = param[0].name + '<br>'
+                param.forEach((item, index) => {
+                    if (item.value && 'bar' == param[index].seriesType) {
+                        relVal += item.marker + ' ' + item.seriesName + ' : ' + item.value + unit + '</br>'
+                    } else if (item.value && 'line' == param[index].seriesType) {
+
+                    } else {
+                        relVal += item.marker + ' ' + item.seriesName + ' : - </br>'
+                    }
+                })
+                return relVal
+            }
+
+        },
+        toolbox: {
+            show: 1,
+            itemSize: 24,
+            x: 'right',
+            y: 'top',
+            feature: {
+                saveAsImage: {
+                    show: true,
+                    title: '下载图片',
+                    type: 'png'
+                }
+            }
+        },
+        series: [
+            {
+                name: seriesName,
+                type: 'bar',
+                // stack: 'all',
+                barMaxwidth: 35,
+                barGap: '10%',
+                color: {
+                    type: 'linear',
+                    x: 0,
+                    y: 1,
+                    colorStops: [
+                        {
+                            offset: 0,
+                            color: '#6633ff',
+                        },
+                        {
+                            offset: 0.35,
+                            color: '#6699ff'
+                        },
+                        {
+                            offset: 1,
+                            color: '#66ffff'
+                        }
+                    ]
+                },
+                label: {
+                    show: true,
+                    color: '#000000',
+                    position: 'top',
+                    formatter(p) {
+                        return db != 1 ? (p.value / db).toFixed(2) : p.value
+                    }
+                },
+                data: Ydata,
+                emphasis: {
+                    itemStyle: {
+                        borderRadius: 30
+                    }
+                },
+                itemStyle: {
+                    borderRadius: [12, 12, 0, 0],
+                }
+            },
+        ]
+    })
+
+    window.onresize = function () {
+        //自适应大小, 不用的话不会自适应大小。
+        linearBarDom.resize()
+    }
+}
+
+export function highPieUtils(id, name, data) {
+    // 验证 这个 是否被创建了
+    let linearBarDom = echarts.getInstanceByDom(id)
+
+    if (linearBarDom == null) {
+        linearBarDom = echarts.init(id)
+    }
+
+    linearBarDom.setOption({
+        title: {
+            text: name, // 设置主标题文本
+            show: true, // 显示标题组件
+            x: 'center', //水平安放位置,默认为'left',可选为:'center' | 'left' | 'right' | {number}(x坐标,单位px)
+            y: 'bottom', //垂直安放位置,默认为top,可选为:'top' | 'bottom' | 'center' | {number}(y坐标,单位px)
+            padding: [10, 0, 0, 0], //可设定图例[距上方距离,距右方距离,距下方距离,距左方距离]
+        },
+        // 这个就是旁边的那个颜色小方块
+        legend: {
+            //朝向 : 垂直(vertical),水平(horizontal)
+            orient: 'vertical',
+            type: 'scroll', // 分页滚动
+            x: 'left', //可设定图例在left、right、center
+            y: 'top', //可设定图例在top、bottom、center
+            padding: [0, 10, 0, 10], //可设定图例[距上方距离,距右方距离,距下方距离,距左方距离]
+            // 这个是 圆形旁边的 小方块 自定义
+            formatter: function (name) {
+                // 通过name获取到数组对象中的单个对象
+                let singleData = data.filter(function (item) {
+                    return item.name == name
+                })
+                return `${name} | ${singleData[0].value} ${singleData[0].unit}`
+            },
+            textStyle: {
+                rich: {
+                    a: {
+                        width: 120,
+                        lineHeight: 12
+                    }
+                }
+            }
+        },
+        tooltip: {
+            //提示框组件
+            trigger: 'item', //item数据项图形触发,主要在散点图,饼图等无类目轴的图表中使用。
+            // backgroundColor: 'rgba(255,255,255,0.8)', //设置背景图片 rgba格式
+            // color: 'black',
+            // borderWidth: '1', //边框宽度设置1
+            // borderColor: 'gray', //设置边框颜色
+            // textStyle: {
+            //   color: 'black', //设置文字颜色
+            // },
+            axisPointer: {
+                // 坐标轴指示器,坐标轴触发有效
+                type: 'shadow', // 默认为直线,可选为:'line' | 'shadow'
+            },
+            // formatter: '{a} <br/>{b} : {c} <br/>百分比 : {d}%', //{a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
+            //原来的 替换成我需要的 这个是鼠标移上去出现的
+            formatter: function (data) {
+                return `
+          <span style="background-color:${data.color};display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px"></span>
+                <span>${data.seriesName}<span><br/>
+                <span>${data.name} : <span style="color:red;">${data.value}</span> ${data.data.unit}<span><br/>
+                <span>百分比 : ${data.percent} %</span>
+                `
+            },
+        },
+        toolbox: {
+            // 导出组件
+            show: 1,
+            itemSize: 24,
+            x: 'right',
+            y: 'top',
+            feature: {
+                saveAsImage: {
+                    show: true,
+                    title: '下载图片',
+                    type: 'png'
+                }
+            }
+        },
+        series: [
+            {
+                center: ['50%', '50%'],
+                radius: '50%', // 饼图的半径,外半径为可视区尺寸(容器高宽中较小一项)的 55% 长度。
+                type: 'pie', // 类型 圆形
+                data: data, // 数据
+                name: name, // 名字
+                minAngle: 10, //设置扇形的最小占比 不然有些太小了 就看不到了
+            },
+        ],
+        //color: createColorCode(data),
+    })
+    window.onresize = function () {
+        //自适应大小, 不用的话不会自适应大小。
+        linearBarDom.resize()
+    }
+}

+ 108 - 0
src/views/operate-monitoring/OperateMonitoring.vue

@@ -0,0 +1,108 @@
+<template>
+    <page-layer>
+        <template #main>
+            <xc-table :data="returnData" :openPaging="false" :height="15">
+                <el-table-column type="index" label="序号" width="100">
+                    <template #default="scope">
+                        <span class="index_common">{{ scope.$index + 1 }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column prop="result" label="统计结果" width="500" show-overflow-tooltip>
+                    <template #default="scope">
+                        {{ scope.row.reportName }}:
+                        <span style="color: #fc0404;">{{ scope.row.overview }}</span>
+                        {{ scope.row.unit }}
+                    </template>
+                </el-table-column>
+                <el-table-column prop="timeFine" label="统计日期" width="220">
+                    <template #default="scope">
+                        <span v-if="scope.row.kssj">{{ scope.row.kssj }} 至 {{ scope.row.jssj }}</span>
+                        <span v-else>{{ nowdate }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column prop="port" label="操作" width="120">
+                    <template #default="scope">
+                        <el-button type="primary" size="small" @click="reportFirstInfo(scope.row)">详细信息</el-button>
+                    </template>
+                </el-table-column>
+            </xc-table>
+        </template>
+    </page-layer>
+    <el-dialog :title="titleChart" v-model="fstDrawer" fullscreen destroy-on-close>
+        <ReportFirstPage :reportFirst="reportFirst" />
+    </el-dialog>
+</template>
+<script setup name="OperateMonitoring">
+import PageLayer from '@/layout/PageLayer.vue'
+import { getDate } from '@/utils/date'
+import { clone } from '@/utils/clone'
+import router from "@/router"
+import { ref } from '@vue/reactivity'
+import XcTable from "@/components/xiao-chan/xc-table/XcTable"
+import { selectReportPortal, selectReportGroup } from '@/api/reports/high-report'
+import ReportFirstPage from '@/components/operate-monitoring/ReportFirstPage.vue'
+
+const nowdate = getDate()
+const queryTerm = ref({})
+onMounted(() => {
+    let val = router.options.routes.filter(e => e.path === '/operateMonitoring')[0].children;
+    let param = val.filter(f => f.path === 'inpatient/inHospital')[0].params
+    queryTerm.value = param
+    query();
+});
+const returnData = ref({
+    currentPage: 1,
+    pageSize: 30,
+    total: 0,
+    title: '',
+    data: []
+});
+const query = async () => {
+    selectReportPortal(queryTerm.value)
+        .then((res) => {
+            returnData.value.data = res.data
+            returnData.value.title = res.title
+        });
+};
+// ------------------------------详细信息----------------------------------------
+const fstDrawer = ref(false)
+const reportFirst = ref({})
+const titleChart = ref('')
+const reportFirstInfo = (row) => {
+    const params = {
+        reportId: row.reportId,
+        reportName: row.reportName,
+        reportType: row.reportType,
+        displayType: row.displayType,
+        menuId: row.menuId,
+        levelType: queryTerm.value.levelType,
+        type: queryTerm.value.type,
+    }
+    selectReportGroup(params).then((res) => {
+        reportFirst.value = res
+        titleChart.value = res.title
+        fstDrawer.value = true
+        reportFirst.value.row = row
+        reportFirst.value.params = clone(params)
+    })
+}
+</script>
+<style scoped>
+.index_common {
+    text-shadow: none;
+    font-size: 10px;
+    padding-top: 1px;
+    padding-bottom: 3px;
+    font-weight: normal;
+    line-height: 12px;
+    display: inline-block;
+    min-width: 10px;
+    padding: 3px 7px;
+    text-align: center;
+    white-space: nowrap;
+    vertical-align: baseline;
+    border-radius: 4em;
+    color: #fff;
+    background: #1e90ff;
+}
+</style>

+ 141 - 0
src/views/operate-monitoring/OperateMonitoringDate.vue

@@ -0,0 +1,141 @@
+<template>
+    <page-layer>
+        <template #header>
+            <el-date-picker v-model="dateRange" type="daterange" range-separator="至" start-placeholder="开始日期"
+                end-placeholder="结束日期" :shortcuts="shortcuts"> </el-date-picker>
+            <el-divider direction="vertical"></el-divider>
+            <el-button icon="Search" type="primary" @click="query">查询</el-button>
+        </template>
+        <template #main>
+            <xc-table :data="returnData" :openPaging="false" :height="48">
+                <el-table-column type="index" label="序号" width="100">
+                    <template #default="scope">
+                        <span class="index_common">{{ scope.$index + 1 }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column prop="result" label="统计结果" width="500" show-overflow-tooltip>
+                    <template #default="scope">
+                        {{ scope.row.reportName }}:
+                        <span style="color: #fc0404;">{{ scope.row.overview }}</span>
+                        {{ scope.row.unit }}
+                    </template>
+                </el-table-column>
+                <el-table-column prop="timeFine" label="统计日期" width="220">
+                    <template #default="scope">
+                        <span>{{ kssj }} 至 {{ jssj }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column prop="port" label="操作" width="120">
+                    <template #default="scope">
+                        <el-button type="primary" size="small" @click="reportFirstInfo(scope.row)">详细信息</el-button>
+                    </template>
+                </el-table-column>
+            </xc-table>
+        </template>
+    </page-layer>
+    <el-dialog :title="titleChart" v-model="fstDrawer" fullscreen destroy-on-close>
+        <ReportFirstPage :reportFirst="reportFirst" />
+    </el-dialog>
+</template>
+<script setup name="OperateMonitoring">
+import PageLayer from '@/layout/PageLayer.vue'
+import { shortcuts, clockinShortcuts } from '@/data/shortcuts'
+import { formatDate, getDateRangeFormatDate } from '@/utils/date'
+import { ref } from '@vue/reactivity'
+import router from "@/router"
+import { clone } from '@/utils/clone'
+import XcTable from "@/components/xiao-chan/xc-table/XcTable"
+import { selectReportPortal, selectReportGroup } from '@/api/reports/high-report'
+import ReportFirstPage from '@/components/operate-monitoring/ReportFirstPage.vue'
+
+const start = formatDate(clockinShortcuts[1].value[1])
+const end = formatDate(clockinShortcuts[1].value[1])
+const queryTerm = ref({})
+const kssj = ref('')
+const jssj = ref('')
+onMounted(() => {
+    let val = router.options.routes.filter(e => e.path === '/operateMonitoring')[0].children;
+    let param = val.filter(f => f.path === 'inpatient/outHospital' || f.path === 'outpatient/outpatientDept')[0].params
+    queryTerm.value = param
+    kssj.value = start
+    jssj.value = end
+    queryTerm.value.startTime = start;
+    queryTerm.value.endTime = end + " 23:59:59";
+    dateRange.value = [start, end];
+    query();
+});
+const returnData = ref({
+    currentPage: 1,
+    pageSize: 30,
+    total: 0,
+    title: '',
+    data: []
+});
+const dateRange = ref([]);
+const query = async () => {
+    if (dateRange.value) {
+        let dateS = getDateRangeFormatDate(dateRange.value);
+        queryTerm.value.startTime = dateS.startTime;
+        queryTerm.value.endTime = dateS.endTime;
+        kssj.value = formatDate(dateRange.value[0])
+        jssj.value = formatDate(dateRange.value[1])
+    } else {
+        queryTerm.value.startTime = start;
+        queryTerm.value.endTime = end;
+        ElMessage({
+            type: "info",
+            message: "默认查询当天的数据",
+            duration: 2500,
+            showClose: true,
+        });
+    }
+    selectReportPortal(queryTerm.value)
+        .then((res) => {
+            returnData.value.data = res.data
+            returnData.value.title = res.title
+        });
+};
+// ------------------------------详细信息----------------------------------------
+const fstDrawer = ref(false)
+const reportFirst = ref({})
+const titleChart = ref('')
+const reportFirstInfo = (row) => {
+    const params = {
+        startTime: queryTerm.value.startTime,
+        endTime: queryTerm.value.endTime,
+        reportId: row.reportId,
+        reportName: row.reportName,
+        reportType: row.reportType,
+        displayType: row.displayType,
+        menuId: row.menuId,
+        levelType: queryTerm.value.levelType,
+        type: queryTerm.value.type,
+    }
+    selectReportGroup(params).then((res) => {
+        reportFirst.value = res
+        titleChart.value = res.title
+        fstDrawer.value = true
+        reportFirst.value.row = row
+        reportFirst.value.params = clone(params)
+    })
+}
+</script>
+<style scoped>
+.index_common {
+    text-shadow: none;
+    font-size: 10px;
+    padding-top: 1px;
+    padding-bottom: 3px;
+    font-weight: normal;
+    line-height: 12px;
+    display: inline-block;
+    min-width: 10px;
+    padding: 3px 7px;
+    text-align: center;
+    white-space: nowrap;
+    vertical-align: baseline;
+    border-radius: 4em;
+    color: #fff;
+    background: #1e90ff;
+}
+</style>