WXL (wul)
5 天以前 77970a545af56e946e439ead97b23557d0b44f0f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
<template>
  <div class="data-overview">
    <!-- 表格一:各服务项目满意度统计 -->
    <el-card shadow="never" class="overview-card">
      <div slot="header" class="card-header">
        <span class="card-title">各服务项目满意度统计</span>
        <el-button type="warning" size="small" icon="el-icon-download" @click="exportTable('table1')">导出Excel</el-button>
      </div>
      <el-table id="table1" :data="serviceSatisfaction" border size="small" :header-cell-style="{ background: '#f5f7fa', color: '#303133' }">
        <el-table-column prop="category" label="分类/题目" min-width="220" fixed="left" />
        <el-table-column label="非常满意" align="center">
          <el-table-column prop="veryGoodCount" label="数量" width="90" />
          <el-table-column prop="veryGoodRate" label="比例" width="90" />
        </el-table-column>
        <el-table-column label="满意" align="center">
          <el-table-column prop="goodCount" label="数量" width="90" />
          <el-table-column prop="goodRate" label="比例" width="90" />
        </el-table-column>
        <el-table-column label="一般" align="center">
          <el-table-column prop="normalCount" label="数量" width="90" />
          <el-table-column prop="normalRate" label="比例" width="90" />
        </el-table-column>
        <el-table-column label="不满意" align="center">
          <el-table-column prop="badCount" label="数量" width="90" />
          <el-table-column prop="badRate" label="比例" width="90" />
        </el-table-column>
        <el-table-column label="不适用" align="center">
          <el-table-column prop="naCount" label="数量" width="90" />
          <el-table-column prop="naRate" label="比例" width="90" />
        </el-table-column>
        <el-table-column prop="score" label="综合得分" width="100" align="center" />
      </el-table>
    </el-card>
 
    <!-- 表格二:单选题/多选题统计 -->
    <el-card shadow="never" class="overview-card">
      <div slot="header" class="card-header">
        <span class="card-title">单选题/多选题统计</span>
        <el-button type="warning" size="small" icon="el-icon-download" @click="exportTable('table2')">导出Excel</el-button>
      </div>
      <div class="question-block" v-for="(q, qi) in questionStats" :key="qi">
        <h4 class="q-title">{{ q.title }}</h4>
        <el-table :data="q.options" border size="small" :header-cell-style="{ background: '#f5f7fa', color: '#303133' }">
          <el-table-column prop="option" label="选项" min-width="180" />
          <el-table-column prop="count" label="数量" width="100" align="center" />
          <el-table-column prop="rate" label="比例" width="100" align="center" />
        </el-table>
        <div v-if="q.total" class="q-footer">本题有效填写人次:<b>{{ q.total }}</b></div>
      </div>
    </el-card>
 
    <!-- 表格三:各科室满意度评分对比 -->
    <el-card shadow="never" class="overview-card">
      <div slot="header" class="card-header">
        <span class="card-title">各科室满意度评分对比</span>
        <el-button type="warning" size="small" icon="el-icon-download" @click="exportTable('table3')">导出Excel</el-button>
      </div>
      <el-table id="table3" :data="deptComparison" border size="small" :header-cell-style="{ background: '#f5f7fa', color: '#303133' }">
        <el-table-column prop="dept" label="科室"fixed="left" align="center" />
        <el-table-column label="第1题" align="center">
          <el-table-column prop="q1VeryGood" label="非常满意" width="100" />
          <el-table-column prop="q1Good" label="满意" width="90" />
          <el-table-column prop="q1Normal" label="一般" width="90" />
          <el-table-column prop="q1Bad" label="不满意" width="90" />
          <el-table-column prop="q1Score" label="得分" width="100" />
        </el-table-column>
        <el-table-column label="第2题" align="center">
          <el-table-column prop="q2VeryGood" label="非常满意" width="100" />
          <el-table-column prop="q2Good" label="满意" width="90" />
          <el-table-column prop="q2Normal" label="一般" width="90" />
          <el-table-column prop="q2Bad" label="不满意" width="90" />
          <el-table-column prop="q2Score" label="得分" width="100" />
        </el-table-column>
        <el-table-column prop="totalScore" label="综合得分"  align="center" />
      </el-table>
    </el-card>
  </div>
</template>
 
<script>
import XLSX from 'xlsx';
 
