From d725dc65cf7f74df3aa3f5a0297fd6f8b767cdbc Mon Sep 17 00:00:00 2001
From: liusheng <337615773@qq.com>
Date: 星期五, 30 十月 2026 10:23:03 +0800
Subject: [PATCH] Merge branch 'subtask' of http://116.62.18.175:6699/r/~yxh/smartor-web into subtask
---
src/views/Satisfaction/sfstatistics/components/DataOverview.vue | 221 ++++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 160 insertions(+), 61 deletions(-)
diff --git a/src/views/Satisfaction/sfstatistics/components/DataOverview.vue b/src/views/Satisfaction/sfstatistics/components/DataOverview.vue
index 4539a87..3e8f084 100644
--- a/src/views/Satisfaction/sfstatistics/components/DataOverview.vue
+++ b/src/views/Satisfaction/sfstatistics/components/DataOverview.vue
@@ -106,6 +106,13 @@
<el-button size="small" icon="el-icon-refresh" @click="handleReset"
>閲嶇疆</el-button
>
+ <el-button
+ type="warning"
+ size="small"
+ icon="el-icon-download"
+ @click="exportTable()"
+ >瀵煎嚭Excel</el-button
+ >
</el-form-item>
</el-form>
</el-card>
@@ -115,13 +122,6 @@
<div slot="header" class="card-header">
<span class="card-title">鍚勬湇鍔¢」鐩弧鎰忓害缁熻</span>
<span class="card-subtitle">锛堝叚妗h瘎鍒嗛锛氬緢婊℃剰/婊℃剰/涓�鑸�/涓嶆弧鎰�/寰堜笉婊℃剰/鏈粡鍘嗭級</span>
- <el-button
- type="warning"
- size="small"
- icon="el-icon-download"
- @click="exportTable('table1')"
- >瀵煎嚭Excel</el-button
- >
</div>
<el-table
id="table1"
@@ -186,13 +186,6 @@
placeholder="鎸夐鐩ā绯婃煡璇�"
class="search-input"
/>
- <el-button
- type="warning"
- size="small"
- icon="el-icon-download"
- @click="exportTable('table2')"
- >瀵煎嚭Excel</el-button
- >
</div>
</div>
<div id="table2" v-loading="loading" element-loading-text="缁熻涓�...">
@@ -271,13 +264,6 @@
/>
</template>
</el-select>
- <el-button
- type="warning"
- size="small"
- icon="el-icon-download"
- @click="exportTable('table3')"
- >瀵煎嚭Excel</el-button
- >
</div>
</div>
<el-table
@@ -336,7 +322,7 @@
<script>
import { sltdMydTotalByScore,statQuestionOptionByKsOrBq } from "@/api/AiCentre/satisfaction";
import { deptTreeSelect } from "@/api/system/user";
-import XLSX from "xlsx";
+import * as XLSX from "xlsx";
// 婊℃剰搴﹂鐨勫浐瀹氶�夐」锛堥『搴忓嵆琛ㄦ牸鍒楅『搴忥級鈥斺�旇繖浜涢�夐」鐨勯鐩繘琛ㄤ竴锛屽叾浣欒繘琛ㄤ簩
const FIXED_OPTIONS = ["寰堟弧鎰�", "婊℃剰", "涓�鑸�", "涓嶆弧鎰�", "寰堜笉婊℃剰", "鏈粡鍘�"];
@@ -1128,52 +1114,165 @@
const hit = opts.find((o) => String(o.label) === String(name));
return hit ? hit.value : name;
},
+ // 瀵煎嚭 Excel锛氫竴娆″鍑烘暣椤典笁涓〃锛堝悇涓�涓� sheet锛夛紝鍜岄〉闈㈡樉绀轰繚鎸佷竴鑷�
exportTable(tableId) {
- const tableNames = {
- table1: "鍚勬湇鍔¢」鐩弧鎰忓害缁熻",
- table2: "鍏朵粬棰樼洰缁熻",
- table3: "鍚勭瀹ゆ弧鎰忓害璇勫垎瀵规瘮",
- };
- const name = tableNames[tableId] || "缁熻鏁版嵁";
- const table = document.getElementById(tableId);
- if (!table) return;
-
try {
- // 浠庤〃鏍兼彁鍙栨暟鎹瀯寤哄甫鏍峰紡鐨� Excel
+ const order = ["table1", "table2", "table3"];
+ if (tableId && order.indexOf(tableId) > 0) {
+ order.splice(order.indexOf(tableId), 1);
+ order.unshift(tableId);
+ }
+ const builders = {
+ table1: () => this.buildExportTable1(),
+ table2: () => this.buildExportTable2(),
+ table3: () => this.buildExportTable3(),
+ };
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);
+ let count = 0;
+ order.forEach((id) => {
+ const sheet = builders[id]();
+ if (!sheet) return;
+ const ws = XLSX.utils.aoa_to_sheet(sheet.data);
+ ws["!merges"] = sheet.merges || [];
+ const widthRow = sheet.data.find((r) => r && r.length) || [];
+ ws["!cols"] = widthRow.map((_, i) => ({ wch: i === 0 ? 32 : 12 }));
+ XLSX.utils.book_append_sheet(wb, ws, sheet.name);
+ count++;
});
-
- 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");
+ if (!count) {
+ this.$message.warning("娌℃湁鍙鍑虹殑鏁版嵁");
+ return;
+ }
+ XLSX.writeFile(wb, "婊℃剰搴︽暟鎹�昏.xlsx");
+ this.$message.success("瀵煎嚭鎴愬姛");
} 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();
+ console.error("瀵煎嚭澶辫触:", e);
+ this.$message.error("瀵煎嚭澶辫触锛�" + (e.message || e));
}
},
+
+ // 琛ㄤ竴锛氬悇鏈嶅姟椤圭洰婊℃剰搴︾粺璁�
+ buildExportTable1() {
+ const rows = this.serviceSatisfaction || [];
+ if (!rows.length) return null;
+ const data = [
+ ["鍚勬湇鍔¢」鐩弧鎰忓害缁熻锛堝叚妗h瘎鍒嗛锛氬緢婊℃剰/婊℃剰/涓�鑸�/涓嶆弧鎰�/寰堜笉婊℃剰/鏈粡鍘嗭級"],
+ [
+ "鍒嗙被/棰樼洰",
+ "寰堟弧鎰�", "", "婊℃剰", "", "涓�鑸�", "",
+ "涓嶆弧鎰�", "", "寰堜笉婊℃剰", "", "鏈粡鍘�", "",
+ "缁煎悎寰楀垎",
+ ],
+ [
+ "",
+ "鏁伴噺", "姣斾緥", "鏁伴噺", "姣斾緥", "鏁伴噺", "姣斾緥",
+ "鏁伴噺", "姣斾緥", "鏁伴噺", "姣斾緥", "鏁伴噺", "姣斾緥",
+ "",
+ ],
+ ];
+ rows.forEach((r) => {
+ data.push([
+ r.category,
+ r.veryGoodCount, r.veryGoodRate,
+ r.goodCount, r.goodRate,
+ r.normalCount, r.normalRate,
+ r.badCount, r.badRate,
+ r.veryBadCount, r.veryBadRate,
+ r.naCount, r.naRate,
+ r.score,
+ ]);
+ });
+ const merges = [
+ { s: { r: 0, c: 0 }, e: { r: 0, c: 13 } },
+ { s: { r: 1, c: 0 }, e: { r: 2, c: 0 } },
+ ];
+ for (let i = 0; i < 6; i++) {
+ merges.push({ s: { r: 1, c: 1 + i * 2 }, e: { r: 1, c: 2 + i * 2 } });
+ }
+ merges.push({ s: { r: 1, c: 13 }, e: { r: 2, c: 13 } });
+ return { name: "鍚勬湇鍔¢」鐩弧鎰忓害", data, merges };
+ },
+
+ // 琛ㄤ簩锛氬叾浠栭鐩粺璁★紙姣忛涓�鍧楋細棰樼洰鏍囬 鈫� 閫夐」/鏁伴噺/姣斾緥 鈫� 鏈濉姤鎬婚噺锛�
+ buildExportTable2() {
+ const list = this.filteredQuestionStats || [];
+ if (!list.length) return null;
+ const data = [
+ ["鍏朵粬棰樼洰缁熻锛堝叚妗f弧鎰忓害棰樺凡鍦ㄤ笂琛紝杩欓噷鍙垪鍏朵綑棰樺瀷锛氭帹鑽愩�佹姳鎬ㄥ洖搴斻�佹剰瑙佺瓑锛�"],
+ [],
+ ];
+ const merges = [{ s: { r: 0, c: 0 }, e: { r: 0, c: 2 } }];
+ list.forEach((q) => {
+ data.push([q.title, "", ""]);
+ merges.push({
+ s: { r: data.length - 1, c: 0 },
+ e: { r: data.length - 1, c: 2 },
+ });
+ data.push(["閫夐」", "鏁伴噺", "姣斾緥"]);
+ const opts =
+ q.options && q.options.length
+ ? q.options
+ : [{ option: "锛堟棤閫夐」锛�", count: 0, rate: "-" }];
+ opts.forEach((o) => {
+ data.push([o.option, o.count, o.rate]);
+ });
+ data.push([`鏈濉姤鎬婚噺锛�${q.total}`, "", ""]);
+ merges.push({
+ s: { r: data.length - 1, c: 0 },
+ e: { r: data.length - 1, c: 2 },
+ });
+ data.push([]);
+ });
+ return { name: "鍏朵粬棰樼洰缁熻", data, merges };
+ },
+
+ // 琛ㄤ笁锛氬悇绉戝/鐥呭尯婊℃剰搴﹁瘎鍒嗗姣旓紙涓よ鍔ㄦ�佽〃澶达級
+ buildExportTable3() {
+ const rows = this.table3Rows || [];
+ const questions = this.table3Questions || [];
+ if (!rows.length) return null;
+ const head1 = [this.statDimension === "dept" ? "绉戝" : "鐥呭尯"];
+ const head2 = [""];
+ const groups = [];
+ questions.forEach((q) => {
+ const opts = q.options || [];
+ const startCol = head1.length;
+ head1.push(q.title);
+ for (let i = 1; i < opts.length + 1; i++) head1.push("");
+ groups.push({ start: startCol, end: startCol + opts.length });
+ opts.forEach((opt) => head2.push(opt));
+ head2.push("寰楀垎");
+ });
+ head1.push("缁煎悎寰楀垎");
+ head2.push("");
+ const data = [["鍚勭瀹�/鐥呭尯婊℃剰搴﹁瘎鍒嗗姣�"], head1, head2];
+ const merges = [
+ { s: { r: 0, c: 0 }, e: { r: 0, c: head1.length - 1 } },
+ { s: { r: 1, c: 0 }, e: { r: 2, c: 0 } },
+ {
+ s: { r: 1, c: head1.length - 1 },
+ e: { r: 2, c: head1.length - 1 },
+ },
+ ];
+ groups.forEach((g) => {
+ if (g.end > g.start) {
+ merges.push({ s: { r: 1, c: g.start }, e: { r: 1, c: g.end } });
+ }
+ });
+ rows.forEach((row) => {
+ const line = [row.name];
+ questions.forEach((q) => {
+ const cell = (row.cells && row.cells[q.title]) || {};
+ (q.options || []).forEach((opt) => {
+ line.push((cell[opt] && cell[opt].count) || 0);
+ });
+ line.push(cell._score || "0.00");
+ });
+ line.push(row.totalScore);
+ data.push(line);
+ });
+ return { name: "鍚勭瀹ょ梾鍖鸿瘎鍒嗗姣�", data, merges };
+ },
},
};
</script>
--
Gitblit v1.9.3