WXL (wul)
6 天以前 25b6d3d875c1c24f70de8a06f8098b301a2790d5
src/views/sfstatistics/percentage/index.vue
@@ -1,37 +1,6 @@
<template>
  <div class="Questionnairemanagement">
    <!-- 左侧栏 -->
    <!-- <div class="sidecolumn">
      <div class="sidecolumn-top">
        <div class="top-wj">患者范围</div>
      </div>
      <div class="bottom-fl">
        <el-tabs
          tab-position="right"
          v-model="activeName"
          @tab-click="handleClick"
        >
          <el-tab-pane label="全部" name="first"></el-tab-pane>
          <el-tab-pane label="住院" name="bhospitalized"></el-tab-pane>
          <el-tab-pane label="在院" name="Inhospital"></el-tab-pane>
          <el-tab-pane label="门诊" name="outpatient"></el-tab-pane>
          <el-tab-pane label="体检" name="physical"></el-tab-pane>
        </el-tabs>
      </div>
    </div> -->
    <!-- 右侧数据 -->
    <div class="leftvlue">
      <!-- <div class="leftvlue-top">
        <el-tabs v-model="topactiveName" @tab-click="tophandleClick">
          <el-tab-pane name="Local">
            <span class="mulsz" slot="label">按出院病区统计 </span>
          </el-tab-pane>
          <el-tab-pane name="sharing">
            <span class="mulsz" slot="label">按出院科室统计 </span>
          </el-tab-pane>
        </el-tabs>
      </div> -->
      <div class="leftvlue-bg">
        <el-row :gutter="20">
          <!--标签数据-->
@@ -44,12 +13,6 @@
              v-show="showSearch"
              label-width="98px"
            >
              <!-- <el-form-item label="责任医生" prop="userName">
                <el-input
                  v-model="queryParams.drname"
                  placeholder="请输入主治医生"
                ></el-input>
              </el-form-item> -->
              <el-form-item label="统计类型" prop="userName">
                <el-select
                  v-model="queryParams.statisticaltype"
@@ -86,7 +49,7 @@
                  size="medium"
                  multiple
                  filterable
                  placeholder="请选择科室"
                  placeholder="请选择课题组"
                >
                  <el-option
                    v-for="item in flatArraydept"
@@ -153,6 +116,14 @@
                  @click="handleExport"
                  >导出</el-button
                >
                <el-button
                  type="primary"
                  plain
                  icon="el-icon-data-line"
                  size="medium"
                  @click="showChartDialog"
                  >统计趋势图</el-button
                >
              </el-col>
            </el-form>
            <el-table
@@ -180,8 +151,8 @@
                      align="center"
                    />
                    <el-table-column
                      label="科室"
                       width="120"
                      label="课题组"
                      width="120"
                      prop="deptname"
                      align="center"
                    />
@@ -214,9 +185,9 @@
                      prop="followUpNeeded"
                    >
                    </el-table-column>
                    <el-table-column align="center" label="首次出院随访">
                    <el-table-column align="center" label="首次课题随访">
                      <el-table-column
                        label="应随访"
                        label="需随访"
                        align="center"
                        key="needFollowUp"
                        prop="needFollowUp"
@@ -302,7 +273,7 @@
                    </el-table-column>
                    <el-table-column align="center" label="再次出院随访">
                      <el-table-column
                        label="应随访"
                        label="需随访"
                        align="center"
                        key="needFollowUpAgain"
                        prop="needFollowUpAgain"
@@ -370,7 +341,7 @@
                </template>
              </el-table-column>
              <el-table-column
                label="出院病区"
                label="病区"
                align="center"
                sortable
                key="leavehospitaldistrictname"
@@ -379,7 +350,7 @@
                :show-overflow-tooltip="true"
              />
              <el-table-column
                label="科室"
                label="课题组"
                align="center"
                key="deptname"
                prop="deptname"
@@ -411,7 +382,7 @@
              </el-table-column>
              <el-table-column align="center" label="首次出院随访">
                <el-table-column
                  label="应随访"
                  label="需随访"
                  align="center"
                  key="needFollowUp"
                  prop="needFollowUp"
