WXL (wul)
2 天以前 7c71fcb61dd0bfc6a179a973f9cab5ef979ad5f2
src/views/sfstatistics/percentage/index.vue
@@ -395,6 +395,21 @@
                    key="needFollowUp"
                    prop="needFollowUp"
                  >
                    <template slot-scope="scope">
                      <el-button
                        size="medium"
                        type="text"
                        @click="
                          viewDetails(
                            scope.row.needFollowUpInfo,
                            scope.row.leavehospitaldistrictname + '需随访列表'
                          )
                        "
                        ><span class="button-zx">{{
                          scope.row.needFollowUp
                        }}</span></el-button
                      >
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="待随访"
@@ -424,6 +439,21 @@
                    key="followUpSuccess"
                    prop="followUpSuccess"
                  >
                    <template slot-scope="scope">
                      <el-button
                        size="medium"
                        type="text"
                        @click="
                          viewDetails(
                            scope.row.followUpSuccessInfo,
                            scope.row.leavehospitaldistrictname + '随访成功列表'
                          )
                        "
                        ><span class="button-zx">{{
                          scope.row.followUpSuccess
                        }}</span></el-button
                      >
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="随访失败"
@@ -488,6 +518,21 @@
                    key="manual"
                    prop="manual"
                  >
                    <template slot-scope="scope">
                      <el-button
                        size="medium"
                        type="text"
                        @click="
                          viewDetails(
                            scope.row.manualInfo,
                            scope.row.leavehospitaldistrictname + '人工随访列表'
                          )
                        "
                        ><span class="button-zx">{{
                          scope.row.manual
                        }}</span></el-button
                      >
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="短信"
@@ -495,6 +540,21 @@
                    key="sms"
                    prop="sms"
                  >
                    <template slot-scope="scope">
                      <el-button
                        size="medium"
                        type="text"
                        @click="
                          viewDetails(
                            scope.row.smsInfo,
                            scope.row.leavehospitaldistrictname + '短信随访列表'
                          )
                        "
                        ><span class="button-zx">{{
                          scope.row.sms
                        }}</span></el-button
                      >
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="微信"
@@ -502,6 +562,21 @@
                    key="weChat"
                    prop="weChat"
                  >
                    <template slot-scope="scope">
                      <el-button
                        size="medium"
                        type="text"
                        @click="
                          viewDetails(
                            scope.row.weChatInfo,
                            scope.row.leavehospitaldistrictname + '微信随访列表'
                          )
                        "
                        ><span class="button-zx">{{
                          scope.row.weChat
                        }}</span></el-button
                      >
                    </template>
                  </el-table-column>
                </el-table-column>
                <el-table-column align="center" label="再次出院随访">