export default {
  name: "DataOverview",
  data() {
    return {
      serviceSatisfaction: [
        { category: "诊疗过程中,医务人员是否注意保护您的隐私?", veryGoodCount: 3219, veryGoodRate: "67.84%", goodCount: 1351, goodRate: "28.47%", normalCount: 142, normalRate: "2.99%", badCount: 33, badRate: "0.70%", naCount: 0, naRate: "0.00%", score: "87.82" },
        { category: "您对医院服务设施的总体印象如何?", veryGoodCount: 3110, veryGoodRate: "65.54%", goodCount: 1369, goodRate: "28.85%", normalCount: 217, normalRate: "4.57%", badCount: 49, badRate: "1.03%", naCount: 0, naRate: "0.00%", score: "86.30" },
        { category: "医院的厕所是否清洁无异味?", veryGoodCount: 2973, veryGoodRate: "62.66%", goodCount: 1504, goodRate: "31.70%", normalCount: 235, normalRate: "4.95%", badCount: 33, badRate: "0.70%", naCount: 0, naRate: "0.00%", score: "85.44" },
        { category: "医院内的路标和指示是否明确?", veryGoodCount: 3234, veryGoodRate: "68.16%", goodCount: 1289, goodRate: "27.17%", normalCount: 196, normalRate: "4.13%", badCount: 26, badRate: "0.55%", naCount: 0, naRate: "0.00%", score: "87.64" },
        { category: "医院的空间布局是否便利?", veryGoodCount: 3037, veryGoodRate: "64.00%", goodCount: 1460, goodRate: "30.77%", normalCount: 209, normalRate: "4.40%", badCount: 39, badRate: "0.82%", naCount: 0, naRate: "0.00%", score: "85.99" },
        { category: "看病期间,您的抱怨和不满能否及时得到回应?", veryGoodCount: 3019, veryGoodRate: "63.62%", goodCount: 1317, goodRate: "27.76%", normalCount: 294, normalRate: "6.20%", badCount: 115, badRate: "2.42%", naCount: 0, naRate: "0.00%", score: "84.19" },
        { category: "医生是否用您听得懂的方式解释问题?", veryGoodCount: 3402, veryGoodRate: "71.70%", goodCount: 967, goodRate: "20.38%", normalCount: 254, normalRate: "5.35%", badCount: 122, badRate: "2.57%", naCount: 0, naRate: "0.00%", score: "87.07" },
        { category: "医生对您是否尊重?", veryGoodCount: 3495, veryGoodRate: "73.66%", goodCount: 897, goodRate: "18.90%", normalCount: 249, normalRate: "5.25%", badCount: 104, badRate: "2.19%", naCount: 0, naRate: "0.00%", score: "88.01" },
        { category: "医生是否仔细倾听您讲话?", veryGoodCount: 3422, veryGoodRate: "72.12%", goodCount: 937, goodRate: "19.75%", normalCount: 251, normalRate: "5.29%", badCount: 135, badRate: "2.85%", naCount: 0, naRate: "0.00%", score: "87.05" },
        { category: "对挂号服务人员服务态度是否满意", veryGoodCount: 3458, veryGoodRate: "72.88%", goodCount: 1205, goodRate: "25.40%", normalCount: 52, normalRate: "1.10%", badCount: 30, badRate: "0.63%", naCount: 0, naRate: "0.00%", score: "90.17" },
        { category: "您对预约挂号是否满意?", veryGoodCount: 3527, veryGoodRate: "74.33%", goodCount: 1088, goodRate: "22.93%", normalCount: 72, normalRate: "1.52%", badCount: 58, badRate: "1.22%", naCount: 0, naRate: "0.00%", score: "90.12" },
        { category: "护士对您是否尊重?", veryGoodCount: 3420, veryGoodRate: "72.08%", goodCount: 1184, goodRate: "24.95%", normalCount: 113, normalRate: "2.38%", badCount: 28, badRate: "0.59%", naCount: 0, naRate: "0.00%", score: "89.50" },
        { category: "护士是否用您听得懂的方式解释问题?", veryGoodCount: 3346, veryGoodRate: "70.52%", goodCount: 1250, goodRate: "26.34%", normalCount: 122, normalRate: "2.57%", badCount: 27, badRate: "0.57%", naCount: 0, naRate: "0.00%", score: "88.94" },
        { category: "护士是否仔细倾听您讲话?", veryGoodCount: 3378, veryGoodRate: "71.19%", goodCount: 1205, goodRate: "25.40%", normalCount: 134, normalRate: "2.82%", badCount: 28, badRate: "0.59%", naCount: 0, naRate: "0.00%", score: "89.06" },
        { category: "总计", veryGoodCount: 54863, veryGoodRate: "69.02%", goodCount: 20800, goodRate: "26.17%", normalCount: 2920, normalRate: "3.67%", badCount: 908, badRate: "1.14%", naCount: 0, naRate: "0.00%", score: "87.66" },
      ],
      questionStats: [
        {
          title: "第1题:您对我院工作人员的服务质量满意不满意?【分值单选题】- 综合得分",
          options: [
            { option: "非常满意", count: 1084, rate: "75.66%" },
            { option: "满意", count: 1959, rate: "20.92%" },
            { option: "一般", count: 167, rate: "1.78%" },
            { option: "不满意", count: 153, rate: "1.63%" },
          ],
          total: 3363
        },
        {
          title: "第2题:您对哪部分服务不满意?【多选题】",
          options: [
            { option: "医生诊断和诊疗", count: 131, rate: "32.11%" },
            { option: "护理服务", count: 47, rate: "11.52%" },
            { option: "其他医务人员技术水平", count: 30, rate: "7.33%" },
            { option: "工人", count: 72, rate: "17.65%" },
          ],
          total: 408
        },
        {
          title: "第3题:医生诊断和治疗中哪些服务质量不满意?【多选题】",
          options: [
            { option: "医生诊断错误", count: 23, rate: "15.44%" },
            { option: "对治疗效果不满意", count: 72, rate: "48.32%" },
            { option: "其他", count: 54, rate: "36.24%" },
          ],
          total: 131
        },
      ],
      deptComparison: [
        { dept: "内分泌科", q1VeryGood: 103, q1Good: 34, q1Normal: 0, q1Bad: 0, q1Score: "377.00", q2VeryGood: 101, q2Good: 35, q2Normal: 1, q2Bad: 0, q2Score: "374.00", totalScore: "75.25" },
        { dept: "皮肤科", q1VeryGood: 112, q1Good: 25, q1Normal: 2, q1Bad: 3, q1Score: "388.00", q2VeryGood: 111, q2Good: 27, q2Normal: 3, q2Bad: 1, q2Score: "390.00", totalScore: "76.12" },
        { dept: "肿瘤内科", q1VeryGood: 24, q1Good: 12, q1Normal: 2, q1Bad: 0, q1Score: "98.00", q2VeryGood: 25, q2Good: 12, q2Normal: 1, q2Bad: 0, q2Score: "100.00", totalScore: "70.22" },
        { dept: "消化内科", q1VeryGood: 180, q1Good: 52, q1Normal: 1, q1Bad: 0, q1Score: "645.00", q2VeryGood: 168, q2Good: 62, q2Normal: 3, q2Bad: 0, q2Score: "631.00", totalScore: "73.56" },
        { dept: "肾内科", q1VeryGood: 21, q1Good: 4, q1Normal: 0, q1Bad: 0, q1Score: "71.00", q2VeryGood: 19, q2Good: 6, q2Normal: 0, q2Bad: 0, q2Score: "65.00", totalScore: "68.50" },
      ],
    };
  },
  methods: {
    exportTable(tableId) {
      const tableNames = { table1: '各服务项目满意度统计', table2: '单选题多选题统计', table3: '各科室满意度评分对比' };
      const name = tableNames[tableId] || '统计数据';
      const table = document.getElementById(tableId);
      if (!table) return;
 
      try {
        // 从表格提取数据构建带样式的 Excel
        const wb = XLSX.utils.book_new();
        const data = [];
        table.querySelectorAll('tr').forEach(tr => {
          const row = [];
          tr.querySelectorAll('th,td').forEach(td => {
            row.push((td.innerText || '').trim());
          });
          if (row.length) data.push(row);
        });
 
        const ws = XLSX.utils.aoa_to_sheet(data);
        // 设置列宽
        const colWidths = data[0] ? data[0].map(() => ({ wch: 16 })) : [];
        ws['!cols'] = colWidths;
 
        XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
        XLSX.writeFile(wb, name + '.xlsx');
      } catch (e) {
        // fallback: CSV
        let csv = '';
        table.querySelectorAll('tr').forEach(tr => {
          const row = [];
          tr.querySelectorAll('th,td').forEach(td => row.push('"' + (td.innerText || '').replace(/"/g, '""') + '"'));
          csv += row.join(',') + '\n';
        });
        const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
        const link = document.createElement('a');
        link.href = URL.createObjectURL(blob); link.download = name + '.csv'; link.click();
      }
    },
  },
};
</script>
 
<style lang="scss" scoped>
.data-overview { .overview-card { margin-bottom: 20px; } }
.card-header { display: flex; justify-content: space-between; align-items: center; }
.card-title { font-size: 16px; font-weight: 600; color: #303133; }
.question-block { margin-bottom: 24px;
  .q-title { margin: 0 0 12px 0; font-size: 14px; color: #606266; }
  .q-footer { margin-top: 8px; font-size: 13px; color: #909399; text-align: right; }
}
</style>