|  |  | 
 |  |  | <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"> | 
 |  |  |           <!--标签数据--> | 
 |  |  | 
 |  |  |               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" | 
 |  |  | 
 |  |  |                   @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 | 
 |  |  | 
 |  |  |                     /> | 
 |  |  |                     <el-table-column | 
 |  |  |                       label="科室" | 
 |  |  |                        width="120" | 
 |  |  |                       width="120" | 
 |  |  |                       prop="deptname" | 
 |  |  |                       align="center" | 
 |  |  |                     /> | 
 |  |  | 
 |  |  |                     </el-table-column> | 
 |  |  |                     <el-table-column align="center" label="首次出院随访"> | 
 |  |  |                       <el-table-column | 
 |  |  |                         label="应随访" | 
 |  |  |                         label="需随访" | 
 |  |  |                         align="center" | 
 |  |  |                         key="needFollowUp" | 
 |  |  |                         prop="needFollowUp" | 
 |  |  | 
 |  |  |                     </el-table-column> | 
 |  |  |                     <el-table-column align="center" label="再次出院随访"> | 
 |  |  |                       <el-table-column | 
 |  |  |                         label="应随访" | 
 |  |  |                         label="需随访" | 
 |  |  |                         align="center" | 
 |  |  |                         key="needFollowUpAgain" | 
 |  |  |                         prop="needFollowUpAgain" | 
 |  |  | 
 |  |  |               </el-table-column> | 
 |  |  |               <el-table-column align="center" label="首次出院随访"> | 
 |  |  |                 <el-table-column | 
 |  |  |                   label="应随访" | 
 |  |  |                   label="需随访" | 
 |  |  |                   align="center" | 
 |  |  |                   key="needFollowUp" | 
 |  |  |                   prop="needFollowUp" | 
 |  |  | 
 |  |  |               </el-table-column> | 
 |  |  |               <el-table-column align="center" label="再次出院随访"> | 
 |  |  |                 <el-table-column | 
 |  |  |                   label="应随访" | 
 |  |  |                   label="需随访" | 
 |  |  |                   align="center" | 
 |  |  |                   key="needFollowUpAgain" | 
 |  |  |                   prop="needFollowUpAgain" | 
 |  |  | 
 |  |  |         </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" | 
 |  |  | 
 |  |  |       // 遮罩层 | 
 |  |  |       loading: false, | 
 |  |  |       Seedloading: false, | 
 |  |  |       chartDialogVisible: false, | 
 |  |  |       pieChart: null, | 
 |  |  |       barLineChart: null, | 
 |  |  |       // 选中数组 | 
 |  |  |       ids: [], | 
 |  |  |       // 非单个禁用 | 
 |  |  | 
 |  |  |       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; | 
 |  |  | 
 |  |  |  | 
 |  |  |     // 处理行点击展开 | 
 |  |  |     handleRowClick(row) { | 
 |  |  |       console.log(row,'row'); | 
 |  |  |       console.log(row, "row"); | 
 |  |  |  | 
 |  |  |       // 如果已经展开则收起 | 
 |  |  |       if (this.expands.includes(this.getRowKey(row))) { | 
 |  |  | 
 |  |  |         `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> |