@@ -511,6 +586,22 @@
                    key="needFollowUpAgain"
                    prop="needFollowUpAgain"
                  >
                    <template slot-scope="scope">
                      <el-button
                        size="medium"
                        type="text"
                        @click="
                          viewDetails(
                            scope.row.needFollowUpAgainInfo,
                            scope.row.leavehospitaldistrictname +
                              '再次随访需随访列表'
                          )
                        "
                        ><span class="button-zx">{{
                          scope.row.needFollowUpAgain
                        }}</span></el-button
                      >
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="待随访"
@@ -518,6 +609,22 @@
                    key="pendingFollowUpAgain"
                    prop="pendingFollowUpAgain"
                  >
                    <template slot-scope="scope">
                      <el-button
                        size="medium"
                        type="text"
                        @click="
                          viewDetails(
                            scope.row.pendingFollowUpAgainInfo,
                            scope.row.leavehospitaldistrictname +
                              '再次随访待随访列表'
                          )
                        "
                        ><span class="button-zx">{{
                          scope.row.pendingFollowUpAgain
                        }}</span></el-button
                      >
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="随访成功"
@@ -525,6 +632,22 @@
                    key="followUpSuccessAgain"
                    prop="followUpSuccessAgain"
                  >
                    <template slot-scope="scope">
                      <el-button
                        size="medium"
                        type="text"
                        @click="
                          viewDetails(
                            scope.row.followUpSuccessAgainInfo,
                            scope.row.leavehospitaldistrictname +
                              '再次随访随访成功列表'
                          )
                        "
                        ><span class="button-zx">{{
                          scope.row.followUpSuccessAgain
                        }}</span></el-button
                      >
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="随访失败"
@@ -532,6 +655,22 @@
                    key="followUpFailAgain"
                    prop="followUpFailAgain"
                  >
                    <template slot-scope="scope">
                      <el-button
                        size="medium"
                        type="text"
                        @click="
                          viewDetails(
                            scope.row.followUpFailAgainInfo,
                            scope.row.leavehospitaldistrictname +
                              '再次随访随访失败列表'
                          )
                        "
                        ><span class="button-zx">{{
                          scope.row.followUpFailAgain
                        }}</span></el-button
                      >
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="随访率"
@@ -554,6 +693,22 @@
                    key="manualAgain"
                    prop="manualAgain"
                  >
                    <template slot-scope="scope">
                      <el-button
                        size="medium"
                        type="text"
                        @click="
                          viewDetails(
                            scope.row.manualAgainInfo,
                            scope.row.leavehospitaldistrictname +
                              '再次随访人工随访列表'
                          )
                        "
                        ><span class="button-zx">{{
                          scope.row.manualAgain
                        }}</span></el-button
                      >
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="短信"
@@ -561,6 +716,22 @@
                    key="smsAgain"
                    prop="smsAgain"
                  >
                    <template slot-scope="scope">
                      <el-button
                        size="medium"
                        type="text"
                        @click="
                          viewDetails(
                            scope.row.smsAgainInfo,
                            scope.row.leavehospitaldistrictname +
                              '再次随访短信随访列表'
                          )
                        "
                        ><span class="button-zx">{{
                          scope.row.smsAgain
                        }}</span></el-button
                      >
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="微信"
@@ -568,6 +739,22 @@
                    key="weChatAgain"
                    prop="weChatAgain"
                  >
                    <template slot-scope="scope">
                      <el-button
                        size="medium"
                        type="text"
                        @click="
                          viewDetails(
                            scope.row.weChatAgainInfo,
                            scope.row.leavehospitaldistrictname +
                              '再次随访微信随访列表'
                          )
                        "
                        ><span class="button-zx">{{
                          scope.row.weChatAgain
                        }}</span></el-button
                      >
                    </template>
                  </el-table-column>
                </el-table-column>
                <el-table-column
@@ -894,179 +1081,207 @@
      width="70%"
      :close-on-click-modal="false"
    >
      <div style="margin-bottom: 16px; display: flex; align-items: center">
        <span style="margin-right: 10px; font-weight: bold">患者姓名查询:</span>
        <el-input
          v-model="searchName"
          placeholder="请输入患者姓名进行筛选"
          clearable
          style="width: 300px"
          @input="handleSearch"
          @clear="handleSearch"
        >
        </el-input>
        <span
          style="margin-left: 10px; color: rgb(35, 81, 233); font-size: 16px"
        >
          共 {{ infotitlelist.length }} 条记录
        </span>
      </div>
      <div class="examine-jic">
        <div class="jic-value">
          <el-row :gutter="20">
            <!-- 选择患者列表 -->
            <el-table :data="infotitlelist" height="660" style="width: 100%">
              <el-table-column
                prop="sendname"
                align="center"
                label="姓名"
                width="100"
            <div
              class="data-list"
              ref="dataList"
              @scroll="handleScroll"
              v-loading="infotitloading"
            >
              <el-table
                :data="currentDisplayList"
                height="660"
                style="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
                  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
                  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="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-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>
            </div>
          </el-row>
          <pagination
            v-show="patienttotal > 0 && this.patientqueryParams.allhosp != 6"
@@ -1131,11 +1346,16 @@
      orgname: "",
      expands: [],
      infotitlelist: [],
      currentDisplayList: [], // 当前显示的数据
      loadIndex: 0, // 当前已加载的数据索引
      pageSize: 100, // 每次加载的数据量
      isLoading: false, // 防止滚动时重复加载
      // 遮罩层
      loading: false,
      Seedloading: false,
      chartDialogVisible: false,
      infotitleVisible: false,
      searchName: "", // 搜索关键词
      infotitloading: false,
      infotitle: "",
      pieChart: null,
