| | |
| | | :hide-delay="3000" |
| | | primary-color="#1890ff" |
| | | /> |
| | | <!-- å³ä¸è§ï¼å½åç»å½äººå¾
å¤çé访任å¡ï¼æåºé¢å¹´æï¼ --> |
| | | <PendingTaskBox v-if="Assvite" /> |
| | | <!-- 临è¿è¶
æ¶ä»»å¡ç»å½åå¼¹çªï¼ä»
æ¯å®/æ°åä¸¤å®¶æºæè§¦åï¼ --> |
| | | <!-- <NearTimeoutDialog v-if="Assvite" /> --> |
| | | </div> |
| | |
| | | components: { |
| | | ThemePicker, |
| | | Assistant: () => import("./components/Assistant"), |
| | | PendingTaskBox: () => import("./components/PendingTaskBox"), |
| | | NearTimeoutDialog: () => import("./components/NearTimeoutDialog"), |
| | | }, |
| | | data() { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import axios from 'axios' |
| | | import { getToken } from '@/utils/auth' |
| | | |
| | | /** |
| | | * å½åç»å½äººå¾
å¤çé访任å¡ç»è®¡ï¼æåºé¢å¹´æåç»ï¼ |
| | | * |
| | | * å端å£å¾ï¼service_subtask ä¸ |
| | | * service_type = '2' åºé¢é访 / '3' é¨è¯é访ï¼åå¼è®¡æ°ï¼ |
| | | * current_preachform = '1'ï¼äººå·¥ï¼ |
| | | * å¾
éè®¿ç¶æï¼sendstate in 1,2,3,5,7ï¼ |
| | | * åºé¢æ¶é´ endtime æ©äºçäºä»å¤© - 7 天 |
| | | * åªç»è®¡æè¿ 4 个åºé¢æä»½ï¼å«å½æï¼ |
| | | * |
| | | * 该æ¥å£ç¨äºå³ä¸è§å¸¸é©»å¡çï¼å±äºåå°è½®è¯¢ï¼ |
| | | * ä¸èµ° @/utils/request çå
¨å±æ¦æªå¨ï¼é¿å
æ¥å£æªé¨ç½²/ç½ç»å¼å¸¸æ¶åå¤å¼¹å
¨å±é误æç¤ºï¼ |
| | | * 失败信æ¯ç±å¡çå
é¨èªè¡å±ç¤ºã |
| | | * |
| | | * @returns {Promise<{userName: string, nickName: string, total: number, |
| | | * months: Array<{month: string, dischargeCount: number, outpatientCount: number}>}>} |
| | | * months åªå
å«ææ°æ®çæä»½ï¼æ²¡æ°æ®çæä»½ç±å¡çè¡¥ 0 |
| | | */ |
| | | export function getPendingTaskMonthStats() { |
| | | return axios({ |
| | | baseURL: process.env.VUE_APP_BASE_API, |
| | | url: '/smartor/serviceSubtask/pendingTaskMonthStats', |
| | | method: 'post', |
| | | timeout: 15000, |
| | | headers: { |
| | | Authorization: 'Bearer ' + getToken() |
| | | } |
| | | }).then(res => res.data) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="ptb-root"> |
| | | <!-- æ¶èµ·æï¼å³ä¸è§å°è¶å --> |
| | | <button |
| | | v-if="collapsed" |
| | | class="ptb-pill" |
| | | type="button" |
| | | title="å±å¼å¾
å¤çä»»å¡" |
| | | @click="toggle" |
| | | > |
| | | <span class="ptb-pill-dot"></span> |
| | | <span class="ptb-pill-text">å¾
å¤ç</span> |
| | | <span class="ptb-pill-num">{{ total }}</span> |
| | | </button> |
| | | |
| | | <!-- å±å¼æï¼å½åç»å½äºº + è¿ 4 个æåºé¢/é¨è¯é访å¾
å¤ç --> |
| | | <div v-else class="ptb-card"> |
| | | <div class="ptb-header"> |
| | | <div class="ptb-header-left"> |
| | | <svg |
| | | class="ptb-header-icon" |
| | | viewBox="0 0 24 24" |
| | | fill="none" |
| | | stroke="currentColor" |
| | | stroke-width="2" |
| | | > |
| | | <path d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2" /> |
| | | <path d="M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" /> |
| | | <path d="M9 14l2 2 4-4" /> |
| | | </svg> |
| | | <span class="ptb-header-title" title="åºé¢æ»¡ 7 天ãä»å¾
é访çåºé¢/é¨è¯ä»»å¡"> |
| | | å¾
å¤çéè®¿ä»»å¡ |
| | | </span> |
| | | </div> |
| | | <div class="ptb-header-actions"> |
| | | <span |
| | | class="ptb-icon-btn" |
| | | :class="{ 'is-loading': loading }" |
| | | title="å·æ°" |
| | | @click="load" |
| | | >↻</span> |
| | | <span class="ptb-icon-btn" title="æ¶èµ·" @click="toggle">–</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="ptb-body"> |
| | | <div class="ptb-user"> |
| | | <div class="ptb-avatar">{{ userInitial }}</div> |
| | | <div class="ptb-user-meta"> |
| | | <div class="ptb-user-name" :title="displayName">{{ displayName }}</div> |
| | | <div class="ptb-user-scope" :title="scopeText">{{ scopeText }}</div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="ptb-months"> |
| | | <div |
| | | v-for="row in monthRows" |
| | | :key="row.key" |
| | | class="ptb-month-row" |
| | | > |
| | | <span class="ptb-month-label">{{ row.label }}</span> |
| | | <span |
| | | class="ptb-month-seg is-clickable" |
| | | title="ç¹å»æ¥ç该æå¾
é访æ£è
" |
| | | @click="goToTasks(row, 2)" |
| | | >åºé¢é访å¾
å¤ç<b class="ptb-num is-discharge">{{ row.dischargeCount }}</b>个</span> |
| | | <span class="ptb-month-comma">ï¼</span> |
| | | <span |
| | | class="ptb-month-seg is-clickable" |
| | | title="ç¹å»æ¥ç该æå¾
é访æ£è
" |
| | | @click="goToTasks(row, 3)" |
| | | >é¨è¯é访å¾
å¤ç<b class="ptb-num is-outpatient">{{ row.outpatientCount }}</b>个</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-if="errorMsg" class="ptb-error">{{ errorMsg }}</div> |
| | | </div> |
| | | |
| | | <div class="ptb-footer"> |
| | | <span class="ptb-update-time">æ´æ°äº {{ updateTime || '--:--' }}</span> |
| | | <span class="ptb-footer-refresh" @click="load">å·æ°</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getPendingTaskMonthStats } from '@/api/smartor/pendingTask' |
| | | import { getToken } from '@/utils/auth' |
| | | |
| | | const COLLAPSE_KEY = 'pendingTaskBoxCollapsed' |
| | | const REFRESH_INTERVAL = 5 * 60 * 1000 |
| | | // åºå®å±ç¤ºï¼å½æ + å¾å 3 个æ |
| | | const MONTH_COUNT = 4 |
| | | |
| | | export default { |
| | | name: 'PendingTaskBox', |
| | | data() { |
| | | return { |
| | | collapsed: localStorage.getItem(COLLAPSE_KEY) === '1', |
| | | loading: false, |
| | | errorMsg: '', |
| | | userName: '', |
| | | nickName: '', |
| | | total: 0, |
| | | months: [], |
| | | updateTime: '', |
| | | timer: null, |
| | | retryTimer: null, |
| | | retryCount: 0, |
| | | lastLoadAt: 0 |
| | | } |
| | | }, |
| | | computed: { |
| | | displayName() { |
| | | return ( |
| | | this.nickName || |
| | | this.$store.getters.nickName || |
| | | this.userName || |
| | | this.$store.getters.name || |
| | | 'æªç»å½' |
| | | ) |
| | | }, |
| | | userInitial() { |
| | | const name = this.displayName |
| | | return name ? name.slice(0, 1) : '-' |
| | | }, |
| | | scopeText() { |
| | | const depts = (this.$store.getters.belongDepts || []) |
| | | .map(item => item.deptName) |
| | | .filter(Boolean) |
| | | const wards = (this.$store.getters.belongWards || []) |
| | | .map(item => item.districtName) |
| | | .filter(Boolean) |
| | | const scope = wards.length ? wards : depts |
| | | if (!scope.length) { |
| | | return 'å½åç»å½äºº' |
| | | } |
| | | return scope.length > 2 ? scope.slice(0, 2).join('ã') + ' ç' : scope.join('ã') |
| | | }, |
| | | monthMap() { |
| | | const map = {} |
| | | this.months.forEach(item => { |
| | | if (item && item.month) { |
| | | map[item.month] = { |
| | | dischargeCount: Number(item.dischargeCount) || 0, |
| | | outpatientCount: Number(item.outpatientCount) || 0 |
| | | } |
| | | } |
| | | }) |
| | | return map |
| | | }, |
| | | // 彿 + å 3 个æï¼æ²¡ææ°æ®çæä»½è¡¥ 0 |
| | | monthRows() { |
| | | const rows = [] |
| | | const now = new Date() |
| | | for (let i = 0; i < MONTH_COUNT; i++) { |
| | | const date = new Date(now.getFullYear(), now.getMonth() - i, 1) |
| | | const month = String(date.getMonth() + 1).padStart(2, '0') |
| | | const key = date.getFullYear() + '-' + month |
| | | const data = this.monthMap[key] || { dischargeCount: 0, outpatientCount: 0 } |
| | | rows.push({ |
| | | key, |
| | | label: date.getFullYear() + 'å¹´' + month + 'æ', |
| | | dischargeCount: data.dischargeCount, |
| | | outpatientCount: data.outpatientCount |
| | | }) |
| | | } |
| | | return rows |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.load() |
| | | this.timer = setInterval(() => this.load(), REFRESH_INTERVAL) |
| | | document.addEventListener('visibilitychange', this.handleVisible) |
| | | }, |
| | | beforeDestroy() { |
| | | clearInterval(this.timer) |
| | | this.clearRetry() |
| | | document.removeEventListener('visibilitychange', this.handleVisible) |
| | | }, |
| | | methods: { |
| | | toggle() { |
| | | this.collapsed = !this.collapsed |
| | | localStorage.setItem(COLLAPSE_KEY, this.collapsed ? '1' : '0') |
| | | if (!this.collapsed && Date.now() - this.lastLoadAt > 60 * 1000) { |
| | | this.load() |
| | | } |
| | | }, |
| | | handleVisible() { |
| | | if (document.visibilityState === 'visible' && Date.now() - this.lastLoadAt > 60 * 1000) { |
| | | this.load() |
| | | } |
| | | }, |
| | | async load() { |
| | | if (this.loading) { |
| | | return |
| | | } |
| | | if (!getToken()) { |
| | | // åå·æ°é¡µé¢æ¶ç»å½æå¯è½è¿æ²¡å°±ç»ªï¼ç¨åéè¯ |
| | | this.scheduleRetry(4000) |
| | | return |
| | | } |
| | | this.loading = true |
| | | try { |
| | | const res = await getPendingTaskMonthStats() |
| | | const payload = res && res.data && res.data.months ? res.data : res || {} |
| | | this.nickName = payload.nickName || this.nickName |
| | | this.userName = payload.userName || this.userName |
| | | this.months = Array.isArray(payload.months) ? payload.months : [] |
| | | const sum = this.months.reduce((acc, item) => { |
| | | return acc + (Number(item.dischargeCount) || 0) + (Number(item.outpatientCount) || 0) |
| | | }, 0) |
| | | this.total = Number(payload.total) || sum |
| | | this.errorMsg = '' |
| | | this.updateTime = this.formatTime(new Date()) |
| | | this.retryCount = 0 |
| | | this.clearRetry() |
| | | } catch (error) { |
| | | // å端éå¯/ç½ç»æå¨æ¶èªå¨éè¯ï¼ä¸ç¨ç 5 åé |
| | | this.errorMsg = 'ç»è®¡æ¥å£æä¸å¯ç¨ï¼ç¨åèªå¨éè¯' |
| | | this.scheduleRetry(20000) |
| | | } finally { |
| | | this.lastLoadAt = Date.now() |
| | | this.loading = false |
| | | } |
| | | }, |
| | | scheduleRetry(delay) { |
| | | if (this.retryCount >= 5) { |
| | | return |
| | | } |
| | | this.retryCount += 1 |
| | | this.clearRetry() |
| | | this.retryTimer = setTimeout(() => this.load(), delay) |
| | | }, |
| | | clearRetry() { |
| | | if (this.retryTimer) { |
| | | clearTimeout(this.retryTimer) |
| | | this.retryTimer = null |
| | | } |
| | | }, |
| | | formatTime(date) { |
| | | const pad = value => String(value).padStart(2, '0') |
| | | return pad(date.getHours()) + ':' + pad(date.getMinutes()) |
| | | }, |
| | | // ç¹å»æä¸ªæçæ°åï¼è·³å°é访å表æ¥ç对åºçå¾
é访æ£è
|
| | | goToTasks(row, serviceType) { |
| | | const path = |
| | | serviceType === 3 ? '/followvisit/outpatientService' : '/followvisit/discharge' |
| | | this.$router |
| | | .push({ |
| | | path, |
| | | query: { |
| | | month: row.key, |
| | | serviceType: String(serviceType), |
| | | fromPendingTask: '1', |
| | | _t: String(Date.now()) |
| | | } |
| | | }) |
| | | .catch(() => {}) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .ptb-root { |
| | | position: fixed; |
| | | right: 24px; |
| | | bottom: 24px; |
| | | z-index: 1998; |
| | | color: #1f2d3d; |
| | | font-size: 13px; |
| | | line-height: 1.4; |
| | | } |
| | | |
| | | /* æ¶èµ·æ */ |
| | | .ptb-pill { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | height: 42px; |
| | | padding: 0 16px 0 14px; |
| | | border: none; |
| | | border-radius: 21px; |
| | | background: linear-gradient(135deg, #1890ff 0%, #4f8cff 100%); |
| | | color: #fff; |
| | | font-size: 13px; |
| | | cursor: pointer; |
| | | outline: none; |
| | | box-shadow: 0 8px 20px rgba(24, 144, 255, 0.35); |
| | | transition: transform 0.2s ease, box-shadow 0.2s ease; |
| | | } |
| | | |
| | | .ptb-pill:hover { |
| | | transform: translateY(-2px); |
| | | box-shadow: 0 12px 24px rgba(24, 144, 255, 0.42); |
| | | } |
| | | |
| | | .ptb-pill-dot { |
| | | width: 8px; |
| | | height: 8px; |
| | | border-radius: 50%; |
| | | background: #fff; |
| | | box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.22); |
| | | } |
| | | |
| | | .ptb-pill-num { |
| | | display: inline-flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | min-width: 24px; |
| | | height: 22px; |
| | | padding: 0 7px; |
| | | border-radius: 11px; |
| | | background: rgba(255, 255, 255, 0.94); |
| | | color: #1890ff; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | /* å±å¼æ */ |
| | | .ptb-card { |
| | | width: 364px; |
| | | max-width: calc(100vw - 24px); |
| | | background: #fff; |
| | | border: 1px solid rgba(24, 144, 255, 0.12); |
| | | border-radius: 14px; |
| | | box-shadow: 0 12px 32px rgba(15, 23, 42, 0.14), 0 2px 6px rgba(15, 23, 42, 0.06); |
| | | overflow: hidden; |
| | | animation: ptb-fade-in 0.18s ease-out; |
| | | } |
| | | |
| | | @keyframes ptb-fade-in { |
| | | from { |
| | | opacity: 0; |
| | | transform: translateY(8px); |
| | | } |
| | | to { |
| | | opacity: 1; |
| | | transform: translateY(0); |
| | | } |
| | | } |
| | | |
| | | .ptb-header { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding: 11px 12px 11px 14px; |
| | | background: linear-gradient(135deg, #1890ff 0%, #4f8cff 100%); |
| | | color: #fff; |
| | | } |
| | | |
| | | .ptb-header-left { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 7px; |
| | | min-width: 0; |
| | | } |
| | | |
| | | .ptb-header-icon { |
| | | width: 16px; |
| | | height: 16px; |
| | | flex: none; |
| | | } |
| | | |
| | | .ptb-header-title { |
| | | font-size: 13px; |
| | | font-weight: 600; |
| | | letter-spacing: 0.3px; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .ptb-header-actions { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 2px; |
| | | } |
| | | |
| | | .ptb-icon-btn { |
| | | display: inline-flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | width: 22px; |
| | | height: 22px; |
| | | border-radius: 6px; |
| | | font-size: 15px; |
| | | line-height: 1; |
| | | cursor: pointer; |
| | | opacity: 0.85; |
| | | transition: background-color 0.15s ease, opacity 0.15s ease; |
| | | } |
| | | |
| | | .ptb-icon-btn:hover { |
| | | background: rgba(255, 255, 255, 0.2); |
| | | opacity: 1; |
| | | } |
| | | |
| | | .ptb-icon-btn.is-loading { |
| | | animation: ptb-spin 0.9s linear infinite; |
| | | } |
| | | |
| | | @keyframes ptb-spin { |
| | | to { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | .ptb-body { |
| | | padding: 12px 14px 8px; |
| | | } |
| | | |
| | | .ptb-user { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 9px; |
| | | padding-bottom: 10px; |
| | | border-bottom: 1px solid #f2f4f8; |
| | | } |
| | | |
| | | .ptb-avatar { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | width: 32px; |
| | | height: 32px; |
| | | flex: none; |
| | | border-radius: 50%; |
| | | background: linear-gradient(135deg, #e6f4ff 0%, #bae0ff 100%); |
| | | color: #1890ff; |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .ptb-user-meta { |
| | | min-width: 0; |
| | | flex: 1; |
| | | } |
| | | |
| | | .ptb-user-name { |
| | | overflow: hidden; |
| | | color: #1f2d3d; |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .ptb-user-scope { |
| | | overflow: hidden; |
| | | color: #8c98a8; |
| | | font-size: 11px; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | /* 4 è¡ï¼2026å¹´10æåºé¢é访å¾
å¤ç109个ï¼é¨è¯é访å¾
å¤ç109个 */ |
| | | .ptb-months { |
| | | margin-top: 4px; |
| | | } |
| | | |
| | | .ptb-month-row { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 6px 6px; |
| | | margin: 0 -6px; |
| | | border-radius: 6px; |
| | | font-size: 12px; |
| | | line-height: 1.5; |
| | | white-space: nowrap; |
| | | transition: background-color 0.15s ease; |
| | | } |
| | | |
| | | .ptb-month-row:hover { |
| | | background: #f5faff; |
| | | } |
| | | |
| | | .ptb-month-label { |
| | | color: #3f4d5f; |
| | | font-weight: 600; |
| | | font-variant-numeric: tabular-nums; |
| | | } |
| | | |
| | | .ptb-month-seg { |
| | | color: #5a6b80; |
| | | } |
| | | |
| | | /* æ°åå¯ç¹å»è·³è½¬å°é访å表 */ |
| | | .ptb-month-seg.is-clickable { |
| | | cursor: pointer; |
| | | transition: color 0.15s ease; |
| | | } |
| | | |
| | | .ptb-month-seg.is-clickable:hover { |
| | | color: #1890ff; |
| | | } |
| | | |
| | | .ptb-month-seg.is-clickable:hover .ptb-num { |
| | | text-decoration: underline; |
| | | } |
| | | |
| | | .ptb-month-comma { |
| | | color: #b6c0cc; |
| | | } |
| | | |
| | | .ptb-num { |
| | | margin: 0 2px; |
| | | font-size: 13px; |
| | | font-weight: 700; |
| | | font-variant-numeric: tabular-nums; |
| | | } |
| | | |
| | | .ptb-num.is-discharge { |
| | | color: #1890ff; |
| | | } |
| | | |
| | | .ptb-num.is-outpatient { |
| | | color: #13a8a8; |
| | | } |
| | | |
| | | .ptb-error { |
| | | margin-top: 8px; |
| | | padding: 5px 8px; |
| | | border-radius: 6px; |
| | | background: #fff7e6; |
| | | color: #d46b08; |
| | | font-size: 11px; |
| | | } |
| | | |
| | | .ptb-footer { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding: 7px 14px; |
| | | border-top: 1px solid #f2f4f8; |
| | | background: #fafcff; |
| | | } |
| | | |
| | | .ptb-update-time { |
| | | color: #a3adba; |
| | | font-size: 11px; |
| | | } |
| | | |
| | | .ptb-footer-refresh { |
| | | color: #1890ff; |
| | | font-size: 11px; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .ptb-footer-refresh:hover { |
| | | text-decoration: underline; |
| | | } |
| | | |
| | | @media (max-width: 768px) { |
| | | .ptb-root { |
| | | right: 12px; |
| | | bottom: 12px; |
| | | } |
| | | |
| | | .ptb-card { |
| | | width: calc(100vw - 24px); |
| | | } |
| | | |
| | | .ptb-month-row { |
| | | white-space: normal; |
| | | flex-wrap: wrap; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | > |
| | | <el-card |
| | | shadow="hover" |
| | | :body-style="item.router ? 'cursor: pointer' : 'cursor: default'" |
| | | :body-style="isClickable(item) ? 'cursor: pointer' : 'cursor: default'" |
| | | :class="getCardClass(item.name)" |
| | | @click.native="handleCardClick(item)" |
| | | > |
| | | <div class="card-content" @click="handleCardClick(item)"> |
| | | <div |
| | | class="card-content" |
| | | :style="{ cursor: isClickable(item) ? 'pointer' : 'default' }" |
| | | > |
| | | <div class="card-label"> |
| | | <span class="label-text">{{ item.name }}</span> |
| | | </div> |
| | |
| | | default: 0, |
| | | }, |
| | | showWarningCondition: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | // æ¯å¦å
许ç¹å»å¡çï¼ç¹å»åç±ç¶ç»ä»¶å³å®å¦ä½çéä¸é¢çåè¡¨ï¼ |
| | | clickable: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | |
| | | return tooltips[name] || ""; |
| | | }, |
| | | |
| | | isClickable(item) { |
| | | return !!(item && item.router) || this.clickable; |
| | | }, |
| | | handleCardClick(item) { |
| | | if (item.router) { |
| | | this.$router.push(item.router); |
| | |
| | | import { getConfig, getConfigKey, listConfig } from "@/api/system/config"; |
| | | import { getToken, setToken, removeToken } from "@/utils/auth"; |
| | | |
| | | /** |
| | | * sys_user_dept éåä¸ç§å®¤/ç
åºå¯è½åå¨å¤§ééå¤è¡ï¼HIS 忥/éå¤ä¿å导è´ï¼ï¼ |
| | | * æ¥å£ä¼åæ ·è¿åï¼è¿éæç¼ç å»éï¼é¿å
个人ä¸å¿ãå¾
å¤çå¡ççå¤éå¤å±ç¤º |
| | | */ |
| | | function uniqueByCode(list) { |
| | | const seen = {}; |
| | | return (list || []).filter((item) => { |
| | | if (!item) return false; |
| | | const code = |
| | | item.districtCode || item.deptCode || item.districtId || item.deptId; |
| | | const key = String(code === undefined || code === null ? "" : code); |
| | | if (!key || seen[key]) return false; |
| | | seen[key] = true; |
| | | return true; |
| | | }); |
| | | } |
| | | |
| | | const user = { |
| | | state: { |
| | | token: getToken(), |
| | |
| | | commit("SET_Id", user.userId); |
| | | commit("SET_hisUserId", user.hisUserId); |
| | | commit("SET_satisfactionCategories", user.satisfactionCategories); |
| | | commit("SET_leavehospitaldistrictcodes", user.belongWards); |
| | | commit("SET_leaveldeptcodes", user.belongDepts); |
| | | commit("SET_leavehospitaldistrictcodes", uniqueByCode(user.belongWards)); |
| | | commit("SET_leaveldeptcodes", uniqueByCode(user.belongDepts)); |
| | | commit("SET_AVATAR", avatar); |
| | | // æ£ç¡®è°ç¨æ¹å¼ï¼éè¿ dispatch |
| | | dispatch("GetConfig") |
| | |
| | | <div class="answer-text"> |
| | | <strong>åçï¼</strong>{{ row.asrtext || "æ åç" }} |
| | | </div> |
| | | <div class="matched-text" v-if="row.matchedtext"> |
| | | <strong>è§£æå¼ï¼</strong>{{ row.matchedtext }} |
| | | <div class="matched-text"> |
| | | <strong>夿³¨ï¼</strong>{{ row.answerps || "" }} |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <div class="info-item"> |
| | | <span class="label">è§£æå¼ï¼</span> |
| | | <span class="value">{{ currentRecord.matchedtext || 'æ ' }}</span> |
| | | <span class="label">夿³¨ï¼</span> |
| | | <span class="value">{{ currentRecord.answerps || 'æ ' }}</span> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | |
| | | <el-card shadow="never" class="overview-card"> |
| | | <div slot="header" class="card-header"> |
| | | <span class="card-title">åæå¡é¡¹ç®æ»¡æåº¦ç»è®¡</span> |
| | | <span class="card-subtitle">ï¼å
æ¡£è¯åé¢ï¼å¾æ»¡æ/满æ/ä¸è¬/䏿»¡æ/å¾ä¸æ»¡æ/æªç»åï¼</span> |
| | | <el-button |
| | | type="warning" |
| | | size="small" |
| | |
| | | <!-- è¡¨æ ¼äºï¼åéé¢/å¤éé¢ç»è®¡ï¼å
¶ä½é¢ç®ï¼ --> |
| | | <el-card shadow="never" class="overview-card"> |
| | | <div slot="header" class="card-header"> |
| | | <span class="card-title">åéé¢/å¤éé¢ç»è®¡</span> |
| | | <span class="card-title">å
¶ä»é¢ç®ç»è®¡</span> |
| | | <span class="card-subtitle">ï¼å
档满æåº¦é¢å·²å¨ä¸è¡¨ï¼è¿éåªåå
¶ä½é¢åï¼æ¨èãæ±æ¨ååºãæè§çï¼</span> |
| | | <div class="header-right"> |
| | | <el-input |
| | | v-model="questionSearch" |
| | |
| | | |
| | | <script> |
| | | import { sltdMydTotalByScore,statQuestionOptionByKsOrBq } from "@/api/AiCentre/satisfaction"; |
| | | import { deptTreeSelect } from "@/api/system/user"; |
| | | import XLSX from "xlsx"; |
| | | |
| | | // 满æåº¦é¢çåºå®é项ï¼é¡ºåºå³è¡¨æ ¼å顺åºï¼ââè¿äºé项çé¢ç®è¿è¡¨ä¸ï¼å
¶ä½è¿è¡¨äº |
| | |
| | | // æå¡ç±»åé»è®¤éä¸é¡¹ï¼æ label å¹é
ï¼éé
ä¸ååå
¸ç value å·®å¼ï¼ |
| | | const DEFAULT_SERVICE_LABELS = ["ä½é¢æ»¡æåº¦", "é¨è¯æ»¡æåº¦"]; |
| | | |
| | | // å
åºï¼store 䏿 ç§å®¤/ç
åºæ°æ®æ¶ä½¿ç¨ï¼è¡¨ä¸å¯¹æ¯ + çéä¸æï¼ |
| | | const DEPTS = ["å
åæ³ç§", "ç®è¤ç§", "è¿ç¤å
ç§", "æ¶åå
ç§", "è¾å
ç§"]; |
| | | const WARDS = ["ä¸ç
åº", "äºç
åº", "ä¸ç
åº", "åç
åº", "äºç
åº"]; |
| | | // 注æï¼è¿é以åç¨ DEPTS / WARDS ä¸¤ä¸ªãæ¼ç¤ºç¨ãåç§°æ°ç»å
åºï¼ |
| | | // ç»æè¢«å½æç¼ç å¡è¿ leavehospitaldistrictcodes / leaveldeptcodesï¼ |
| | | // å端æ leavehospitaldistrictcode IN ('ä¸ç
åº','äºç
åº'â¦) è¿æ»¤ â 䏿¡ä¹å¹é
ä¸ä¸ã |
| | | // ç§å®¤/ç
åºä¸å¾åªç¨çå®ç¼ç ï¼æå½å±å storeï¼æ å½å±ï¼å¦ç®¡çåï¼å deptTreeSelect åå
¸ã |
| | | |
| | | /** |
| | | * æ¥å£æ°æ® â 页é¢å
é¨é¢ç®ç»æ |
| | |
| | | // 表ä¸ï¼ç§å®¤/ç
åºè¯å对æ¯ï¼rows=è¡æ°æ®ï¼questions=卿åï¼ |
| | | deptComparison: { rows: [], questions: [] }, |
| | | wardComparison: { rows: [], questions: [] }, |
| | | |
| | | // ç§å®¤/ç
åºåå
¸ï¼å½åè´¦å·æ²¡æå½å±ç§å®¤/ç
åºæ¶ï¼å¦ç®¡çåï¼ä» deptTreeSelect æåï¼ |
| | | // ä¿è¯ä¸æéæ¾çæ¯çå®ç¼ç ï¼deptCode / districtCodeï¼ï¼è䏿¯åç§° |
| | | deptDict: [], |
| | | wardDict: [], |
| | | }; |
| | | }, |
| | | computed: { |
| | | // ç§å®¤é项ï¼ä¼å
åå½åç¨æ·æå±ç§å®¤ï¼æ åå
åº |
| | | // ç§å®¤é项ï¼ä¼å
åå½åç¨æ·æå±ç§å®¤ï¼æ²¡æå½å±æ¶ç¨ç§å®¤åå
¸ï¼çå® deptCodeï¼ |
| | | deptOptions() { |
| | | const list = this.$store.getters.belongDepts || []; |
| | | return list.length |
| | | ? list.map((d) => ({ label: d.deptName, value: d.deptCode })) |
| | | : DEPTS.map((d) => ({ label: d, value: d })); |
| | | const list = (this.$store.getters.belongDepts || []) |
| | | .map((d) => ({ label: d.deptName, value: d.deptCode })) |
| | | .filter((d) => d.label && d.value); |
| | | return list.length ? list : this.deptDict; |
| | | }, |
| | | // ç
åºé项ï¼ä¼å
åå½åç¨æ·æå±ç
åºï¼æ åå
åº |
| | | // ç
åºé项ï¼ä¼å
åå½åç¨æ·æå±ç
åºï¼æ²¡æå½å±æ¶ç¨ç
åºåå
¸ï¼çå® districtCodeï¼ |
| | | wardOptions() { |
| | | const list = this.$store.getters.belongWards || []; |
| | | return list.length |
| | | ? list.map((w) => ({ label: w.districtName, value: w.districtCode })) |
| | | : WARDS.map((w) => ({ label: w, value: w })); |
| | | const list = (this.$store.getters.belongWards || []) |
| | | .map((w) => ({ label: w.districtName, value: w.districtCode })) |
| | | .filter((w) => w.label && w.value); |
| | | return list.length ? list : this.wardDict; |
| | | }, |
| | | // æå¡ç±»å䏿ï¼å store çé访类ååå
¸ tasktypesï¼åä¸å°æ¶å
åºæ¬å° SERVICE_TYPES |
| | | serviceTypeOptions() { |
| | |
| | | const taskTypes = toOptions(this.$store.getters.tasktypes); |
| | | return taskTypes.length ? taskTypes : SERVICE_TYPES; |
| | | }, |
| | | // æªéç
åºæ¶çé»è®¤æ¥è¯¢èå´ï¼å
¨é¨ç
åºç¼ç |
| | | // æªéç
åºæ¶çé»è®¤æ¥è¯¢èå´ï¼å
¨é¨ç
åºç¼ç ï¼ç©ºæ°ç» = ä¸éï¼åç«¯ä¸æ¼è¿æ»¤æ¡ä»¶ï¼ |
| | | defaultWardCodes() { |
| | | return Array.from(new Set(this.wardOptions.map((w) => w.value))); |
| | | return Array.from( |
| | | new Set(this.wardOptions.map((w) => w.value).filter(Boolean)) |
| | | ); |
| | | }, |
| | | // æ¯å¦æãå¨é¢æ»¡æåº¦ãå£å¾æ¥è¯¢ï¼å¨é¢æ»¡æåº¦ç¨ deptcodes/hospitaldistrictcodesï¼ |
| | | // ç¦»é¢æ»¡æåº¦ï¼ä»¥åæ¸
ç©ºä¸ææ¶çé»è®¤å£å¾ï¼ç¨ leaveldeptcodes/leavehospitaldistrictcodes |
| | | isInHospitalSatisfaction() { |
| | | return this.satisfactionScope === "hospital"; |
| | | }, |
| | | // æªéç§å®¤æ¶çé»è®¤æ¥è¯¢èå´ï¼å
¨é¨ç§å®¤ç¼ç |
| | | // æªéç§å®¤æ¶çé»è®¤æ¥è¯¢èå´ï¼å
¨é¨ç§å®¤ç¼ç ï¼ç©ºæ°ç» = ä¸éï¼ |
| | | defaultDeptCodes() { |
| | | return Array.from(new Set(this.deptOptions.map((d) => d.value))); |
| | | return Array.from( |
| | | new Set(this.deptOptions.map((d) => d.value).filter(Boolean)) |
| | | ); |
| | | }, |
| | | // åºå®å
项é项çé¢ç® => è¡¨ä¸ |
| | | satisfactionQuestions() { |
| | |
| | | } |
| | | this.queryParams.serviceTypeList = this.defaultServiceTypes(); |
| | | }, |
| | | mounted() { |
| | | async mounted() { |
| | | // å
æç§å®¤/ç
åºåå
¸è¡¥é½ï¼ä¿è¯é¦æ¬¡æ¥è¯¢ç¨çå°±æ¯çå®ç¼ç |
| | | await this.ensureOrgDict(); |
| | | this.fetchData(); |
| | | }, |
| | | methods: { |
| | |
| | | return item ? item.value : null; |
| | | }).filter((v) => v != null); |
| | | return Array.from(new Set(hit)); |
| | | }, |
| | | // å½ä¸åç§å®¤/ç
åºç¼ç ï¼éä¸é¡¹ä¼å
ï¼å
¶æ¬¡é»è®¤å
¨é¨ï¼å»éãå»ç©º |
| | | // è¿å空æ°ç»è¡¨ç¤ºãä¸éãï¼å端 mapper ç¨ size() > 0 夿ï¼ç©ºéå䏿¼è¿æ»¤æ¡ä»¶ï¼ |
| | | codeList(selected, fallback) { |
| | | const list = (selected && selected.length ? selected : fallback) || []; |
| | | return Array.from( |
| | | new Set( |
| | | list.filter((v) => v !== null && v !== undefined && String(v).trim() !== "") |
| | | ) |
| | | ); |
| | | }, |
| | | // è¡¥å
¨ç§å®¤/ç
åºåå
¸ï¼ä»
å½ store éæ²¡æå½å±æ°æ®æ¶ï¼å
¸åæ¯ç®¡çåè´¦å·ï¼æè¯·æ± |
| | | async ensureOrgDict() { |
| | | const tasks = []; |
| | | if (!(this.$store.getters.belongDepts || []).length) { |
| | | tasks.push(this.loadOrgDict(1)); |
| | | } |
| | | if (!(this.$store.getters.belongWards || []).length) { |
| | | tasks.push(this.loadOrgDict(2)); |
| | | } |
| | | if (tasks.length) await Promise.all(tasks); |
| | | }, |
| | | // deptTypeï¼1=ç§å®¤ï¼2=ç
åºï¼ç»ææ¢ä½ä¸æé项ï¼ä¹ä½ãå
¨é¨ãæ¶çç¼ç æ¥æº |
| | | async loadOrgDict(deptType) { |
| | | let flat = []; |
| | | try { |
| | | const res = await deptTreeSelect(deptType); |
| | | const walk = (nodes) => { |
| | | (Array.isArray(nodes) ? nodes : []).forEach((n) => { |
| | | // deptTreeSelect è¿å TreeSelectï¼{ id, label, deptCode, children } |
| | | // åªè®¤ deptCodeï¼ç¼ºå¤±å°±è·³è¿ââç¨ deptId åå
ç¼ç åæ ·æ¥ä¸å°æ°æ® |
| | | if (n.label && n.deptCode) { |
| | | flat.push({ label: n.label, value: String(n.deptCode) }); |
| | | } |
| | | if (n.children && n.children.length) walk(n.children); |
| | | }); |
| | | }; |
| | | walk(res && res.data); |
| | | } catch (e) { |
| | | console.warn("[DataOverview] è·åç§å®¤/ç
åºåå
¸å¤±è´¥ï¼å°æâå
¨é¨âæ¥è¯¢", e); |
| | | } |
| | | if (deptType === 1) { |
| | | this.deptDict = flat; |
| | | } else { |
| | | this.wardDict = flat; |
| | | } |
| | | }, |
| | | // 表ä¸ç¬ç«æ¡ä»¶ï¼'inherit' æ¶æ²¿ç¨é¡¶é¨æéï¼è¿åéä¸çåç§°æ°ç»ï¼æ¥å£åªååç§°ï¼ï¼ç©ºæ°ç»è¡¨ç¤ºä¸é |
| | | statFilterNames() { |
| | |
| | | endFinishTime: range[1], |
| | | }; |
| | | if (this.queryParams.statMode === "dept") { |
| | | const deptCodes = depts.length |
| | | ? Array.from(new Set(depts)) |
| | | : this.defaultDeptCodes; |
| | | if (this.isInHospitalSatisfaction) { |
| | | payload.deptcodes = deptCodes; |
| | | } else { |
| | | payload.leaveldeptcodes = deptCodes; |
| | | const deptCodes = this.codeList(depts, this.defaultDeptCodes); |
| | | // æç¼ç æä¼ ï¼ç©ºæ°ç»çä»·äºãå
¨é¨ãï¼å端 mapper 对空éå䏿¼æ¡ä»¶ï¼ |
| | | if (deptCodes.length) { |
| | | if (this.isInHospitalSatisfaction) { |
| | | payload.deptcodes = deptCodes; |
| | | } else { |
| | | payload.leaveldeptcodes = deptCodes; |
| | | } |
| | | } |
| | | } else { |
| | | const wardCodes = wards.length |
| | | ? Array.from(new Set(wards)) |
| | | : this.defaultWardCodes; |
| | | if (this.isInHospitalSatisfaction) { |
| | | payload.hospitaldistrictcodes = wardCodes; |
| | | } else { |
| | | payload.leavehospitaldistrictcodes = wardCodes; |
| | | // åªä¼ ãç¨æ·çæ£éä¸çç
åºãï¼æ²¡éï¼= å
¨é¨ç
åºï¼å°±ä¸ä¼ ï¼å端æä¸éå¤çã |
| | | // é¨è¯æ»¡æåº¦çä»»å¡ç leavehospitaldistrictcode ä¸ºç©ºï¼ |
| | | // 忥æãå
¨é¨ç
åºç¼ç ãä¼ ä¸å»ä¼è®©è¿äºä»»å¡è¢« IN æ¡ä»¶æ´æ®µè¿æ»¤æï¼25 é¢åªå© 10 é¢ï¼ã |
| | | const wardCodes = this.codeList(wards, []); |
| | | if (wardCodes.length) { |
| | | if (this.isInHospitalSatisfaction) { |
| | | payload.hospitaldistrictcodes = wardCodes; |
| | | } else { |
| | | payload.leavehospitaldistrictcodes = wardCodes; |
| | | } |
| | | } |
| | | } |
| | | // æå¡ç±»åå¤éï¼éå·åéï¼æ¥å£å段为 serviceType åç¬¦ä¸²ï¼ |
| | |
| | | try { |
| | | // æç§å®¤ç»è®¡ãæç
åºç»è®¡åæ¥ä¸æ¬¡ï¼æ¡ä»¶éãæ»¡æåº¦ç±»åãåæ¢ï¼ |
| | | // å¨é¢æ»¡æåº¦ => deptcodes / hospitaldistrictcodesï¼ç¦»é¢æ»¡æåº¦ => leaveldeptcodes / leavehospitaldistrictcodes |
| | | const deptParam = this.isInHospitalSatisfaction |
| | | ? { deptcodes: this.defaultDeptCodes } |
| | | : { leaveldeptcodes: this.defaultDeptCodes }; |
| | | const wardParam = this.isInHospitalSatisfaction |
| | | ? { hospitaldistrictcodes: this.defaultWardCodes } |
| | | : { leavehospitaldistrictcodes: this.defaultWardCodes }; |
| | | // 没æçå®ç¼ç æ¶ä¸ä¼ è¯¥åæ®µï¼= å
¨é¨ï¼ï¼ç»ä¸æåç§°å½ç¼ç ä¼ |
| | | const deptParam = {}; |
| | | const deptCodes = this.codeList([], this.defaultDeptCodes); |
| | | if (deptCodes.length) { |
| | | if (this.isInHospitalSatisfaction) { |
| | | deptParam.deptcodes = deptCodes; |
| | | } else { |
| | | deptParam.leaveldeptcodes = deptCodes; |
| | | } |
| | | } |
| | | const wardParam = {}; |
| | | const wardCodes = this.codeList([], this.defaultWardCodes); |
| | | if (wardCodes.length) { |
| | | if (this.isInHospitalSatisfaction) { |
| | | wardParam.hospitaldistrictcodes = wardCodes; |
| | | } else { |
| | | wardParam.leavehospitaldistrictcodes = wardCodes; |
| | | } |
| | | } |
| | | const [deptRes, wardRes] = await Promise.all([ |
| | | statQuestionOptionByKsOrBq({ ...base, ...deptParam }), |
| | | statQuestionOptionByKsOrBq({ ...base, ...wardParam }), |
| | |
| | | exportTable(tableId) { |
| | | const tableNames = { |
| | | table1: "åæå¡é¡¹ç®æ»¡æåº¦ç»è®¡", |
| | | table2: "åéé¢å¤éé¢ç»è®¡", |
| | | table2: "å
¶ä»é¢ç®ç»è®¡", |
| | | table3: "åç§å®¤æ»¡æåº¦è¯å对æ¯", |
| | | }; |
| | | const name = tableNames[tableId] || "ç»è®¡æ°æ®"; |
| | |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | .card-subtitle { |
| | | margin-left: 6px; |
| | | font-size: 12px; |
| | | font-weight: 400; |
| | | color: #909399; |
| | | } |
| | | .header-right { |
| | | display: flex; |
| | | align-items: center; |
| | |
| | | <el-form-item label="满æåº¦ç±»å" prop="satisfactionScope"> |
| | | <el-select |
| | | v-model="satisfactionScope" |
| | | placeholder="é»è®¤ç¦»é¢" |
| | | placeholder="é»è®¤å¨é¢" |
| | | clearable |
| | | style="width: 150px" |
| | | @change="handleSatisfactionScopeChange" |
| | |
| | | @selection-change="handleSelectionChange" |
| | | :row-key="getRowKey" |
| | | > |
| | | <!-- ç
åºåï¼ä½é¢æ»¡æåº¦ç»è®¡å¨é¢ç
åºï¼å
¶ä½ç»è®¡åºé¢ç
åº --> |
| | | <!-- ç
åºç»è®¡ï¼å¨é¢ç
åº + 离é¢ç
åº --> |
| | | <el-table-column |
| | | v-if="queryParams.statisticaltype == 1" |
| | | :label="wardColumnLabel" |
| | | label="å¨é¢ç
åº" |
| | | align="center" |
| | | sortable |
| | | key="hospitaldistrictname" |
| | | prop="hospitaldistrictname" |
| | | :show-overflow-tooltip="true" |
| | | :sort-method="sortHospitalWard" |
| | | min-width="120" |
| | | > |
| | | <template slot-scope="scope"> |
| | | {{ scope.row.hospitaldistrictname || "-" }} |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | v-if="queryParams.statisticaltype == 1" |
| | | label="离é¢ç
åº" |
| | | align="center" |
| | | sortable |
| | | key="leavehospitaldistrictname" |
| | | prop="leavehospitaldistrictname" |
| | | :show-overflow-tooltip="true" |
| | | :sort-method="sortChineseNumber" |
| | | :sort-method="sortLeaveWard" |
| | | min-width="120" |
| | | > |
| | | <template slot-scope="scope"> |
| | | {{ getWardName(scope.row) || "-" }} |
| | | {{ scope.row.leavehospitaldistrictname || "-" }} |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <!-- ç§å®¤å --> |
| | | <!-- ç§å®¤ç»è®¡ï¼å¨é¢ç§å®¤ + 离é¢ç§å®¤ --> |
| | | <el-table-column |
| | | v-if="queryParams.statisticaltype == 2" |
| | | label="ç§å®¤" |
| | | label="å¨é¢ç§å®¤" |
| | | align="center" |
| | | key="hospitaldeptname" |
| | | prop="hospitaldeptname" |
| | | :show-overflow-tooltip="true" |
| | | min-width="120" |
| | | > |
| | | <template slot-scope="scope"> |
| | | {{ scope.row.hospitaldeptname || "-" }} |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | v-if="queryParams.statisticaltype == 2" |
| | | label="离é¢ç§å®¤" |
| | | align="center" |
| | | key="deptname" |
| | | prop="deptname" |
| | | :show-overflow-tooltip="true" |
| | | min-width="120" |
| | | /> |
| | | > |
| | | <template slot-scope="scope"> |
| | | {{ scope.row.deptname || "-" }} |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | label="åºé¢äººæ¬¡" |
| | |
| | | data() { |
| | | return { |
| | | // 满æåº¦ç±»åï¼leave=ç¦»é¢æ»¡æåº¦ï¼æåºé¢ç
åºç»è®¡ï¼ï¼hospital=å¨é¢æ»¡æåº¦ï¼æå¨é¢ç
åºç»è®¡ï¼ |
| | | satisfactionScope: "leave", |
| | | // é»è®¤å¨é¢æ»¡æåº¦ |
| | | satisfactionScope: "hospital", |
| | | |
| | | // æ¥è¯¢åæ° |
| | | queryParams: { |
| | | statisticaltype: 1, |
| | | leavehospitaldistrictcodes: ["all"], |
| | | deptcodes: [], |
| | | serviceType: [2], |
| | | // é»è®¤æå¡ç±»åï¼6=ä½é¢æ»¡æåº¦ï¼åºå
¥é¢æ»¡æåº¦ï¼ |
| | | serviceType: [6], |
| | | dateRange: [], |
| | | pageNum: 1, |
| | | pageSize: 20, |
| | |
| | | }, |
| | | |
| | | computed: { |
| | | // æ¯å¦æãå¨é¢æ»¡æåº¦ãå£å¾ç»è®¡ï¼å¨é¢æ£è
æå¨é¢ç
åº(hospitaldistrictcodes)ç»è®¡ï¼ |
| | | // ç¦»é¢æ»¡æåº¦ä»æåºé¢ç
åº(leavehospitaldistrictcodes)ç»è®¡ |
| | | // æ¯å¦æãå¨é¢æ»¡æåº¦ãå£å¾ç»è®¡ï¼å¨é¢ç¨ hospitaldistrictcodes / hospitaldeptcodesï¼ |
| | | // 离é¢ç¨ leavehospitaldistrictcodes / leaveldeptcodes |
| | | // é»è®¤å¨é¢ï¼æä»¥æ¸
ç©ºä¸ææ¶ä»æå¨é¢å£å¾å¤ç |
| | | isInHospitalSatisfaction() { |
| | | return this.satisfactionScope === "hospital"; |
| | | }, |
| | | |
| | | // ç
åºåæ é¢ |
| | | wardColumnLabel() { |
| | | return this.isInHospitalSatisfaction ? "å¨é¢ç
åº" : "åºé¢ç
åº"; |
| | | return this.satisfactionScope !== "leave"; |
| | | }, |
| | | }, |
| | | |
| | |
| | | params.endTime = this.queryParams.dateRange[1]; |
| | | } |
| | | |
| | | // å¤çç
åº/ç§å®¤éæ© |
| | | // å¤çç
åº/ç§å®¤éæ©ï¼åªä¿çå½åç»è®¡ç±»å + å½å满æåº¦ç±»å对åºçåæ®µï¼ |
| | | // é¿å
å¨é¢/离é¢ä¸¤å¥æ¡ä»¶åæ¶æ¼è¿ SQL |
| | | if (params.statisticaltype == 1) { |
| | | // ç
åºç»è®¡ |
| | | let wardCodes = params.leavehospitaldistrictcodes || []; |
| | |
| | | (ward) => ward.districtCode |
| | | ); |
| | | } |
| | | // ä½é¢æ»¡æåº¦é对å¨é¢æ£è
ï¼æå¨é¢ç
åº(hospitaldistrictcodes)ç»è®¡ï¼ |
| | | // åºé¢é访çå
¶ä»æå¡ç±»å仿åºé¢ç
åº(leavehospitaldistrictcodes)ç»è®¡ |
| | | delete params.leavehospitaldistrictcodes; |
| | | delete params.hospitaldistrictcodes; |
| | | delete params.deptcodes; |
| | | delete params.leaveldeptcodes; |
| | | delete params.hospitaldeptcodes; |
| | | if (this.isInHospitalSatisfaction) { |
| | | params.hospitaldistrictcodes = wardCodes; |
| | | } else { |
| | |
| | | } |
| | | } else if (params.statisticaltype == 2) { |
| | | // ç§å®¤ç»è®¡ |
| | | if (params.deptcodes.includes("all")) { |
| | | let deptCodes = params.deptcodes || []; |
| | | if (deptCodes.includes("all")) { |
| | | // 妿鿩äº"å
¨é¨"ï¼åç§»é¤"all"å¼ |
| | | params.deptcodes = params.deptcodes.filter( |
| | | (item) => item !== "all" |
| | | ); |
| | | deptCodes = deptCodes.filter((item) => item !== "all"); |
| | | // 妿éè¦ä¼ ææç§å®¤ä»£ç ï¼å¯ä»¥ä»storeä¸è·å |
| | | params.deptcodes = (this.$store.getters.belongDepts || []).map( |
| | | deptCodes = (this.$store.getters.belongDepts || []).map( |
| | | (dept) => dept.deptCode |
| | | ); |
| | | } |
| | | delete params.deptcodes; |
| | | delete params.leaveldeptcodes; |
| | | delete params.hospitaldeptcodes; |
| | | delete params.leavehospitaldistrictcodes; |
| | | delete params.hospitaldistrictcodes; |
| | | if (this.isInHospitalSatisfaction) { |
| | | params.hospitaldeptcodes = deptCodes; |
| | | } else { |
| | | params.leaveldeptcodes = deptCodes; |
| | | } |
| | | } |
| | | |
| | | const response = await getSfStatisticsJoy(params); |
| | | this.userList = this.customSort(response.data) || []; |
| | | // ç§å®¤ç»è®¡ææ¥å£è¿å顺åºï¼ç
åºç»è®¡ä¿æåæç䏿åºå·æåº |
| | | this.userList = |
| | | this.queryParams.statisticaltype == 1 |
| | | ? this.customSort(response.data) || [] |
| | | : response.data || []; |
| | | this.total = response.total || 0; |
| | | } catch (error) { |
| | | console.error("è·åç»è®¡å表失败:", error); |
| | |
| | | } |
| | | }, |
| | | sortChineseNumber(aRow, bRow) { |
| | | const a = this.getWardName(aRow); |
| | | const b = this.getWardName(bRow); |
| | | |
| | | return this.compareWardNames(this.getWardName(aRow), this.getWardName(bRow)); |
| | | }, |
| | | sortHospitalWard(aRow, bRow) { |
| | | return this.compareWardNames( |
| | | aRow && aRow.hospitaldistrictname, |
| | | bRow && bRow.hospitaldistrictname |
| | | ); |
| | | }, |
| | | sortLeaveWard(aRow, bRow) { |
| | | return this.compareWardNames( |
| | | aRow && aRow.leavehospitaldistrictname, |
| | | bRow && bRow.leavehospitaldistrictname |
| | | ); |
| | | }, |
| | | // æ¯è¾ä¸¤ä¸ªç
åºåç§°ç䏿åºå·ï¼æ åºå·æ¶æå符串æ¯è¾ |
| | | compareWardNames(a, b) { |
| | | // 䏿æ°åå°é¿æä¼¯æ°åçæ å°ï¼æ©å±å°45ï¼ |
| | | const chineseNumMap = { |
| | | ä¸: 1, |
| | |
| | | this.getList(); |
| | | }, |
| | | |
| | | // éç½®æ¥è¯¢ |
| | | // éç½®æ¥è¯¢ï¼æ¢å¤é»è®¤ï¼å¨é¢æ»¡æåº¦ + æå¡ç±»å 6ï¼ |
| | | resetQuery() { |
| | | this.satisfactionScope = "hospital"; |
| | | this.queryParams = { |
| | | statisticaltype: 1, |
| | | leavehospitaldistrictcodes: [], |
| | | deptcodes: [], |
| | | serviceType: [2], |
| | | serviceType: [6], |
| | | dateRange: [], |
| | | pageNum: 1, |
| | | pageSize: 20, |
| | |
| | | this.multiple = !selection.length; |
| | | }, |
| | | |
| | | // è·åè¡key |
| | | // è·åè¡keyï¼æå½åç»è®¡ç±»åå对åºç»´åº¦ç¼ç ï¼ |
| | | getRowKey(row) { |
| | | return row.statisticaltype === 1 |
| | | return this.queryParams.statisticaltype == 1 |
| | | ? row.hospitaldistrictcode || row.leavehospitaldistrictcode |
| | | : row.deptcode; |
| | | : row.hospitaldeptcode || row.deptcode; |
| | | }, |
| | | |
| | | // ç
åºåç§°ï¼ä½é¢æ»¡æåº¦æ¥å£è¿åå¨é¢ç
åºå段ï¼å
¶ä½è¿ååºé¢ç
åºå段 |
| | | // å½å满æåº¦ç±»å对åºçç
åºåç§°ï¼ç¨äºæåº/导åº/详æ
æ é¢ï¼ |
| | | getWardName(row) { |
| | | if (!row) return ""; |
| | | return row.hospitaldistrictname || row.leavehospitaldistrictname || ""; |
| | | return this.isInHospitalSatisfaction |
| | | ? row.hospitaldistrictname || "" |
| | | : row.leavehospitaldistrictname || ""; |
| | | }, |
| | | |
| | | // æ ¼å¼åç¾åæ¯ |
| | |
| | | params.endTime = this.queryParams.dateRange[1]; |
| | | } |
| | | |
| | | // 详æ
åªæå½ååç»ç»´åº¦è¿æ»¤ï¼æ¸
æå
¶ä½ç»´åº¦ï¼é¿å
å¨é¢/ç¦»é¢æ¡ä»¶äºç¸å¹²æ° |
| | | delete params.deptcodes; |
| | | delete params.leaveldeptcodes; |
| | | delete params.hospitaldeptcodes; |
| | | delete params.leavehospitaldistrictcodes; |
| | | delete params.hospitaldistrictcodes; |
| | | |
| | | if (this.queryParams.statisticaltype == 1) { |
| | | this.topicvalue.name = this.getWardName(row); |
| | | // ä½é¢æ»¡æåº¦æå¨é¢ç
åºç»è®¡ï¼å
¶ä½æåºé¢ç
åºç»è®¡ |
| | | if (this.isInHospitalSatisfaction) { |
| | | delete params.leavehospitaldistrictcodes; |
| | | params.hospitaldistrictcodes = [ |
| | | row.hospitaldistrictcode || row.leavehospitaldistrictcode, |
| | | ]; |
| | | this.topicvalue.name = row.hospitaldistrictname || "-"; |
| | | params.hospitaldistrictcodes = [row.hospitaldistrictcode].filter( |
| | | Boolean |
| | | ); |
| | | } else { |
| | | this.topicvalue.name = row.leavehospitaldistrictname || "-"; |
| | | params.leavehospitaldistrictcodes = [ |
| | | row.leavehospitaldistrictcode, |
| | | ]; |
| | | ].filter(Boolean); |
| | | } |
| | | } else { |
| | | this.topicvalue.name = row.deptname; |
| | | params.deptcodes = [row.deptcode]; |
| | | if (this.isInHospitalSatisfaction) { |
| | | this.topicvalue.name = row.hospitaldeptname || "-"; |
| | | params.hospitaldeptcodes = [row.hospitaldeptcode].filter(Boolean); |
| | | } else { |
| | | this.topicvalue.name = row.deptname || "-"; |
| | | params.leaveldeptcodes = [row.deptcode].filter(Boolean); |
| | | } |
| | | } |
| | | |
| | | const response = await getSfStatisticsJoyInfo(params); |
| | |
| | | }, |
| | | }; |
| | | |
| | | // æ·»å æ»æ é¢ |
| | | // æ·»å æ»æ é¢ï¼ä¸¤å维度 + å
«ä¸ªææ åï¼å
± 10 åï¼ |
| | | worksheet.mergeCells(1, 1, 1, 10); |
| | | const titleCell = worksheet.getCell(1, 1); |
| | | titleCell.value = `满æåº¦é访ç»è®¡è¡¨ï¼${sheetNameSuffix}ï¼`; |
| | | titleCell.style = titleStyle; |
| | | worksheet.getRow(1).height = 35; |
| | | |
| | | // æ·»å 表头 |
| | | // æ·»å 表头ï¼ç§å®¤ç»è®¡å¯¼åºå¨é¢ç§å®¤+离é¢ç§å®¤ï¼ç
åºç»è®¡å¯¼åºå¨é¢ç
åº+离é¢ç
åºï¼ |
| | | const isWardStatistics = this.queryParams.statisticaltype == 1; |
| | | const headers = [ |
| | | this.queryParams.statisticaltype == 1 ? this.wardColumnLabel : "ç§å®¤", |
| | | isWardStatistics ? "å¨é¢ç
åº" : "å¨é¢ç§å®¤", |
| | | isWardStatistics ? "离é¢ç
åº" : "离é¢ç§å®¤", |
| | | "åºé¢äººæ¬¡", |
| | | "æ éé访人次", |
| | | "åºé访人次", |
| | |
| | | // æ·»å æ°æ®è¡ |
| | | this.userList.forEach((item) => { |
| | | const dataRow = worksheet.addRow([ |
| | | this.queryParams.statisticaltype == 1 |
| | | ? this.getWardName(item) |
| | | : item.deptname, |
| | | isWardStatistics |
| | | ? item.hospitaldistrictname || "-" |
| | | : item.hospitaldeptname || "-", |
| | | isWardStatistics |
| | | ? item.leavehospitaldistrictname || "-" |
| | | : item.deptname || "-", |
| | | item.dischargeCount || 0, |
| | | item.nonFollowUp || 0, |
| | | item.followUpNeeded || 0, |
| | |
| | | // 设置å宽 |
| | | worksheet.columns = [ |
| | | { width: 20 }, |
| | | { width: 20 }, |
| | | { width: 12 }, |
| | | { width: 12 }, |
| | | { width: 12 }, |
| | |
| | | :ycvalue="ycvalue" |
| | | :jgvalue="jgvalue" |
| | | :show-warning-condition="orgname == 'çç«åå¾·ç¿ èé¢åº'" |
| | | clickable |
| | | @card-click="handleCardClick" |
| | | /> |
| | | <el-row :gutter="20"> |
| | | <!--ç¨æ·æ°æ®--> |
| | |
| | | </span> |
| | | </div> |
| | | </el-row> |
| | | <div v-if="cardFilter" class="card-filter-tip"> |
| | | å½åæé¡¶é¨å¡ççéï¼<b>{{ cardFilter }}</b> |
| | | <span class="tip-desc">ï¼ä¸å½±å䏿¹è¡¨åæ¡ä»¶ï¼ç¹ãæç´¢ã坿¢å¤è¡¨åæ¡ä»¶ï¼</span> |
| | | <el-button type="text" size="mini" @click="clearCardFilter">æ¸
é¤</el-button> |
| | | </div> |
| | | <div class="selected-info"> |
| | | å·²éä¸ |
| | | <span style="color: #409eff; font-weight: bold">{{ |
| | |
| | | ], |
| | | lastScopeType: 3, // æ£è
èå´ä¸æ¬¡éæ©çä¸çº§ç±»åï¼1=ç§å®¤ï¼2=ç
åºï¼3=å
¨é¨ï¼ |
| | | loading: false, |
| | | // é¡¶é¨å¡çç¹å»å¸¦æ¥ç临æ¶çéï¼åªä½ç¨äºä¸é¢å表ï¼ä¸å¨è¡¨åã䏿¹å¡çæ°åï¼ç¹ãæç´¢ãæ¶æ¸
ç©ºï¼ |
| | | cardFilter: null, |
| | | cardlist: [ |
| | | { |
| | | name: "æ£è
æå¡æ»é", |
| | |
| | | // çå¬è·¯ç±åæ°åå |
| | | "$route.query": { |
| | | handler(newQuery, oldQuery) { |
| | | // å³ä¸è§ãå¾
å¤çé访任å¡ãå¡ç忬¡ç¹å»ï¼å½å已卿¬é¡µï¼ |
| | | if ( |
| | | newQuery?.month && |
| | | newQuery?.fromPendingTask === "1" && |
| | | this.taskQueryReady |
| | | ) { |
| | | this.applyPendingTaskQuery(); |
| | | return; |
| | | } |
| | | if (newQuery?.errtype !== oldQuery?.errtype) { |
| | | console.log(22); |
| | | this.loadData(); |
| | |
| | | }); |
| | | // å
ç»ç´è¾¾ï¼æ ¹æ®ç§å®¤/ç
åºç¼ç é¢å¡«æ£è
èå´ |
| | | this.applyFollowUpScope(); |
| | | if (this.errtype == 1) { |
| | | // å³ä¸è§ãå¾
å¤çé访任å¡ãå¡çè·³è½¬ï¼æåºé¢å¹´æ + å¾
é访 + åºé¢æ»¡ 7 å¤©è¿æ»¤ |
| | | if (this.applyPendingTaskQuery()) { |
| | | // å·²æå¡çæ¡ä»¶æ¥è¯¢ï¼ä¸åèµ°é»è®¤åæ¯ |
| | | } else if (this.errtype == 1) { |
| | | this.toleadExport(2); |
| | | } else if (this.errtype == 2) { |
| | | // å¾
é访 |
| | |
| | | this.getConfigKey("sys.user.initPassword").then((response) => { |
| | | this.initPassword = response.msg; |
| | | }); |
| | | // created åå§å宿ï¼ä¹åè·¯ç± query ååææå¡çæ¡ä»¶éæ°æ¥è¯¢ |
| | | this.taskQueryReady = true; |
| | | }, |
| | | activated() { |
| | | // ä»å«çæ ç¾é¡µå忥æ¶ï¼ä»¥è¡¨åæ¡ä»¶ä¸ºåï¼ä¸¢å¼å¡ç带æ¥ç䏿¬¡æ§çé |
| | | this.cardFilter = null; |
| | | this.errtype = this.$route.query.errtype; |
| | | if (this.applyPendingTaskQuery()) { |
| | | return; |
| | | } |
| | | if (this.errtype == 1) { |
| | | this.toleadExport(2); |
| | | } else if (this.errtype == 2) { |
| | |
| | | } |
| | | |
| | | try { |
| | | const response = await getTaskservelist(this.topqueryParams); |
| | | // é¡¶é¨å¡çç¹å»çä¸´æ¶æ¡ä»¶åªå 卿¬æ¬¡è¯·æ±ä¸ï¼ä¸åå表å |
| | | const query = this.applyCardFilter({ ...this.topqueryParams }); |
| | | const response = await getTaskservelist(query); |
| | | |
| | | // â
ç¬¬ä¸æ¥ï¼å
é宿¢å¤ç¶æ |
| | | this.isRestoring = true; |
| | |
| | | |
| | | // â
ç¬¬åæ¥ï¼å¤çå
¶ä»æ°æ® |
| | | if (refresh) { |
| | | this.cardlist[0].value = |
| | | Number(response.rows[0].wxsf) + Number(response.rows[0].xsf) || 0; |
| | | this.cardlist[1].value = response.rows[0].wxsf || 0; |
| | | this.ycvalue = Number(response.rows[0].yc) || 0; |
| | | this.jgvalue = response.rows[0].jg; |
| | | this.cardlist[2].value = response.rows[0].xsf || 0; |
| | | this.cardlist[3].value = response.rows[0].dsf || 0; |
| | | this.cardlist[4].value = response.rows[0].ywc || 0; |
| | | this.yfsvalue = response.rows[0].yfs; |
| | | // é¡¶é¨å¡ççæ°åä¸è·ãéè®¿ç¶æ/å¼å¸¸ãèµ°ï¼åç¬æ¥ä¸æ¬¡å»æç¶ææ¡ä»¶çç»è®¡ï¼ |
| | | // å¦åçäºãå¾
é访ãåãå·²å®æãæ°¸è¿æ¯ 0ï¼ççåç®éäº |
| | | this.refreshCardCounts(query); |
| | | } |
| | | |
| | | // â
ç¬¬äºæ¥ï¼å¤ç preachform çå
¶ä»æ°æ® |
| | |
| | | }, |
| | | /** æç´¢æé®æä½ */ |
| | | handleQuery(refresh) { |
| | | // ç¹ãæç´¢ãæ¶ä»¥è¡¨åæ¡ä»¶ä¸ºåï¼æ¸
æå¡çç¹å»å¸¦æ¥çä¸´æ¶æ¡ä»¶ |
| | | this.cardFilter = null; |
| | | this.applyDeptWardScope(); |
| | | this.clearAllSelection(); |
| | | this.topqueryParams.pageNum = 1; |
| | |
| | | if (wardCode) scope.push([2, wardCode]); |
| | | this.topqueryParams.scopetype = scope; |
| | | this.lastScopeType = deptCode ? 1 : 2; |
| | | }, |
| | | /** |
| | | * å³ä¸è§ãå¾
å¤çé访任å¡ãå¡çç¹å»æ°åè·³è½¬è¿æ¥ï¼ |
| | | * æåºé¢å¹´æ + å¾
é访ï¼sendstate 1/2/3/5/7ï¼+ åºé¢æ»¡ 7 天 è¿æ»¤ï¼å£å¾ä¸å¡çä¸è´ |
| | | * @returns {boolean} æ¯å¦å·²æå¡çæ¡ä»¶åèµ·æ¥è¯¢ |
| | | */ |
| | | applyPendingTaskQuery() { |
| | | const query = this.$route.query || {}; |
| | | if (!query.month || query.fromPendingTask !== "1") { |
| | | return false; |
| | | } |
| | | // 页é¢è¢« keep-alive å¤ç¨æ¶ä¼éå¤è§¦å activatedï¼å䏿¬¡ç¹å»åªå¤ç䏿¬¡ |
| | | if (this.pendingTaskToken && this.pendingTaskToken === query._t) { |
| | | return false; |
| | | } |
| | | this.pendingTaskToken = query._t; |
| | | |
| | | const month = String(query.month); |
| | | const serviceType = Number(query.serviceType) === 3 ? 3 : 2; |
| | | this.errtype = undefined; |
| | | const start = month + "-01"; |
| | | let end = this.pendingTaskMonthEnd(month); |
| | | // æå 7 天å
ï¼"ä»å¤©-7天" 伿©äºæåï¼å
åºææåï¼é¿å
æ¥æåºé´åæ |
| | | if (end < start) { |
| | | end = start; |
| | | } |
| | | this.dateRange = [start, end]; |
| | | this.topqueryParams.serviceType = serviceType; |
| | | this.topqueryParams.sendstateView = 1; |
| | | this.topqueryParams.sendstate = null; |
| | | // å¡çç»è®¡çæ¯å
¨é¨å¾
é访任å¡ï¼ä¸åºåé¦è½®/å¤è¯ï¼ï¼å表è¿é忥æ¾å¼ |
| | | this.topqueryParams.visitCount = null; |
| | | this.topqueryParams.pageNum = 1; |
| | | this.handleQuery(1); |
| | | return true; |
| | | }, |
| | | /** |
| | | * å¡çå£å¾çæä»½ç»ææ¥ï¼ |
| | | * 彿åªç»è®¡åºé¢æ»¡ 7 天çï¼æä»¥åãä»å¤© - 7 天ãï¼å岿份å彿æåä¸å¤© |
| | | */ |
| | | pendingTaskMonthEnd(month) { |
| | | const parts = String(month).split("-"); |
| | | const year = Number(parts[0]); |
| | | const mon = Number(parts[1]); |
| | | const now = new Date(); |
| | | let date; |
| | | if (year === now.getFullYear() && mon === now.getMonth() + 1) { |
| | | date = new Date(year, mon - 1, now.getDate() - 7); |
| | | } else { |
| | | date = new Date(year, mon, 0); |
| | | } |
| | | const mm = String(date.getMonth() + 1).padStart(2, "0"); |
| | | const dd = String(date.getDate()).padStart(2, "0"); |
| | | return date.getFullYear() + "-" + mm + "-" + dd; |
| | | }, |
| | | // æ£è
èå´å¤çï¼ä»å¤é级è scopetype è§£æç§å®¤/ç
åº |
| | | applyDeptWardScope() { |
| | |
| | | this.topqueryParams.scopetype = null; |
| | | } |
| | | this.handleQuery(1); |
| | | }, |
| | | // é¡¶é¨ç»è®¡å¡çç¹å»ï¼æå¯¹åºç鿡件ä¸å¸¦å°ä¸é¢çåè¡¨ï¼æ°å¼ä¸º 0 çå¡çåæ ·å¯ç¹ï¼ |
| | | // é¡¶é¨å¡çç»è®¡ï¼å»æãéè®¿ç¶æ / å¼å¸¸ãæ¡ä»¶ååç»è®¡ï¼ |
| | | // è¿æ ·å¡çæ°ååªè·æ¥æãç§å®¤/ç
åºçæ¡ä»¶èµ°ï¼ä¸ä¼å 为çäºãå¾
é访ãå°±æã已宿ãç®æ 0 |
| | | async refreshCardCounts(baseQuery) { |
| | | const query = { |
| | | ...(baseQuery || this.topqueryParams), |
| | | pageNum: 1, |
| | | pageSize: 1, |
| | | sendstate: null, |
| | | sendstateView: null, |
| | | sendstates: null, |
| | | excep: null, |
| | | }; |
| | | try { |
| | | const res = await getTaskservelist(query); |
| | | const row = (res && res.rows && res.rows[0]) || {}; |
| | | this.cardlist[0].value = Number(row.wxsf || 0) + Number(row.xsf || 0); |
| | | this.cardlist[1].value = Number(row.wxsf) || 0; |
| | | this.cardlist[2].value = Number(row.xsf) || 0; |
| | | this.cardlist[3].value = Number(row.dsf) || 0; |
| | | this.cardlist[4].value = Number(row.ywc) || 0; |
| | | this.ycvalue = Number(row.yc) || 0; |
| | | this.jgvalue = Number(row.jg) || 0; |
| | | } catch (e) { |
| | | console.warn("å·æ°é¡¶é¨å¡çç»è®¡å¤±è´¥", e); |
| | | } |
| | | }, |
| | | // é¡¶é¨ç»è®¡å¡çç¹å»ï¼åªç»ä¸é¢çå表å ä¸´æ¶æ¡ä»¶ï¼ä¸å¨ä¸æ¹è¡¨åãä¹ä¸æ¹å¡çæ°åï¼ |
| | | // å¡çæ°ååªå¨ç¹ãæç´¢ãæ¶æè¡¨åæ¡ä»¶éç® |
| | | handleCardClick(item) { |
| | | this.cardFilter = item && item.name ? item.name : null; |
| | | this.topqueryParams.pageNum = 1; |
| | | // ä¼ 0ï¼å·æ°å表ï¼ä½ä¸ååé¡¶é¨å¡çæ°å |
| | | this.getList(0); |
| | | }, |
| | | // æå¡çç¹å»çæ¡ä»¶å å å°æ¥è¯¢åæ°ï¼è¿åæ°å¯¹è±¡ï¼ä¸ä¿®æ¹è¡¨åæ¬èº«ï¼ |
| | | applyCardFilter(query) { |
| | | const name = this.cardFilter; |
| | | if (!name) return query; |
| | | // å¡çæ°åæ¯ãä¸å«éè®¿ç¶æ/å¼å¸¸ãçæ»éï¼æä»¥ç¹å¡çæ¶ä¹æè¡¨åéçç¶ææ¡ä»¶å»æï¼ |
| | | // åªæå¡çèªå·±çæ¡ä»¶æ¥ï¼å¦åä¼åºç°ãå¡ç 922ãå表 3 æ¡ã |
| | | query.sendstate = null; |
| | | query.sendstateView = null; |
| | | query.sendstates = null; |
| | | query.excep = null; |
| | | |
| | | if (name === "æ éé访") { |
| | | query.sendstateView = 3; |
| | | } else if (name === "å¾
é访") { |
| | | query.sendstateView = 1; |
| | | } else if (name === "已宿") { |
| | | query.sendstateView = 2; |
| | | } else if (name === "éé访") { |
| | | query.sendstates = [1, 2, 3, 5, 6, 7]; |
| | | } else if (name === "å¼å¸¸") { |
| | | query.excep = "1"; |
| | | } else if (name === "è¦å") { |
| | | query.excep = "2"; |
| | | } |
| | | // ãæ£è
æå¡æ»éã= åªå»æç¶ææ¡ä»¶ï¼ä¸å å«ç |
| | | return query; |
| | | }, |
| | | // æ¸
é¤å¡ççéï¼åå°è¡¨åæ¡ä»¶ |
| | | clearCardFilter() { |
| | | this.cardFilter = null; |
| | | this.topqueryParams.pageNum = 1; |
| | | this.getList(0); |
| | | }, |
| | | /** å¯¼åºæé®æä½ */ |
| | | handleExport() { |
| | |
| | | font-size: 14px; |
| | | color: #666; |
| | | } |
| | | .card-filter-tip { |
| | | margin: 2px 0 4px; |
| | | padding: 6px 10px; |
| | | font-size: 13px; |
| | | color: #303133; |
| | | background: #f0f7ff; |
| | | border: 1px solid #d6e9ff; |
| | | border-radius: 4px; |
| | | } |
| | | .card-filter-tip .tip-desc { |
| | | margin: 0 6px; |
| | | font-size: 12px; |
| | | color: #909399; |
| | | } |
| | | /* ================= æ¸
æ°é«çº§ç®çº¦é£ ================= */ |
| | | .app-container { |
| | | background: #f5f7fb; |
| | |
| | | rules: {}, |
| | | }; |
| | | }, |
| | | watch: {}, |
| | | watch: { |
| | | // å³ä¸è§ãå¾
å¤çé访任å¡ãå¡ç忬¡ç¹å»ï¼å½å已卿¬é¡µï¼ |
| | | "$route.query": { |
| | | handler(newQuery) { |
| | | if ( |
| | | newQuery?.month && |
| | | newQuery?.fromPendingTask === "1" && |
| | | this.taskQueryReady |
| | | ) { |
| | | this.applyPendingTaskQuery(); |
| | | } |
| | | }, |
| | | immediate: true, |
| | | }, |
| | | }, |
| | | created() { |
| | | this.serviceState = store.getters.serviceState; |
| | | this.checkboxlist = store.getters.checkboxlist; |
| | |
| | | value: dept.districtCode, |
| | | }; |
| | | }); |
| | | if (this.errtype) { |
| | | if (this.applyPendingTaskQuery()) { |
| | | // å³ä¸è§ãå¾
å¤çé访任å¡ãå¡ç跳转ï¼å·²æå¹´æ + å¾
é访æ¡ä»¶æ¥è¯¢ |
| | | } else if (this.errtype) { |
| | | this.toleadExport(2); |
| | | } else { |
| | | this.getList(1); |
| | |
| | | this.getConfigKey("sys.user.initPassword").then((response) => { |
| | | this.initPassword = response.msg; |
| | | }); |
| | | // created åå§å宿ï¼ä¹åè·¯ç± query ååææå¡çæ¡ä»¶éæ°æ¥è¯¢ |
| | | this.taskQueryReady = true; |
| | | }, |
| | | activated() { |
| | | if (this.applyPendingTaskQuery()) { |
| | | return; |
| | | } |
| | | this.getList(1); |
| | | }, |
| | | methods: { |
| | |
| | | }; |
| | | this.resetForm("form"); |
| | | }, |
| | | /** |
| | | * å³ä¸è§ãå¾
å¤çé访任å¡ãå¡çç¹å»æ°åè·³è½¬è¿æ¥ï¼ |
| | | * æåºé¢å¹´æ + å¾
é访ï¼sendstate 1/2/3/5/7ï¼+ åºé¢æ»¡ 7 天 è¿æ»¤ï¼å£å¾ä¸å¡çä¸è´ |
| | | * @returns {boolean} æ¯å¦å·²æå¡çæ¡ä»¶åèµ·æ¥è¯¢ |
| | | */ |
| | | applyPendingTaskQuery() { |
| | | const query = this.$route.query || {}; |
| | | if (!query.month || query.fromPendingTask !== "1") { |
| | | return false; |
| | | } |
| | | // 页é¢è¢« keep-alive å¤ç¨æ¶ä¼éå¤è§¦å activatedï¼å䏿¬¡ç¹å»åªå¤ç䏿¬¡ |
| | | if (this.pendingTaskToken && this.pendingTaskToken === query._t) { |
| | | return false; |
| | | } |
| | | this.pendingTaskToken = query._t; |
| | | |
| | | const month = String(query.month); |
| | | const serviceType = Number(query.serviceType) === 3 ? 3 : 2; |
| | | this.errtype = undefined; |
| | | const start = month + "-01"; |
| | | let end = this.pendingTaskMonthEnd(month); |
| | | // æå 7 天å
ï¼"ä»å¤©-7天" 伿©äºæåï¼å
åºææåï¼é¿å
æ¥æåºé´åæ |
| | | if (end < start) { |
| | | end = start; |
| | | } |
| | | this.dateRange = [start, end]; |
| | | this.topqueryParams.serviceType = serviceType; |
| | | this.topqueryParams.sendstateView = 1; |
| | | this.topqueryParams.sendstate = null; |
| | | // å¡çç»è®¡çæ¯å
¨é¨å¾
é访任å¡ï¼ä¸åºåé¦è½®/å¤è¯ï¼ï¼å表è¿é忥æ¾å¼ |
| | | this.topqueryParams.visitCount = null; |
| | | this.topqueryParams.pageNum = 1; |
| | | this.handleQuery(1); |
| | | return true; |
| | | }, |
| | | /** |
| | | * å¡çå£å¾çæä»½ç»ææ¥ï¼ |
| | | * 彿åªç»è®¡åºé¢æ»¡ 7 天çï¼æä»¥åãä»å¤© - 7 天ãï¼å岿份å彿æåä¸å¤© |
| | | */ |
| | | pendingTaskMonthEnd(month) { |
| | | const parts = String(month).split("-"); |
| | | const year = Number(parts[0]); |
| | | const mon = Number(parts[1]); |
| | | const now = new Date(); |
| | | let date; |
| | | if (year === now.getFullYear() && mon === now.getMonth() + 1) { |
| | | date = new Date(year, mon - 1, now.getDate() - 7); |
| | | } else { |
| | | date = new Date(year, mon, 0); |
| | | } |
| | | const mm = String(date.getMonth() + 1).padStart(2, "0"); |
| | | const dd = String(date.getDate()).padStart(2, "0"); |
| | | return date.getFullYear() + "-" + mm + "-" + dd; |
| | | }, |
| | | /** æç´¢æé®æä½ */ |
| | | handleQuery(refresh) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | |
| | | </li> |
| | | |
| | | <!-- ===== æå±ç
åº ===== --> |
| | | <li class="list-group-item" v-if="user.belongWards && user.belongWards.length"> |
| | | <li class="list-group-item" v-if="uniqueWards && uniqueWards.length"> |
| | | <svg-icon icon-class="tree" />æå±ç
åº |
| | | <div class="pull-right"> |
| | | <!-- ååéä¸ï¼å¯ç¼è¾æ¨¡å¼ --> |
| | |
| | | <!-- ååéä¸ï¼åªè¯»æ¨¡å¼ --> |
| | | <template v-else-if="isNanhua"> |
| | | <el-tag |
| | | v-for="ward in user.belongWards" |
| | | v-for="ward in uniqueWards" |
| | | :key="ward.districtId" |
| | | size="small" |
| | | class="ward-tag" |
| | |
| | | popper-class="ward-popover" |
| | | > |
| | | <div class="popover-content"> |
| | | <p v-for="ward in user.belongWards" :key="ward.districtId" class="popover-item"> |
| | | <p v-for="ward in uniqueWards" :key="ward.districtId" class="popover-item"> |
| | | {{ ward.districtName }} |
| | | </p> |
| | | </div> |
| | |
| | | class="ward-tag" |
| | | >{{ ward.districtName }}</el-tag> |
| | | <el-tag |
| | | v-if="user.belongWards.length > maxTagCount" |
| | | v-if="uniqueWards.length > maxTagCount" |
| | | size="small" |
| | | class="more-tag" |
| | | @click="showAllWardsPopover = !showAllWardsPopover" |
| | | >+{{ user.belongWards.length - maxTagCount }}</el-tag> |
| | | >+{{ uniqueWards.length - maxTagCount }}</el-tag> |
| | | </div> |
| | | </el-popover> |
| | | </template> |
| | |
| | | </li> |
| | | |
| | | <!-- ===== æå±ç§å®¤ ===== --> |
| | | <li class="list-group-item" v-if="user.belongDepts && user.belongDepts.length"> |
| | | <li class="list-group-item" v-if="uniqueDepts && uniqueDepts.length"> |
| | | <svg-icon icon-class="tree" />æå±ç§å®¤ |
| | | <div class="pull-right"> |
| | | <!-- ååéä¸ï¼å¯ç¼è¾æ¨¡å¼ --> |
| | |
| | | <!-- ååéä¸ï¼åªè¯»æ¨¡å¼ --> |
| | | <template v-else-if="isNanhua"> |
| | | <el-tag |
| | | v-for="dept in user.belongDepts" |
| | | v-for="dept in uniqueDepts" |
| | | :key="dept.deptId" |
| | | size="small" |
| | | class="dept-tag" |
| | |
| | | popper-class="dept-popover" |
| | | > |
| | | <div class="popover-content"> |
| | | <p v-for="dept in user.belongDepts" :key="dept.deptId" class="popover-item"> |
| | | <p v-for="dept in uniqueDepts" :key="dept.deptId" class="popover-item"> |
| | | {{ dept.deptName }} |
| | | </p> |
| | | </div> |
| | |
| | | class="dept-tag" |
| | | >{{ dept.deptName }}</el-tag> |
| | | <el-tag |
| | | v-if="user.belongDepts.length > maxTagCount" |
| | | v-if="uniqueDepts.length > maxTagCount" |
| | | size="small" |
| | | class="more-tag" |
| | | @click="showAllDeptsPopover = !showAllDeptsPopover" |
| | | >+{{ user.belongDepts.length - maxTagCount }}</el-tag> |
| | | >+{{ uniqueDepts.length - maxTagCount }}</el-tag> |
| | | </div> |
| | | </el-popover> |
| | | </template> |
| | |
| | | }; |
| | | }, |
| | | computed: { |
| | | // sys_user_dept éåä¸ç
åºå¯è½æå åæ¡éå¤è¡ï¼æ¥å£åæ ·è¿åï¼è¿éæç¼ç å»é |
| | | uniqueWards() { |
| | | return this.uniqueByCode(this.user.belongWards); |
| | | }, |
| | | uniqueDepts() { |
| | | return this.uniqueByCode(this.user.belongDepts); |
| | | }, |
| | | // 计ç®è¦æ¾ç¤ºçç
åºæ ç¾ï¼åmaxTagCountä¸ªï¼ |
| | | displayWards() { |
| | | if (!this.user.belongWards) return []; |
| | | return this.user.belongWards.slice(0, this.maxTagCount); |
| | | if (!this.uniqueWards) return []; |
| | | return this.uniqueWards.slice(0, this.maxTagCount); |
| | | }, |
| | | // 计ç®è¦æ¾ç¤ºçç§å®¤æ ç¾ï¼åmaxTagCountä¸ªï¼ |
| | | displayDepts() { |
| | | if (!this.user.belongDepts) return []; |
| | | return this.user.belongDepts.slice(0, this.maxTagCount); |
| | | if (!this.uniqueDepts) return []; |
| | | return this.uniqueDepts.slice(0, this.maxTagCount); |
| | | }, |
| | | // åå大å¦éå±ç¬¬ä¸å»é¢ å
许ç¼è¾ç§å®¤/ç
åº |
| | | isNanhua() { |
| | |
| | | } |
| | | }, |
| | | methods: { |
| | | // æç§å®¤/ç
åºç¼ç å»éï¼sys_user_dept åå¨éå¤è¡ï¼ |
| | | uniqueByCode(list) { |
| | | const seen = {}; |
| | | return (list || []).filter((item) => { |
| | | if (!item) return false; |
| | | const code = |
| | | item.districtCode || item.deptCode || item.districtId || item.deptId; |
| | | const key = String(code === undefined || code === null ? "" : code); |
| | | if (!key || seen[key]) return false; |
| | | seen[key] = true; |
| | | return true; |
| | | }); |
| | | }, |
| | | getUser() { |
| | | getUserProfile().then((response) => { |
| | | this.user = response.data; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import java.io.*; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.sql.*; |
| | | |
| | | public class Probe17 { |
| | | static final String URL = "jdbc:mysql://haiershi.a1.luyouxia.net:23844/smartor_sltd" |
| | | + "?useUnicode=true&characterEncoding=utf8&useSSL=false" |
| | | + "&serverTimezone=GMT%2B8&connectTimeout=15000&socketTimeout=90000"; |
| | | |
| | | public static void main(String[] args) throws Exception { |
| | | Class.forName("com.mysql.cj.jdbc.Driver"); |
| | | try (Connection c = DriverManager.getConnection(URL, "smartor", "Smartor.2023"); |
| | | PrintWriter out = new PrintWriter(new OutputStreamWriter( |
| | | new FileOutputStream("probe17.txt"), StandardCharsets.UTF_8))) { |
| | | run(c, out, "select config_key, config_value from sys_config where config_key='sys.authority.campus.all'"); |
| | | run(c, out, "select d.dept_code, d.dept_name, d.campusid, count(*) dup from sys_dept d " |
| | | + "inner join sys_user_dept ud on d.dept_code = ud.dept_code " |
| | | + "where d.del_flag=0 and ud.del_flag=0 and d.orgid='20001001' and ud.orgid='20001001' " |
| | | + "and ud.user_id=2609 and d.dept_type='2' group by d.dept_code, d.dept_name, d.campusid"); |
| | | run(c, out, "select d.dept_code, d.dept_name, d.campusid from sys_dept d " |
| | | + "inner join sys_user_dept ud on d.dept_code = ud.dept_code " |
| | | + "where d.del_flag=0 and ud.del_flag=0 and d.orgid='20001001' and ud.orgid='20001001' " |
| | | + "and d.campusid='30001002' and ud.user_id=2609 and d.dept_type='2' group by d.dept_code, d.dept_name, d.campusid"); |
| | | run(c, out, "select leavehospitaldistrictcode, leavehospitaldistrictname, count(*) cnt from service_subtask " |
| | | + "where del_flag='0' and service_type='2' and sendstate in (1,2,3,5,7) " |
| | | + "and endtime>='2026-10-01' and endtime<'2026-11-01' and endtime <= DATE_SUB(CURDATE(), INTERVAL 7 DAY) " |
| | | + "and leavehospitaldistrictcode in ('40003047','40003048') group by leavehospitaldistrictcode, leavehospitaldistrictname"); |
| | | out.flush(); |
| | | } |
| | | System.out.println("done"); |
| | | } |
| | | |
| | | static void run(Connection c, PrintWriter out, String sql) { |
| | | out.println("\n--- " + sql); |
| | | try (Statement st = c.createStatement(); ResultSet rs = st.executeQuery(sql)) { |
| | | ResultSetMetaData md = rs.getMetaData(); |
| | | int n = md.getColumnCount(); |
| | | StringBuilder head = new StringBuilder(); |
| | | for (int i = 1; i <= n; i++) head.append(md.getColumnLabel(i)).append(i == n ? "" : " | "); |
| | | out.println(head); |
| | | int rows = 0; |
| | | while (rs.next() && rows < 40) { |
| | | StringBuilder line = new StringBuilder(); |
| | | for (int i = 1; i <= n; i++) line.append(rs.getString(i)).append(i == n ? "" : " | "); |
| | | out.println(line); |
| | | rows++; |
| | | } |
| | | } catch (Exception e) { |
| | | out.println("SQL ERROR: " + e.getMessage()); |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import java.io.*; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.sql.*; |
| | | |
| | | public class Probe18 { |
| | | static final String URL = "jdbc:mysql://haiershi.a1.luyouxia.net:23844/smartor_sltd" |
| | | + "?useUnicode=true&characterEncoding=utf8&useSSL=false" |
| | | + "&serverTimezone=GMT%2B8&connectTimeout=15000&socketTimeout=90000"; |
| | | |
| | | public static void main(String[] args) throws Exception { |
| | | Class.forName("com.mysql.cj.jdbc.Driver"); |
| | | try (Connection c = DriverManager.getConnection(URL, "smartor", "Smartor.2023"); |
| | | PrintWriter out = new PrintWriter(new OutputStreamWriter( |
| | | new FileOutputStream("probe18.txt"), StandardCharsets.UTF_8))) { |
| | | String base = "from service_subtask where del_flag='0' and service_type='2' and sendstate in (1,2,3,5,7) " |
| | | + "and leavehospitaldistrictcode='40003047' and endtime>='2026-10-01' "; |
| | | run(c, out, "select " |
| | | + "(select count(*) " + base + "and endtime <= DATE_SUB(CURDATE(), INTERVAL 7 DAY)) old_cut, " |
| | | + "(select count(*) " + base + "and endtime < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL 7 DAY), INTERVAL 1 DAY)) new_cut, " |
| | | + "(select count(*) " + base + "and endtime >= '2026-10-21' and endtime < '2026-10-22') on_1021"); |
| | | run(c, out, "select DATE(endtime) d, count(*) cnt " + base + "and endtime < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL 7 DAY), INTERVAL 1 DAY) group by DATE(endtime) order by d desc limit 6"); |
| | | out.flush(); |
| | | } |
| | | System.out.println("done"); |
| | | } |
| | | |
| | | static void run(Connection c, PrintWriter out, String sql) { |
| | | out.println("\n--- " + sql); |
| | | try (Statement st = c.createStatement(); ResultSet rs = st.executeQuery(sql)) { |
| | | ResultSetMetaData md = rs.getMetaData(); |
| | | int n = md.getColumnCount(); |
| | | StringBuilder head = new StringBuilder(); |
| | | for (int i = 1; i <= n; i++) head.append(md.getColumnLabel(i)).append(i == n ? "" : " | "); |
| | | out.println(head); |
| | | int rows = 0; |
| | | while (rs.next() && rows < 20) { |
| | | StringBuilder line = new StringBuilder(); |
| | | for (int i = 1; i <= n; i++) line.append(rs.getString(i)).append(i == n ? "" : " | "); |
| | | out.println(line); |
| | | rows++; |
| | | } |
| | | } catch (Exception e) { |
| | | out.println("SQL ERROR: " + e.getMessage()); |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | |
| | | --- select config_key, config_value from sys_config where config_key='sys.authority.campus.all' |
| | | config_key | config_value |
| | | |
| | | --- select d.dept_code, d.dept_name, d.campusid, count(*) dup from sys_dept d inner join sys_user_dept ud on d.dept_code = ud.dept_code where d.del_flag=0 and ud.del_flag=0 and d.orgid='20001001' and ud.orgid='20001001' and ud.user_id=2609 and d.dept_type='2' group by d.dept_code, d.dept_name, d.campusid |
| | | dept_code | dept_name | campusid | dup |
| | | 40003047 | 2-6ä¸ç
åºï¼éª¨ä¼¤ä¸å¿ä¸ï¼ | 30001002 | 40 |
| | | |
| | | --- select d.dept_code, d.dept_name, d.campusid from sys_dept d inner join sys_user_dept ud on d.dept_code = ud.dept_code where d.del_flag=0 and ud.del_flag=0 and d.orgid='20001001' and ud.orgid='20001001' and d.campusid='30001002' and ud.user_id=2609 and d.dept_type='2' group by d.dept_code, d.dept_name, d.campusid |
| | | dept_code | dept_name | campusid |
| | | 40003047 | 2-6ä¸ç
åºï¼éª¨ä¼¤ä¸å¿ä¸ï¼ | 30001002 |
| | | |
| | | --- select leavehospitaldistrictcode, leavehospitaldistrictname, count(*) cnt from service_subtask where del_flag='0' and service_type='2' and sendstate in (1,2,3,5,7) and endtime>='2026-10-01' and endtime<'2026-11-01' and endtime <= DATE_SUB(CURDATE(), INTERVAL 7 DAY) and leavehospitaldistrictcode in ('40003047','40003048') group by leavehospitaldistrictcode, leavehospitaldistrictname |
| | | leavehospitaldistrictcode | leavehospitaldistrictname | cnt |
| | | 40003047 | 2-6ä¸ç
åºï¼éª¨ä¼¤ä¸å¿ä¸ï¼ | 90 |
| | | 40003048 | 2-6西ç
åºï¼éª¨ä¼¤ä¸å¿äºï¼ | 25 |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | |
| | | --- select (select count(*) from service_subtask where del_flag='0' and service_type='2' and sendstate in (1,2,3,5,7) and leavehospitaldistrictcode='40003047' and endtime>='2026-10-01' and endtime <= DATE_SUB(CURDATE(), INTERVAL 7 DAY)) old_cut, (select count(*) from service_subtask where del_flag='0' and service_type='2' and sendstate in (1,2,3,5,7) and leavehospitaldistrictcode='40003047' and endtime>='2026-10-01' and endtime < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL 7 DAY), INTERVAL 1 DAY)) new_cut, (select count(*) from service_subtask where del_flag='0' and service_type='2' and sendstate in (1,2,3,5,7) and leavehospitaldistrictcode='40003047' and endtime>='2026-10-01' and endtime >= '2026-10-21' and endtime < '2026-10-22') on_1021 |
| | | old_cut | new_cut | on_1021 |
| | | 90 | 99 | 9 |
| | | |
| | | --- select DATE(endtime) d, count(*) cnt from service_subtask where del_flag='0' and service_type='2' and sendstate in (1,2,3,5,7) and leavehospitaldistrictcode='40003047' and endtime>='2026-10-01' and endtime < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL 7 DAY), INTERVAL 1 DAY) group by DATE(endtime) order by d desc limit 6 |
| | | d | cnt |
| | | 2026-10-21 | 9 |
| | | 2026-10-20 | 7 |
| | | 2026-10-19 | 10 |
| | | 2026-10-18 | 2 |
| | | 2026-10-17 | 3 |
| | | 2026-10-16 | 6 |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import java.io.*; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.sql.*; |
| | | |
| | | public class Probe42 { |
| | | static final String URL = "jdbc:mysql://haiershi.a1.luyouxia.net:23844/smartor_sltd" |
| | | + "?useUnicode=true&characterEncoding=utf8&useSSL=false" |
| | | + "&serverTimezone=GMT%2B8&connectTimeout=15000&socketTimeout=90000"; |
| | | |
| | | public static void main(String[] args) throws Exception { |
| | | Class.forName("com.mysql.cj.jdbc.Driver"); |
| | | try (Connection c = DriverManager.getConnection(URL, "smartor", "Smartor.2023"); |
| | | PrintWriter out = new PrintWriter(new OutputStreamWriter( |
| | | new FileOutputStream("probe42.txt"), StandardCharsets.UTF_8))) { |
| | | String base = "from service_subtask where del_flag='0' and endtime >= '2026-10-01' and endtime < '2026-10-31' and leavehospitaldistrictcode='40003047' "; |
| | | run(c, out, "select count(*) db_total " + base); |
| | | run(c, out, "select service_type, visit_count, count(*) cnt " + base + "group by service_type, visit_count order by service_type, visit_count"); |
| | | run(c, out, "select count(*) page_like " + base + "and service_type='2' and visit_count=1"); |
| | | run(c, out, "select count(*) page_like_no_vc " + base + "and service_type='2'"); |
| | | run(c, out, "select count(*) all_status " + base + "and service_type='2' and visit_count=1 and sendstate in (1,2,3,4,5,6,7)"); |
| | | out.flush(); |
| | | } |
| | | System.out.println("done"); |
| | | } |
| | | |
| | | static void run(Connection c, PrintWriter out, String sql) { |
| | | out.println("\n--- " + sql); |
| | | try (Statement st = c.createStatement(); ResultSet rs = st.executeQuery(sql)) { |
| | | ResultSetMetaData md = rs.getMetaData(); |
| | | int n = md.getColumnCount(); |
| | | StringBuilder head = new StringBuilder(); |
| | | for (int i = 1; i <= n; i++) head.append(md.getColumnLabel(i)).append(i == n ? "" : " | "); |
| | | out.println(head); |
| | | int rows = 0; |
| | | while (rs.next() && rows < 20) { |
| | | StringBuilder line = new StringBuilder(); |
| | | for (int i = 1; i <= n; i++) line.append(rs.getString(i)).append(i == n ? "" : " | "); |
| | | out.println(line); |
| | | rows++; |
| | | } |
| | | } catch (Exception e) { |
| | | out.println("SQL ERROR: " + e.getMessage()); |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | |
| | | --- select count(*) db_total from service_subtask where del_flag='0' and endtime >= '2026-10-01' and endtime < '2026-10-31' and leavehospitaldistrictcode='40003047' |
| | | db_total |
| | | 119 |
| | | |
| | | --- select service_type, visit_count, count(*) cnt from service_subtask where del_flag='0' and endtime >= '2026-10-01' and endtime < '2026-10-31' and leavehospitaldistrictcode='40003047' group by service_type, visit_count order by service_type, visit_count |
| | | service_type | visit_count | cnt |
| | | 2 | 1 | 110 |
| | | 4 | 1 | 9 |
| | | |
| | | --- select count(*) page_like from service_subtask where del_flag='0' and endtime >= '2026-10-01' and endtime < '2026-10-31' and leavehospitaldistrictcode='40003047' and service_type='2' and visit_count=1 |
| | | page_like |
| | | 110 |
| | | |
| | | --- select count(*) page_like_no_vc from service_subtask where del_flag='0' and endtime >= '2026-10-01' and endtime < '2026-10-31' and leavehospitaldistrictcode='40003047' and service_type='2' |
| | | page_like_no_vc |
| | | 110 |
| | | |
| | | --- select count(*) all_status from service_subtask where del_flag='0' and endtime >= '2026-10-01' and endtime < '2026-10-31' and leavehospitaldistrictcode='40003047' and service_type='2' and visit_count=1 and sendstate in (1,2,3,4,5,6,7) |
| | | all_status |
| | | 110 |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import java.io.*; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.sql.*; |
| | | |
| | | public class Probe41 { |
| | | static final String URL = "jdbc:mysql://haiershi.a1.luyouxia.net:23844/smartor_sltd" |
| | | + "?useUnicode=true&characterEncoding=utf8&useSSL=false" |
| | | + "&serverTimezone=GMT%2B8&connectTimeout=15000&socketTimeout=90000"; |
| | | |
| | | public static void main(String[] args) throws Exception { |
| | | Class.forName("com.mysql.cj.jdbc.Driver"); |
| | | try (Connection c = DriverManager.getConnection(URL, "smartor", "Smartor.2023"); |
| | | PrintWriter out = new PrintWriter(new OutputStreamWriter( |
| | | new FileOutputStream("probe41.txt"), StandardCharsets.UTF_8))) { |
| | | run(c, out, "select d.questiontext, sum(case when d.asrtext is null or trim(d.asrtext)='' then 1 else 0 end) blank, count(*) total " |
| | | + "from service_subtask s join service_subtask_detail d on d.sub_id=s.id " |
| | | + "where s.del_flag='0' and d.del_flag='0' and s.service_type in ('6','14') and s.sendstate=6 " |
| | | + "and s.finishtime >= '2026-07-29' and s.finishtime < '2026-10-29' " |
| | | + "and d.id = (select max(d2.id) from service_subtask_detail d2 where d2.sub_id=d.sub_id and d2.questiontext <=> d.questiontext and d2.del_flag='0') " |
| | | + "group by d.questiontext order by blank desc"); |
| | | out.flush(); |
| | | } |
| | | System.out.println("done"); |
| | | } |
| | | |
| | | static void run(Connection c, PrintWriter out, String sql) { |
| | | out.println("\n--- " + sql); |
| | | try (Statement st = c.createStatement(); ResultSet rs = st.executeQuery(sql)) { |
| | | ResultSetMetaData md = rs.getMetaData(); |
| | | int n = md.getColumnCount(); |
| | | StringBuilder head = new StringBuilder(); |
| | | for (int i = 1; i <= n; i++) head.append(md.getColumnLabel(i)).append(i == n ? "" : " | "); |
| | | out.println(head); |
| | | int rows = 0; |
| | | while (rs.next() && rows < 30) { |
| | | StringBuilder line = new StringBuilder(); |
| | | for (int i = 1; i <= n; i++) line.append(rs.getString(i)).append(i == n ? "" : " | "); |
| | | out.println(line); |
| | | rows++; |
| | | } |
| | | } catch (Exception e) { |
| | | out.println("SQL ERROR: " + e.getMessage()); |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | |
| | | --- select d.questiontext, sum(case when d.asrtext is null or trim(d.asrtext)='' then 1 else 0 end) blank, count(*) total from service_subtask s join service_subtask_detail d on d.sub_id=s.id where s.del_flag='0' and d.del_flag='0' and s.service_type in ('6','14') and s.sendstate=6 and s.finishtime >= '2026-07-29' and s.finishtime < '2026-10-29' and d.id = (select max(d2.id) from service_subtask_detail d2 where d2.sub_id=d.sub_id and d2.questiontext <=> d.questiontext and d2.del_flag='0') group by d.questiontext order by blank desc |
| | | questiontext | blank | total |
| | | 请æ¨çä¸å®è´µçæè§/建议 | 6 | 25 |
| | | æ¨å¯¹æé¢æè¯æ»¡å¤çæ»¡ä¸æ»¡æï¼ | 1 | 8 |
| | | çªå£/åå¤/ä¿å®äººåæå¡ | 0 | 17 |
| | | æ¨å¯¹æé¢ç¥æ
åç¥æ»¡ä¸æ»¡æï¼ | 0 | 8 |
| | | æ¨å¯¹ä¾¿æ°æå¡æ¯å¦æ»¡æ | 0 | 17 |
| | | æ¨å¯¹æé¢æå¡æçæ»¡ä¸æ»¡æï¼ | 0 | 8 |
| | | æç¤ºçã导å»çæ¸
æ¥ç¨åº¦ | 0 | 17 |
| | | æ¨å¯¹æé¢ä¼é£æ
嵿»¡ä¸æ»¡æï¼ | 0 | 8 |
| | | é¨è¯ç¯å¢å«ç/声é³(åæãç¯å¢å«çãåªé³ç) | 0 | 17 |
| | | æ¨å¯¹æé¢æ´ä½ç¯å¢æ»¡ä¸æ»¡æï¼ | 0 | 8 |
| | | æå·é¢çº¦/ä¸å®¶ä¿¡æ¯è·å | 0 | 17 |
| | | çç
æé´ï¼æ¨çæ±æ¨å䏿»¡è½å¦åæ¶å¾å°ååºï¼ | 0 | 17 |
| | | æå·/å°±è¯/æ£éª/æ£æ¥çç¯èçåæ¶é´ | 0 | 17 |
| | | æ»ä½æ»¡æåº¦ | 0 | 17 |
| | | æ¨æ¯å¦åäº²åæ¨èè¿å®¶å»é¢ | 0 | 8 |
| | | æ¨å¯¹å»æ¤è¯çè¿ç¨æ¯å¦æ»¡æ*(çè¯æ¶é´/å¥åº·å®£æ/æå«ç/éç§ä¿æ¤) | 0 | 17 |
| | | æ¨æ¯å¦ä¼åäº²åæ¨èè¿å®¶å»é¢ | 0 | 17 |
| | | å»çæå¡ |
| | | | 0 | 17 |
| | | æ¤å£«æå¡ | 0 | 17 |
| | | æ¨å¯¹æé¢å·¥ä½äººåçæå¡è´¨éæ»¡ä¸æ»¡æï¼ | 0 | 8 |
| | | æ£æ¥äººåæå¡ï¼Bè¶
/å¿çµå¾/CT/ç£å
±æ¯/X线/å
éçï¼ | 0 | 17 |
| | | æ¨å¯¹æé¢å·¥ä½äººåçæå¡æåº¦æ»¡ä¸æ»¡æï¼ | 0 | 8 |
| | | è¯æ¿äººåæå¡ | 0 | 17 |
| | | æ¨å¯¹æé¢éç§ä¿æ¤æ»¡ä¸æ»¡æï¼ | 0 | 8 |