@@ -495,7 +466,7 @@
              </el-table-column>
              <el-table-column align="center" label="再次出院随访">
                <el-table-column
                  label="应随访"
                  label="需随访"
                  align="center"
                  key="needFollowUpAgain"
                  prop="needFollowUpAgain"
@@ -572,6 +543,26 @@
        </el-row>
      </div>
    </div>
    <!-- 统计趋势图弹窗 -->
    <el-dialog
      title="随访统计趋势图"
      :visible.sync="chartDialogVisible"
      width="80%"
      :close-on-click-modal="false"
    >
      <div class="chart-container">
        <el-row :gutter="20">
          <el-col :span="12">
            <div class="chart-title">随访状态分布</div>
            <div id="pieChart" style="width: 100%; height: 400px"></div>
          </el-col>
          <el-col :span="12">
            <div class="chart-title">随访趋势分析</div>
            <div id="barLineChart" style="width: 100%; height: 400px"></div>
          </el-col>
        </el-row>
      </div>
    </el-dialog>
    <el-dialog
      title="未及时随访患者服务"
      :visible.sync="SeedetailsVisible"
@@ -851,6 +842,9 @@
      // 遮罩层
      loading: false,
      Seedloading: false,
      chartDialogVisible: false,
      pieChart: null,
      barLineChart: null,
      // 选中数组
      ids: [],
      // 非单个禁用
@@ -872,7 +866,7 @@
          value: 1,
        },
        {
          label: "科室统计",
          label: "课题组统计",
          value: 2,
        },
      ],
@@ -907,7 +901,7 @@
      postOptions: [],
      // 角色选项
      roleOptions: [],
      // 存储所有科室代码
      // 存储所有课题组代码
      allDeptCodes: [],
      // 存储所有病区代码
      allWardCodes: [],