@@ -1227,8 +1447,6 @@
      },
      // 查询标签列表参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        serviceType: [2],
        dateRange: [],
        statisticaltype: 1,
@@ -1276,7 +1494,72 @@
      getSfStatistics(params).then((response) => {
        console.log(response);
        // this.total = response.total;
        this.userList = response.data;
        this.userList = this.customSort(response.data);
      });
    },
    // 搜索处理函数
    handleSearch() {
      if (!this.searchName.trim()) {
        // 如果搜索框为空,显示所有数据
        this.currentDisplayList = [...this.infotitlelist];
      } else {
        // 根据患者姓名进行筛选(不区分大小写)
        const keyword = this.searchName.toLowerCase();
        this.currentDisplayList = this.infotitlelist.filter((item) => {
          return item.sendname && item.sendname.toLowerCase().includes(keyword);
        });
      }
    },
    customSort(data) {
      // 定义您期望的病区顺序(扩展到三十)
      const order = [
        "二",
        "三",
        "四",
        "五",
        "六",
        "七",
        "八",
        "九",
        "十",
        "十一",
        "十二",
        "十三",
        "十四",
        "十五",
        "十六",
        "十七",
        "十八",
        "十九",
        "二十",
        "二十一",
        "二十二",
        "二十三",
        "二十四",
        "二十五",
        "二十六",
        "二十七",
        "二十八",
        "二十九",
        "三十",
      ];
      return data.sort((a, b) => {
        // 提取病区名称中的中文数字部分[6](@ref)
        const getIndex = (name) => {
          const numStr = name.match(
            /^(二|三|四|五|六|七|八|九|十|十一|十二|十三|十四|十五|十六|十七|十八|十九|二十|二十一|二十二|二十三|二十四|二十五|二十六|二十七|二十八|二十九|三十)/
          )?.[1];
          return order.indexOf(numStr);
        };
        const indexA = getIndex(a.leavehospitaldistrictname);
        const indexB = getIndex(b.leavehospitaldistrictname);
        // 如果都在定义的顺序中,按定义顺序排;否则,未定义的排在后面[2](@ref)
        if (indexA === -1) return 1;
        if (indexB === -1) return -1;
        return indexA - indexB;
      });
    },
    getRowKey(row) {
@@ -1298,9 +1581,16 @@
      const params = {
        ...this.queryParams,
        // 如果选择了"全部",则传所有病区/科室代码
        deptcodes: this.queryParams.deptcodes.includes("all")
          ? this.allDeptCodes
          : this.queryParams.deptcodes,
        leavehospitaldistrictcodes: [row.leavehospitaldistrictcode],
        drcode: "1",
      };
      // 移除可能存在的"all"值
      delete params.leavehospitaldistrictcodes.all;
      delete params.deptcodes.all;
      // 如果该行还没有加载医生数据,则加载
      if (!row.doctorStats) {
        this.loading = true;
@@ -1560,7 +1850,44 @@
    viewDetails(row, title) {
      this.infotitleVisible = true;
      this.infotitle = title;
      this.infotitlelist = row;
      this.infotitlelist = row; // 假设row就是需要展示的详细数组
      // 初始化加载
      this.loadIndex = 0;
      this.currentDisplayList = [];
      this.$nextTick(() => {
        this.loadMoreData();
      });
    },
    loadMoreData() {
      if (this.isLoading) return;
      this.isLoading = true;
      // 模拟异步加载,实际可能是直接切片本地数据
      setTimeout(() => {
        const nextChunk = this.infotitlelist.slice(
          this.loadIndex,
          this.loadIndex + this.pageSize
        );
        this.currentDisplayList = this.currentDisplayList.concat(nextChunk);
        this.loadIndex += this.pageSize;
        this.isLoading = false;
      }, 200);
    },
    handleScroll(event) {
      const scrollContainer = event.target;
      // 判断是否滚动到底部
      const isAtBottom =
        scrollContainer.scrollTop + scrollContainer.clientHeight >=
        scrollContainer.scrollHeight - 10;
      if (
        isAtBottom &&
        !this.isLoading &&
        this.loadIndex < this.infotitlelist.length
      ) {
        this.loadMoreData();
      }
    },
    SeedetailsgGo(row) {
      this.SeedetailsVisible = false;
@@ -1702,40 +2029,68 @@
    // 替换您原来的 exportTable 方法
    async exportTable() {
      try {
        // 获取当前日期
        const now = new Date();
        // 获取当前月份(注意月份从0开始,需要加1)
        const currentMonth = now.getMonth() + 1;
        // 构建文件名
        const excelName = `${currentMonth}月出院随访统计表.xlsx`;
        // 1. 获取并格式化日期范围
        let dateRangeString = ""; // 用于文件名
        let sheetNameSuffix = ""; // 用于工作表名
        // 检查是否存在选中的日期范围
        if (
          this.queryParams.dateRange &&
          this.queryParams.dateRange.length === 2
        ) {
          const startDateStr = this.queryParams.dateRange[0]; // 开始日期字符串,例如 "2026-01-01 00:00:00"
          const endDateStr = this.queryParams.dateRange[1]; // 结束日期字符串
          // 格式化日期为 YYYY-MM-DD(去掉时间部分)
          const formatDateForDisplay = (dateTimeStr) => {
            return dateTimeStr.split(" ")[0]; // 取空格前的部分,即 "YYYY-MM-DD"
          };
          const startDateFormatted = formatDateForDisplay(startDateStr);
          const endDateFormatted = formatDateForDisplay(endDateStr);
          // 构建日期范围字符串
          dateRangeString = `${startDateFormatted}至${endDateFormatted}`;
          sheetNameSuffix = `${startDateFormatted}至${endDateFormatted}`;
        } else {
          // 如果没有选择日期范围,则使用当前月份作为备选方案
          const now = new Date();
          const currentMonth = now.getMonth() + 1;
          dateRangeString = `${currentMonth}月`;
          sheetNameSuffix = `${currentMonth}月`;
        }
        // 2. 动态构建文件名和工作表名
        const excelName = `出院随访统计表_${dateRangeString}.xlsx`;
        const worksheetName = `随访统计_${sheetNameSuffix}`; // 工作表名不能超过31个字符[2](@ref)
        // 创建新的工作簿和工作表
        const workbook = new ExcelJS.Workbook();
        const worksheet = workbook.addWorksheet(`${currentMonth}月出院随访统计表`);
// 定义样式(新增总标题样式)
    const titleStyle = {
      font: {
        name: "微软雅黑",
        size: 16,
        bold: true,
        color: { argb: "FF000000" },
      },
      fill: {
        type: "pattern",
        pattern: "solid",
        fgColor: { argb: "FFE6F3FF" },
      },
      alignment: {
        vertical: "middle",
        horizontal: "center",
        wrapText: true,
      },
      border: {
        top: { style: "thin", color: { argb: "FFD0D0D0" } },
        left: { style: "thin", color: { argb: "FFD0D0D0" } },
        bottom: { style: "thin", color: { argb: "FFD0D0D0" } },
        right: { style: "thin", color: { argb: "FFD0D0D0" } },
      },
    };
        const worksheet = workbook.addWorksheet(worksheetName); // 使用动态工作表名
        // 定义样式(新增总标题样式)
        const titleStyle = {
          font: {
            name: "微软雅黑",
            size: 16,
            bold: true,
            color: { argb: "FF000000" },
          },
          fill: {
            type: "pattern",
            pattern: "solid",
            fgColor: { argb: "FFE6F3FF" },
          },
          alignment: {
            vertical: "middle",
            horizontal: "center",
            wrapText: true,
          },
          border: {
            top: { style: "thin", color: { argb: "FFD0D0D0" } },
            left: { style: "thin", color: { argb: "FFD0D0D0" } },
            bottom: { style: "thin", color: { argb: "FFD0D0D0" } },
            right: { style: "thin", color: { argb: "FFD0D0D0" } },
          },
        };
        // 定义样式
        const headerStyle = {
          font: {
@@ -1803,12 +2158,12 @@
            right: { style: "thin", color: { argb: "FFD0D0D0" } },
          },
        };
// 1. 添加总标题行(第一行)
    worksheet.mergeCells(1, 1, 1, 23); // 合并A1到W1的所有列[1,4](@ref)
    const titleCell = worksheet.getCell(1, 1);
    titleCell.value = `${currentMonth}月出院随访统计表`; // 使用文件名作为总标题
    titleCell.style = titleStyle;
    worksheet.getRow(1).height = 35; // 设置总标题行高
        // 1. 添加总标题行(第一行)
        worksheet.mergeCells(1, 1, 1, 23); // 合并A1到W1的所有列[1,4](@ref)
        const titleCell = worksheet.getCell(1, 1);
        titleCell.value = `${sheetNameSuffix}出院随访统计表`; // 使用文件名作为总标题
        titleCell.style = titleStyle;
        worksheet.getRow(1).height = 35; // 设置总标题行高
        // 1. 首先,创建并设置第二行(子表头)的所有单元格
        const secondRowHeaders = [
          "", // A2 展开列占位(其值将由第一行合并后的主单元格决定)
@@ -1839,95 +2194,98 @@
        ];
        // 添加第二行(原第一行下移)
    secondRowHeaders.forEach((header, index) => {
      const cell = worksheet.getCell(3, index + 1); // 改为第3行
      cell.value = header;
      cell.style = headerStyle;
    });
        secondRowHeaders.forEach((header, index) => {
          const cell = worksheet.getCell(3, index + 1); // 改为第3行
          cell.value = header;
          cell.style = headerStyle;
        });
    // 3. 调整原合并单元格位置(原第1行合并单元格下移到第2行)
    // 合并 A2:A3
    worksheet.mergeCells(2, 1, 3, 1);
    worksheet.getCell(2, 1).value = "";
    worksheet.getCell(2, 1).style = headerStyle;
        // 3. 调整原合并单元格位置(原第1行合并单元格下移到第2行)
        // 合并 A2:A3
        worksheet.mergeCells(2, 1, 3, 1);
        worksheet.getCell(2, 1).value = "";
        worksheet.getCell(2, 1).style = headerStyle;
    // 合并 B2:B3
    worksheet.mergeCells(2, 2, 3, 2);
    worksheet.getCell(2, 2).value = "出院病区";
    worksheet.getCell(2, 2).style = headerStyle;
        // 合并 B2:B3
        worksheet.mergeCells(2, 2, 3, 2);
        worksheet.getCell(2, 2).value = "出院病区";
        worksheet.getCell(2, 2).style = headerStyle;
    // 合并 C2:C3
    worksheet.mergeCells(2, 3, 3, 3);
    worksheet.getCell(2, 3).value = "科室";
    worksheet.getCell(2, 3).style = headerStyle;
        // 合并 C2:C3
        worksheet.mergeCells(2, 3, 3, 3);
        worksheet.getCell(2, 3).value = "科室";
        worksheet.getCell(2, 3).style = headerStyle;
    // 合并 D2:D3
    worksheet.mergeCells(2, 4, 3, 4);
    worksheet.getCell(2, 4).value = "出院人次";
    worksheet.getCell(2, 4).style = headerStyle;
        // 合并 D2:D3
        worksheet.mergeCells(2, 4, 3, 4);
        worksheet.getCell(2, 4).value = "出院人次";
        worksheet.getCell(2, 4).style = headerStyle;
    // 合并 E2:E3
    worksheet.mergeCells(2, 5, 3, 5);
    worksheet.getCell(2, 5).value = "无需随访人次";
    worksheet.getCell(2, 5).style = headerStyle;
        // 合并 E2:E3
        worksheet.mergeCells(2, 5, 3, 5);
        worksheet.getCell(2, 5).value = "无需随访人次";
        worksheet.getCell(2, 5).style = headerStyle;
    // 合并 F2:F3
    worksheet.mergeCells(2, 6, 3, 6);
    worksheet.getCell(2, 6).value = "应随访人次";
    worksheet.getCell(2, 6).style = headerStyle;
        // 合并 F2:F3
        worksheet.mergeCells(2, 6, 3, 6);
        worksheet.getCell(2, 6).value = "应随访人次";
        worksheet.getCell(2, 6).style = headerStyle;
    // 4. 调整横向合并标题位置(下移到第2行)
    // 首次出院随访(合并G2:O2)
    worksheet.mergeCells(2, 7, 2, 15); // G2:O2
    worksheet.getCell(2, 7).value = "首次出院随访";
    worksheet.getCell(2, 7).style = headerStyle;
        // 4. 调整横向合并标题位置(下移到第2行)
        // 首次出院随访(合并G2:O2)
        worksheet.mergeCells(2, 7, 2, 15); // G2:O2
        worksheet.getCell(2, 7).value = "首次出院随访";
        worksheet.getCell(2, 7).style = headerStyle;
    // 再次出院随访(合并P2:W2)
    worksheet.mergeCells(2, 16, 2, 23); // P2:W2
    worksheet.getCell(2, 16).value = "再次出院随访";
    worksheet.getCell(2, 16).style = headerStyle;
        // 再次出院随访(合并P2:W2)
        worksheet.mergeCells(2, 16, 2, 23); // P2:W2
        worksheet.getCell(2, 16).value = "再次出院随访";
        worksheet.getCell(2, 16).style = headerStyle;
    // 5. 设置行高
    worksheet.getRow(1).height = 35; // 总标题行高
    worksheet.getRow(2).height = 28; // 原第一行下移
    worksheet.getRow(3).height = 25; // 原第二行下移
        // 5. 设置行高
        worksheet.getRow(1).height = 35; // 总标题行高
        worksheet.getRow(2).height = 28; // 原第一行下移
        worksheet.getRow(3).height = 25; // 原第二行下移
    // 6. 添加数据行(注意行索引需要+1,因为上面插入了一行)
    this.userList.forEach((item, rowIndex) => {
      const dataRow = worksheet.addRow([
        "", // 展开列
        item.leavehospitaldistrictname || "",
        item.deptname || "",
        item.dischargeCount || 0,
        item.nonFollowUp || 0,
        item.followUpNeeded || 0,
        // 首次出院随访数据
        item.needFollowUp || 0,
        item.pendingFollowUp || 0,
        item.followUpSuccess || 0,
        item.followUpFail || 0,
        item.followUpRate || "0%",
        item.rate ? (Number(item.rate) * 100).toFixed(2) + "%" : "0%",
        item.manual || 0,
        item.sms || 0,
        item.weChat || 0,
        // 再次出院随访数据
        item.needFollowUpAgain || 0,
        item.pendingFollowUpAgain || 0,
        item.followUpSuccessAgain || 0,
        item.followUpFailAgain || 0,
        item.followUpRateAgain || "0%",
        item.manualAgain || 0,
        item.smsAgain || 0,
        item.weChatAgain || 0,
      ], rowIndex + 4); // 从第4行开始添加数据(原第3行)
        // 6. 添加数据行(注意行索引需要+1,因为上面插入了一行)
        this.userList.forEach((item, rowIndex) => {
          const dataRow = worksheet.addRow(
            [
              "", // 展开列
              item.leavehospitaldistrictname || "",
              item.deptname || "",
              item.dischargeCount || 0,
              item.nonFollowUp || 0,
              item.followUpNeeded || 0,
              // 首次出院随访数据
              item.needFollowUp || 0,
              item.pendingFollowUp || 0,
              item.followUpSuccess || 0,
              item.followUpFail || 0,
              item.followUpRate || "0%",
              item.rate ? (Number(item.rate) * 100).toFixed(2) + "%" : "0%",
              item.manual || 0,
              item.sms || 0,
              item.weChat || 0,
              // 再次出院随访数据
              item.needFollowUpAgain || 0,
              item.pendingFollowUpAgain || 0,
              item.followUpSuccessAgain || 0,
              item.followUpFailAgain || 0,
              item.followUpRateAgain || "0%",
              item.manualAgain || 0,
              item.smsAgain || 0,
              item.weChatAgain || 0,
            ],
            rowIndex + 4
          ); // 从第4行开始添加数据(原第3行)
      // 应用数据行样式
      dataRow.eachCell((cell) => {
        cell.style = cellStyle;
      });
      dataRow.height = 24;
    });
          // 应用数据行样式
          dataRow.eachCell((cell) => {
            cell.style = cellStyle;
          });
          dataRow.height = 24;
        });
        // 添加合计行
        const summaries = this.getSummaries({
@@ -2559,6 +2917,10 @@
  width: 100px;
  height: 50px;
}
.data-list {
  max-height: 800px;
  overflow-y: auto;
}
.documentf {
  display: flex;
  justify-content: flex-end;