WXL (wul)
2025-11-13 de147dda682f8ac597bbcc8555b57acbdf45dba2
src/views/sfstatistics/percentage/satisfaction.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1533 @@
<template>
  <div class="Questionnairemanagement">
    <div class="leftvlue">
      <div class="leftvlue-bg">
        <el-row :gutter="20">
          <!--标签数据-->
          <el-col :span="24" :xs="24">
            <el-form
              :model="queryParams"
              ref="queryForm"
              size="small"
              :inline="true"
              v-show="showSearch"
              label-width="98px"
            >
              <el-form-item label="统计类型" prop="userName">
                <el-select
                  v-model="queryParams.statisticaltype"
                  placeholder="请选择统计类型"
                >
                  <el-option
                    v-for="item in Statisticallist"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </el-select>
                <el-select
                  style="margin-left: 10px"
                  v-if="queryParams.statisticaltype == 1"
                  v-model="queryParams.leavehospitaldistrictcodes"
                  size="medium"
                  multiple
                  filterable
                  placeholder="请选择病区"
                >
                  <el-option
                    v-for="item in flatArrayhospit"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </el-select>
                <el-select
                  v-else-if="queryParams.statisticaltype == 2"
                  v-model="queryParams.deptcodes"
                  size="medium"
                  multiple
                  filterable
                  placeholder="请选择科室"
                >
                  <el-option
                    v-for="item in flatArraydept"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item label="统计题目" prop="userName">
                <el-select
                  v-model="queryParams.serviceType"
                  multiple
                  placeholder="请选择"
                >
                  <el-option
                    v-for="item in options"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item
                label-width="200"
                label="随访时间范围"
                prop="userName"
              >
                <el-date-picker
                  v-model="queryParams.dateRange"
                  value-format="yyyy-MM-dd"
                  type="daterange"
                  range-separator="至"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                >
                </el-date-picker>
              </el-form-item>
              <el-form-item>
                <el-button
                  type="primary"
                  icon="el-icon-search"
                  size="medium"
                  @click="handleQuery"
                  >搜索</el-button
                >
                <el-button
                  icon="el-icon-refresh"
                  size="medium"
                  @click="resetQuery"
                  >重置</el-button
                >
              </el-form-item>
              <el-col :span="19">
                <el-button
                  type="warning"
                  plain
                  icon="el-icon-download"
                  size="medium"
                  @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
              v-loading="loading"
              :data="userList"
              :border="true"
              @selection-change="handleSelectionChange"
              :row-key="getRowKey"
              :expand-row-keys="expands"
            >
              <el-table-column
                label="出院病区"
                align="center"
                sortable
                key="leavehospitaldistrictname"
                prop="leavehospitaldistrictname"
                :show-overflow-tooltip="true"
              />
              <el-table-column
                label="科室"
                align="center"
                key="deptname"
                prop="deptname"
                :show-overflow-tooltip="true"
              />
              <el-table-column
                label="出院人次"
                align="center"
                key="dischargeCount"
                prop="dischargeCount"
              >
              </el-table-column>
              <el-table-column
                label="无需随访人次"
                align="center"
                key="nonFollowUp"
                prop="nonFollowUp"
              >
              </el-table-column>
              <el-table-column
                label="应随访人次"
                align="center"
                key="followUpNeeded"
                prop="followUpNeeded"
              >
              </el-table-column>
              <el-table-column
                label="随访率"
                align="center"
                key="followUpRate"
                prop="followUpRate"
              >
                <!-- <template slot-scope="scope">
                    <span
                      >{{
                        (Number(scope.row.followUpRate) * 100).toFixed(2)
                      }}%</span
                    >
                  </template> -->
              </el-table-column>
              <el-table-column
                label="及时率"
                align="center"
                key="rate"
                prop="rate"
              >
                <template slot-scope="scope">
                  <el-button
                    size="medium"
                    type="text"
                    @click="Seedetails(scope.row)"
                    ><span class="button-zx"
                      >{{ (Number(scope.row.rate) * 100).toFixed(2) }}%</span
                    ></el-button
                  >
                </template>
              </el-table-column>
              <el-table-column
                label="满意度题目总量"
                align="center"
                key="joyAllCount"
                prop="joyAllCount"
              >
              </el-table-column>
              <el-table-column
                label="满意度填报量"
                align="center"
                key="joyCount"
                prop="joyCount"
              >
              </el-table-column>
              <el-table-column
                label="完成比率"
                align="center"
                key="joyTotal"
                prop="joyTotal"
              >
                <template slot-scope="scope">
                  <span class="button-zx"
                      >{{
                        (Number(scope.row.joyTotal) * 100).toFixed(2)
                      }}%</span
                    >
                </template>
              </el-table-column>
              <el-table-column
                label="操作"
                align="center"
                fixed="right"
                width="300"
                class-name="small-padding fixed-width"
              >
                <template slot-scope="scope">
                  <el-button
                    size="medium"
                    type="text"
                    @click="getinfo(scope.row)"
                    ><span class="button-zx"
                      ><i class="el-icon-s-order"></i>查看详情</span
                    ></el-button
                  >
                </template>
              </el-table-column>
            </el-table>
            <!-- <pagination
              v-show="total > 0"
              :total="total"
              :page.sync="queryParams.pageNum"
              :limit.sync="queryParams.pageSize"
              @pagination="getList"
            /> -->
          </el-col>
        </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"
      v-loading="Seedloading"
      width="70%"
      :close-on-click-modal="false"
    >
      <div class="examine-jic">
        <div class="jic-value">
          <el-row :gutter="20">
            <!--用户数据-->
            <el-form
              :model="patientqueryParams"
              ref="queryForm"
              size="small"
              :inline="true"
              label-width="98px"
            >
              <el-form-item label="患者:">
                <el-input
                  v-model="patientqueryParams.name"
                  @keyup.enter.native="handleQuery"
                ></el-input>
              </el-form-item>
              <el-form-item label="患者诊断:">
                <el-input
                  v-model="patientqueryParams.leavediagname"
                  @keyup.enter.native="handleQuery"
                ></el-input>
              </el-form-item>
              <el-form-item>
                <el-button
                  type="primary"
                  icon="el-icon-search"
                  size="medium"
                  @click="handleQuery"
                  >搜索</el-button
                >
                <el-button
                  icon="el-icon-refresh"
                  size="medium"
                  @click="resetQuery"
                  >取消创建</el-button
                >
              </el-form-item>
            </el-form>
            <!-- é€‰æ‹©æ‚£è€…列表 -->
            <el-table :data="logsheetlist" style="width: 100%">
              <el-table-column
                prop="sendname"
                align="center"
                label="姓名"
                width="100"
              >
              </el-table-column>
              <el-table-column
                prop="taskName"
                align="center"
                width="200"
                show-overflow-tooltip
                label="任务名称"
              >
              </el-table-column>
              <el-table-column
                prop="sendstate"
                align="center"
                width="200"
                label="任务状态"
              >
                <template slot-scope="scope">
                  <div v-if="scope.row.sendstate == 1">
                    <el-tag type="primary" :disable-transitions="false"
                      >表单已领取</el-tag
                    >
                  </div>
                  <div v-if="scope.row.sendstate == 2">
                    <el-tag type="primary" :disable-transitions="false"
                      >待随访</el-tag
                    >
                  </div>
                  <div v-if="scope.row.sendstate == 3">
                    <el-tag type="success" :disable-transitions="false"
                      >表单已发送</el-tag
                    >
                  </div>
                  <div v-if="scope.row.sendstate == 4">
                    <el-tag type="info" :disable-transitions="false"
                      >不执行</el-tag
                    >
                  </div>
                  <div v-if="scope.row.sendstate == 5">
                    <el-tag type="danger" :disable-transitions="false"
                      >发送失败</el-tag
                    >
                  </div>
                  <div v-if="scope.row.sendstate == 6">
                    <el-tag type="success" :disable-transitions="false"
                      >已完成</el-tag
                    >
                  </div>
                </template>
              </el-table-column>
              <el-table-column
                prop="visitTime"
                align="center"
                label="应随访时间"
                width="200"
                show-overflow-tooltip
              >
              </el-table-column>
              <el-table-column
                prop="finishtime"
                align="center"
                label="随访完成时间"
                width="200"
                show-overflow-tooltip
              >
              </el-table-column>
              <el-table-column
                label="出院日期"
                width="200"
                align="center"
                key="endtime"
                prop="endtime"
              >
                <template slot-scope="scope">
                  <span>{{ formatTime(scope.row.endtime) }}</span>
                </template></el-table-column
              >
              <el-table-column
                label="责任护士"
                width="120"
                align="center"
                key="nurseName"
                prop="nurseName"
              />
              <el-table-column
                label="主治医生"
                width="120"
                align="center"
                key="drname"
                prop="drname"
              />
              <el-table-column
                label="结果状态"
                align="center"
                key="excep"
                prop="excep"
                width="120"
              >
                <template slot-scope="scope">
                  <dict-tag
                    :options="dict.type.sys_yujing"
                    :value="scope.row.excep"
                  />
                </template>
              </el-table-column>
              <el-table-column
                label="处理意见"
                align="center"
                key="suggest"
                prop="suggest"
                width="120"
              >
                <template slot-scope="scope">
                  <dict-tag
                    :options="dict.type.sys_suggest"
                    :value="scope.row.suggest"
                  />
                </template>
              </el-table-column>
              <el-table-column
                prop="templatename"
                align="center"
                label="服务模板"
                width="200"
                show-overflow-tooltip
              >
              </el-table-column>
              <el-table-column
                prop="remark"
                align="center"
                label="服务记录"
                width="200"
                show-overflow-tooltip
              >
              </el-table-column>
              <el-table-column
                prop="bankcardno"
                align="center"
                label="呼叫状态"
                width="210"
              >
              </el-table-column>
              <el-table-column
                label="操作"
                fixed="right"
                align="center"
                width="200"
                class-name="small-padding fixed-width"
              >
                <template slot-scope="scope">
                  <el-button
                    size="medium"
                    type="text"
                    @click="SeedetailsgGo(scope.row)"
                    ><span class="button-zx"
                      ><i class="el-icon-s-order"></i>查看</span
                    ></el-button
                  >
                </template>
              </el-table-column>
            </el-table>
          </el-row>
          <pagination
            v-show="patienttotal > 0 && this.patientqueryParams.allhosp != 6"
            :total="patienttotal"
            :page.sync="patientqueryParams.pn"
            :limit.sync="patientqueryParams.ps"
            @pagination="Seedetails"
          />
        </div>
      </div>
    </el-dialog>
    <!-- å•科室统计详情 -->
     <el-dialog :visible.sync="topicVisible" width="45%">
      <div class="topicdia">
        <div class="top-text">{{ topicvalue.name }}</div>
        <div class="top-mintext">随访完成数{{ topicvalue.number }}</div>
        <div style="overflow-x: hidden; overflow-y: auto; max-height: 65vh">
          <div class="ttaabbcc" v-for="item in topiclist" :key="item.name">
            <div class="describe">
              ç¬¬{{ item.number }}题: {{ item.name }}?<span
                >[{{ item.type == 1 ? "单选题" : "多选题" }}]</span
              >
            </div>
            <div>
              <el-table :data="tableData" style="width: 100%">
                <el-table-column prop="date" label="问题选项">
                </el-table-column>
                <el-table-column prop="name" label="选择人数">
                </el-table-column>
                <el-table-column prop="address" label="比例"> </el-table-column>
              </el-table>
            </div>
          </div>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="topicVisible = false">关 é—­</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {
  toamendtag,
  addapitag,
  deletetag,
  changetagcategory,
} from "@/api/system/label";
import store from "@/store";
import {
  getSfStatisticsJoydetails,
  getSfStatisticsJoy,
  selectTimelyRate,
} from "@/api/system/user";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
const shortcuts = [
  {
    text: "今天",
    onClick(picker) {
      picker.$emit("pick", new Date());
    },
  },
  {
    text: "昨天",
    onClick(picker) {
      const date = new Date();
      date.setTime(date.getTime() - 3600 * 1000 * 24);
      picker.$emit("pick", date);
    },
  },
  {
    text: "一周前",
    onClick(picker) {
      const date = new Date();
      date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
      picker.$emit("pick", date);
    },
  },
];
export default {
  name: "Percentage",
  dicts: ["sys_normal_disable", "sys_user_sex"],
  components: { Treeselect },
  data() {
    return {
      topactiveName: "Local", //顶部选择
      activeName: "first", //侧边选择
      expands: [],
      // é®ç½©å±‚
      loading: false,
      Seedloading: false,
      chartDialogVisible: false,
      pieChart: null,
      barLineChart: null,
      // é€‰ä¸­æ•°ç»„
      ids: [],
      // éžå•个禁用
      single: true,
      // éžå¤šä¸ªç¦ç”¨
      multiple: true,
      // æ˜¾ç¤ºæœç´¢æ¡ä»¶
      showSearch: true,
      idds: "", //分类id
      // æ€»æ¡æ•°
      total: 0,
      flatArrayhospit: [],
      flatArraydept: [],
      patienttotal: 0,
      logsheetlist: [],
      Statisticallist: [
        {
          label: "病区统计",
          value: 1,
        },
        {
          label: "科室统计",
          value: 2,
        },
      ],
      patientqueryParams: {
        pn: 1,
        ps: 10,
      },
      topiclist: [
        {
          name: "您的身体康复情况如何",
          number: 1,
          type: 1,
        },
        {
          name: "您的饮食情况如何",
          number: 2,
          type: 2,
        },
        {
          name: "您的恢复情况如何",
          number: 3,
          type: 1,
        },
      ],
        tableData: [
        {
          date: "好",
          name: 12,
          address: "50%",
        },
        {
          date: "一般",
          name: 2,
          address: "6.2%",
        },
        {
          date: "å·®",
          name: 0,
          address: "0%",
        },
      ],
      amendtag: false, //是否修改类别
      lstamendtag: false, //是否修改标签
      scavisible: false, //删除弹框
      deleteVisible: false, //分类删除弹框
      deletefenl: "高血压", //删除项
      //修改添加标签弹框数据
      tagform: {
        isupload: "",
        tagname: "",
        tagcategoryid: "",
        tagdescription: "",
      },
      classifyform: {
        categoryname: "",
      },
      // æ ‡ç­¾è¡¨æ ¼æ•°æ®
      userList: [],
      // å¼¹å‡ºå±‚标题
      title: "",
      // æ˜¯å¦æ˜¾ç¤ºå¼¹å‡ºå±‚
      open: false,
      // æ—¥æœŸèŒƒå›´
      dateRange: [],
      // å²—位选项
      postOptions: [],
      // è§’色选项
      roleOptions: [],
      // å­˜å‚¨æ‰€æœ‰ç§‘室代码
      allDeptCodes: [],
      // å­˜å‚¨æ‰€æœ‰ç—…区代码
      allWardCodes: [],
      // è¡¨å•参数
      form: {},
      forms: {
        name: "",
      },
      numberlb: 22,
      dialogFormVisible: false, //添加、修改类别弹框
      lstamendtagVisible: false, //添加、修改标签弹框
      goQRCodeVisible: false, //二维码弹框
      topicVisible: false, //控制单题弹框
      topicvalue: {
        name: "骨科随访模板",
        number: 222,
      },
      sidecolumnval: "", //类别搜索
      propss: { multiple: true },
      SeedetailsVisible: false,
      options: store.getters.tasktypes,
      pickerOptions: {
        disabledDate(time) {
          return time.getTime() < Date.now() - 3600 * 1000 * 24;
        },
        shortcuts: shortcuts,
      },
      pickerOptionsa: {
        disabledDate(time) {
          return time.getTime() > Date.now();
        },
        shortcuts: shortcuts,
      },
      // æŸ¥è¯¢æ ‡ç­¾åˆ—表参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        serviceType: [2],
        dateRange: [],
        statisticaltype: 1,
        leavehospitaldistrictcodes: ["all"], // é»˜è®¤é€‰ä¸­å…¨éƒ¨ç—…区
        deptcodes: [], // é»˜è®¤é€‰ä¸­å…¨éƒ¨ç§‘室
      },
      // åˆ—信息
      columns: [
        { key: 0, label: `标签编号`, visible: true },
        { key: 1, label: `标签名称`, visible: true },
        { key: 2, label: `标签昵称`, visible: true },
        { key: 3, label: `部门`, visible: true },
        { key: 4, label: `手机号码`, visible: true },
        { key: 5, label: `状态`, visible: true },
        { key: 6, label: `创建时间`, visible: true },
      ],
    };
  },
  watch: {},
  created() {
    this.getDeptTree();
    this.getList();
  },
  methods: {
    /** æŸ¥è¯¢æ ‡ç­¾åˆ—表 */
    getList() {
      // å¤„理查询参数
      const params = {
        ...this.queryParams,
        // å¦‚果选择了"全部",则传所有病区/科室代码
        leavehospitaldistrictcodes:
          this.queryParams.leavehospitaldistrictcodes.includes("all")
            ? this.allWardCodes
            : this.queryParams.leavehospitaldistrictcodes,
        deptcodes: this.queryParams.deptcodes.includes("all")
          ? this.allDeptCodes
          : this.queryParams.deptcodes,
      };
      // ç§»é™¤å¯èƒ½å­˜åœ¨çš„"all"值
      delete params.leavehospitaldistrictcodes.all;
      delete params.deptcodes.all;
      getSfStatisticsJoy(params).then((response) => {
        console.log(response);
        // this.total = response.total;
        this.userList = response.data;
      });
    },
    getRowKey(row) {
      return row.statisticaltype === 1
        ? row.leavehospitaldistrictcode
        : row.deptcode;
    },
    /** ä¿®æ”¹æ ‡ç­¾ */
    handleUpdate(row) {
      console.log(row, "修改标签");
      this.lstamendtagVisible = true;
      this.lstamendtag = true;
      this.tagform = {
        isupload: row.isupload,
        tagname: row.tagname,
        tagcategoryid: row.tagcategoryid,
        tagdescription: row.tagdescription,
        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
      );
      // ç—…区列表
      this.flatArrayhospit = store.getters.belongWards.map((ward) => {
        return {
          label: ward.districtName,
          value: ward.districtCode,
        };
      });
      // å­˜å‚¨æ‰€æœ‰ç—…区代码
      this.allWardCodes = store.getters.belongWards.map(
        (ward) => ward.districtCode
      );
      this.flatArraydept.push({ label: "全部", value: "all" });
      this.flatArrayhospit.push({ label: "全部", value: "all" });
    },
    flattenArray(multiArray) {
      let result = [];
      // é€’归函数,用于将多级数组转换为一维数组,只包含最底层的元素
      function flatten(element) {
        // å¦‚果当前元素有子元素,继续递归
        if (element.children && element.children.length > 0) {
          element.children.forEach((child) => flatten(child));
        } else {
          // å…‹éš†å…ƒç´ ä»¥é¿å…ä¿®æ”¹åŽŸå§‹æ•°æ®
          let item = JSON.parse(JSON.stringify(element));
          result.push(item); // å°†æœ€åº•层的元素添加到结果数组
        }
      }
      // ä»Žé¡¶å±‚元素开始递归
      multiArray.forEach((element) => flatten(element));
      return result; // è¿”回只包含最底层元素的一维数组
    },
    addladeltag() {
      this.lstamendtagVisible = true;
      this.lstamendtag = false;
      this.tagform = {
        isupload: "",
        tagname: "",
        tagcategoryid: "",
        tagdescription: "",
        tagid: "",
      };
    },
    Seedetails(row) {
      this.SeedetailsVisible = true;
      this.Seedloading = true;
      this.patientqueryParams.starttime = this.parseTime(
        this.queryParams.dateRange[0]
      );
      this.patientqueryParams.endtime = this.parseTime(
        this.queryParams.dateRange[1]
      );
      this.patientqueryParams.deptcode = row.deptcode;
      selectTimelyRate(this.patientqueryParams).then((response) => {
        this.logsheetlist = response.data.detail;
        this.patienttotal = response.data.total;
        this.Seedloading = false;
      });
    },
    SeedetailsgGo(row) {
      this.SeedetailsVisible = false;
      let type = "";
      if (row.preachformson && row.preachformson.includes("3")) {
        type = 1;
      }
      setTimeout(() => {
        this.$router.push({
          path: "/followvisit/record/detailpage/",
          query: {
            taskid: row.taskid,
            patid: row.patid,
            id: row.id,
            Voicetype: type,
            // visitCount: this.topqueryParams.visitCount,
          },
        });
      }, 300);
    },
    // è°ƒèµ·è¯¦æƒ…
    getinfo(row) {
      this.topicVisible = true;
    },
    // æ·»åŠ /修改标签
    Maintenancetag() {
      if (this.lstamendtag) {
        toamendtag(this.addDateRange(this.tagform)).then((response) => {
          console.log(response);
          this.getList();
        });
      } else {
        addapitag(this.addDateRange(this.tagform)).then((response) => {
          console.log(response);
          this.getList();
        });
      }
      this.tagform = {
        isupload: "",
        tagname: "",
        tagcategoryid: "",
        tagdescription: "",
        tagid: "",
      };
    },
    routerErr(row) {
      console.log(row, "跳转异常");
      this.$router.push({
        path: "/followvisit/discharge",
        query: {
          errtype: 1,
          leavehospitaldistrictcode: row.leavehospitaldistrictcode,
        },
      });
    },
    // è¡¨å•重置
    reset() {
      this.form = {
        userId: undefined,
        deptId: undefined,
        userName: undefined,
        nickName: undefined,
        password: undefined,
        phonenumber: undefined,
        email: undefined,
        sex: undefined,
        status: "0",
        remark: undefined,
        postIds: [],
        roleIds: [],
      };
      this.resetForm("form");
    },
    // æ ‡ç­¾çŠ¶æ€ä¿®æ”¹
    handleStatusChange(row) {
      console.log(row.isupload);
      let text = row.isupload === "0" ? "启用" : "停用";
      this.$modal
        .confirm('确认要"' + text + '""' + row.tagname + '"标签吗?')
        .then(function () {
          return changetagcategory(row.tagid, row.isupload);
        })
        .then(() => {
          this.$modal.msgSuccess(text + "成功");
        })
        .catch(function () {
          row.isupload = row.isupload === "0" ? "1" : "0";
        });
    },
    /** æœç´¢æŒ‰é’®æ“ä½œ */
    handleQuery() {
      this.queryParams.pageNum = 1;
      if (!this.queryParams.dateRange) this.queryParams.dateRange = [];
      if (this.queryParams.statisticaltype == 1) {
        this.queryParams.deptcodes = [];
      } else if (this.queryParams.statisticaltype == 2) {
        this.queryParams.leavehospitaldistrictcodes = [];
      }
      console.log(this.queryParams.dateRange);
      this.queryParams.startTime = this.parseTime(
        this.queryParams.dateRange[0]
      );
      this.queryParams.endTime = this.parseTime(this.queryParams.dateRange[1]);
      this.getList();
    },
    /** é‡ç½®æŒ‰é’®æ“ä½œ */
    resetQuery() {
      this.queryParams.dateRange = [];
      this.queryParams.leavehospitaldistrictcodes = [];
      this.handleQuery();
    },
    // å¤šé€‰æ¡†é€‰ä¸­æ•°æ®
    handleSelectionChange(selection) {
      this.ids = selection.map((item) => item.tagid);
      this.single = selection.length != 1;
      this.multiple = !selection.length;
    },
    /** åˆ é™¤æŒ‰é’®æ“ä½œ */
    handleDelete(row) {
      console.log(row, "删除弹窗");
      const tagids = row.tagid || this.ids;
      console.log(tagids);
      const tagname = row.tagname;
      this.$modal
        .confirm(
          tagname
            ? '是否确认删除标签名称为"' + tagname + '"的数据项?'
            : "是否确认删除选中的数据项?"
        )
        .then(function () {
          return deletetag(tagids);
        })
        .then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        })
        .catch(() => {});
    },
    /** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
    handleExport() {
      this.download(
        "smartor/serviceSubtask/getSfStatisticsExport",
        {
          ...this.queryParams,
        },
        `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>
<style lang="scss" scoped>
.sidecolumn {
  width: 180px;
  min-height: 100vh;
  text-align: center;
  //   display: flex;
  margin-top: 20px;
  margin: 20px;
  padding: 30px;
  background: #edf1f7;
  border: 1px solid #dcdfe6;
  -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12),
    0 0 6px 0 rgba(0, 0, 0, 0.04);
  .sidecolumn-top {
    display: flex;
    justify-content: space-between;
    .top-wj {
      font-size: 20px;
    }
    .top-tj {
      font-size: 18px;
      color: rgb(0, 89, 255);
      cursor: pointer;
    }
  }
  .center-ss {
    margin-top: 30px;
    .input-with-select {
      height: 40px !important;
    }
  }
  .bottom-fl {
    margin-top: 30px;
    display: center !important;
  }
}
.qrcode-dialo {
  text-align: center;
  //   display: flex;
  margin: 20px;
  padding: 30px;
  background: #edf1f7;
  border: 1px solid #dcdfe6;
  -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12),
    0 0 6px 0 rgba(0, 0, 0, 0.04);
  .qrcode-text {
    font-size: 20px;
    span {
      margin-left: 20px;
    }
  }
  .qrcode-img {
    width: 300px;
    height: 400px;
  }
}
::v-deep.el-tabs--left,
.el-tabs--right {
  overflow: hidden;
  align-items: center;
  display: flex;
}
::v-deep.el-input--medium .el-input__inner {
  height: 40px !important;
}
::v-deep.el-tabs--right .el-tabs__active-bar.is-right {
  height: 40px;
  width: 5px;
  left: 0;
}
::v-deep.el-tabs--right .el-tabs__item.is-right {
  display: block;
  text-align: left;
  font-size: 20px;
}
.leftvlue {
  //   display: flex;
  //   flex: 1;
  // width: 80%;
  // margin-top: 20px;
  margin: 20px;
  padding: 30px;
  background: #ffff;
  border: 1px solid #dcdfe6;
  -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12),
    0 0 6px 0 rgba(0, 0, 0, 0.04);
  .mulsz {
    font-size: 20px;
  }
}
/* ä½¿è¡Œæœ‰æ‰‹åž‹æŒ‡é’ˆ */
.el-table__row {
  cursor: pointer;
}
/* å†…层医生表格样式 */
.inner-table {
  // è¡¨å¤´èƒŒæ™¯è‰²
  ::v-deep .el-table__header-wrapper {
    background-color: #f0f7ff !important;
    th {
      background-color: #f0f7ff !important;
    }
  }
  // è¡¨æ ¼è¡ŒèƒŒæ™¯è‰²
  ::v-deep .el-table__body-wrapper {
    tr {
      background-color: #f9fbfe !important;
      &:hover {
        background-color: #e6f1ff !important;
      }
    }
  }
  // è¾¹æ¡†é¢œè‰²
  ::v-deep .el-table--border {
    border-color: #d9e8ff !important;
    td,
    th {
      border-color: #d9e8ff !important;
    }
  }
  // æ–‘马纹效果
  ::v-deep .el-table--striped .el-table__body tr.el-table__row--striped td {
    background-color: #f5f9ff !important;
  }
}
/* å±•开行样式 */
.el-table__expanded-cell {
  padding: 10px 0 !important;
  background: #f8f8f8;
}
.document {
  width: 100px;
  height: 50px;
}
.documentf {
  display: flex;
  justify-content: flex-end;
}
.button-text {
  color: rgb(70, 204, 238);
}
.button-textck {
  color: rgb(39, 167, 67);
}
.button-textxg {
  color: rgb(35, 81, 233);
}
.button-textsc {
  color: rgb(235, 23, 23);
}
</style>