已删除1个文件
已重命名1个文件
已修改16个文件
已添加2个文件
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <!-- StatisticsMain.vue --> |
| | | <template> |
| | | <div class="statistics-main"> |
| | | <el-tabs v-model="activeTab" @tab-click="handleTabChange"> |
| | | <el-tab-pane label="满æåº¦ç»è®¡" name="followup"> |
| | | <followup-statistics |
| | | v-if="activeTab === 'followup'" |
| | | ref="followupRef" |
| | | /> |
| | | </el-tab-pane> |
| | | <el-tab-pane label="å¤è¯éç¥ç»è®¡" name="visitStatistics"> |
| | | <visit-Statistics |
| | | v-if="activeTab === 'visitStatistics'" |
| | | ref="visitStatisticsRef" |
| | | /> |
| | | </el-tab-pane> |
| | | |
| | | </el-tabs> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import FollowupStatistics from "./components/FollowupStatistics.vue"; |
| | | import visitStatistics from "./components/visitStatistics.vue"; |
| | | import SatisfactionStatistics from "./components/SatisfactionStatistics.vue"; |
| | | |
| | | export default { |
| | | name: "StatisticsMain", |
| | | components: { |
| | | FollowupStatistics, |
| | | SatisfactionStatistics, |
| | | visitStatistics, |
| | | }, |
| | | data() { |
| | | return { |
| | | activeTab: "followup", |
| | | }; |
| | | }, |
| | | methods: { |
| | | handleTabChange(tab) { |
| | | console.log("忢å°:", tab.name); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .statistics-main { |
| | | padding: 20px; |
| | | background: #fff; |
| | | min-height: calc(100vh - 84px); |
| | | |
| | | ::v-deep .el-tabs__header { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | ::v-deep .el-tabs__item { |
| | | font-size: 16px; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | ::v-deep .el-tabs__nav-wrap::after { |
| | | height: 1px; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | v-if="queryParams.statisticaltype == 1" |
| | | label="åºé¢ç
åº" |
| | | align="center" |
| | | sortable |
| | | key="leavehospitaldistrictname" |
| | | prop="leavehospitaldistrictname" |
| | | :show-overflow-tooltip="true" |
| | | :sort-method="sortChineseNumber" |
| | | min-width="120" |
| | | /> |
| | | |
| | |
| | | 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> |
| | |
| | | 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> |
| | |
| | | :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" |
| | | /> |
| | |
| | | </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 }, |
| | | ], |
| | | |
| | | // ç
åºå表 |
| | |
| | | // 满æåº¦è¯¦æ
æ°æ® |
| | | 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(); |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | }; |
| | | }, |
| | | |
| | |
| | | this.options = this.$store.getters.tasktypes || []; |
| | | |
| | | // è·åç§å®¤å表 |
| | | this.flatArraydept = (this.$store.getters.belongDepts || []).map((dept) => { |
| | | this.flatArraydept = (this.$store.getters.belongDepts || []).map( |
| | | (dept) => { |
| | | return { |
| | | label: dept.deptName, |
| | | value: dept.deptCode |
| | | value: dept.deptCode, |
| | | }; |
| | | }); |
| | | } |
| | | ); |
| | | |
| | | // è·åç
åºå表 |
| | | this.flatArrayhospit = (this.$store.getters.belongWards || []).map((ward) => { |
| | | this.flatArrayhospit = (this.$store.getters.belongWards || []).map( |
| | | (ward) => { |
| | | return { |
| | | label: ward.districtName, |
| | | value: ward.districtCode |
| | | value: ward.districtCode, |
| | | }; |
| | | }); |
| | | } |
| | | ); |
| | | |
| | | // æ·»å å
¨é¨é项 |
| | | this.flatArraydept.push({ label: "å
¨é¨", value: "all" }); |
| | |
| | | // å¤çæ¥è¯¢åæ° |
| | | 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]; |
| | | } |
| | |
| | | // ç
åºç»è®¡ |
| | | if (params.leavehospitaldistrictcodes.includes("all")) { |
| | | // 妿鿩äº"å
¨é¨"ï¼åç§»é¤"all"å¼ |
| | | params.leavehospitaldistrictcodes = params.leavehospitaldistrictcodes.filter(item => item !== "all"); |
| | | params.leavehospitaldistrictcodes = |
| | | params.leavehospitaldistrictcodes.filter( |
| | | (item) => item !== "all" |
| | | ); |
| | | // 妿éè¦ä¼ ææç
åºä»£ç ï¼å¯ä»¥ä»storeä¸è·å |
| | | 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" |
| | | ); |
| | | // 妿éè¦ä¼ ææç§å®¤ä»£ç ï¼å¯ä»¥ä»storeä¸è·å |
| | | 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); |
| | | |
| | | // å¤çæ æ³è§£æçæ
åµ |
| | | 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) { |
| | |
| | | serviceType: [2], |
| | | dateRange: [], |
| | | pageNum: 1, |
| | | pageSize: 20 |
| | | pageSize: 20, |
| | | }; |
| | | this.getList(); |
| | | }, |
| | |
| | | |
| | | // å¤çè¡éæ© |
| | | 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; |
| | | }, |
| | |
| | | |
| | | // æ ¼å¼åç¾åæ¯ |
| | | 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)}%`; |
| | | }, |
| | | |
| | |
| | | // æ¥ç满æåº¦è¯¦æ
|
| | | 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]; |
| | | } |
| | |
| | | |
| | | 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; |
| | | } |
| | | |
| | |
| | | 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}`; |
| | |
| | | // å®ä¹æ ·å¼ |
| | | 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 = { |
| | |
| | | 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 headerRow = worksheet.addRow(headers); |
| | |
| | | // æ·»å æ°æ®è¡ |
| | | 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, |
| | |
| | | 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) => { |
| | |
| | | { 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); |
| | |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | |
| | | <div class="topic-dialog"> |
| | | <div class="topicdia"> |
| | | <div style="overflow-x: hidden; overflow-y: auto; max-height: 65vh"> |
| | | <!-- ä¿®æ¹è¿éï¼ä½¿ç¨ processedTopicList è䏿¯ topicList --> |
| | | <div |
| | | v-for="(item, index) in topiclist" |
| | | :key="index" |
| | | v-for="(item, index) in processedTopicList" |
| | | :key="item.scriptid" |
| | | class="ttaabbcc" |
| | | > |
| | | <div class="describe"> |
| | | 第{{ index + 1 }}é¢ï¼ {{ item.scriptContent }}? |
| | | 第{{ index + 1 }}é¢ï¼ {{ item.scriptContent }} |
| | | <span>[{{ item.scriptType == 1 ? "åéé¢" : "å¤éé¢" }}]</span> |
| | | </div> |
| | | <div> |
| | |
| | | label="éæ©äººæ°" |
| | | align="center" |
| | | min-width="120" |
| | | /> |
| | | > |
| | | <template slot-scope="{ row }"> |
| | | {{ row.chosenQuantity || 0 }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | prop="chosenPercentage" |
| | | label="æ¯ä¾" |
| | |
| | | min-width="120" |
| | | > |
| | | <template slot-scope="{ row }"> |
| | | <span v-if="row.chosenPercentage !== null && row.chosenPercentage !== undefined"> |
| | | {{ formatPercent(row.chosenPercentage) }} |
| | | <span |
| | | v-if=" |
| | | row.chosenPercentage !== null && |
| | | row.chosenPercentage !== undefined |
| | | " |
| | | > |
| | | {{ (Number(row.chosenPercentage) * 100).toFixed(2) }}% |
| | | </span> |
| | | <span v-else>-</span> |
| | | </template> |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | <div slot="footer" class="dialog-footer" style="text-align: center; padding-top: 20px;"> |
| | | <!-- å¦ææ²¡ææ°æ® --> |
| | | <div |
| | | v-if="!processedTopicList.length" |
| | | class="no-data" |
| | | style="text-align: center; padding: 50px 0" |
| | | > |
| | | <el-empty description="ææ æ°æ®"></el-empty> |
| | | </div> |
| | | |
| | | <div |
| | | slot="footer" |
| | | class="dialog-footer" |
| | | style="text-align: center; padding-top: 20px" |
| | | > |
| | | <el-button @click="handleClose">å
³ é</el-button> |
| | | </div> |
| | | </div> |
| | |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'TopicDialog', |
| | | name: "TopicDialog", |
| | | props: { |
| | | rowData: { |
| | | type: Object, |
| | | default: () => ({}) |
| | | default: () => ({}), |
| | | }, |
| | | queryParams: { |
| | | type: Object, |
| | | default: () => ({}) |
| | | } |
| | | default: () => ({}), |
| | | }, |
| | | topicList: { |
| | | type: [Array, Object], |
| | | default: () => ({}), |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | topiclist: [] |
| | | processedTopicList: [], // å¤çåçæ°æ® |
| | | }; |
| | | }, |
| | | |
| | | mounted() { |
| | | this.loadData(); |
| | | watch: { |
| | | // çå¬ç¶ç»ä»¶ä¼ éçæ°æ®åå |
| | | topicList: { |
| | | immediate: true, |
| | | handler(newVal) { |
| | | console.log("TopicDialogæ¥æ¶å°ç¶ç»ä»¶æ°æ®:", newVal); |
| | | this.processTopicList(newVal); |
| | | }, |
| | | |
| | | }, |
| | | }, |
| | | mounted() { |
| | | console.log("TopicDialog mounted, props:", this.$props); |
| | | }, |
| | | methods: { |
| | | // å è½½æ°æ® |
| | | async loadData() { |
| | | try { |
| | | // è¿éä»ç¶ç»ä»¶ä¼ éæ°æ®ï¼ä¸éè¦éæ°è°ç¨API |
| | | this.topiclist = this.$parent.topiclist || []; |
| | | } catch (error) { |
| | | console.error('å è½½é¢ç®è¯¦æ
失败:', error); |
| | | this.$message.error('å è½½é¢ç®è¯¦æ
失败'); |
| | | // å¤çtopicListæ°æ® |
| | | processTopicList(data) { |
| | | console.log("å¼å§å¤çæ°æ®:", data); |
| | | |
| | | if (!data || typeof data !== "object") { |
| | | this.processedTopicList = []; |
| | | return; |
| | | } |
| | | |
| | | // å°å¯¹è±¡è½¬æ¢ä¸ºæ°ç» |
| | | const result = []; |
| | | |
| | | Object.keys(data).forEach((key) => { |
| | | const item = data[key]; |
| | | if (item && item.scriptContent) { |
| | | // æ·±æ·è´itemï¼é¿å
ä¿®æ¹åæ°æ® |
| | | const processedItem = JSON.parse(JSON.stringify(item)); |
| | | |
| | | // è¿æ»¤detailsï¼åªä¿çæéé¡¹ææ¬ç |
| | | if (processedItem.details && Array.isArray(processedItem.details)) { |
| | | processedItem.details = processedItem.details.filter( |
| | | (detail) => detail && detail.optionText |
| | | ); |
| | | } |
| | | |
| | | result.push(processedItem); |
| | | } |
| | | }); |
| | | |
| | | console.log("å¤çåçæ°æ®:", result); |
| | | this.processedTopicList = result; |
| | | }, |
| | | |
| | | // æ ¼å¼åç¾åæ¯ |
| | | formatPercent(value) { |
| | | if (value === null || value === undefined) return '-'; |
| | | if (value === null || value === undefined) return "-"; |
| | | const num = parseFloat(value); |
| | | if (isNaN(num)) return '-'; |
| | | return `${(num * 100).toFixed(2)}%`; |
| | | if (isNaN(num)) return "-"; |
| | | return `${num.toFixed(2)}%`; // 注æï¼ä½ çæ°æ®ä¸ç¾åæ¯å·²ç»æ¯0-100çå½¢å¼ |
| | | }, |
| | | |
| | | // å
³éå¯¹è¯æ¡ |
| | | handleClose() { |
| | | this.$emit('close'); |
| | | } |
| | | } |
| | | this.$emit("close"); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="followup-statistics"> |
| | | <div class="query-section"> |
| | | <el-form |
| | | :model="queryParams" |
| | | ref="queryForm" |
| | | size="medium" |
| | | :inline="true" |
| | | label-width="100px" |
| | | class="query-form" |
| | | > |
| | | <el-form-item label="ç»è®¡ç±»å" prop="statisticaltype"> |
| | | <el-select |
| | | v-model="queryParams.statisticaltype" |
| | | placeholder="è¯·éæ©ç»è®¡ç±»å" |
| | | clearable |
| | | @change="handleStatisticalTypeChange" |
| | | > |
| | | <el-option |
| | | v-for="item in Statisticallist" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <!-- ç
åºéæ© --> |
| | | <el-form-item |
| | | v-if="queryParams.statisticaltype == 1" |
| | | label="ç
åº" |
| | | prop="leavehospitaldistrictcodes" |
| | | > |
| | | <el-select |
| | | v-model="queryParams.leavehospitaldistrictcodes" |
| | | placeholder="è¯·éæ©ç
åº" |
| | | multiple |
| | | collapse-tags |
| | | filterable |
| | | clearable |
| | | style="width: 300px" |
| | | > |
| | | <el-option |
| | | v-for="item in flatArrayhospit" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <!-- ç§å®¤éæ© --> |
| | | <el-form-item |
| | | v-if="queryParams.statisticaltype == 2" |
| | | label="ç§å®¤" |
| | | prop="deptcodes" |
| | | > |
| | | <el-select |
| | | v-model="queryParams.deptcodes" |
| | | placeholder="è¯·éæ©ç§å®¤" |
| | | multiple |
| | | collapse-tags |
| | | filterable |
| | | clearable |
| | | style="width: 300px" |
| | | > |
| | | <el-option |
| | | v-for="item in flatArraydept" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="æå¡ç±»å" prop="serviceType"> |
| | | <el-select |
| | | v-model="queryParams.serviceType" |
| | | placeholder="è¯·éæ©æå¡ç±»å" |
| | | multiple |
| | | collapse-tags |
| | | clearable |
| | | style="width: 300px" |
| | | > |
| | | <el-option |
| | | v-for="item in options" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="é访æ¶é´" prop="dateRange"> |
| | | <el-date-picker |
| | | v-model="queryParams.dateRange" |
| | | type="daterange" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | value-format="yyyy-MM-dd" |
| | | :picker-options="pickerOptions" |
| | | style="width: 380px" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-button |
| | | type="primary" |
| | | icon="el-icon-search" |
| | | @click="handleQuery" |
| | | :loading="loading" |
| | | > |
| | | æç´¢ |
| | | </el-button> |
| | | <el-button icon="el-icon-refresh" @click="resetQuery"> |
| | | éç½® |
| | | </el-button> |
| | | <el-button |
| | | type="warning" |
| | | icon="el-icon-download" |
| | | @click="handleExport" |
| | | :disabled="!userList.length" |
| | | > |
| | | å¯¼åº |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | |
| | | <div class="table-section"> |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="userList" |
| | | :border="true" |
| | | style="width: 100%" |
| | | @selection-change="handleSelectionChange" |
| | | :row-key="getRowKey" |
| | | > |
| | | <!-- ç
åºå --> |
| | | <el-table-column |
| | | v-if="queryParams.statisticaltype == 1" |
| | | label="åºé¢ç
åº" |
| | | align="center" |
| | | sortable |
| | | key="leavehospitaldistrictname" |
| | | prop="leavehospitaldistrictname" |
| | | :show-overflow-tooltip="true" |
| | | :sort-method="sortChineseNumber" |
| | | min-width="120" |
| | | /> |
| | | |
| | | <!-- ç§å®¤å --> |
| | | <el-table-column |
| | | v-if="queryParams.statisticaltype == 2" |
| | | label="ç§å®¤" |
| | | align="center" |
| | | key="deptname" |
| | | prop="deptname" |
| | | :show-overflow-tooltip="true" |
| | | min-width="120" |
| | | /> |
| | | |
| | | <el-table-column |
| | | label="åºé¢äººæ¬¡" |
| | | align="center" |
| | | key="dischargeCount" |
| | | prop="dischargeCount" |
| | | min-width="100" |
| | | /> |
| | | |
| | | <el-table-column |
| | | label="æ éé访人次" |
| | | align="center" |
| | | key="nonFollowUp" |
| | | prop="nonFollowUp" |
| | | min-width="120" |
| | | /> |
| | | |
| | | <el-table-column |
| | | label="åºé访人次" |
| | | align="center" |
| | | key="followUpNeeded" |
| | | prop="followUpNeeded" |
| | | min-width="120" |
| | | /> |
| | | |
| | | <el-table-column |
| | | label="é访ç" |
| | | align="center" |
| | | key="followUpRate" |
| | | prop="followUpRate" |
| | | min-width="100" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <span |
| | | v-if=" |
| | | scope.row.followUpRate !== null && |
| | | scope.row.followUpRate !== undefined |
| | | " |
| | | > |
| | | {{ formatPercent(scope.row.followUpRate) }} |
| | | </span> |
| | | <span v-else>-</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | label="åæ¶ç" |
| | | align="center" |
| | | key="rate" |
| | | prop="rate" |
| | | min-width="100" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | v-if="scope.row.rate !== null && scope.row.rate !== undefined" |
| | | type="text" |
| | | @click="handleSeedetails(scope.row)" |
| | | > |
| | | {{ formatPercent(scope.row.rate) }} |
| | | </el-button> |
| | | <span v-else style="color: #909399">-</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | label="å¤è¯éç¥é¢ç®æ»é" |
| | | align="center" |
| | | key="joyAllCount" |
| | | prop="joyAllCount" |
| | | min-width="140" |
| | | /> |
| | | |
| | | <el-table-column |
| | | label="å¤è¯éç¥å¡«æ¥é" |
| | | align="center" |
| | | key="joyCount" |
| | | prop="joyCount" |
| | | min-width="120" |
| | | /> |
| | | |
| | | <el-table-column |
| | | label="宿æ¯ç" |
| | | align="center" |
| | | key="joyTotal" |
| | | prop="joyTotal" |
| | | min-width="100" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <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"> |
| | | <template slot-scope="scope"> |
| | | <el-button type="text" @click="getinfo(scope.row)"> |
| | | <i class="el-icon-s-order" style="margin-right: 4px"></i> |
| | | æ¥ç详æ
|
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | |
| | | <!-- å页 --> |
| | | <div class="pagination-section" v-if="total > 0"> |
| | | <el-pagination |
| | | background |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :current-page="queryParams.pageNum" |
| | | :page-size="queryParams.pageSize" |
| | | :page-sizes="[10, 20, 30, 50]" |
| | | :total="total" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handlePageChange" |
| | | /> |
| | | </div> |
| | | |
| | | <!-- æªåæ¶é访详æ
å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | title="æªåæ¶é访æ£è
æå¡" |
| | | :visible.sync="SeedetailsVisible" |
| | | width="80%" |
| | | :close-on-click-modal="false" |
| | | > |
| | | <SeedetailsDialog |
| | | v-if="SeedetailsVisible" |
| | | :row-data="currentRow" |
| | | :query-params="queryParams" |
| | | @close="SeedetailsVisible = false" |
| | | /> |
| | | </el-dialog> |
| | | |
| | | <!-- å¤è¯éç¥è¯¦æ
å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | :visible.sync="topicVisible" |
| | | width="60%" |
| | | :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> |
| | | <span>{{ topicvalue.name }}</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" |
| | | /> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | 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"; |
| | | |
| | | export default { |
| | | name: "FollowupStatistics", |
| | | components: { |
| | | SeedetailsDialog, |
| | | TopicDialog, |
| | | }, |
| | | data() { |
| | | return { |
| | | // æ¥è¯¢åæ° |
| | | queryParams: { |
| | | statisticaltype: 1, |
| | | leavehospitaldistrictcodes: ["all"], |
| | | deptcodes: [], |
| | | serviceType: [2], |
| | | dateRange: [], |
| | | pageNum: 1, |
| | | pageSize: 20, |
| | | }, |
| | | |
| | | // ç»è®¡ç±»åå表 |
| | | Statisticallist: [ |
| | | { label: "ç
åºç»è®¡", value: 1 }, |
| | | { label: "ç§å®¤ç»è®¡", value: 2 }, |
| | | ], |
| | | |
| | | // ç
åºå表 |
| | | flatArrayhospit: [], |
| | | |
| | | // ç§å®¤å表 |
| | | flatArraydept: [], |
| | | |
| | | // æå¡ç±»åé项 |
| | | options: [], |
| | | |
| | | // è¡¨æ ¼æ°æ® |
| | | userList: [], |
| | | |
| | | // æ»æ¡æ° |
| | | total: 0, |
| | | |
| | | // å è½½ç¶æ |
| | | loading: false, |
| | | |
| | | // éä¸çè¡ |
| | | ids: [], |
| | | single: true, |
| | | multiple: true, |
| | | |
| | | // å½åæä½çè¡ |
| | | currentRow: null, |
| | | |
| | | // å¯¹è¯æ¡æ¾ç¤ºæ§å¶ |
| | | SeedetailsVisible: false, |
| | | topicVisible: false, |
| | | |
| | | // å¤è¯éç¥è¯¦æ
æ°æ® |
| | | topiclist: [], |
| | | topicvalue: { |
| | | name: "", |
| | | }, |
| | | |
| | | // æ¥æéæ©å¨é项 |
| | | pickerOptions: { |
| | | shortcuts: [ |
| | | { |
| | | text: "æè¿ä¸å¨", |
| | | onClick(picker) { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 7); |
| | | picker.$emit("pick", [start, end]); |
| | | }, |
| | | }, |
| | | { |
| | | text: "æè¿ä¸ä¸ªæ", |
| | | onClick(picker) { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 30); |
| | | picker.$emit("pick", [start, end]); |
| | | }, |
| | | }, |
| | | { |
| | | text: "æè¿ä¸ä¸ªæ", |
| | | onClick(picker) { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 90); |
| | | picker.$emit("pick", [start, end]); |
| | | }, |
| | | }, |
| | | ], |
| | | disabledDate(time) { |
| | | return time.getTime() > Date.now(); |
| | | }, |
| | | }, |
| | | }; |
| | | }, |
| | | |
| | | created() { |
| | | this.initData(); |
| | | }, |
| | | |
| | | methods: { |
| | | // åå§åæ°æ® |
| | | async initData() { |
| | | await this.getDeptTree(); |
| | | await this.getList(); |
| | | }, |
| | | |
| | | // è·åç§å®¤æ |
| | | getDeptTree() { |
| | | // è·åæå¡ç±»å |
| | | this.options = this.$store.getters.tasktypes || []; |
| | | |
| | | // è·åç§å®¤å表 |
| | | 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.flatArraydept.push({ label: "å
¨é¨", value: "all" }); |
| | | this.flatArrayhospit.push({ label: "å
¨é¨", value: "all" }); |
| | | }, |
| | | |
| | | // è·åç»è®¡å表 |
| | | async getList() { |
| | | this.loading = true; |
| | | try { |
| | | // å¤çæ¥è¯¢åæ° |
| | | const params = { |
| | | configKey: "returnVisitCount", |
| | | ...this.queryParams, |
| | | }; |
| | | |
| | | // å¤çæ¥æèå´ |
| | | if ( |
| | | this.queryParams.dateRange && |
| | | this.queryParams.dateRange.length === 2 |
| | | ) { |
| | | params.startTime = this.queryParams.dateRange[0]; |
| | | params.endTime = this.queryParams.dateRange[1]; |
| | | } |
| | | |
| | | // å¤çç
åº/ç§å®¤éæ© |
| | | if (params.statisticaltype == 1) { |
| | | // ç
åºç»è®¡ |
| | | if (params.leavehospitaldistrictcodes.includes("all")) { |
| | | // 妿鿩äº"å
¨é¨"ï¼åç§»é¤"all"å¼ |
| | | params.leavehospitaldistrictcodes = |
| | | params.leavehospitaldistrictcodes.filter( |
| | | (item) => item !== "all" |
| | | ); |
| | | // 妿éè¦ä¼ ææç
åºä»£ç ï¼å¯ä»¥ä»storeä¸è·å |
| | | 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" |
| | | ); |
| | | // 妿éè¦ä¼ ææç§å®¤ä»£ç ï¼å¯ä»¥ä»storeä¸è·å |
| | | params.deptcodes = (this.$store.getters.belongDepts || []).map( |
| | | (dept) => dept.deptCode |
| | | ); |
| | | } |
| | | } |
| | | |
| | | const response = await getSfStatisticsJoy(params); |
| | | this.userList = this.customSort(response.data) || []; |
| | | this.total = response.total || 0; |
| | | } catch (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); |
| | | |
| | | // å¤çæ æ³è§£æçæ
åµ |
| | | 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) { |
| | | this.queryParams.deptcodes = []; |
| | | } else { |
| | | this.queryParams.leavehospitaldistrictcodes = []; |
| | | } |
| | | this.queryParams.pageNum = 1; |
| | | this.getList(); |
| | | }, |
| | | |
| | | // å¤çæ¥è¯¢ |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1; |
| | | this.getList(); |
| | | }, |
| | | |
| | | // éç½®æ¥è¯¢ |
| | | resetQuery() { |
| | | this.queryParams = { |
| | | statisticaltype: 1, |
| | | leavehospitaldistrictcodes: [], |
| | | deptcodes: [], |
| | | serviceType: [2], |
| | | dateRange: [], |
| | | pageNum: 1, |
| | | pageSize: 20, |
| | | }; |
| | | this.getList(); |
| | | }, |
| | | |
| | | // å¤çå页大å°åå |
| | | handleSizeChange(size) { |
| | | this.queryParams.pageSize = size; |
| | | this.queryParams.pageNum = 1; |
| | | this.getList(); |
| | | }, |
| | | |
| | | // å¤ç页ç åå |
| | | handlePageChange(page) { |
| | | this.queryParams.pageNum = page; |
| | | this.getList(); |
| | | }, |
| | | |
| | | // å¤çè¡éæ© |
| | | handleSelectionChange(selection) { |
| | | this.ids = selection.map((item) => item.id); |
| | | this.single = selection.length !== 1; |
| | | this.multiple = !selection.length; |
| | | }, |
| | | |
| | | // è·åè¡key |
| | | getRowKey(row) { |
| | | return row.statisticaltype === 1 |
| | | ? row.leavehospitaldistrictcode |
| | | : row.deptcode; |
| | | }, |
| | | |
| | | // æ ¼å¼åç¾åæ¯ |
| | | formatPercent(value) { |
| | | if (value === null || value === undefined) return "-"; |
| | | const num = parseFloat(value); |
| | | if (isNaN(num)) return "-"; |
| | | return `${(num * 100).toFixed(2)}%`; |
| | | }, |
| | | |
| | | // æ¥çæªåæ¶é访详æ
|
| | | handleSeedetails(row) { |
| | | this.currentRow = row; |
| | | this.SeedetailsVisible = true; |
| | | }, |
| | | |
| | | // æ¥çå¤è¯éç¥è¯¦æ
|
| | | async getinfo(row) { |
| | | this.currentRow = row; |
| | | |
| | | try { |
| | | // å¤çæ¥è¯¢åæ° |
| | | const params = { |
| | | configKey: "returnVisitCount", |
| | | ...this.queryParams, |
| | | }; |
| | | |
| | | // å¤çæ¥æèå´ |
| | | if ( |
| | | this.queryParams.dateRange && |
| | | this.queryParams.dateRange.length === 2 |
| | | ) { |
| | | params.startTime = this.queryParams.dateRange[0]; |
| | | params.endTime = this.queryParams.dateRange[1]; |
| | | } |
| | | |
| | | if (this.queryParams.statisticaltype == 1) { |
| | | this.topicvalue.name = row.leavehospitaldistrictname; |
| | | params.leavehospitaldistrictcodes = [row.leavehospitaldistrictcode]; |
| | | } else { |
| | | this.topicvalue.name = row.deptname; |
| | | params.deptcodes = [row.deptcode]; |
| | | } |
| | | |
| | | const response = await getSfStatisticsJoyInfo(params); |
| | | this.topiclist = response.data || []; |
| | | console.log(this.topiclist); |
| | | this.topicVisible = true; |
| | | } catch (error) { |
| | | console.error("è·åå¤è¯éç¥è¯¦æ
失败:", error); |
| | | this.$message.error("è·å详æ
失败"); |
| | | } |
| | | }, |
| | | |
| | | // å¯¼åºæ°æ® |
| | | async handleExport() { |
| | | if (!this.userList.length) { |
| | | this.$message.warning("æ²¡ææ°æ®å¯å¯¼åº"); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | this.loading = true; |
| | | |
| | | // æå»ºæ¥æèå´å符串 |
| | | let dateRangeString = ""; |
| | | let sheetNameSuffix = ""; |
| | | |
| | | if ( |
| | | this.queryParams.dateRange && |
| | | this.queryParams.dateRange.length === 2 |
| | | ) { |
| | | const startDateFormatted = this.queryParams.dateRange[0]; |
| | | const endDateFormatted = this.queryParams.dateRange[1]; |
| | | dateRangeString = `${startDateFormatted}è³${endDateFormatted}`; |
| | | sheetNameSuffix = `${startDateFormatted}è³${endDateFormatted}`; |
| | | } else { |
| | | const now = new Date(); |
| | | const currentMonth = now.getMonth() + 1; |
| | | dateRangeString = `${currentMonth}æ`; |
| | | sheetNameSuffix = `${currentMonth}æ`; |
| | | } |
| | | |
| | | const excelName = `é访ç»è®¡è¡¨_${dateRangeString}.xlsx`; |
| | | const worksheetName = `é访ç»è®¡_${sheetNameSuffix}`; |
| | | |
| | | // å建Excelå·¥ä½ç°¿ |
| | | const workbook = new ExcelJS.Workbook(); |
| | | const worksheet = workbook.addWorksheet(worksheetName); |
| | | |
| | | // å®ä¹æ ·å¼ |
| | | const titleStyle = { |
| | | font: { name: "微软é
é»", size: 16, bold: true }, |
| | | 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" } }, |
| | | }, |
| | | }; |
| | | |
| | | const headerStyle = { |
| | | font: { name: "微软é
é»", size: 11, bold: true }, |
| | | 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" } }, |
| | | }, |
| | | }; |
| | | |
| | | const cellStyle = { |
| | | font: { name: "å®ä½", size: 10 }, |
| | | 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" } }, |
| | | }, |
| | | }; |
| | | |
| | | // æ·»å æ»æ é¢ |
| | | worksheet.mergeCells(1, 1, 1, 10); |
| | | const titleCell = worksheet.getCell(1, 1); |
| | | titleCell.value = `é访ç»è®¡è¡¨ï¼${sheetNameSuffix}ï¼`; |
| | | titleCell.style = titleStyle; |
| | | worksheet.getRow(1).height = 35; |
| | | |
| | | // æ·»å 表头 |
| | | const headers = [ |
| | | this.queryParams.statisticaltype == 1 ? "åºé¢ç
åº" : "ç§å®¤", |
| | | "åºé¢äººæ¬¡", |
| | | "æ éé访人次", |
| | | "åºé访人次", |
| | | "é访ç", |
| | | "åæ¶ç", |
| | | "å¤è¯éç¥é¢ç®æ»é", |
| | | "å¤è¯éç¥å¡«æ¥é", |
| | | "宿æ¯ç", |
| | | ]; |
| | | |
| | | const headerRow = worksheet.addRow(headers); |
| | | headerRow.eachCell((cell) => { |
| | | cell.style = headerStyle; |
| | | }); |
| | | headerRow.height = 25; |
| | | |
| | | // æ·»å æ°æ®è¡ |
| | | this.userList.forEach((item) => { |
| | | const dataRow = worksheet.addRow([ |
| | | this.queryParams.statisticaltype == 1 |
| | | ? item.leavehospitaldistrictname |
| | | : item.deptname, |
| | | item.dischargeCount || 0, |
| | | item.nonFollowUp || 0, |
| | | item.followUpNeeded || 0, |
| | | item.followUpRate || "0%", |
| | | item.rate ? this.formatPercent(item.rate) : "0%", |
| | | item.joyAllCount || 0, |
| | | item.joyCount || 0, |
| | | item.joyTotal ? this.formatPercent(item.joyTotal) : "0%", |
| | | ]); |
| | | |
| | | dataRow.eachCell((cell) => { |
| | | cell.style = cellStyle; |
| | | }); |
| | | dataRow.height = 22; |
| | | }); |
| | | |
| | | // 设置å宽 |
| | | worksheet.columns = [ |
| | | { width: 20 }, |
| | | { width: 12 }, |
| | | { width: 12 }, |
| | | { width: 12 }, |
| | | { width: 12 }, |
| | | { width: 12 }, |
| | | { width: 15 }, |
| | | { width: 15 }, |
| | | { width: 12 }, |
| | | ]; |
| | | |
| | | // çæå¹¶ä¸è½½æä»¶ |
| | | const buffer = await workbook.xlsx.writeBuffer(); |
| | | const blob = new Blob([buffer], { |
| | | type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", |
| | | }); |
| | | |
| | | saveAs(blob, excelName); |
| | | this.$message.success("å¯¼åºæå"); |
| | | } catch (error) { |
| | | console.error("导åºå¤±è´¥:", error); |
| | | this.$message.error(`导åºå¤±è´¥: ${error.message}`); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .followup-statistics { |
| | | .query-section { |
| | | background: #fff; |
| | | padding: 20px; |
| | | border-radius: 4px; |
| | | margin-bottom: 20px; |
| | | |
| | | .query-form { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | |
| | | ::v-deep .el-form-item { |
| | | margin-bottom: 20px; |
| | | |
| | | &:not(:last-child) { |
| | | margin-right: 20px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .table-section { |
| | | background: #fff; |
| | | padding: 20px; |
| | | border-radius: 4px; |
| | | margin-bottom: 20px; |
| | | |
| | | ::v-deep .el-table { |
| | | th { |
| | | background-color: #f8f9fa; |
| | | font-weight: 600; |
| | | color: #333; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .pagination-section { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | background: #fff; |
| | | padding: 20px; |
| | | border-radius: 4px; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | this.zcform.remark = |
| | | this.zcform.remark + "ã" + this.getCurrentTime() + "ã"; |
| | | let form = structuredClone(this.zcform); |
| | | form.longSendTime = this.formatTime(form.date1); |
| | | form.visitTime = this.formatTime(form.date1); |
| | | form.finishtime = ""; |
| | | if (form.resource) { |
| | | if (form.resource == 2) { |
| | |
| | | this.zcform.remark = |
| | | this.zcform.remark + "ã" + this.getCurrentTime() + "ã"; |
| | | let form = structuredClone(this.zcform); |
| | | form.longSendTime = this.formatTime(form.date1); |
| | | form.visitTime = this.formatTime(form.date1); |
| | | form.finishtime = ""; |
| | | if (form.resource) { |
| | | if (form.resource == 2) { |
| | |
| | | this.zcform.remark = |
| | | this.zcform.remark + "ã" + this.getCurrentTime() + "ã"; |
| | | let form = structuredClone(this.zcform); |
| | | form.longSendTime = this.formatTime(form.date1); |
| | | form.visitTime = this.formatTime(form.date1); |
| | | form.finishtime = ""; |
| | | if (form.resource) { |
| | | if (form.resource == 2) { |
| | |
| | | this.zcform.remark = |
| | | this.zcform.remark + "ã" + this.getCurrentTime() + "ã"; |
| | | let form = structuredClone(this.zcform); |
| | | form.longSendTime = this.formatTime(form.date1); |
| | | form.visitTime = this.formatTime(form.date1); |
| | | form.finishtime = ""; |
| | | if (form.resource) { |
| | | if (form.resource == 2) { |
| | |
| | | this.zcform.remark = |
| | | this.zcform.remark + "ã" + this.getCurrentTime() + "ã"; |
| | | let form = structuredClone(this.zcform); |
| | | form.longSendTime = this.formatTime(form.date1); |
| | | form.visitTime = this.formatTime(form.date1); |
| | | form.finishtime = ""; |
| | | if (form.resource) { |
| | | if (form.resource == 2) { |
| | |
| | | this.zcform.remark = |
| | | this.zcform.remark + "ã" + this.getCurrentTime() + "ã"; |
| | | let form = structuredClone(this.zcform); |
| | | form.longSendTime = this.formatTime(form.date1); |
| | | form.visitTime = this.formatTime(form.date1); |
| | | form.finishtime = ""; |
| | | if (form.resource) { |
| | | if (form.resource == 2) { |
| | |
| | | // 忬¡éè®¿æ°æ®æ´æ¿ |
| | | formtidy() { |
| | | this.form.visitType2 = this.form.visitType; |
| | | this.form.date2 = this.form.longSendTime; |
| | | this.form.date2 = this.form.visitTime; |
| | | // this.form.date1 = this.setCurrentDate(); |
| | | this.form.remark2 = this.form.remark; |
| | | }, |
| | |
| | | this.logsheetlist = res.rows[0].serviceSubtaskList; |
| | | this.templateid = this.form.templateid; |
| | | this.selectedTag = this.form.excep; |
| | | const targetDate = new Date(this.form.longSendTime); // ç®æ æ¥æ |
| | | const targetDate = new Date(this.form.visitTime); // ç®æ æ¥æ |
| | | const now = new Date(); // å½åæ¶é´ |
| | | if (now < targetDate && this.form.sendstate == 2) { |
| | | this.$confirm("å½åæå¡æªå°åéæ¶é´è¯·è°¨æ
ä¿®æ¹", "æç¤º", { |
| | |
| | | this.form.remark = |
| | | this.form.remark + "ã" + this.getCurrentTime() + "ã"; |
| | | let form = structuredClone(this.form); |
| | | form.longSendTime = this.formatTime(form.date1); |
| | | form.visitTime = this.formatTime(form.date1); |
| | | form.finishtime = ""; |
| | | if (form.resource) { |
| | | if (form.resource == 2) { |
| | |
| | | // 忬¡éè®¿æ°æ®æ´æ¿ |
| | | formtidy() { |
| | | this.form.visitType2 = this.form.visitType; |
| | | this.form.date2 = this.form.longSendTime; |
| | | this.form.date2 = this.form.visitTime; |
| | | // this.form.date1 = this.setCurrentDate(); |
| | | this.form.remark2 = this.form.remark; |
| | | }, |
| | |
| | | this.logsheetlist = res.rows[0].serviceSubtaskList; |
| | | this.templateid = this.form.templateid; |
| | | this.selectedTag = this.form.excep; |
| | | const targetDate = new Date(this.form.longSendTime); // ç®æ æ¥æ |
| | | const targetDate = new Date(this.form.visitTime); // ç®æ æ¥æ |
| | | const now = new Date(); // å½åæ¶é´ |
| | | if (now < targetDate && this.form.sendstate == 2) { |
| | | this.$confirm("å½åæå¡æªå°åéæ¶é´è¯·è°¨æ
ä¿®æ¹", "æç¤º", { |
| | |
| | | this.form.remark = |
| | | this.form.remark + "ã" + this.getCurrentTime() + "ã"; |
| | | let form = structuredClone(this.form); |
| | | form.longSendTime = this.formatTime(form.date1); |
| | | form.visitTime = this.formatTime(form.date1); |
| | | form.finishtime = ""; |
| | | if (form.resource) { |
| | | if (form.resource == 2) { |
| | |
| | | // 忬¡éè®¿æ°æ®æ´æ¿ |
| | | formtidy() { |
| | | this.form.visitType2 = this.form.visitType; |
| | | this.form.date2 = this.form.longSendTime; |
| | | this.form.date2 = this.form.visitTime; |
| | | this.form.remark2 = this.form.remark; |
| | | }, |
| | | // è·åæ£è
è®°å½ |
| | |
| | | } |
| | | this.logsheetlist = res.rows[0].serviceSubtaskList; |
| | | this.templateid = this.logsheetlist[0].templateid; |
| | | const targetDate = new Date(this.form.longSendTime); // ç®æ æ¥æ |
| | | const targetDate = new Date(this.form.visitTime); // ç®æ æ¥æ |
| | | const now = new Date(); // å½åæ¶é´ |
| | | this.form.endtime = this.formatTime(this.form.endtime); |
| | | if (now < targetDate && this.form.sendstate == 2) { |
| | |
| | | this.form.remark = |
| | | this.form.remark + "ã" + this.getCurrentTime() + "ã"; |
| | | let form = structuredClone(this.form); |
| | | form.longSendTime = this.formatTime(form.date1); |
| | | form.visitTime = this.formatTime(form.date1); |
| | | form.finishtime = ""; |
| | | if (form.resource) { |
| | | if (form.resource == 2) { |
| | |
| | | this.zcform.remark = |
| | | this.zcform.remark + "ã" + this.getCurrentTime() + "ã"; |
| | | let form = structuredClone(this.zcform); |
| | | form.longSendTime = this.formatTime(form.date1); |
| | | form.visitTime = this.formatTime(form.date1); |
| | | form.finishtime = ""; |
| | | if (form.resource) { |
| | | if (form.resource == 2) { |
| | |
| | | <el-col :span="20" |
| | | ><el-form-item label="éç¨ææ¯" prop="region"> |
| | | <el-select |
| | | v-model="operationcodes" |
| | | v-model="form.oplevelcode" |
| | | style="width: 400px" |
| | | @remove-tag="removeopera" |
| | | size="medium" |
| | | :remote-method="remoteopcode" |
| | | multiple |
| | | filterable |
| | | remote |
| | | placeholder="è¯·éæ©ææ¯" |
| | |
| | | <el-option |
| | | class="ruleFormaa" |
| | | v-for="item in baseoperaList" |
| | | :label="item.opdesc" |
| | | :value="item.opcode" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | > |
| | | </el-option> |
| | | </el-select> </el-form-item |
| | |
| | | dialogVisiblepatientjb: false, //æ·»å ç¾ç
å¼¹æ¡ |
| | | deptcodesWards: [], //ç§å®¤æ°æ® |
| | | leavehospitaldistrictcodes: [], //ç
åºæ°æ® |
| | | operationcodes: [], //ææ¯æ°æ® |
| | | illnesscodes: [], //ç¾ç
æ°æ® |
| | | radio: 1, |
| | | checkboxlist: [], |
| | | tableLabel: [], |
| | | questionList: [], |
| | | donorchargeList: [], |
| | | baseoperaList: [], |
| | | baseoperaList: [ |
| | | { value: "1", label: "ä¸çº§ææ¯" }, |
| | | { value: "2", label: "äºçº§ææ¯" }, |
| | | { value: "3", label: "ä¸çº§ææ¯" }, |
| | | { value: "4", label: "åçº§ææ¯" }, |
| | | ], |
| | | usable: [ |
| | | { value: "0", label: "å¯ç¨" }, |
| | | { value: "1", label: "åç¨" }, |
| | |
| | | ]; |
| | | if (this.form.appltype == 1) { |
| | | this.leavehospitaldistrictcodes = []; |
| | | this.operationcodes = []; |
| | | this.form.oplevelcode = null; |
| | | this.illnesscodes = []; |
| | | } else if (this.form.appltype == 2) { |
| | | this.deptcodesWards = []; |
| | | this.operationcodes = []; |
| | | this.form.oplevelcode = null; |
| | | this.illnesscodes = []; |
| | | } else if (this.form.appltype == 3) { |
| | | this.deptcodesWards = []; |
| | | this.leavehospitaldistrictcodes = []; |
| | | this.operationcodes = []; |
| | | this.form.oplevelcode = null; |
| | | } else if (this.form.appltype == 4) { |
| | | this.deptcodesWards = []; |
| | | this.illnesscodes = []; |
| | |
| | | this.deptcodesWards[0] || |
| | | this.leavehospitaldistrictcodes[0] || |
| | | this.diagglist[0] || |
| | | this.operationcodes[0] || |
| | | this.form.oplevelcode || |
| | | this.form.longTask == 2 || |
| | | this.serviceType == 3 |
| | | ) { |
| | |
| | | this.form.deptcode = this.deptcodesWards.join(","); |
| | | this.form.leavehospitaldistrictcode = |
| | | this.leavehospitaldistrictcodes.join(","); |
| | | this.form.opcode = this.operationcodes.join(","); |
| | | // this.form.opcode = this.operationcodes.join(","); |
| | | this.form.icd10code = this.diagglist |
| | | .map((item) => item.icdcode) |
| | | .join(","); |
| | |
| | | }).then((res) => { |
| | | this.donorchargeList = res.rows; |
| | | }); |
| | | getbaseopera({ |
| | | pageNum: 1, |
| | | pageSize: 1000, |
| | | }).then((res) => { |
| | | this.baseoperaList = res.rows; |
| | | }); |
| | | // getbaseopera({ |
| | | // pageNum: 1, |
| | | // pageSize: 1000, |
| | | // }).then((res) => { |
| | | // this.baseoperaList = res.rows; |
| | | // }); |
| | | }, |
| | | // ææ¯æ¥è¯¢ |
| | | remoteopcode(name) { |
| | | if (name) { |
| | | getbaseopera({ |
| | | pageNum: 1, |
| | | pageSize: 1000, |
| | | opdesc: name, |
| | | }).then((res) => { |
| | | this.baseoperaList = res.rows; |
| | | }); |
| | | } |
| | | // if (name) { |
| | | // getbaseopera({ |
| | | // pageNum: 1, |
| | | // pageSize: 1000, |
| | | // opdesc: name, |
| | | // }).then((res) => { |
| | | // this.baseoperaList = res.rows; |
| | | // }); |
| | | // } |
| | | }, |
| | | // ç¾ç
æ¥è¯¢ |
| | | remotedonor(name) { |
| | | if (name) { |
| | | getbaseopera({ |
| | | pageNum: 1, |
| | | pageSize: 1000, |
| | | opdesc: name, |
| | | }).then((res) => { |
| | | this.baseoperaList = res.rows; |
| | | }); |
| | | } |
| | | // if (name) { |
| | | // getbaseopera({ |
| | | // pageNum: 1, |
| | | // pageSize: 1000, |
| | | // opdesc: name, |
| | | // }).then((res) => { |
| | | // this.baseoperaList = res.rows; |
| | | // }); |
| | | // } |
| | | }, |
| | | // å¤çé®é¢å±åé |
| | | Variablehandling(arr, type) { |
| | |
| | | label="åºå®£ææ¥æ" |
| | | width="200" |
| | | align="center" |
| | | key="longSendTime" |
| | | prop="longSendTime" |
| | | key="visitTime" |
| | | prop="visitTime" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <span>{{ formatTime(scope.row.longSendTime) }}</span> |
| | | <span>{{ formatTime(scope.row.visitTime) }}</span> |
| | | </template></el-table-column |
| | | > |
| | | <el-table-column |
| | |
| | | getSfStatistics(params).then((response) => { |
| | | this.loading = false; |
| | | |
| | | // this.total = response.total; |
| | | this.total = response.total; |
| | | // this.userList = response.data; |
| | | this.userList = this.customSort(response.data); |
| | | }); |
| | | }, |
| | | sortChineseNumber(a, b) { |
| | | // æå䏿æ°å |
| | | const chineseNumbers = [ |
| | | "ä¸", |
| | | "äº", |
| | | "ä¸", |
| | | "å", |
| | | "äº", |
| | | "å
", |
| | | "ä¸", |
| | | "å
«", |
| | | "ä¹", |
| | | "å", |
| | | "åä¸", |
| | | "åäº", |
| | | ]; |
| | | 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) return -1; |
| | | if (!text || typeof text !== "string") return -1; |
| | | |
| | | // å¹é
䏿æ°åï¼æ¯æä¸å°ååäº |
| | | const match = text.match(/^([ä¸äºä¸åäºå
ä¸å
«ä¹å]+)/); |
| | | |
| | | if (match && match[1]) { |
| | | return chineseNumbers.indexOf(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); |
| | | |
| | | if (numA === -1 && numB === -1) return 0; |
| | | if (numA === -1) return 1; // æ æ³è§£æçæ¾å°åé¢ |
| | | if (numB === -1) return -1; // æ æ³è§£æçæ¾å°åé¢ |
| | | // å¤çæ æ³è§£æçæ
åµ |
| | | 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) => { |
| | | // æåç
åºåç§°ä¸ç䏿æ°åé¨å[6](@ref) |
| | | // æåç
åºåç§°ä¸ç䏿æ°åé¨å |
| | | const getIndex = (name) => { |
| | | const numStr = name.match( |
| | | /^(äº|ä¸|å|äº|å
|ä¸|å
«|ä¹|å|åä¸|åäº|åä¸|åå|åäº|åå
|åä¸|åå
«|åä¹|äºå|äºåä¸|äºåäº|äºåä¸|äºåå|äºåäº|äºåå
|äºåä¸|äºåå
«|äºåä¹|ä¸å)/ |
| | | )?.[1]; |
| | | return order.indexOf(numStr); |
| | | 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); |
| | | |
| | | // 妿é½å¨å®ä¹ç顺åºä¸ï¼æå®ä¹é¡ºåºæï¼å¦åï¼æªå®ä¹çæå¨åé¢[2](@ref) |
| | | // æåºé»è¾ |
| | | if (indexA === -1 && indexB === -1) { |
| | | return (a.leavehospitaldistrictname || "").localeCompare( |
| | | b.leavehospitaldistrictname || "" |
| | | ); |
| | | } |
| | | if (indexA === -1) return 1; |
| | | if (indexB === -1) return -1; |
| | | return indexA - indexB; |
| | |
| | | // detail: https://cli.vuejs.org/config/#devserver-proxy |
| | | [process.env.VUE_APP_BASE_API]: { |
| | | // target: `https://www.health-y.cn/lssf`, |
| | | // target: `http://192.168.100.10:8096`, |
| | | target: `http://192.168.100.10:8094`,//çç«åå¾· |
| | | target: `http://192.168.100.10:8096`, |
| | | // target: `http://192.168.100.10:8094`,//çç«åå¾· |
| | | // target: `http://192.168.100.10:8095`,//æ°å |
| | | // target:`http://localhost:8095`, |
| | | // target:`http://35z1t16164.qicp.vip`, |