From 4c5d48b7e9450e8e793970576caf2f3510e99dba Mon Sep 17 00:00:00 2001
From: WXL (wul) <wl_5969728@163.com>
Date: 星期五, 27 三月 2026 09:33:01 +0800
Subject: [PATCH] 测试完成
---
src/views/Satisfaction/sfstatistics/components/FollowupStatistics.vue | 387 +++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 304 insertions(+), 83 deletions(-)
diff --git a/src/views/Satisfaction/sfstatistics/components/FollowupStatistics.vue b/src/views/Satisfaction/sfstatistics/components/FollowupStatistics.vue
index 07f6c19..1b59b49 100644
--- a/src/views/Satisfaction/sfstatistics/components/FollowupStatistics.vue
+++ b/src/views/Satisfaction/sfstatistics/components/FollowupStatistics.vue
@@ -142,9 +142,11 @@
v-if="queryParams.statisticaltype == 1"
label="鍑洪櫌鐥呭尯"
align="center"
+ sortable
key="leavehospitaldistrictname"
prop="leavehospitaldistrictname"
:show-overflow-tooltip="true"
+ :sort-method="sortChineseNumber"
min-width="120"
/>
@@ -191,7 +193,12 @@
min-width="100"
>
<template slot-scope="scope">
- <span v-if="scope.row.followUpRate !== null && scope.row.followUpRate !== undefined">
+ <span
+ v-if="
+ scope.row.followUpRate !== null &&
+ scope.row.followUpRate !== undefined
+ "
+ >
{{ formatPercent(scope.row.followUpRate) }}
</span>
<span v-else>-</span>
@@ -241,24 +248,20 @@
min-width="100"
>
<template slot-scope="scope">
- <span v-if="scope.row.joyTotal !== null && scope.row.joyTotal !== undefined">
+ <span
+ v-if="
+ scope.row.joyTotal !== null && scope.row.joyTotal !== undefined
+ "
+ >
{{ formatPercent(scope.row.joyTotal) }}
</span>
<span v-else>-</span>
</template>
</el-table-column>
- <el-table-column
- label="鎿嶄綔"
- align="center"
- fixed="right"
- width="120"
- >
+ <el-table-column label="鎿嶄綔" align="center" fixed="right" width="120">
<template slot-scope="scope">
- <el-button
- type="text"
- @click="getinfo(scope.row)"
- >
+ <el-button type="text" @click="getinfo(scope.row)">
<i class="el-icon-s-order" style="margin-right: 4px"></i>
鏌ョ湅璇︽儏
</el-button>
@@ -303,15 +306,21 @@
:close-on-click-modal="false"
>
<template #title>
- <div style="display: flex; align-items: center;">
- <i class="el-icon-s-data" style="margin-right: 8px; color: #409EFF;"></i>
+ <div style="display: flex; align-items: center">
+ <i
+ class="el-icon-s-data"
+ style="margin-right: 8px; color: #409eff"
+ ></i>
<span>{{ topicvalue.name }}</span>
- <span style="margin-left: 10px; color: #666; font-size: 14px;">婊℃剰搴︽寚鏍囪鎯�</span>
+ <span style="margin-left: 10px; color: #666; font-size: 14px"
+ >婊℃剰搴︽寚鏍囪鎯�</span
+ >
</div>
</template>
<topic-dialog
v-if="topicVisible"
:row-data="currentRow"
+ :topicList="topiclist"
:query-params="queryParams"
@close="topicVisible = false"
/>
@@ -320,35 +329,39 @@
</template>
<script>
-import { getSfStatisticsJoy, getSfStatisticsJoyInfo, selectTimelyRate } from "@/api/system/user";
+import {
+ getSfStatisticsJoy,
+ getSfStatisticsJoyInfo,
+ selectTimelyRate,
+} from "@/api/system/user";
import ExcelJS from "exceljs";
import { saveAs } from "file-saver";
-import SeedetailsDialog from './components/SeedetailsDialog.vue';
-import TopicDialog from './components/TopicDialog.vue';
+import SeedetailsDialog from "./components/SeedetailsDialog.vue";
+import TopicDialog from "./components/TopicDialog.vue";
export default {
- name: 'FollowupStatistics',
+ name: "FollowupStatistics",
components: {
SeedetailsDialog,
- TopicDialog
+ TopicDialog,
},
data() {
return {
// 鏌ヨ鍙傛暟
queryParams: {
statisticaltype: 1,
- leavehospitaldistrictcodes: [],
+ leavehospitaldistrictcodes: ["all"],
deptcodes: [],
serviceType: [2],
dateRange: [],
pageNum: 1,
- pageSize: 20
+ pageSize: 20,
},
// 缁熻绫诲瀷鍒楄〃
Statisticallist: [
{ label: "鐥呭尯缁熻", value: 1 },
- { label: "绉戝缁熻", value: 2 }
+ { label: "绉戝缁熻", value: 2 },
],
// 鐥呭尯鍒楄〃
@@ -384,44 +397,44 @@
// 婊℃剰搴﹁鎯呮暟鎹�
topiclist: [],
topicvalue: {
- name: ''
+ name: "",
},
// 鏃ユ湡閫夋嫨鍣ㄩ�夐」
pickerOptions: {
shortcuts: [
{
- text: '鏈�杩戜竴鍛�',
+ text: "鏈�杩戜竴鍛�",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
- picker.$emit('pick', [start, end]);
- }
+ picker.$emit("pick", [start, end]);
+ },
},
{
- text: '鏈�杩戜竴涓湀',
+ text: "鏈�杩戜竴涓湀",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
- picker.$emit('pick', [start, end]);
- }
+ picker.$emit("pick", [start, end]);
+ },
},
{
- text: '鏈�杩戜笁涓湀',
+ text: "鏈�杩戜笁涓湀",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
- picker.$emit('pick', [start, end]);
- }
- }
+ picker.$emit("pick", [start, end]);
+ },
+ },
],
disabledDate(time) {
return time.getTime() > Date.now();
- }
- }
+ },
+ },
};
},
@@ -442,20 +455,24 @@
this.options = this.$store.getters.tasktypes || [];
// 鑾峰彇绉戝鍒楄〃
- this.flatArraydept = (this.$store.getters.belongDepts || []).map((dept) => {
- return {
- label: dept.deptName,
- value: dept.deptCode
- };
- });
+ this.flatArraydept = (this.$store.getters.belongDepts || []).map(
+ (dept) => {
+ return {
+ label: dept.deptName,
+ value: dept.deptCode,
+ };
+ }
+ );
// 鑾峰彇鐥呭尯鍒楄〃
- this.flatArrayhospit = (this.$store.getters.belongWards || []).map((ward) => {
- return {
- label: ward.districtName,
- value: ward.districtCode
- };
- });
+ this.flatArrayhospit = (this.$store.getters.belongWards || []).map(
+ (ward) => {
+ return {
+ label: ward.districtName,
+ value: ward.districtCode,
+ };
+ }
+ );
// 娣诲姞鍏ㄩ儴閫夐」
this.flatArraydept.push({ label: "鍏ㄩ儴", value: "all" });
@@ -469,11 +486,14 @@
// 澶勭悊鏌ヨ鍙傛暟
const params = {
configKey: "joyCount",
- ...this.queryParams
+ ...this.queryParams,
};
// 澶勭悊鏃ユ湡鑼冨洿
- if (this.queryParams.dateRange && this.queryParams.dateRange.length === 2) {
+ if (
+ this.queryParams.dateRange &&
+ this.queryParams.dateRange.length === 2
+ ) {
params.startTime = this.queryParams.dateRange[0];
params.endTime = this.queryParams.dateRange[1];
}
@@ -483,31 +503,215 @@
// 鐥呭尯缁熻
if (params.leavehospitaldistrictcodes.includes("all")) {
// 濡傛灉閫夋嫨浜�"鍏ㄩ儴"锛屽垯绉婚櫎"all"鍊�
- params.leavehospitaldistrictcodes = params.leavehospitaldistrictcodes.filter(item => item !== "all");
+ params.leavehospitaldistrictcodes =
+ params.leavehospitaldistrictcodes.filter(
+ (item) => item !== "all"
+ );
// 濡傛灉闇�瑕佷紶鎵�鏈夌梾鍖轰唬鐮侊紝鍙互浠巗tore涓幏鍙�
- params.leavehospitaldistrictcodes = (this.$store.getters.belongWards || []).map(ward => ward.districtCode);
+ params.leavehospitaldistrictcodes = (
+ this.$store.getters.belongWards || []
+ ).map((ward) => ward.districtCode);
}
} else if (params.statisticaltype == 2) {
// 绉戝缁熻
if (params.deptcodes.includes("all")) {
// 濡傛灉閫夋嫨浜�"鍏ㄩ儴"锛屽垯绉婚櫎"all"鍊�
- params.deptcodes = params.deptcodes.filter(item => item !== "all");
+ params.deptcodes = params.deptcodes.filter(
+ (item) => item !== "all"
+ );
// 濡傛灉闇�瑕佷紶鎵�鏈夌瀹や唬鐮侊紝鍙互浠巗tore涓幏鍙�
- params.deptcodes = (this.$store.getters.belongDepts || []).map(dept => dept.deptCode);
+ params.deptcodes = (this.$store.getters.belongDepts || []).map(
+ (dept) => dept.deptCode
+ );
}
}
const response = await getSfStatisticsJoy(params);
- this.userList = response.data || [];
+ this.userList = this.customSort(response.data) || [];
this.total = response.total || 0;
} catch (error) {
- console.error('鑾峰彇缁熻鍒楄〃澶辫触:', error);
- this.$message.error('鑾峰彇鏁版嵁澶辫触');
+ console.error("鑾峰彇缁熻鍒楄〃澶辫触:", error);
+ this.$message.error("鑾峰彇鏁版嵁澶辫触");
} finally {
this.loading = false;
}
},
+ sortChineseNumber(aRow, bRow) {
+ const a = aRow.leavehospitaldistrictname;
+ const b = bRow.leavehospitaldistrictname;
+ // 涓枃鏁板瓧鍒伴樋鎷変集鏁板瓧鐨勬槧灏勶紙鎵╁睍鍒�45锛�
+ const chineseNumMap = {
+ 涓�: 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,
+ };
+
+ // 鎻愬彇涓枃鏁板瓧
+ const getNumberFromText = (text) => {
+ if (!text || typeof text !== "string") return -1;
+
+ // 鍖归厤涓枃鏁板瓧锛屾敮鎸佷竴鍒板洓鍗佷簲
+ const match = text.match(/^([涓�浜屼笁鍥涗簲鍏竷鍏節鍗乚+)/);
+
+ if (match && match[1]) {
+ const chineseNum = match[1];
+ return chineseNumMap[chineseNum] !== undefined
+ ? chineseNumMap[chineseNum]
+ : -1;
+ }
+
+ // 濡傛灉娌℃湁鍖归厤鍒颁腑鏂囨暟瀛楋紝灏濊瘯鍖归厤闃挎媺浼暟瀛�
+ const arabicMatch = text.match(/^(\d+)/);
+ if (arabicMatch && arabicMatch[1]) {
+ const num = parseInt(arabicMatch[1], 10);
+ return num >= 1 && num <= 45 ? num : -1;
+ }
+
+ return -1;
+ };
+
+ const numA = getNumberFromText(a);
+ const numB = getNumberFromText(b);
+
+ // 澶勭悊鏃犳硶瑙f瀽鐨勬儏鍐�
+ if (numA === -1 && numB === -1) {
+ return (a || "").localeCompare(b || "");
+ }
+ if (numA === -1) return 1;
+ if (numB === -1) return -1;
+
+ return numA - numB;
+ },
+ customSort(data) {
+ // 瀹氫箟鎮ㄦ湡鏈涚殑鐥呭尯椤哄簭锛堟墿灞曞埌鍥涘崄浜旓級
+ const order = [
+ "涓�",
+ "浜�",
+ "涓�",
+ "鍥�",
+ "浜�",
+ "鍏�",
+ "涓�",
+ "鍏�",
+ "涔�",
+ "鍗�",
+ "鍗佷竴",
+ "鍗佷簩",
+ "鍗佷笁",
+ "鍗佸洓",
+ "鍗佷簲",
+ "鍗佸叚",
+ "鍗佷竷",
+ "鍗佸叓",
+ "鍗佷節",
+ "浜屽崄",
+ "浜屽崄涓�",
+ "浜屽崄浜�",
+ "浜屽崄涓�",
+ "浜屽崄鍥�",
+ "浜屽崄浜�",
+ "浜屽崄鍏�",
+ "浜屽崄涓�",
+ "浜屽崄鍏�",
+ "浜屽崄涔�",
+ "涓夊崄",
+ "涓夊崄涓�",
+ "涓夊崄浜�",
+ "涓夊崄涓�",
+ "涓夊崄鍥�",
+ "涓夊崄浜�",
+ "涓夊崄鍏�",
+ "涓夊崄涓�",
+ "涓夊崄鍏�",
+ "涓夊崄涔�",
+ "鍥涘崄",
+ "鍥涘崄涓�",
+ "鍥涘崄浜�",
+ "鍥涘崄涓�",
+ "鍥涘崄鍥�",
+ "鍥涘崄浜�",
+ ];
+
+ return data.sort((a, b) => {
+ // 鎻愬彇鐥呭尯鍚嶇О涓殑涓枃鏁板瓧閮ㄥ垎
+ const getIndex = (name) => {
+ if (!name || typeof name !== "string") return -1;
+
+ // 鍖归厤涓枃鏁板瓧
+ const chineseMatch = name.match(/^([涓�浜屼笁鍥涗簲鍏竷鍏節鍗乚+)/);
+ if (chineseMatch && chineseMatch[1]) {
+ return order.indexOf(chineseMatch[1]);
+ }
+
+ // 鍖归厤闃挎媺浼暟瀛�
+ const arabicMatch = name.match(/^(\d+)/);
+ if (arabicMatch && arabicMatch[1]) {
+ const num = parseInt(arabicMatch[1], 10);
+ if (num >= 1 && num <= 45) {
+ return num - 1; // 鍥犱负鏁扮粍绱㈠紩浠�0寮�濮�
+ }
+ }
+
+ return -1;
+ };
+
+ const indexA = getIndex(a.leavehospitaldistrictname);
+ const indexB = getIndex(b.leavehospitaldistrictname);
+
+ // 鎺掑簭閫昏緫
+ if (indexA === -1 && indexB === -1) {
+ return (a.leavehospitaldistrictname || "").localeCompare(
+ b.leavehospitaldistrictname || ""
+ );
+ }
+ if (indexA === -1) return 1;
+ if (indexB === -1) return -1;
+ return indexA - indexB;
+ });
+ },
// 澶勭悊缁熻绫诲瀷鍙樺寲
handleStatisticalTypeChange(value) {
if (value === 1) {
@@ -534,7 +738,7 @@
serviceType: [2],
dateRange: [],
pageNum: 1,
- pageSize: 20
+ pageSize: 20,
};
this.getList();
},
@@ -554,7 +758,7 @@
// 澶勭悊琛岄�夋嫨
handleSelectionChange(selection) {
- this.ids = selection.map(item => item.id);
+ this.ids = selection.map((item) => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
@@ -568,9 +772,9 @@
// 鏍煎紡鍖栫櫨鍒嗘瘮
formatPercent(value) {
- if (value === null || value === undefined) return '-';
+ if (value === null || value === undefined) return "-";
const num = parseFloat(value);
- if (isNaN(num)) return '-';
+ if (isNaN(num)) return "-";
return `${(num * 100).toFixed(2)}%`;
},
@@ -583,17 +787,19 @@
// 鏌ョ湅婊℃剰搴﹁鎯�
async getinfo(row) {
this.currentRow = row;
- this.topicVisible = true;
try {
// 澶勭悊鏌ヨ鍙傛暟
const params = {
configKey: "joyCount",
- ...this.queryParams
+ ...this.queryParams,
};
// 澶勭悊鏃ユ湡鑼冨洿
- if (this.queryParams.dateRange && this.queryParams.dateRange.length === 2) {
+ if (
+ this.queryParams.dateRange &&
+ this.queryParams.dateRange.length === 2
+ ) {
params.startTime = this.queryParams.dateRange[0];
params.endTime = this.queryParams.dateRange[1];
}
@@ -608,16 +814,18 @@
const response = await getSfStatisticsJoyInfo(params);
this.topiclist = response.data || [];
+ this.topicVisible = true;
+
} catch (error) {
- console.error('鑾峰彇婊℃剰搴﹁鎯呭け璐�:', error);
- this.$message.error('鑾峰彇璇︽儏澶辫触');
+ console.error("鑾峰彇婊℃剰搴﹁鎯呭け璐�:", error);
+ this.$message.error("鑾峰彇璇︽儏澶辫触");
}
},
// 瀵煎嚭鏁版嵁
async handleExport() {
if (!this.userList.length) {
- this.$message.warning('娌℃湁鏁版嵁鍙鍑�');
+ this.$message.warning("娌℃湁鏁版嵁鍙鍑�");
return;
}
@@ -628,7 +836,10 @@
let dateRangeString = "";
let sheetNameSuffix = "";
- if (this.queryParams.dateRange && this.queryParams.dateRange.length === 2) {
+ if (
+ this.queryParams.dateRange &&
+ this.queryParams.dateRange.length === 2
+ ) {
const startDateFormatted = this.queryParams.dateRange[0];
const endDateFormatted = this.queryParams.dateRange[1];
dateRangeString = `${startDateFormatted}鑷�${endDateFormatted}`;
@@ -650,26 +861,34 @@
// 瀹氫箟鏍峰紡
const titleStyle = {
font: { name: "寰蒋闆呴粦", size: 16, bold: true },
- fill: { type: "pattern", pattern: "solid", fgColor: { argb: "FFE6F3FF" } },
+ fill: {
+ type: "pattern",
+ pattern: "solid",
+ fgColor: { argb: "FFE6F3FF" },
+ },
alignment: { vertical: "middle", horizontal: "center" },
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" } }
- }
+ right: { style: "thin", color: { argb: "FFD0D0D0" } },
+ },
};
const headerStyle = {
font: { name: "寰蒋闆呴粦", size: 11, bold: true },
- fill: { type: "pattern", pattern: "solid", fgColor: { argb: "FFF5F7FA" } },
+ fill: {
+ type: "pattern",
+ pattern: "solid",
+ fgColor: { argb: "FFF5F7FA" },
+ },
alignment: { vertical: "middle", horizontal: "center" },
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" } }
- }
+ right: { style: "thin", color: { argb: "FFD0D0D0" } },
+ },
};
const cellStyle = {
@@ -679,8 +898,8 @@
top: { style: "thin", color: { argb: "FFD0D0D0" } },
left: { style: "thin", color: { argb: "FFD0D0D0" } },
bottom: { style: "thin", color: { argb: "FFD0D0D0" } },
- right: { style: "thin", color: { argb: "FFD0D0D0" } }
- }
+ right: { style: "thin", color: { argb: "FFD0D0D0" } },
+ },
};
// 娣诲姞鎬绘爣棰�
@@ -700,7 +919,7 @@
"鍙婃椂鐜�",
"婊℃剰搴﹂鐩�婚噺",
"婊℃剰搴﹀~鎶ラ噺",
- "瀹屾垚姣旂巼"
+ "瀹屾垚姣旂巼",
];
const headerRow = worksheet.addRow(headers);
@@ -712,7 +931,9 @@
// 娣诲姞鏁版嵁琛�
this.userList.forEach((item) => {
const dataRow = worksheet.addRow([
- this.queryParams.statisticaltype == 1 ? item.leavehospitaldistrictname : item.deptname,
+ this.queryParams.statisticaltype == 1
+ ? item.leavehospitaldistrictname
+ : item.deptname,
item.dischargeCount || 0,
item.nonFollowUp || 0,
item.followUpNeeded || 0,
@@ -720,7 +941,7 @@
item.rate ? this.formatPercent(item.rate) : "0%",
item.joyAllCount || 0,
item.joyCount || 0,
- item.joyTotal ? this.formatPercent(item.joyTotal) : "0%"
+ item.joyTotal ? this.formatPercent(item.joyTotal) : "0%",
]);
dataRow.eachCell((cell) => {
@@ -739,13 +960,13 @@
{ width: 12 },
{ width: 15 },
{ width: 15 },
- { width: 12 }
+ { width: 12 },
];
// 鐢熸垚骞朵笅杞芥枃浠�
const buffer = await workbook.xlsx.writeBuffer();
const blob = new Blob([buffer], {
- type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+ type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
});
saveAs(blob, excelName);
@@ -756,8 +977,8 @@
} finally {
this.loading = false;
}
- }
- }
+ },
+ },
};
</script>
--
Gitblit v1.9.3