@@ -923,51 +917,7 @@
      sidecolumnval: "", //类别搜索
      propss: { multiple: true },
      SeedetailsVisible: false,
      options: [
        {
          value: 1,
          label: "监测评估",
        },
        {
          value: 2,
          label: "出院随访",
        },
        {
          value: 3,
          label: "门诊随访",
        },
        {
          value: 4,
          label: "宣教关怀",
        },
        {
          value: 5,
          label: "复诊管理",
        },
        {
          value: 7,
          label: "患者报告",
        },
        {
          value: 9,
          label: "体检随访",
        },
        {
          value: 11,
          label: "影像随访",
        },
        {
          value: 12,
          label: "心电随访",
        },
        {
          value: 13,
          label: "专病随访",
        },
      ],
      options: store.getters.tasktypes,
      pickerOptions: {
        disabledDate(time) {
          return time.getTime() < Date.now() - 3600 * 1000 * 24;
@@ -988,7 +938,7 @@
        dateRange: [],
        statisticaltype: 1,
        leavehospitaldistrictcodes: ["all"], // 默认选中全部病区
        deptcodes: [], // 默认选中全部科室
        deptcodes: [], // 默认选中全部课题组
      },
      // 列信息
      columns: [
@@ -1014,7 +964,7 @@
      // 处理查询参数
      const params = {
        ...this.queryParams,
        // 如果选择了"全部",则传所有病区/科室代码
        // 如果选择了"全部",则传所有病区/课题组代码
        leavehospitaldistrictcodes:
          this.queryParams.leavehospitaldistrictcodes.includes("all")
            ? this.allWardCodes
@@ -1041,7 +991,7 @@
    // 处理行点击展开
    handleRowClick(row) {
      console.log(row,'row');
      console.log(row, "row");
      // 如果已经展开则收起
      if (this.expands.includes(this.getRowKey(row))) {
@@ -1051,7 +1001,7 @@
      // 处理查询参数
      const params = {
        ...this.queryParams,
        // 如果选择了"全部",则传所有病区/科室代码
        // 如果选择了"全部",则传所有病区/课题组代码
        leavehospitaldistrictcodes: [row.leavehospitaldistrictcode],
        drcode: "1",
      };
@@ -1080,16 +1030,16 @@
        tagid: row.tagid,
      };
    },
    // 获取科室树
    // 获取课题组树
    getDeptTree() {
      // 科室列表
      // 课题组列表
      this.flatArraydept = store.getters.belongDepts.map((dept) => {
        return {
          label: dept.deptName,
          value: dept.deptCode,
        };
      });
      // 存储所有科室代码
      // 存储所有课题组代码
      this.allDeptCodes = store.getters.belongDepts.map(
        (dept) => dept.deptCode
      );
@@ -1301,6 +1251,358 @@
        `user_${new Date().getTime()}.xlsx`
      );
    },
    // 显示图表弹窗
    showChartDialog() {
      this.chartDialogVisible = true;
      this.$nextTick(() => {
        this.initPieChart();
        this.initBarLineChart();
      });
    },
    // 在methods中修改统计方法
    showChartDialog() {
      this.chartDialogVisible = true;
      this.$nextTick(() => {
        console.log(this.userList, "this.userList");
        this.initCharts();
      });
    },
    // 新增初始化图表方法
    initCharts() {
      this.initPieChart();
      this.initBarLineChart();
    },
    // 初始化饼图
    initPieChart() {
      const echarts = require("echarts");
      const pieDom = document.getElementById("pieChart");
      if (!pieDom) return;
      if (this.pieChart) {
        this.pieChart.dispose();
      }
      this.pieChart = echarts.init(pieDom);
      // 计算饼图数据
      const followUpData = {
        pending: 0,
        success: 0,
        fail: 0,
      };
      this.userList.forEach((item) => {
        followUpData.pending += item.pendingFollowUp || 0;
        followUpData.success += item.followUpSuccess || 0;
        followUpData.fail += item.followUpFail || 0;
      });
      // 使用更美观的颜色方案
      const pieOption = {
        title: {
          text: "随访状态分布",
          left: "center",
          textStyle: {
            color: "#333",
            fontSize: 16,
          },
        },
        tooltip: {
          trigger: "item",
          formatter: "{a} <br/>{b}: {c} ({d}%)",
        },
        legend: {
          orient: "vertical",
          left: "left",
          data: ["待随访", "随访成功", "随访失败"],
          textStyle: {
            color: "#666",
          },
        },
        color: ["#FF9D4D", "#36B37E", "#FF5C5C"], // 新的配色方案
        series: [
          {
            name: "随访状态",
            type: "pie",
            radius: ["40%", "70%"],
            avoidLabelOverlap: true,
            itemStyle: {
              borderRadius: 10,
              borderColor: "#fff",
              borderWidth: 2,
            },
            label: {
              show: true,
              formatter: "{b}: {c} ({d}%)",
              color: "#333",
            },
            emphasis: {
              label: {
                show: true,
                fontSize: "18",
                fontWeight: "bold",
              },
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: "rgba(0, 0, 0, 0.5)",
              },
            },
            data: [
              {
                value: followUpData.pending,
                name: "待随访",
              },
              {
                value: followUpData.success,
                name: "随访成功",
              },
              {
                value: followUpData.fail,
                name: "随访失败",
              },
            ],
          },
        ],
      };
      this.pieChart.setOption(pieOption);
      window.addEventListener("resize", this.resizePieChart);
    },
    // 初始化柱状折线图
    initBarLineChart() {
      const echarts = require("echarts");
      const barDom = document.getElementById("barLineChart");
      if (!barDom) return;
      if (this.barLineChart) {
        this.barLineChart.dispose();
      }
      this.barLineChart = echarts.init(barDom);
      // 准备数据
      const categories = this.userList.map(
        (item) => item.leavehospitaldistrictname || item.deptname
      );
      const dischargeData = this.userList.map(
        (item) => item.dischargeCount || 0
      );
      const followUpData = this.userList.map(
        (item) => item.followUpNeeded || 0
      );
      // 新增两条折线数据
      const followUpRateData = this.userList.map((item) => {
        if (!item.followUpRate) return 0;
        // 去掉百分号并转为数字
        const rateStr = String(item.followUpRate).replace("%", "");
        return parseFloat(rateStr) || 0;
      });
      const timelyRateData = this.userList.map((item) =>
        item.rate ? (Number(item.rate) * 100).toFixed(2) : 0
      );
      const option = {
        title: {
          text: "课题组/病区随访趋势",
          left: "center",
          textStyle: {
            color: "#333",
            fontSize: 16,
          },
        },
        tooltip: {
          trigger: "axis",
          axisPointer: {
            type: "cross",
            crossStyle: {
              color: "#999",
            },
          },
        },
        legend: {
          data: ["出院人次", "应随访人次", "随访率(%)", "及时率(%)"],
          top: "bottom",
          textStyle: {
            color: "#666",
          },
        },
        color: ["#5470C6", "#91CC75", "#EE6666", "#9A60B4"], // 新增紫色用于及时率
        xAxis: {
          type: "category",
          data: categories,
          axisLabel: {
            interval: 0,
            rotate: 30,
            color: "#666",
          },
          axisLine: {
            lineStyle: {
              color: "#ddd",
            },
          },
        },
        yAxis: [
          {
            type: "value",
            name: "人次",
            min: 0,
            axisLabel: {
              color: "#666",
            },
            axisLine: {
              lineStyle: {
                color: "#ddd",
              },
            },
            splitLine: {
              lineStyle: {
                color: "#f0f0f0",
              },
            },
          },
          {
            type: "value",
            name: "百分比(%)",
            min: 0,
            max: 100,
            axisLabel: {
              color: "#666",
              formatter: "{value}%",
            },
            axisLine: {
              lineStyle: {
                color: "#ddd",
              },
            },
            splitLine: {
              show: false,
            },
          },
        ],
        series: [
          {
            name: "出院人次",
            type: "bar",
            barWidth: "25%",
            data: dischargeData,
            itemStyle: {
              borderRadius: [4, 4, 0, 0],
            },
          },
          {
            name: "应随访人次",
            type: "bar",
            barWidth: "25%",
            data: followUpData,
            itemStyle: {
              borderRadius: [4, 4, 0, 0],
            },
          },
          {
            name: "随访率(%)",
            type: "line",
            yAxisIndex: 1,
            data: followUpRateData,
            symbolSize: 8,
            lineStyle: {
              width: 3,
            },
            markLine: {
              silent: true,
              data: [
                {
                  yAxis: 80,
                  lineStyle: {
                    color: "#EE6666",
                    type: "dashed",
                  },
                  // label: {
                  //   position: 'end',
                  //   formatter: '目标80%'
                  // }
                },
              ],
            },
          },
          {
            name: "及时率(%)",
            type: "line",
            yAxisIndex: 1,
            data: timelyRateData,
            symbolSize: 8,
            lineStyle: {
              width: 3,
              type: "dotted", // 使用虚线区分
            },
            markLine: {
              silent: true,
              data: [
                {
                  yAxis: 90,
                  lineStyle: {
                    color: "#9A60B4",
                    type: "dashed",
                  },
                  // label: {
                  //   position: 'end',
                  //   formatter: '目标90%'
                  // }
                },
              ],
            },
          },
        ],
        grid: {
          top: "15%",
          left: "3%",
          right: "4%",
          bottom: "15%",
          containLabel: true,
        },
      };
      this.barLineChart.setOption(option);
      window.addEventListener("resize", this.resizeBarLineChart);
    },
    // 图表响应式调整方法
    resizePieChart() {
      if (this.pieChart) {
        this.pieChart.resize();
      }
    },
    resizeBarLineChart() {
      if (this.barLineChart) {
        this.barLineChart.resize();
      }
    },
    // 在组件销毁时清理
    beforeDestroy() {
      // 移除事件监听
      window.removeEventListener("resize", this.resizePieChart);
      window.removeEventListener("resize", this.resizeBarLineChart);
      // 销毁图表实例
      if (this.pieChart) {
        this.pieChart.dispose();
        this.pieChart = null;
      }
      if (this.barLineChart) {
        this.barLineChart.dispose();
        this.barLineChart = null;
      }
    },
  },
};
</script>