已删除4个文件
已重命名1个文件
已修改35个文件
已添加9个文件
| | |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | |
| | | // å项æå¡æ»¡æåº¦æ°æ®ç»è®¡ |
| | | export function sltdMydTotalByScore(data) { |
| | | return request({ |
| | | url: "/smartor/serviceSubtaskDetail/sltdMydTotalByScore", |
| | | method: "post", |
| | | data: data |
| | | }); |
| | | } |
| | | // å项æå¡æ»¡æåº¦æ°æ®ç»è®¡ |
| | | export function mzMydScoreRank(data) { |
| | | return request({ |
| | | url: "/smartor/serviceSubtaskDetail/mzMydScoreRank", |
| | | method: "post", |
| | | data: data |
| | | }); |
| | | } |
| | | // åç§å®¤/ç
åºæ»¡æåº¦è¯åå¯¹æ¯ |
| | | export function statQuestionOptionByKsOrBq(data) { |
| | | return request({ |
| | | url: "/smartor/serviceSubtaskDetail/statQuestionOptionByKsOrBq", |
| | | method: "post", |
| | | data: data |
| | | }); |
| | | } |
| | | // è¯åè¶å¿ |
| | | export function mydTrend(data) { |
| | | return request({ |
| | | url: "/smartor/serviceSubtaskDetail/mydTrend", |
| | | method: "post", |
| | | data: data |
| | | }); |
| | | } |
| | | // çç«åå¾·æ£è
满æåº¦ç»´æ¤ï¼æç»´åº¦/é¢åºç»è®¡ï¼ |
| | | export function sltdMydTotalByDimension(data) { |
| | | return request({ |
| | | url: "/smartor/serviceSubtaskDetail/sltdMydTotalByDimension", |
| | | method: "post", |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // ç¼åé®å· |
| | | export function saveMYDQuestionAnswer(data) { |
| | |
| | | <span class="filter-label">åºé´ç±»åï¼</span> |
| | | <el-radio-group v-model="queryParams.interval" size="small" @change="refreshAll"> |
| | | <el-radio-button label="day">æå¤©</el-radio-button> |
| | | <el-radio-button label="week">æå¨</el-radio-button> |
| | | <el-radio-button label="month">ææ</el-radio-button> |
| | | <el-radio-button label="year">æå¹´</el-radio-button> |
| | | </el-radio-group> |
| | | <span class="filter-label">ç»è®¡ç»´åº¦ï¼</span> |
| | | <el-radio-group v-model="queryParams.dimension" size="small" @change="onDimensionChange"> |
| | | <el-radio-button label="ward">æç
åºç»è®¡</el-radio-button> |
| | | <el-radio-button label="dept">æç§å®¤ç»è®¡</el-radio-button> |
| | | </el-radio-group> |
| | | <el-button type="primary" size="small" icon="el-icon-search" @click="refreshAll">æ¥è¯¢</el-button> |
| | | <el-button size="small" icon="el-icon-refresh" @click="handleReset">éç½®</el-button> |
| | |
| | | <el-col :span="12"> |
| | | <el-card shadow="never" class="chart-card"> |
| | | <div slot="header" class="card-header"> |
| | | <span>æ¶é´ç»´åº¦ · é¨è¯æ£è
满æåº¦è¶å¿</span> |
| | | <span>æ£è
满æåº¦ç»¼åå¾åè¶å¿</span> |
| | | <el-tag type="success" size="small">ç¯æ¯ {{ trendMoM }}</el-tag> |
| | | </div> |
| | | <div class="chart-wrap" v-loading="trendLoading" element-loading-text="è¶å¿å è½½ä¸..."> |
| | | <div ref="chart1" class="chart-box"></div> |
| | | <div v-if="!trendLoading && !trend.buckets.length" class="chart-empty">ææ è¶å¿æ°æ®</div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | |
| | | <div slot="header" class="card-header"> |
| | | <span>å类维度 · åææ {{ intervalLabel }}对æ¯</span> |
| | | </div> |
| | | <div class="chart-wrap" v-loading="categoryLoading" element-loading-text="å类维度å è½½ä¸..."> |
| | | <div ref="chart2" class="chart-box"></div> |
| | | <div v-if="!categoryLoading && !categoryCompare.categories.length" class="chart-empty">ææ åç±»ç»´åº¦æ°æ®</div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | <div slot="header" class="card-header"> |
| | | <span>åé¢ Â· é项ç»è®¡</span> |
| | | <div class="header-right"> |
| | | <el-select v-model="singleQuestionId" size="small" class="sel sel-lg" @change="refreshAll"> |
| | | <el-option v-for="q in questionOptions" :key="q.id" :label="q.title" :value="q.id" /> |
| | | <el-select v-model="singleQuestionId" size="small" class="sel sel-lg" filterable remote clearable |
| | | :remote-method="searchQuestions" :loading="questionLoading" placeholder="请è¾å
¥é®é¢å
容æç´¢" @change="onSingleQuestionChange"> |
| | | <el-option v-for="q in questionOptions" :key="q.id" :label="q.scriptContent || q.title" :value="q.id" /> |
| | | </el-select> |
| | | <el-select v-model="singleDeptWards" multiple collapse-tags size="small" class="sel" clearable filterable placeholder="å
¨é¨ç§å®¤/ç
åº" @change="refreshAll"> |
| | | <el-option-group label="ç§å®¤"> |
| | | <el-select v-model="singleDeptWards" multiple collapse-tags size="small" class="sel" clearable filterable :placeholder="queryParams.dimension === 'dept' ? 'å
¨é¨ç§å®¤' : 'å
¨é¨ç
åº'" @change="refreshAll"> |
| | | <template v-if="queryParams.dimension === 'dept'"> |
| | | <el-option v-for="d in deptOptions" :key="'dept:' + d" :label="d" :value="'dept:' + d" /> |
| | | </el-option-group> |
| | | <el-option-group label="ç
åº"> |
| | | </template> |
| | | <template v-else> |
| | | <el-option v-for="w in wardOptions" :key="'ward:' + w" :label="w" :value="'ward:' + w" /> |
| | | </el-option-group> |
| | | </template> |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | | <el-table :data="singleQuestionData" border size="small"> |
| | | <el-table :data="singleQuestionData" border size="small" v-loading="singleLoading" element-loading-text="é项ç»è®¡å è½½ä¸..."> |
| | | <el-table-column prop="option" label="é项" /> |
| | | <el-table-column prop="count" label="å计æ°é" width="120" align="center" /> |
| | | <el-table-column prop="rate" label="å æ¯æ¯ä¾" width="120" align="center" /> |
| | | </el-table> |
| | | <div class="table-footer">æ¬é¢ææå¡«å人次ï¼<b>{{ singleQuestionMeta.total }}</b>ãç»¼åæ»¡æåº¦ï¼<b>{{ singleQuestionMeta.score }}</b></div> |
| | | <div class="table-footer">æ¬é¢ææå¡«å人次ï¼<b>{{ singleQuestionMeta.total }}</b>ã综åå¾åï¼<b>{{ singleQuestionMeta.score }}</b></div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | |
| | | <div slot="header" class="card-header"> |
| | | <span>é¢åºç»´åº¦ · åé¢åº{{ intervalLabel }}对æ¯</span> |
| | | </div> |
| | | <div class="chart-wrap" v-loading="hospitalLoading" element-loading-text="é¢åºç»´åº¦å è½½ä¸..."> |
| | | <div ref="chart4" class="chart-box"></div> |
| | | <div v-if="!hospitalLoading && !hospitalCompare.hospitals.length" class="chart-empty">ææ é¢åºç»´åº¦æ°æ®</div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | | <el-table :data="rankRows" border size="small" max-height="400"> |
| | | <el-table-column type="index" label="æå" width="60" align="center" /> |
| | | <el-table :data="rankRows" border size="small" max-height="400" v-loading="rankLoading" element-loading-text="æåå è½½ä¸..."> |
| | | <el-table-column prop="rank" label="æå" width="60" align="center" /> |
| | | <el-table-column prop="name" :label="rankDimLabel" /> |
| | | <el-table-column prop="score" label="综åå¾å" width="120" align="center" /> |
| | | <el-table-column prop="itemCount" label="项æ°" width="100" align="center" /> |
| | | </el-table> |
| | | </el-card> |
| | | </el-col> |
| | |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | | <el-table :data="crossRows" border size="small" max-height="400"> |
| | | <el-table-column type="index" label="æå" width="60" align="center" /> |
| | | <el-table :data="crossRows" border size="small" max-height="400" v-loading="crossLoading" element-loading-text="æåå è½½ä¸..."> |
| | | <el-table-column prop="rank" label="æå" width="60" align="center" /> |
| | | <el-table-column prop="name" :label="crossDimLabel" /> |
| | | <el-table-column prop="score" label="综åå¾å" width="120" align="center" /> |
| | | <el-table-column prop="itemCount" label="项æ°" width="100" align="center" /> |
| | | </el-table> |
| | | </el-card> |
| | | </el-col> |
| | |
| | | |
| | | <script> |
| | | import * as echarts from 'echarts'; |
| | | import { mydTrend, sltdMydTotalByDimension, sltdMydTotalByScore ,mzMydScoreRank} from "@/api/AiCentre/satisfaction"; |
| | | import { getissuelist } from "@/api/AiCentre/questionnaire"; |
| | | |
| | | // åé¢é项 |
| | | const QUESTION_OPTIONS = ['é常满æ', '满æ', 'ä¸è¬', '䏿»¡æ']; |
| | | // å¯éé¢ç® |
| | | const QUESTIONS = [ |
| | | { id: 22, title: '第22é¢ï¼æ±æ¨å䏿»¡è½å¦åæ¶å¾å°ååºï¼' }, |
| | | { id: 1, title: '第1é¢ï¼æ¨å¯¹æé¢å·¥ä½äººåçæå¡è´¨é满æä¸æ»¡æï¼' }, |
| | | { id: 5, title: '第5é¢ï¼æ¨å¯¹å»é¢æå¡è®¾æ½çæ»ä½å°è±¡å¦ä½ï¼' }, |
| | | { id: 8, title: '第8é¢ï¼å»çå¯¹æ¨æ¯å¦å°éï¼' }, |
| | | { id: 12, title: '第12é¢ï¼æ¤å£«å¯¹æ¨æ¯å¦å°éï¼' }, |
| | | { id: 15, title: '第15é¢ï¼æ¨å¯¹é¢çº¦æå·æ¯å¦æ»¡æï¼' }, |
| | | ]; |
| | | const DEPTS = ['ä¿å¥ç§', 'ä»å
¥æ²»çç§', 'ä¸ç§æ¤å£«é¨è¯', '康å¤å»å¦ç§', 'ç®è¤ç§', 'å
åæ³ç§', 'æ¶åå
ç§', 'è¾å
ç§', 'å¼å¸å
ç§', 'å¿è¡ç®¡å
ç§', 'ç¥ç»å
ç§', 'è¡æ¶²ç§', '飿¹¿å
ç«ç§', 'è¿ç¤å
ç§', 'ææç§', 'èå¹´ç§', 'æ®å¤ç§', '骨ç§', 'æ³å°¿å¤ç§', 'å¦äº§ç§']; |
| | | const WARDS = ['ä¸ç
åº', 'äºç
åº', 'ä¸ç
åº', 'åç
åº', 'äºç
åº', 'å
ç
åº', 'ä¸ç
åº', 'å
«ç
åº']; |
| | | |
| | | // ç¡®å®æ§ä¼ªéæº |
| | | function hashString(str) { |
| | | let h = 2166136261; |
| | | for (let i = 0; i < str.length; i++) { |
| | | h ^= str.charCodeAt(i); |
| | | h = Math.imul(h, 16777619); |
| | | } |
| | | return h >>> 0; |
| | | } |
| | | function mulberry32(a) { |
| | | return function () { |
| | | a |= 0; |
| | | a = (a + 0x6d2b79f5) | 0; |
| | | let t = Math.imul(a ^ (a >>> 15), 1 | a); |
| | | t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; |
| | | return ((t ^ (t >>> 14)) >>> 0) / 4294967296; |
| | | }; |
| | | } |
| | | |
| | | export default { |
| | | name: 'ChartsPanel', |
| | | dicts: ['dimensionality_type'], |
| | | data() { |
| | | return { |
| | | queryParams: { |
| | | dateRange: [], |
| | | interval: 'month', |
| | | dimension: 'ward', // ç»è®¡ç»´åº¦ï¼ward=æç
åºç»è®¡ dept=æç§å®¤ç»è®¡ |
| | | }, |
| | | deptOptions: DEPTS, |
| | | wardOptions: WARDS, |
| | | questionOptions: QUESTIONS, |
| | | questionOptions: [], |
| | | |
| | | // åé¢çé |
| | | singleQuestionId: 22, |
| | | singleQuestionId: null, |
| | | singleQuestionContent: '', |
| | | singleDeptWards: [], |
| | | |
| | | // æå维度çé |
| | |
| | | crossDeptWards: [], |
| | | |
| | | // å¾è¡¨æ°æ® |
| | | trendLoading: false, |
| | | categoryLoading: false, |
| | | hospitalLoading: false, |
| | | trend: { buckets: [], data: [], seriesName: 'é¨è¯æ£è
满æåº¦' }, |
| | | categoryCompare: { categories: [], seriesNames: [], series1: [], series2: [] }, |
| | | hospitalCompare: { hospitals: [], seriesNames: [], series1: [], series2: [] }, |
| | | |
| | | // åé¢ / æå / 交å表å è½½ç¶æ |
| | | singleLoading: false, |
| | | questionLoading: false, |
| | | rankLoading: false, |
| | | crossLoading: false, |
| | | |
| | | // è¡¨æ ¼æ°æ® |
| | | singleQuestionData: [], |
| | | singleQuestionMeta: { total: '0', score: '0.00%' }, |
| | | deptRankData: [], |
| | | wardRankData: [], |
| | | crossDeptData: [], |
| | | crossWardData: [], |
| | | singleQuestionMeta: { total: '0', score: '0.00' }, |
| | | rankData: [], |
| | | crossData: [], |
| | | }; |
| | | }, |
| | | computed: { |
| | | // ç§å®¤/ç
åºç¼ç ï¼ä¼å
åå½åç¨æ·æå±ï¼æ åå
åºåç§°æ¬èº«ä½ä¸ºç¼ç |
| | | deptCodeList() { |
| | | const list = this.$store.getters.belongDepts || []; |
| | | return list.length ? list : DEPTS.map((d) => ({ deptName: d, deptCode: d })); |
| | | }, |
| | | wardCodeList() { |
| | | const list = this.$store.getters.belongWards || []; |
| | | return list.length ? list : WARDS.map((w) => ({ districtName: w, districtCode: w })); |
| | | }, |
| | | defaultDeptCodes() { |
| | | return Array.from(new Set(this.deptCodeList.map((d) => d.deptCode))); |
| | | }, |
| | | defaultWardCodes() { |
| | | return Array.from(new Set(this.wardCodeList.map((w) => w.districtCode))); |
| | | }, |
| | | intervalLabel() { |
| | | return { day: 'æå¤©', month: 'ææ', year: 'æå¹´' }[this.queryParams.interval] || 'ææ'; |
| | | return { day: 'æå¤©', week: 'æå¨', month: 'ææ', year: 'æå¹´' }[this.queryParams.interval] || 'ææ'; |
| | | }, |
| | | trendMoM() { |
| | | const d = this.trend.data; |
| | |
| | | return this.crossDimension === 'dept' ? this.deptOptions : this.wardOptions; |
| | | }, |
| | | rankRows() { |
| | | const list = this.rankDimension === 'dept' ? this.deptRankData : this.wardRankData; |
| | | if (!this.rankDeptWards.length) return list; |
| | | return list.filter((r) => this.rankDeptWards.includes(r.name)); |
| | | return this.rankData; |
| | | }, |
| | | crossRows() { |
| | | const list = this.crossDimension === 'dept' ? this.crossDeptData : this.crossWardData; |
| | | if (!this.crossDeptWards.length) return list; |
| | | return list.filter((r) => this.crossDeptWards.includes(r.name)); |
| | | return this.crossData; |
| | | }, |
| | | }, |
| | | mounted() { |
| | |
| | | this.queryParams.dateRange = this.defaultRange(); |
| | | } |
| | | this.initCharts(); |
| | | // åå§å峿¾ç¤ºåæ°æ®åçå è½½ç¶æï¼é¿å
å
éªç°âææ æ°æ®â |
| | | this.trendLoading = true; |
| | | this.categoryLoading = true; |
| | | this.hospitalLoading = true; |
| | | this.singleLoading = true; |
| | | this.rankLoading = true; |
| | | this.crossLoading = true; |
| | | // æ°æ®åä¸é¢ç®å表并è¡å è½½ï¼æ°æ®åä¸ä¾èµé¢ç®åè¡¨ï¼æ é串è¡çå¾
|
| | | this.refreshAll(); |
| | | this.loadQuestions('').then(() => { |
| | | if (this.singleQuestionContent) { |
| | | // åé¢é项ç»è®¡ / åé¢äº¤åæåä¾èµé®é¢ææ¬ï¼é¢ç®å è½½å®æåè¡¥æä¸æ¬¡ |
| | | this.fetchSingleQuestion(); |
| | | this.fetchCross(); |
| | | } else { |
| | | // é¢ç®å表为空æå 载失败ï¼ç»æåé¢ç¸å
³å è½½ç¶æ |
| | | this.singleLoading = false; |
| | | this.crossLoading = false; |
| | | } |
| | | }); |
| | | }); |
| | | }, |
| | | methods: { |
| | |
| | | if (c) c.resize(); |
| | | }); |
| | | }, |
| | | // 维度ç¼ç â åå
¸åç§°ï¼dimensionality_typeï¼ |
| | | getDimensionLabel(code) { |
| | | const dict = this.dict && this.dict.type && this.dict.type.dimensionality_type; |
| | | if (dict) { |
| | | const hit = dict.find((item) => String(item.value) === String(code)); |
| | | if (hit) return hit.label; |
| | | } |
| | | return code == null ? '' : String(code); |
| | | }, |
| | | // å¯éé¢ç®ï¼è¿ç¨æ¨¡ç³æç´¢ï¼æé®é¢å
容 scriptContentï¼ |
| | | searchQuestions(keyword) { |
| | | this.loadQuestions(keyword || ''); |
| | | }, |
| | | // å è½½å¯éé¢ç®ï¼åèé®é¢å表页 getissuelistï¼ |
| | | async loadQuestions(keyword) { |
| | | this.questionLoading = true; |
| | | try { |
| | | const res = await getissuelist({ |
| | | pageNum: 1, |
| | | pageSize: 50, |
| | | isavailable: '', |
| | | scriptContent: keyword || '', |
| | | }); |
| | | const rows = (res && res.rows) || []; |
| | | this.questionOptions = rows.map((q) => ({ |
| | | id: q.id, |
| | | scriptContent: q.scriptContent || q.title || '', |
| | | })); |
| | | // æ å
³é®åæ¶é»è®¤éä¸ç¬¬ä¸é¢ |
| | | if (!keyword && this.questionOptions.length && !this.singleQuestionContent) { |
| | | const first = this.questionOptions[0]; |
| | | this.singleQuestionId = first.id; |
| | | this.singleQuestionContent = first.scriptContent; |
| | | } |
| | | } catch (e) { |
| | | this.questionOptions = []; |
| | | } finally { |
| | | this.questionLoading = false; |
| | | } |
| | | }, |
| | | onSingleQuestionChange(val) { |
| | | const q = this.questionOptions.find((o) => String(o.id) === String(val)); |
| | | this.singleQuestionContent = q ? q.scriptContent : ''; |
| | | this.refreshAll(); |
| | | }, |
| | | // ç§å®¤/ç
åºåç§° â ç¼ç |
| | | mapDeptNames(names) { |
| | | return names.map((n) => { |
| | | const hit = this.deptCodeList.find((d) => d.deptName === n); |
| | | return hit ? hit.deptCode : n; |
| | | }); |
| | | }, |
| | | mapWardNames(names) { |
| | | return names.map((n) => { |
| | | const hit = this.wardCodeList.find((w) => w.districtName === n); |
| | | return hit ? hit.districtCode : n; |
| | | }); |
| | | }, |
| | | // 综åå¾åï¼çå®å£å¾ï¼ï¼Î£(é项åå¼ Ã å¡«æ¥é) / Σ(å¡«æ¥é) |
| | | scoreOfOptions(options) { |
| | | let num = 0; |
| | | let den = 0; |
| | | (options || []).forEach((o) => { |
| | | const c = Number(o && o.count) || 0; |
| | | const s = Number(o && o.score); |
| | | if (isNaN(s)) return; |
| | | num += s * c; |
| | | den += c; |
| | | }); |
| | | if (!den) return '0.00'; |
| | | return (num / den).toFixed(2); |
| | | }, |
| | | // è§£ææ¯ä¾å符串ï¼"14.29%"ã"0"ã"0.5" â æ°å¼ï¼ç¾åæ¯ï¼ï¼æ æè¿å null |
| | | parsePercent(value) { |
| | | if (value == null || value === '') return null; |
| | | const n = Number(String(value).replace(/%/g, '').trim()); |
| | | return isNaN(n) ? null : n; |
| | | }, |
| | | // åé¢è¿å List<QuestionResultDTO> â { options, total } |
| | | normalizeSingleQuestion(list) { |
| | | const arr = Array.isArray(list) ? list : (list && (list.list || list.rows)) || []; |
| | | const options = []; |
| | | let total = 0; |
| | | arr.forEach((item) => { |
| | | const details = Array.isArray(item && item.subtaskDetailRatioExportList) |
| | | ? item.subtaskDetailRatioExportList |
| | | : []; |
| | | details.forEach((d) => { |
| | | const option = (d && (d.optionresult || d.targetvalue || d.optioncontent || d.questiontext)) || ''; |
| | | const count = Number(d && d.count) || 0; |
| | | const rawScore = Number(d && d.score); |
| | | const ratio = this.parsePercent(d && d.ratio); |
| | | options.push({ option, count, score: isNaN(rawScore) ? null : rawScore, ratio }); |
| | | total += count; |
| | | }); |
| | | }); |
| | | return { options, total }; |
| | | }, |
| | | // åé¢é项ç»è®¡ï¼ç宿¥å£ /smartor/serviceSubtaskDetail/sltdMydTotalByScoreï¼ |
| | | async fetchSingleQuestion() { |
| | | const range = this.queryParams.dateRange || []; |
| | | if (range.length !== 2 || !range[0] || !range[1] || !this.singleQuestionContent) { |
| | | this.singleQuestionData = []; |
| | | this.singleQuestionMeta = { total: '0', score: '0.00' }; |
| | | return; |
| | | } |
| | | this.singleLoading = true; |
| | | try { |
| | | const payload = { |
| | | deptOrDistrict: '1', |
| | | serviceTypeList: ['6', '14'], |
| | | startFinishTime: range[0], |
| | | endFinishTime: range[1], |
| | | questionContent: this.singleQuestionContent, |
| | | }; |
| | | const sel = this.singleDeptWards || []; |
| | | if (this.queryParams.dimension === 'dept') { |
| | | const names = sel.map((s) => String(s).replace(/^dept:/, '')); |
| | | payload.leaveldeptcodes = names.length ? this.mapDeptNames(names) : this.defaultDeptCodes; |
| | | } else { |
| | | const names = sel.map((s) => String(s).replace(/^ward:/, '')); |
| | | payload.leavehospitaldistrictcodes = names.length ? this.mapWardNames(names) : this.defaultWardCodes; |
| | | } |
| | | const res = await sltdMydTotalByScore(payload); |
| | | console.log('[sltdMydTotalByScore åé¢] code=', res && res.code, 'data=', JSON.stringify(res && res.data).slice(0, 1500)); |
| | | const list = res && res.code === 200 ? res.data : []; |
| | | const { options, total } = this.normalizeSingleQuestion(list); |
| | | this.singleQuestionData = options.map((o) => ({ |
| | | option: o.option, |
| | | count: o.count, |
| | | rate: o.ratio != null |
| | | ? o.ratio.toFixed(2) + '%' |
| | | : (total ? ((o.count / total) * 100).toFixed(2) + '%' : '0.00%'), |
| | | })); |
| | | this.singleQuestionMeta = { |
| | | total: total.toLocaleString(), |
| | | score: this.scoreOfOptions(options), |
| | | }; |
| | | if (!options.length) this.notify('å½åæ¡ä»¶ä¸ææ 该é¢çé项ç»è®¡æ°æ®', 'warning'); |
| | | } catch (e) { |
| | | this.singleQuestionData = []; |
| | | this.singleQuestionMeta = { total: '0', score: '0.00' }; |
| | | this.notify('åé¢é项ç»è®¡æ°æ®è¯·æ±å¤±è´¥ï¼è¯·ç¨åéè¯', 'error'); |
| | | } finally { |
| | | this.singleLoading = false; |
| | | } |
| | | }, |
| | | handleReset() { |
| | | this.queryParams.dateRange = this.defaultRange(); |
| | | this.queryParams.interval = 'month'; |
| | | this.queryParams.dimension = 'ward'; |
| | | this.singleDeptWards = []; |
| | | this.refreshAll(); |
| | | }, |
| | | // 忢å
¨å±ç»è®¡ç»´åº¦æ¶æ¸
空åé¢çéï¼ä¿è¯ç§å®¤/ç
åºäºæ¥ |
| | | onDimensionChange() { |
| | | this.singleDeptWards = []; |
| | | this.refreshAll(); |
| | | }, |
| | | onRankDimensionChange() { |
| | |
| | | defaultRange() { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setDate(start.getDate() - 29); |
| | | start.setDate(start.getDate() - 91); |
| | | const f = (d) => { |
| | | const y = d.getFullYear(); |
| | | const m = String(d.getMonth() + 1).padStart(2, '0'); |
| | |
| | | intervalConfig() { |
| | | const buckets = this.genBuckets(this.queryParams.interval); |
| | | if (this.queryParams.interval === 'day') return { buckets, seriesNames: ['æ¨æ¥', '仿¥'] }; |
| | | if (this.queryParams.interval === 'week') return { buckets, seriesNames: ['ä¸å¨', 'æ¬å¨'] }; |
| | | if (this.queryParams.interval === 'year') return { buckets, seriesNames: ['å»å¹´', 'ä»å¹´'] }; |
| | | return { buckets, seriesNames: ['䏿', 'æ¬æ'] }; |
| | | }, |
| | |
| | | d.setDate(end.getDate() - i); |
| | | buckets.push(`${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`); |
| | | } |
| | | } else if (type === 'week') { |
| | | for (let i = 5; i >= 0; i--) { |
| | | const d = new Date(end); |
| | | d.setDate(end.getDate() - i * 7); |
| | | buckets.push(`${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} å¨`); |
| | | } |
| | | } else if (type === 'year') { |
| | | for (let i = 3; i >= 0; i--) buckets.push(String(end.getFullYear() - i)); |
| | | } else { |
| | |
| | | } |
| | | return buckets; |
| | | }, |
| | | // å·æ°å
¨é¨æ°æ®ï¼æ¨¡æï¼æ¥å£å°±ç»ªåæ¿æ¢ä¸ºçå®è¯·æ±ï¼ |
| | | refreshAll() { |
| | | const baseChart = JSON.stringify(this.queryParams); |
| | | const baseTime = JSON.stringify({ dateRange: this.queryParams.dateRange }); |
| | | |
| | | // å¾è¡¨ï¼åºé´ç±»å + æ¶é´èå´ |
| | | this.genChartData(mulberry32(hashString(baseChart + 'charts'))); |
| | | // åé¢è¡¨ï¼æ¶é´èå´ + é¢ç® + ç§å®¤/ç
åº |
| | | this.genSingleData(mulberry32(hashString(baseTime + JSON.stringify({ sq: this.singleQuestionId, sdw: this.singleDeptWards })))); |
| | | // ç§å®¤/ç
åºæåï¼æ¶é´èå´ + 维度 + éæ© |
| | | this.genRankData(mulberry32(hashString(baseTime + JSON.stringify({ rd: this.rankDimension, rdw: this.rankDeptWards })))); |
| | | // åé¢Ãç§å®¤/ç
åºæåï¼æ¶é´èå´ + 维度 + éæ© + é¢ç® |
| | | this.genCrossData(mulberry32(hashString(baseTime + JSON.stringify({ cd: this.crossDimension, cdw: this.crossDeptWards, sq: this.singleQuestionId })))); |
| | | // å·æ°å
¨é¨æ°æ®ï¼è¶å¿ãå类维度ãé¢åºç»´åº¦ãåé¢ãæåã交åå为ç宿¥å£ï¼ |
| | | async refreshAll() { |
| | | // å
ä¸ªæ°æ®åå¹¶è¡æåï¼ååºååæ¶æ¾ç¤ºåèªçå è½½ç¶æ |
| | | await Promise.all([ |
| | | this.fetchTrend(), |
| | | this.fetchCategoryCompare(), |
| | | this.fetchHospitalCompare(), |
| | | this.fetchSingleQuestion(), |
| | | this.fetchRank(), |
| | | this.fetchCross(), |
| | | ]); |
| | | |
| | | this.renderCharts(); |
| | | }, |
| | | genChartData(rnd) { |
| | | const jitter = (lo, hi) => lo + rnd() * (hi - lo); |
| | | const cfg = this.intervalConfig(); |
| | | const buckets = cfg.buckets; |
| | | // 满æåº¦è¶å¿ï¼ç宿¥å£ï¼ï¼data = [{ period, totalScore }] |
| | | async fetchTrend() { |
| | | const range = this.queryParams.dateRange || []; |
| | | if (range.length !== 2 || !range[0] || !range[1]) { |
| | | this.trend = { buckets: [], data: [], seriesName: 'é¨è¯æ£è
满æåº¦' }; |
| | | return; |
| | | } |
| | | |
| | | this.trendLoading = true; |
| | | try { |
| | | const res = await mydTrend({ |
| | | startFinishTime: range[0], |
| | | endFinishTime: range[1], |
| | | type: this.queryParams.interval, // day / week / month / year |
| | | }); |
| | | const list = res && res.code === 200 && Array.isArray(res.data) ? res.data : []; |
| | | this.trend = { |
| | | buckets, |
| | | seriesName: 'é¨è¯æ£è
满æåº¦', |
| | | data: buckets.map(() => Math.round(jitter(86, 90) * 100) / 100), |
| | | buckets: list.map((i) => String((i && i.period) || '')), |
| | | data: list.map((i) => { |
| | | const n = Number(i && i.totalScore); |
| | | return isNaN(n) ? 0 : Math.round(n * 100) / 100; |
| | | }), |
| | | }; |
| | | |
| | | const categories = ['éç§ä¿æ¤', 'ç¯å¢ä¸æ è¯', 'å»å¡äººåååº', 'å»çæ²é', 'æå·ä½éª', 'æ¤å£«æ²é']; |
| | | this.categoryCompare = { |
| | | categories, |
| | | seriesNames: cfg.seriesNames, |
| | | series1: categories.map(() => Math.round(jitter(82, 88) * 100) / 100), |
| | | series2: categories.map(() => Math.round(jitter(83, 89) * 100) / 100), |
| | | }; |
| | | |
| | | const hospitals = ['é¢åºä¸', 'é¢åºäº', 'é¢åºä¸']; |
| | | this.hospitalCompare = { |
| | | hospitals, |
| | | seriesNames: cfg.seriesNames, |
| | | series1: hospitals.map(() => Math.round(jitter(85, 89) * 100) / 100), |
| | | series2: hospitals.map(() => Math.round(jitter(86, 90) * 100) / 100), |
| | | if (!list.length) this.notify('å½åæ¡ä»¶ä¸ææ è¶å¿æ°æ®', 'warning'); |
| | | } catch (e) { |
| | | this.trend = { buckets: [], data: [], seriesName: 'é¨è¯æ£è
满æåº¦' }; |
| | | this.notify('è¶å¿æ°æ®è¯·æ±å¤±è´¥ï¼è¯·ç¨åéè¯', 'error'); |
| | | } finally { |
| | | this.trendLoading = false; |
| | | } |
| | | }, |
| | | notify(msg, type) { |
| | | const fn = { warning: 'warning', error: 'error', success: 'success' }[type] || 'info'; |
| | | if (this.$message && this.$message[fn]) this.$message[fn](msg); |
| | | }, |
| | | // å类维度对æ¯ï¼ç宿¥å£ï¼ï¼dimensionType=1ï¼data = [{ period, dimension, totalScore }] |
| | | async fetchCategoryCompare() { |
| | | const range = this.queryParams.dateRange || []; |
| | | if (range.length !== 2 || !range[0] || !range[1]) { |
| | | this.categoryCompare = { categories: [], seriesNames: [], series1: [], series2: [] }; |
| | | return; |
| | | } |
| | | this.categoryLoading = true; |
| | | try { |
| | | const res = await sltdMydTotalByDimension({ |
| | | startFinishTime: range[0], |
| | | endFinishTime: range[1], |
| | | type: this.queryParams.interval, // day / week / month / year |
| | | dimensionType: "1", // 1=ææ»¡æåº¦ç»´åº¦ç»è®¡ |
| | | }); |
| | | // ææ¥ç¨ï¼æå°æ¥å£åå§è¿åï¼ä¾¿äºæ ¸å¯¹å段åï¼ç¡®è®¤æ 误åå¯å é¤ï¼ |
| | | console.log("[sltdMydTotalByDimension dimensionType=1] code=", res && res.code, "data=", JSON.stringify(res && res.data).slice(0, 2000)); |
| | | const list = res && res.code === 200 && Array.isArray(res.data) ? res.data : []; |
| | | // 维度ç¼ç â åå
¸åç§°ï¼å¹¶è¿æ»¤ä¸¤æåæ æ°æ®ç维度 |
| | | const d = this.buildCompareData(list, (code) => this.getDimensionLabel(code)); |
| | | this.categoryCompare = { categories: d.labels, seriesNames: d.seriesNames, series1: d.series1, series2: d.series2 }; |
| | | if (!list.length) this.notify('å½åæ¡ä»¶ä¸ææ åç±»ç»´åº¦æ°æ®', 'warning'); |
| | | } catch (e) { |
| | | this.categoryCompare = { categories: [], seriesNames: [], series1: [], series2: [] }; |
| | | this.notify('åç±»ç»´åº¦æ°æ®è¯·æ±å¤±è´¥ï¼è¯·ç¨åéè¯', 'error'); |
| | | } finally { |
| | | this.categoryLoading = false; |
| | | } |
| | | }, |
| | | // é¢åºç»´åº¦å¯¹æ¯ï¼ç宿¥å£ï¼ï¼dimensionType=2ï¼data = [{ period, dimension(é¢åºå), totalScore }] |
| | | async fetchHospitalCompare() { |
| | | const range = this.queryParams.dateRange || []; |
| | | if (range.length !== 2 || !range[0] || !range[1]) { |
| | | this.hospitalCompare = { hospitals: [], seriesNames: [], series1: [], series2: [] }; |
| | | return; |
| | | } |
| | | this.hospitalLoading = true; |
| | | try { |
| | | const res = await sltdMydTotalByDimension({ |
| | | startFinishTime: range[0], |
| | | endFinishTime: range[1], |
| | | type: this.queryParams.interval, // day / week / month / year |
| | | dimensionType: "2", // 2=æé¢åºç»è®¡ |
| | | }); |
| | | // ææ¥ç¨ï¼æå°æ¥å£åå§è¿åï¼ä¾¿äºæ ¸å¯¹å段åï¼ç¡®è®¤æ 误åå¯å é¤ï¼ |
| | | console.log("[sltdMydTotalByDimension dimensionType=2] code=", res && res.code, "data=", JSON.stringify(res && res.data).slice(0, 2000)); |
| | | const list = res && res.code === 200 && Array.isArray(res.data) ? res.data : []; |
| | | const d = this.buildCompareData(list); |
| | | this.hospitalCompare = { hospitals: d.labels, seriesNames: d.seriesNames, series1: d.series1, series2: d.series2 }; |
| | | if (!list.length) this.notify('å½åæ¡ä»¶ä¸ææ é¢åºç»´åº¦æ°æ®', 'warning'); |
| | | } catch (e) { |
| | | this.hospitalCompare = { hospitals: [], seriesNames: [], series1: [], series2: [] }; |
| | | this.notify('é¢åºç»´åº¦æ°æ®è¯·æ±å¤±è´¥ï¼è¯·ç¨åéè¯', 'error'); |
| | | } finally { |
| | | this.hospitalLoading = false; |
| | | } |
| | | }, |
| | | // å° [{ period, dimension, totalScore }] ç»è£
为åç»æ±ç¶å¾æ°æ®ï¼ä¸æ/æ¬æä¸¤ç»å¯¹æ¯ï¼ |
| | | // labelFnï¼å¯éï¼ç¨äºæç»´åº¦ç¼ç æ å°ä¸ºåå
¸åç§°ï¼å类维度å¾ä¼ å
¥ï¼ |
| | | buildCompareData(list, labelFn) { |
| | | const labels = []; |
| | | const byCat = {}; |
| | | list.forEach((i) => { |
| | | // 维度ç¼ç ï¼dimensionType=1ï¼æé¢åºåç§°ï¼dimensionType=2ï¼ï¼è¥åç«¯åæ®µå½åä¸åï¼å
åºå period |
| | | const key = (i && (i.dimension || i.campusName || i.campusid)) || (i && i.period) || ''; |
| | | if (!key) return; |
| | | if (!byCat[key]) { byCat[key] = {}; labels.push(key); } |
| | | const n = Number(i.totalScore); |
| | | byCat[key][i.period] = isNaN(n) ? 0 : Math.round(n * 100) / 100; |
| | | }); |
| | | // åç«¯ææ¶é´ååºè¿åï¼åæåä¸¤ä¸ªå¨æä½ä¸ºâ䏿 / æ¬æâ |
| | | const periods = [...new Set(list.map((i) => i && i.period).filter(Boolean))]; |
| | | const cur = periods[periods.length - 1]; |
| | | const prev = periods[periods.length - 2]; |
| | | const val = (cat, p) => (p != null && byCat[cat][p] != null ? byCat[cat][p] : 0); |
| | | // è¿æ»¤ä¸¤æåæ æ°æ®ç维度 |
| | | const cats = labels.filter((c) => val(c, prev) !== 0 || val(c, cur) !== 0); |
| | | const display = labelFn ? cats.map((c) => labelFn(c)) : cats; |
| | | return { |
| | | labels: display, |
| | | seriesNames: this.intervalConfig().seriesNames, |
| | | series1: cats.map((c) => val(c, prev)), |
| | | series2: cats.map((c) => val(c, cur)), |
| | | }; |
| | | }, |
| | | genSingleData(rnd) { |
| | | const jitter = (lo, hi) => lo + rnd() * (hi - lo); |
| | | const scopeFactor = this.singleDeptWards.length ? 0.18 : 1; |
| | | const total = Math.round(jitter(20000, 30000) * scopeFactor); |
| | | const weights = [0.62, 0.27, 0.07, 0.04]; |
| | | const counts = weights.map((w) => Math.max(0, Math.round(total * w * jitter(0.92, 1.08)))); |
| | | const good = counts[0] + counts[1]; |
| | | this.singleQuestionData = QUESTION_OPTIONS.map((opt, i) => ({ |
| | | option: opt, |
| | | count: counts[i], |
| | | rate: ((counts[i] / total) * 100).toFixed(2) + '%', |
| | | // ç§å®¤/ç
åºç»´åº¦ · é¨è¯æ£è
满æåº¦å¾åæåï¼ç宿¥å£ /mzMydScoreRankï¼ä¸å¸¦é®é¢ææ¬ï¼ |
| | | async fetchRank() { |
| | | const range = this.queryParams.dateRange || []; |
| | | if (range.length !== 2 || !range[0] || !range[1]) { |
| | | this.rankData = []; |
| | | return; |
| | | } |
| | | this.rankLoading = true; |
| | | try { |
| | | const res = await mzMydScoreRank(this.buildRankPayload(this.rankDimension, this.rankDeptWards, '')); |
| | | this.rankData = this.normalizeRank(res); |
| | | if (!this.rankData.length) this.notify('å½åæ¡ä»¶ä¸ææ æåæ°æ®', 'warning'); |
| | | } catch (e) { |
| | | this.rankData = []; |
| | | this.notify('æåæ°æ®è¯·æ±å¤±è´¥ï¼è¯·ç¨åéè¯', 'error'); |
| | | } finally { |
| | | this.rankLoading = false; |
| | | } |
| | | }, |
| | | // åé¢Ãç§å®¤/ç
åº Â· å¾åæåï¼ç宿¥å£ /mzMydScoreRankï¼å¸¦é®é¢ææ¬ï¼ |
| | | async fetchCross() { |
| | | const range = this.queryParams.dateRange || []; |
| | | if (range.length !== 2 || !range[0] || !range[1] || !this.singleQuestionContent) { |
| | | this.crossData = []; |
| | | return; |
| | | } |
| | | this.crossLoading = true; |
| | | try { |
| | | const res = await mzMydScoreRank(this.buildRankPayload(this.crossDimension, this.crossDeptWards, this.singleQuestionContent)); |
| | | this.crossData = this.normalizeRank(res); |
| | | if (!this.crossData.length) this.notify('å½åæ¡ä»¶ä¸ææ æåæ°æ®', 'warning'); |
| | | } catch (e) { |
| | | this.crossData = []; |
| | | this.notify('æåæ°æ®è¯·æ±å¤±è´¥ï¼è¯·ç¨åéè¯', 'error'); |
| | | } finally { |
| | | this.crossLoading = false; |
| | | } |
| | | }, |
| | | // ç»è£
æåæ¥å£è¯·æ±ä½ï¼dimensionType/serviceType/deptCodes/districtCodes/æ¶é´/questionTextï¼ |
| | | buildRankPayload(dimension, selectedNames, questionText) { |
| | | const range = this.queryParams.dateRange || []; |
| | | const payload = { |
| | | dimensionType: dimension === 'dept' ? '1' : '2', |
| | | serviceTypes: ['6', '14'], |
| | | startFinishTime: range[0], |
| | | endFinishTime: range[1], |
| | | }; |
| | | if (questionText) payload.questionText = questionText; |
| | | if (selectedNames && selectedNames.length) { |
| | | if (dimension === 'dept') { |
| | | payload.deptCodes = this.mapDeptNames(selectedNames); |
| | | } else { |
| | | payload.districtCodes = this.mapWardNames(selectedNames); |
| | | } |
| | | } |
| | | return payload; |
| | | }, |
| | | // å½ä¸åæåè¿å List<MzMydScoreRankDTO> â [{ rank, code, name, score, itemCount }] |
| | | normalizeRank(res) { |
| | | const list = res && res.code === 200 && Array.isArray(res.data) ? res.data : []; |
| | | return list.map((item) => ({ |
| | | rank: item.rank, |
| | | code: item.code, |
| | | name: item.name, |
| | | score: item.score, |
| | | itemCount: item.itemCount, |
| | | })); |
| | | this.singleQuestionMeta = { |
| | | total: total.toLocaleString(), |
| | | score: ((good / total) * 100).toFixed(2) + '%', |
| | | }; |
| | | }, |
| | | genRankData(rnd) { |
| | | const jitter = (lo, hi) => lo + rnd() * (hi - lo); |
| | | this.deptRankData = DEPTS |
| | | .map((d) => ({ name: d, score: jitter(70, 85).toFixed(2) })) |
| | | .sort((a, b) => Number(b.score) - Number(a.score)); |
| | | this.wardRankData = WARDS |
| | | .map((w) => ({ name: w, score: jitter(70, 85).toFixed(2) })) |
| | | .sort((a, b) => Number(b.score) - Number(a.score)); |
| | | }, |
| | | genCrossData(rnd) { |
| | | const jitter = (lo, hi) => lo + rnd() * (hi - lo); |
| | | this.crossDeptData = DEPTS |
| | | .map((d) => ({ name: d, score: jitter(70, 85).toFixed(2) })) |
| | | .sort((a, b) => Number(b.score) - Number(a.score)); |
| | | this.crossWardData = WARDS |
| | | .map((w) => ({ name: w, score: jitter(70, 85).toFixed(2) })) |
| | | .sort((a, b) => Number(b.score) - Number(a.score)); |
| | | }, |
| | | renderCharts() { |
| | | const c1 = echarts.getInstanceByDom(this.$refs.chart1); |
| | |
| | | }); |
| | | |
| | | // 2. åç»æ±ç¶å¾ - å类维度 |
| | | c2.setOption({ |
| | | // åç±»è¾å¤ï¼å¦åå 个满æåº¦ç»´åº¦ï¼æ¶åºé¨åç§°ä¼éå ï¼è¿éææ°é卿éé
ï¼ |
| | | // â¤6 ä¸ªï¼æ£å¸¸æ°´å¹³æ ç¾ï¼ |
| | | // 7~10 个ï¼x è½´æ ç¾å¾æ 35° + åºé¨çç½å 大 + æ±ååç»ï¼ |
| | | // >10 个ï¼åå¯ç¨æ¨ªå缩æ¾ï¼åå§æ¾ç¤ºçº¦ 8 个åç±»ï¼å¯æå¨/æ»å¨æ¥çå
¶ä½ï¼ã |
| | | const catCategories = this.categoryCompare.categories || []; |
| | | const catN = catCategories.length; |
| | | const catRotate = catN > 6 ? 35 : 0; |
| | | const catEnableZoom = catN > 10; |
| | | const catBarWidth = catN > 10 ? 18 : catN > 6 ? 20 : 22; |
| | | const catLegend = catEnableZoom |
| | | ? { data: this.categoryCompare.seriesNames, top: 4, textStyle: { color: '#666', fontSize: 12 } } |
| | | : { data: this.categoryCompare.seriesNames, bottom: 8, textStyle: { color: '#666', fontSize: 12 } }; |
| | | const catGrid = catEnableZoom |
| | | ? { top: 36, right: 30, bottom: 80, left: 85 } |
| | | : { top: 48, right: 30, bottom: catRotate ? 100 : 60, left: 85 }; |
| | | const catOption = { |
| | | color: ['#6DC8EC', '#5B8FF9'], |
| | | grid: barGrid, |
| | | grid: catGrid, |
| | | tooltip: { ...baseTooltip, trigger: 'axis', axisPointer: { type: 'shadow', shadowStyle: { color: 'rgba(0,0,0,0.03)' } } }, |
| | | legend: { data: this.categoryCompare.seriesNames, bottom: 8, textStyle: { color: '#666', fontSize: 12 } }, |
| | | xAxis: [{ ...baseXAxis, data: this.categoryCompare.categories, axisLabel: { ...baseXAxis.axisLabel, interval: 0 } }], |
| | | legend: catLegend, |
| | | xAxis: [{ ...baseXAxis, data: catCategories, axisLabel: { ...baseXAxis.axisLabel, interval: 0, rotate: catRotate } }], |
| | | yAxis: [{ ...baseYAxis, name: 'å¾å', nameTextStyle: { color: '#999', fontSize: 11 } }], |
| | | series: [ |
| | | { name: this.categoryCompare.seriesNames[0], type: 'bar', barWidth: 22, barGap: '30%', |
| | | { name: this.categoryCompare.seriesNames[0], type: 'bar', barWidth: catBarWidth, barGap: '30%', |
| | | itemStyle: { borderRadius: [6, 6, 0, 0], color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: '#6DC8EC' }, { offset: 1, color: '#48B0D5' }]) }, |
| | | data: this.categoryCompare.series1 }, |
| | | { name: this.categoryCompare.seriesNames[1], type: 'bar', barWidth: 22, |
| | | { name: this.categoryCompare.seriesNames[1], type: 'bar', barWidth: catBarWidth, |
| | | itemStyle: { borderRadius: [6, 6, 0, 0], color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: '#5B8FF9' }, { offset: 1, color: '#3D6FDB' }]) }, |
| | | data: this.categoryCompare.series2 }, |
| | | ], |
| | | }); |
| | | }; |
| | | if (catEnableZoom) { |
| | | // åå§åªå±ç¤ºå 8 个å类宽度ï¼é¿å
æ±åæ¤æä¸å¢ï¼ç¨æ·å¯æ¨ªåæ»å¨/æå¨æ¥çå
¶ä½ |
| | | const zoomEnd = catN > 0 ? Math.min(100, Math.round((8 / catN) * 100)) : 100; |
| | | catOption.dataZoom = [ |
| | | { type: 'inside', start: 0, end: zoomEnd }, |
| | | { type: 'slider', height: 16, bottom: 4, start: 0, end: zoomEnd }, |
| | | ]; |
| | | } |
| | | c2.setOption(catOption); |
| | | |
| | | // 4. é¢åºç»´åº¦ - åç»æ±ç¶å¾ |
| | | c4.setOption({ |
| | |
| | | .filter-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; .filter-label { font-size: 13px; color: #606266; } .filter-date { width: 260px; } } |
| | | .chart-card { margin-bottom: 0; } |
| | | .chart-box { width: 100%; height: 360px; } |
| | | .chart-wrap { position: relative; width: 100%; } |
| | | .chart-empty { position: absolute; top: 0; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; background: #fff; color: #909399; font-size: 14px; } |
| | | .card-header { display: flex; justify-content: space-between; align-items: center; span { font-size: 15px; font-weight: 600; color: #303133; } } |
| | | .header-right { display: flex; align-items: center; gap: 10px; .sel { width: 140px; } .sel-lg { width: 240px; } } |
| | | .table-footer { text-align: right; padding: 10px 0 0; font-size: 13px; color: #606266; } |
| | |
| | | <!-- é¡¶é¨çéï¼æ¶é´èå´ + ç§å®¤/ç
åºï¼æ§å¶æ¬é¡µæææ°æ® --> |
| | | <el-card shadow="never" class="overview-card filter-card"> |
| | | <el-form inline class="filter-form"> |
| | | <el-form-item label="æ¶é´èå´"> |
| | | <el-form-item label="åºé¢æ¥æ"> |
| | | <el-date-picker |
| | | v-model="queryParams.dateRange" |
| | | type="daterange" |
| | |
| | | size="small" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç§å®¤/ç
åº"> |
| | | <el-form-item label="ç»è®¡ç»´åº¦"> |
| | | <el-radio-group |
| | | v-model="queryParams.statMode" |
| | | size="small" |
| | | @change="onStatModeChange" |
| | | > |
| | | <el-radio-button label="ward">æç
åºç»è®¡</el-radio-button> |
| | | <el-radio-button label="dept">æç§å®¤ç»è®¡</el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="ç§å®¤" v-if="queryParams.statMode === 'dept'"> |
| | | <el-select |
| | | v-model="queryParams.deptWard" |
| | | v-model="queryParams.deptCodes" |
| | | multiple |
| | | collapse-tags |
| | | clearable |
| | | filterable |
| | | placeholder="å
¨é¨" |
| | | placeholder="å
¨é¨ç§å®¤" |
| | | size="small" |
| | | class="filter-select" |
| | | > |
| | | <el-option-group label="ç§å®¤"> |
| | | <el-option |
| | | v-for="d in deptOptions" |
| | | :key="'dept:' + d" |
| | | :label="d" |
| | | :value="'dept:' + d" |
| | | :key="d.value" |
| | | :label="d.label" |
| | | :value="d.value" |
| | | /> |
| | | </el-option-group> |
| | | <el-option-group label="ç
åº"> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç
åº" v-else> |
| | | <el-select |
| | | v-model="queryParams.wardCodes" |
| | | multiple |
| | | collapse-tags |
| | | clearable |
| | | filterable |
| | | placeholder="å
¨é¨ç
åº" |
| | | size="small" |
| | | class="filter-select" |
| | | > |
| | | <el-option |
| | | v-for="w in wardOptions" |
| | | :key="'ward:' + w" |
| | | :label="w" |
| | | :value="'ward:' + w" |
| | | :key="w.value" |
| | | :label="w.label" |
| | | :value="w.value" |
| | | /> |
| | | </el-option-group> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æå¡ç±»å"> |
| | | <el-select |
| | | v-model="queryParams.serviceTypeList" |
| | | multiple |
| | | collapse-tags |
| | | clearable |
| | | filterable |
| | | placeholder="å
¨é¨ç±»å" |
| | | size="small" |
| | | class="filter-select" |
| | | > |
| | | <el-option |
| | | v-for="s in serviceTypeOptions" |
| | | :key="s.value" |
| | | :label="s.label" |
| | | :value="s.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" size="small" icon="el-icon-search" @click="fetchData">æ¥è¯¢</el-button> |
| | | <el-button size="small" icon="el-icon-refresh" @click="handleReset">éç½®</el-button> |
| | | <el-button |
| | | type="primary" |
| | | size="small" |
| | | icon="el-icon-search" |
| | | :loading="loading" |
| | | @click="fetchData" |
| | | >æ¥è¯¢</el-button |
| | | > |
| | | <el-button size="small" icon="el-icon-refresh" @click="handleReset" |
| | | >éç½®</el-button |
| | | > |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | |
| | | <!-- è¡¨æ ¼ä¸ï¼åæå¡é¡¹ç®æ»¡æåº¦ç»è®¡ï¼åºå®äºé¡¹é项çé¢ç®ï¼ --> |
| | | <!-- è¡¨æ ¼ä¸ï¼åæå¡é¡¹ç®æ»¡æåº¦ç»è®¡ï¼åºå®å
项é项çé¢ç®ï¼ --> |
| | | <el-card shadow="never" class="overview-card"> |
| | | <div slot="header" class="card-header"> |
| | | <span class="card-title">åæå¡é¡¹ç®æ»¡æåº¦ç»è®¡</span> |
| | | <el-button type="warning" size="small" icon="el-icon-download" @click="exportTable('table1')">导åºExcel</el-button> |
| | | <el-button |
| | | type="warning" |
| | | size="small" |
| | | icon="el-icon-download" |
| | | @click="exportTable('table1')" |
| | | >导åºExcel</el-button |
| | | > |
| | | </div> |
| | | <el-table id="table1" :data="serviceSatisfaction" border size="small" :header-cell-style="{ background: '#f5f7fa', color: '#303133' }"> |
| | | <el-table-column prop="category" label="åç±»/é¢ç®" min-width="220" fixed="left" /> |
| | | <el-table-column label="é常满æ" align="center"> |
| | | <el-table |
| | | id="table1" |
| | | v-loading="loading" |
| | | element-loading-text="ç»è®¡ä¸..." |
| | | :data="serviceSatisfaction" |
| | | border |
| | | size="small" |
| | | :header-cell-style="{ background: '#f5f7fa', color: '#303133' }" |
| | | > |
| | | <el-table-column |
| | | prop="category" |
| | | label="åç±»/é¢ç®" |
| | | min-width="220" |
| | | fixed="left" |
| | | /> |
| | | <el-table-column label="徿»¡æ" align="center"> |
| | | <el-table-column prop="veryGoodCount" label="æ°é" width="90" /> |
| | | <el-table-column prop="veryGoodRate" label="æ¯ä¾" width="90" /> |
| | | </el-table-column> |
| | |
| | | <el-table-column prop="badCount" label="æ°é" width="90" /> |
| | | <el-table-column prop="badRate" label="æ¯ä¾" width="90" /> |
| | | </el-table-column> |
| | | <el-table-column label="ä¸éç¨" align="center"> |
| | | <el-table-column label="å¾ä¸æ»¡æ" align="center"> |
| | | <el-table-column prop="veryBadCount" label="æ°é" width="90" /> |
| | | <el-table-column prop="veryBadRate" label="æ¯ä¾" width="90" /> |
| | | </el-table-column> |
| | | <el-table-column label="æªç»å" align="center"> |
| | | <el-table-column prop="naCount" label="æ°é" width="90" /> |
| | | <el-table-column prop="naRate" label="æ¯ä¾" width="90" /> |
| | | </el-table-column> |
| | | <el-table-column prop="score" label="综åå¾å" width="100" align="center" /> |
| | | <el-table-column |
| | | prop="score" |
| | | label="综åå¾å" |
| | | width="100" |
| | | align="center" |
| | | fixed="right" |
| | | /> |
| | | </el-table> |
| | | </el-card> |
| | | |
| | |
| | | <el-card shadow="never" class="overview-card"> |
| | | <div slot="header" class="card-header"> |
| | | <span class="card-title">åéé¢/å¤éé¢ç»è®¡</span> |
| | | <el-button type="warning" size="small" icon="el-icon-download" @click="exportTable('table2')">导åºExcel</el-button> |
| | | <div class="header-right"> |
| | | <el-input |
| | | v-model="questionSearch" |
| | | size="small" |
| | | clearable |
| | | prefix-icon="el-icon-search" |
| | | placeholder="æé¢ç®æ¨¡ç³æ¥è¯¢" |
| | | class="search-input" |
| | | /> |
| | | <el-button |
| | | type="warning" |
| | | size="small" |
| | | icon="el-icon-download" |
| | | @click="exportTable('table2')" |
| | | >导åºExcel</el-button |
| | | > |
| | | </div> |
| | | <div id="table2"> |
| | | <div class="question-block" v-for="(q, qi) in questionStats" :key="qi"> |
| | | </div> |
| | | <div id="table2" v-loading="loading" element-loading-text="ç»è®¡ä¸..."> |
| | | <div class="table2-scroll"> |
| | | <div |
| | | class="question-block" |
| | | v-for="(q, qi) in filteredQuestionStats" |
| | | :key="qi" |
| | | > |
| | | <h4 class="q-title">{{ q.title }}</h4> |
| | | <el-table :data="q.options" border size="small" :header-cell-style="{ background: '#f5f7fa', color: '#303133' }"> |
| | | <el-table |
| | | :data="q.options" |
| | | border |
| | | size="small" |
| | | :header-cell-style="{ background: '#f5f7fa', color: '#303133' }" |
| | | > |
| | | <el-table-column prop="option" label="é项" min-width="180" /> |
| | | <el-table-column prop="count" label="æ°é" width="100" align="center" /> |
| | | <el-table-column prop="rate" label="æ¯ä¾" width="100" align="center" /> |
| | | <el-table-column |
| | | prop="count" |
| | | label="æ°é" |
| | | width="100" |
| | | align="center" |
| | | /> |
| | | <el-table-column |
| | | prop="rate" |
| | | label="æ¯ä¾" |
| | | width="100" |
| | | align="center" |
| | | /> |
| | | </el-table> |
| | | <div v-if="q.total" class="q-footer">æ¬é¢ææå¡«å人次ï¼<b>{{ q.total }}</b></div> |
| | | <div v-if="q.total" class="q-footer"> |
| | | æ¬é¢å¡«æ¥æ»éï¼<b>{{ q.total }}</b> |
| | | </div> |
| | | </div> |
| | | <div v-if="!loading && !filteredQuestionStats.length" class="empty-tip"> |
| | | {{ questionStats.length ? "æªæ¾å°å¹é
çé¢ç®" : "ææ åé/å¤éé¢ç»è®¡æ°æ®" }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | |
| | | <div slot="header" class="card-header"> |
| | | <span class="card-title">åç§å®¤/ç
åºæ»¡æåº¦è¯å对æ¯</span> |
| | | <div class="header-right"> |
| | | <el-radio-group v-model="statDimension" size="small" @change="onStatDimensionChange"> |
| | | <el-radio-group |
| | | v-model="statDimension" |
| | | size="small" |
| | | @change="onStatDimensionChange" |
| | | > |
| | | <el-radio-button label="dept">æç§å®¤</el-radio-button> |
| | | <el-radio-button label="ward">æç
åº</el-radio-button> |
| | | </el-radio-group> |
| | | <el-select v-model="statDeptWard" size="small" class="stat-select" placeholder="沿ç¨é¡¶é¨æ¡ä»¶"> |
| | | <el-select |
| | | v-model="statDeptWard" |
| | | size="small" |
| | | class="stat-select" |
| | | placeholder="沿ç¨é¡¶é¨æ¡ä»¶" |
| | | > |
| | | <el-option label="沿ç¨é¡¶é¨æ¡ä»¶" value="inherit" /> |
| | | <template v-if="statDimension === 'dept'"> |
| | | <el-option v-for="d in deptOptions" :key="'dept:' + d" :label="d" :value="'dept:' + d" /> |
| | | <el-option |
| | | v-for="d in deptOptions" |
| | | :key="'dept:' + d.value" |
| | | :label="d.label" |
| | | :value="'dept:' + d.value" |
| | | /> |
| | | </template> |
| | | <template v-else> |
| | | <el-option v-for="w in wardOptions" :key="'ward:' + w" :label="w" :value="'ward:' + w" /> |
| | | <el-option |
| | | v-for="w in wardOptions" |
| | | :key="'ward:' + w.value" |
| | | :label="w.label" |
| | | :value="'ward:' + w.value" |
| | | /> |
| | | </template> |
| | | </el-select> |
| | | <el-button type="warning" size="small" icon="el-icon-download" @click="exportTable('table3')">导åºExcel</el-button> |
| | | <el-button |
| | | type="warning" |
| | | size="small" |
| | | icon="el-icon-download" |
| | | @click="exportTable('table3')" |
| | | >导åºExcel</el-button |
| | | > |
| | | </div> |
| | | </div> |
| | | <el-table id="table3" :data="table3Rows" border size="small" :header-cell-style="{ background: '#f5f7fa', color: '#303133' }"> |
| | | <el-table-column prop="name" :label="statDimension === 'dept' ? 'ç§å®¤' : 'ç
åº'" fixed="left" align="center" /> |
| | | <el-table-column label="第1é¢" align="center"> |
| | | <el-table-column prop="q1VeryGood" label="é常满æ" width="100" /> |
| | | <el-table-column prop="q1Good" label="满æ" width="90" /> |
| | | <el-table-column prop="q1Normal" label="ä¸è¬" width="90" /> |
| | | <el-table-column prop="q1Bad" label="䏿»¡æ" width="90" /> |
| | | <el-table-column prop="q1Score" label="å¾å" width="100" /> |
| | | <el-table |
| | | id="table3" |
| | | v-loading="loading" |
| | | element-loading-text="ç»è®¡ä¸..." |
| | | :data="table3Rows" |
| | | border |
| | | size="small" |
| | | max-height="500" |
| | | :header-cell-style="{ background: '#f5f7fa', color: '#303133' }" |
| | | > |
| | | <el-table-column |
| | | prop="name" |
| | | :label="statDimension === 'dept' ? 'ç§å®¤' : 'ç
åº'" |
| | | fixed="left" |
| | | align="center" |
| | | /> |
| | | <el-table-column |
| | | v-for="q in table3Questions" |
| | | :key="q.title" |
| | | :label="q.title" |
| | | align="center" |
| | | > |
| | | <el-table-column |
| | | v-for="opt in q.options" |
| | | :key="opt" |
| | | :label="opt" |
| | | width="100" |
| | | > |
| | | <template slot-scope="{ row }"> |
| | | {{ |
| | | (row.cells[q.title] && |
| | | row.cells[q.title][opt] && |
| | | row.cells[q.title][opt].count) || |
| | | 0 |
| | | }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="第2é¢" align="center"> |
| | | <el-table-column prop="q2VeryGood" label="é常满æ" width="100" /> |
| | | <el-table-column prop="q2Good" label="满æ" width="90" /> |
| | | <el-table-column prop="q2Normal" label="ä¸è¬" width="90" /> |
| | | <el-table-column prop="q2Bad" label="䏿»¡æ" width="90" /> |
| | | <el-table-column prop="q2Score" label="å¾å" width="100" /> |
| | | <el-table-column label="å¾å" width="90"> |
| | | <template slot-scope="{ row }"> |
| | | {{ (row.cells[q.title] && row.cells[q.title]._score) || "0.00" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="totalScore" label="综åå¾å" align="center" /> |
| | | </el-table-column> |
| | | <el-table-column label="综åå¾å" align="center"> |
| | | <template slot-scope="{ row }"> |
| | | {{ row.totalScore }} |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import XLSX from 'xlsx'; |
| | | import { sltdMydTotalByScore,statQuestionOptionByKsOrBq } from "@/api/AiCentre/satisfaction"; |
| | | import XLSX from "xlsx"; |
| | | |
| | | // 满æåº¦é¢çåºå®é项ï¼é¡ºåºå³è¡¨æ ¼å顺åºï¼ |
| | | const FIXED_OPTIONS = ['é常满æ', '满æ', 'ä¸è¬', '䏿»¡æ', 'ä¸éç¨']; |
| | | const DEPTS = ['å
åæ³ç§', 'ç®è¤ç§', 'è¿ç¤å
ç§', 'æ¶åå
ç§', 'è¾å
ç§']; |
| | | const WARDS = ['ä¸ç
åº', 'äºç
åº', 'ä¸ç
åº', 'åç
åº', 'äºç
åº']; |
| | | // 满æåº¦é¢çåºå®é项ï¼é¡ºåºå³è¡¨æ ¼å顺åºï¼ââè¿äºé项çé¢ç®è¿è¡¨ä¸ï¼å
¶ä½è¿è¡¨äº |
| | | const FIXED_OPTIONS = ["徿»¡æ", "满æ", "ä¸è¬", "䏿»¡æ", "å¾ä¸æ»¡æ", "æªç»å"]; |
| | | // æ åå¼é项ï¼å¦"æªç»å"ï¼æ¯å¦è®¡å
¥ç»¼åå¾å忝ï¼é»è®¤ falseï¼é¿å
æä½å¾å |
| | | const NO_SCORE_IN_DENOMINATOR = false; |
| | | |
| | | // 满æåº¦é¢ï¼åºå®äºé¡¹é项ï¼counts 顺åºå¯¹åº FIXED_OPTIONSï¼ |
| | | const SATISFACTION_BASE = [ |
| | | ['è¯çè¿ç¨ä¸ï¼å»å¡äººåæ¯å¦æ³¨æä¿æ¤æ¨çéç§ï¼', [3219, 1351, 142, 33, 0]], |
| | | ['æ¨å¯¹å»é¢æå¡è®¾æ½çæ»ä½å°è±¡å¦ä½ï¼', [3110, 1369, 217, 49, 0]], |
| | | ['å»é¢çåææ¯å¦æ¸
æ´æ å¼å³ï¼', [2973, 1504, 235, 33, 0]], |
| | | ['å»é¢å
çè·¯æ åæç¤ºæ¯å¦æç¡®ï¼', [3234, 1289, 196, 26, 0]], |
| | | ['å»é¢ç空é´å¸å±æ¯å¦ä¾¿å©ï¼', [3037, 1460, 209, 39, 0]], |
| | | ['çç
æé´ï¼æ¨çæ±æ¨å䏿»¡è½å¦åæ¶å¾å°ååºï¼', [3019, 1317, 294, 115, 0]], |
| | | ['å»çæ¯å¦ç¨æ¨å¬å¾æçæ¹å¼è§£éé®é¢ï¼', [3402, 967, 254, 122, 0]], |
| | | ['å»çå¯¹æ¨æ¯å¦å°éï¼', [3495, 897, 249, 104, 0]], |
| | | ['å»çæ¯å¦ä»ç»å¾å¬æ¨è®²è¯ï¼', [3422, 937, 251, 135, 0]], |
| | | ['对æå·æå¡äººåæå¡æåº¦æ¯å¦æ»¡æ', [3458, 1205, 52, 30, 0]], |
| | | ['æ¨å¯¹é¢çº¦æå·æ¯å¦æ»¡æï¼', [3527, 1088, 72, 58, 0]], |
| | | ['æ¤å£«å¯¹æ¨æ¯å¦å°éï¼', [3420, 1184, 113, 28, 0]], |
| | | ['æ¤å£«æ¯å¦ç¨æ¨å¬å¾æçæ¹å¼è§£éé®é¢ï¼', [3346, 1250, 122, 27, 0]], |
| | | ['æ¤å£«æ¯å¦ä»ç»å¾å¬æ¨è®²è¯ï¼', [3378, 1205, 134, 28, 0]], |
| | | // æå¡ç±»ååå
¸ï¼æ¥å£ serviceTypeï¼ |
| | | const SERVICE_TYPES = [ |
| | | { value: "1", label: "çæµè¯ä¼°" }, |
| | | { value: "2", label: "åºé¢é访" }, |
| | | { value: "3", label: "é¨è¯é访" }, |
| | | { value: "4", label: "宣æå
³æ" }, |
| | | { value: "5", label: "å¤è¯éç¥" }, |
| | | { value: "6", label: "满æåº¦è°æ¥" }, |
| | | { value: "7", label: "æ£è
æ¥å" }, |
| | | { value: "8", label: "å
¶ä»éç¥" }, |
| | | { value: "9", label: "使£é访" }, |
| | | { value: "10", label: "廿é访" }, |
| | | { value: "11", label: "å½±åä¸ç§é访" }, |
| | | { value: "12", label: "å¿çµä¸ç§é访" }, |
| | | { value: "13", label: "ä¸ç§é访" }, |
| | | ]; |
| | | |
| | | // å
¶ä½é¢ç®ï¼åé/å¤éï¼éåºå®æ»¡æåº¦éé¡¹ï¼ |
| | | const OTHER_BASE = [ |
| | | { |
| | | title: 'æ¨å¯¹æé¢å·¥ä½äººåçæå¡è´¨é满æä¸æ»¡æï¼ãåå¼åéé¢ã', |
| | | type: 'single', |
| | | options: [['é常满æ', 1084], ['满æ', 1959], ['ä¸è¬', 167], ['䏿»¡æ', 153]], |
| | | }, |
| | | { |
| | | title: 'æ¨å¯¹åªé¨åæå¡ä¸æ»¡æï¼ãå¤éé¢ã', |
| | | type: 'multiple', |
| | | total: 408, |
| | | options: [['å»çè¯æåè¯ç', 131], ['æ¤çæå¡', 47], ['å
¶ä»å»å¡äººåææ¯æ°´å¹³', 30], ['工人', 72]], |
| | | }, |
| | | { |
| | | title: 'å»çè¯æåæ²»çä¸åªäºæå¡è´¨é䏿»¡æï¼ãå¤éé¢ã', |
| | | type: 'multiple', |
| | | total: 131, |
| | | options: [['å»çè¯æé误', 23], ['å¯¹æ²»çææä¸æ»¡æ', 72], ['å
¶ä»', 54]], |
| | | }, |
| | | ]; |
| | | // æå¡ç±»åé»è®¤éä¸é¡¹ï¼æ label å¹é
ï¼éé
ä¸ååå
¸ç value å·®å¼ï¼ |
| | | const DEFAULT_SERVICE_LABELS = ["ä½é¢æ»¡æåº¦", "é¨è¯æ»¡æåº¦"]; |
| | | |
| | | // ç»ä¸æ¥å£è¿åçé¢ç®ï¼æ¨¡æï¼ï¼åºå®äºé¡¹é项 => 表ä¸ï¼å
¶ä½ => è¡¨äº |
| | | const RAW_QUESTIONS = [ |
| | | ...SATISFACTION_BASE.map(([title, counts]) => ({ |
| | | title, |
| | | type: 'single', |
| | | options: FIXED_OPTIONS.map((opt, i) => ({ option: opt, count: counts[i] })), |
| | | })), |
| | | ...OTHER_BASE.map((q) => ({ |
| | | title: q.title, |
| | | type: q.type, |
| | | total: q.total, |
| | | options: q.options.map(([option, count]) => ({ option, count })), |
| | | })), |
| | | ]; |
| | | // å
åºï¼store 䏿 ç§å®¤/ç
åºæ°æ®æ¶ä½¿ç¨ï¼è¡¨ä¸å¯¹æ¯ + çéä¸æï¼ |
| | | const DEPTS = ["å
åæ³ç§", "ç®è¤ç§", "è¿ç¤å
ç§", "æ¶åå
ç§", "è¾å
ç§"]; |
| | | const WARDS = ["ä¸ç
åº", "äºç
åº", "ä¸ç
åº", "åç
åº", "äºç
åº"]; |
| | | |
| | | // ç¡®å®æ§ä¼ªéæºï¼ä¾¿äºç鿡件åºå®æ¶ç»æç¨³å®ï¼ |
| | | function hashString(str) { |
| | | let h = 2166136261; |
| | | for (let i = 0; i < str.length; i++) { |
| | | h ^= str.charCodeAt(i); |
| | | h = Math.imul(h, 16777619); |
| | | /** |
| | | * æ¥å£æ°æ® â 页é¢å
é¨é¢ç®ç»æ |
| | | * å
¥åï¼æ¥å£ dataï¼List<QuestionResultDTO>ï¼ |
| | | * åºåï¼[{ title, type, total, options: [{ option, count, score }] }] |
| | | * åä¸é¢ç®å¯è½åæ£å¨å¤ä¸ªä»»å¡ï¼tasknameï¼éï¼è¿éæãé¢ç® + é项ãåå¹¶ç´¯å æ°é |
| | | */ |
| | | function normalizeQuestions(list) { |
| | | const map = new Map(); |
| | | |
| | | // å
¥åå¯è½æ¯æ°ç» / {list} / {rows} / å对象ï¼ç»ä¸è§æ´ææ°ç» |
| | | const arr = Array.isArray(list) |
| | | ? list |
| | | : (list && |
| | | (Array.isArray(list.list) |
| | | ? list.list |
| | | : Array.isArray(list.rows) |
| | | ? list.rows |
| | | : [list])) || |
| | | []; |
| | | |
| | | // é¢ç®ææ¬å段åéï¼æ¬ç³»ç»é¢ç®å
容ç»ä¸å« scriptContentï¼å
¼å®¹åå²å½åï¼ |
| | | const pickTitle = (item) => { |
| | | const keys = [ |
| | | "scriptContent", |
| | | "questionText", |
| | | "qeustionText", |
| | | "questiontext", |
| | | "scriptcontent", |
| | | "title", |
| | | "name", |
| | | "questionName", |
| | | ]; |
| | | for (const k of keys) { |
| | | if (item && item[k] != null && String(item[k]).trim()) { |
| | | return String(item[k]).trim(); |
| | | } |
| | | return h >>> 0; |
| | | } |
| | | function mulberry32(a) { |
| | | return function () { |
| | | a |= 0; |
| | | a = (a + 0x6d2b79f5) | 0; |
| | | let t = Math.imul(a ^ (a >>> 15), 1 | a); |
| | | t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; |
| | | return ((t ^ (t >>> 14)) >>> 0) / 4294967296; |
| | | return ""; |
| | | }; |
| | | |
| | | // é项æç»åè¡¨åæ®µåé |
| | | const pickDetails = (item) => { |
| | | const keys = [ |
| | | "subtaskDetailRatioExportList", |
| | | "details", |
| | | "optionList", |
| | | "options", |
| | | "optionResultList", |
| | | "subtaskDetailRatioExportlist", |
| | | "list", |
| | | ]; |
| | | for (const k of keys) { |
| | | if (item && Array.isArray(item[k])) return item[k]; |
| | | } |
| | | return []; |
| | | }; |
| | | |
| | | // éé¡¹ææ¬åæ®µåé |
| | | const pickOption = (d) => { |
| | | const keys = [ |
| | | "optionresult", |
| | | "optioncontent", |
| | | "optionText", |
| | | "targetvalue", |
| | | "optionName", |
| | | "name", |
| | | "option", |
| | | "content", |
| | | ]; |
| | | for (const k of keys) { |
| | | if (d && d[k] != null && String(d[k]).trim()) { |
| | | return String(d[k]).trim(); |
| | | } |
| | | } |
| | | return ""; |
| | | }; |
| | | |
| | | // æ°éåæ®µåé |
| | | const pickCount = (d) => { |
| | | const keys = ["count", "chosenQuantity", "num", "total", "chosenquantity"]; |
| | | for (const k of keys) { |
| | | if (d && d[k] != null && !isNaN(Number(d[k]))) { |
| | | return Number(d[k]) || 0; |
| | | } |
| | | } |
| | | return 0; |
| | | }; |
| | | |
| | | arr.forEach((item) => { |
| | | if (!item || typeof item !== "object") return; |
| | | const title = pickTitle(item) || "æªå½åé¢ç®"; |
| | | const details = pickDetails(item); |
| | | let node = map.get(title); |
| | | if (!node) { |
| | | node = { title, type: "", options: new Map() }; |
| | | map.set(title, node); |
| | | } |
| | | |
| | | details.forEach((d) => { |
| | | const option = pickOption(d); |
| | | if (!option) return; |
| | | const count = pickCount(d); |
| | | const rawScore = Number(d && d.score); |
| | | const score = isNaN(rawScore) ? null : rawScore; |
| | | // é¢åï¼ä¼å
scriptTypeï¼1åé 2å¤é 4é®çï¼ï¼å
¶æ¬¡ valueTypeï¼1åé 2å¤é 3é®ç 4填空 5å
¶å®ï¼ |
| | | const typeVal = String( |
| | | (item && item.scriptType) || |
| | | (d && d.scriptType) || |
| | | (d && d.valueType) || |
| | | (item && item.valueType) || |
| | | "" |
| | | ); |
| | | if (!node.type) { |
| | | node.type = |
| | | typeVal === "2" ? "multiple" : typeVal === "1" ? "single" : "qa"; |
| | | } |
| | | |
| | | const old = node.options.get(option); |
| | | if (old) { |
| | | old.count += count; |
| | | if (old.score == null) old.score = score; |
| | | } else { |
| | | node.options.set(option, { option, count, score }); |
| | | } |
| | | }); |
| | | }); |
| | | |
| | | return Array.from(map.values()).map((n) => { |
| | | const options = Array.from(n.options.values()); |
| | | const item = { title: n.title, type: n.type, options }; |
| | | // å¤éé¢ï¼ç¨åé项æ°éä¹åä½ä¸ºå¡«æ¥æ»éï¼æ¥å£æªåç¬æä¾äººæ¬¡ï¼ |
| | | if (n.type === "multiple") |
| | | item.total = options.reduce((s, o) => s + o.count, 0); |
| | | return item; |
| | | }); |
| | | } |
| | | |
| | | export default { |
| | | name: 'DataOverview', |
| | | name: "DataOverview", |
| | | data() { |
| | | return { |
| | | // é¡¶é¨å
¨å±çé |
| | | queryParams: { |
| | | dateRange: [], |
| | | deptWard: '', |
| | | deptCodes: [], // ç§å®¤ç¼ç éå => leaveldeptcodes |
| | | wardCodes: [], // åºé¢ç
åºç¼ç éå => leavehospitaldistrictcodesï¼æ¥å£å¿
å¡«ï¼ |
| | | serviceTypeList: [], // æå¡ç±»åå¤éï¼æäº¤æ¶ç¨éå·æ¼æ¥ |
| | | deptOrDistrict: "1", // ç§å®¤/ç
åºç»åæ¹å¼ï¼é»è®¤ 1ï¼ç¦»é¢ç
åº and 离é¢ç§å®¤ |
| | | statMode: "ward", // ç»è®¡ç»´åº¦ï¼ward=æç
åºç»è®¡ dept=æç§å®¤ç»è®¡ |
| | | }, |
| | | deptOptions: DEPTS, |
| | | wardOptions: WARDS, |
| | | SERVICE_TYPES, |
| | | loading: false, |
| | | |
| | | // 表äºï¼é¢ç®æ¨¡ç³æ¥è¯¢å
³é®åï¼çº¯åç«¯è¿æ»¤ï¼ä¸è¯·æ±åç«¯ï¼ |
| | | questionSearch: "", |
| | | |
| | | // è¡¨æ ¼ä¸ï¼ç»è®¡ç»´åº¦ + ç¬ç«ç§å®¤/ç
åºæ¡ä»¶ï¼'inherit' = 沿ç¨é¡¶é¨ï¼ |
| | | statDimension: 'dept', |
| | | statDeptWard: 'inherit', |
| | | statDimension: "ward", |
| | | statDeptWard: "inherit", |
| | | |
| | | // ç»ä¸æ¥å£è¿åçæ°æ®ï¼æ¨¡æï¼ |
| | | // æ¥å£è¿åçåå§æ°æ®ï¼å·²å½ä¸åçé¢ç®åè¡¨ï¼ |
| | | questionList: [], |
| | | deptComparison: [], |
| | | wardComparison: [], |
| | | // 表ä¸ï¼ç§å®¤/ç
åºè¯å对æ¯ï¼rows=è¡æ°æ®ï¼questions=卿åï¼ |
| | | deptComparison: { rows: [], questions: [] }, |
| | | wardComparison: { rows: [], questions: [] }, |
| | | }; |
| | | }, |
| | | computed: { |
| | | // åºå®äºé¡¹é项çé¢ç® => è¡¨ä¸ |
| | | // ç§å®¤é项ï¼ä¼å
åå½åç¨æ·æå±ç§å®¤ï¼æ åå
åº |
| | | 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 })); |
| | | }, |
| | | // ç
åºé项ï¼ä¼å
åå½åç¨æ·æå±ç
åºï¼æ åå
åº |
| | | 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 })); |
| | | }, |
| | | // æå¡ç±»å䏿ï¼å store çé访类ååå
¸ tasktypesï¼åä¸å°æ¶å
åºæ¬å° SERVICE_TYPES |
| | | serviceTypeOptions() { |
| | | const toOptions = (list) => |
| | | (Array.isArray(list) ? list : []) |
| | | .map((i) => ({ |
| | | label: String(i.label || "").trim(), |
| | | value: String(i.value), |
| | | })) |
| | | .filter((i) => i.label && i.value && i.value !== "undefined"); |
| | | 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))); |
| | | }, |
| | | // æªéç§å®¤æ¶çé»è®¤æ¥è¯¢èå´ï¼å
¨é¨ç§å®¤ç¼ç |
| | | defaultDeptCodes() { |
| | | return Array.from(new Set(this.deptOptions.map((d) => d.value))); |
| | | }, |
| | | // åºå®å
项é项çé¢ç® => è¡¨ä¸ |
| | | satisfactionQuestions() { |
| | | return this.questionList.filter((q) => this.isSatisfactionQuestion(q)); |
| | | }, |
| | |
| | | }, |
| | | // 表ä¸ï¼æ»¡æåº¦ç»è®¡ï¼å«æ»è®¡è¡ï¼ |
| | | serviceSatisfaction() { |
| | | // åæå®é项ç { count, score }ï¼æªè¿åå该项为 0 |
| | | const pick = (q, name) => { |
| | | const hit = q.options.find((o) => o.option === name); |
| | | return hit |
| | | ? { count: Number(hit.count) || 0, score: hit.score } |
| | | : { count: 0, score: null }; |
| | | }; |
| | | const NAMES = FIXED_OPTIONS; |
| | | |
| | | const rows = this.satisfactionQuestions.map((q) => { |
| | | const m = {}; |
| | | q.options.forEach((o) => (m[o.option] = o.count)); |
| | | const veryGood = m['é常满æ'] || 0; |
| | | const good = m['满æ'] || 0; |
| | | const normal = m['ä¸è¬'] || 0; |
| | | const bad = m['䏿»¡æ'] || 0; |
| | | const na = m['ä¸éç¨'] || 0; |
| | | const total = veryGood + good + normal + bad + na; |
| | | const veryGood = pick(q, "徿»¡æ"); |
| | | const good = pick(q, "满æ"); |
| | | const normal = pick(q, "ä¸è¬"); |
| | | const bad = pick(q, "䏿»¡æ"); |
| | | const veryBad = pick(q, "å¾ä¸æ»¡æ"); |
| | | const na = pick(q, "æªç»å"); |
| | | const items = [veryGood, good, normal, bad, veryBad, na]; |
| | | const total = items.reduce((s, it) => s + it.count, 0); |
| | | return { |
| | | category: q.title, |
| | | veryGoodCount: veryGood, |
| | | veryGoodRate: this.rateOf(veryGood, total), |
| | | goodCount: good, |
| | | goodRate: this.rateOf(good, total), |
| | | normalCount: normal, |
| | | normalRate: this.rateOf(normal, total), |
| | | badCount: bad, |
| | | badRate: this.rateOf(bad, total), |
| | | naCount: na, |
| | | naRate: this.rateOf(na, total), |
| | | score: this.scoreOf([veryGood, good, normal, bad, na]), |
| | | veryGoodCount: veryGood.count, |
| | | veryGoodRate: this.rateOf(veryGood.count, total), |
| | | goodCount: good.count, |
| | | goodRate: this.rateOf(good.count, total), |
| | | normalCount: normal.count, |
| | | normalRate: this.rateOf(normal.count, total), |
| | | badCount: bad.count, |
| | | badRate: this.rateOf(bad.count, total), |
| | | veryBadCount: veryBad.count, |
| | | veryBadRate: this.rateOf(veryBad.count, total), |
| | | naCount: na.count, |
| | | naRate: this.rateOf(na.count, total), |
| | | score: this.scoreOfItems(items), |
| | | }; |
| | | }); |
| | | |
| | | // æ»è®¡è¡ |
| | | const sum = { veryGood: 0, good: 0, normal: 0, bad: 0, na: 0 }; |
| | | rows.forEach((r) => { |
| | | sum.veryGood += r.veryGoodCount; |
| | | sum.good += r.goodCount; |
| | | sum.normal += r.normalCount; |
| | | sum.bad += r.badCount; |
| | | sum.na += r.naCount; |
| | | // æ»è®¡è¡ï¼åé¢åé项æ°éç´¯å ï¼å弿²¿ç¨è¯¥é项åå¼ |
| | | const sum = NAMES.map(() => ({ count: 0, score: null })); |
| | | this.satisfactionQuestions.forEach((q) => { |
| | | NAMES.forEach((name, i) => { |
| | | const it = pick(q, name); |
| | | sum[i].count += it.count; |
| | | if (sum[i].score == null) sum[i].score = it.score; |
| | | }); |
| | | const total = sum.veryGood + sum.good + sum.normal + sum.bad + sum.na; |
| | | }); |
| | | const total = sum.reduce((s, it) => s + it.count, 0); |
| | | rows.push({ |
| | | category: 'æ»è®¡', |
| | | veryGoodCount: sum.veryGood, |
| | | veryGoodRate: this.rateOf(sum.veryGood, total), |
| | | goodCount: sum.good, |
| | | goodRate: this.rateOf(sum.good, total), |
| | | normalCount: sum.normal, |
| | | normalRate: this.rateOf(sum.normal, total), |
| | | badCount: sum.bad, |
| | | badRate: this.rateOf(sum.bad, total), |
| | | naCount: sum.na, |
| | | naRate: this.rateOf(sum.na, total), |
| | | score: this.scoreOf([sum.veryGood, sum.good, sum.normal, sum.bad, sum.na]), |
| | | category: "æ»è®¡", |
| | | veryGoodCount: sum[0].count, |
| | | veryGoodRate: this.rateOf(sum[0].count, total), |
| | | goodCount: sum[1].count, |
| | | goodRate: this.rateOf(sum[1].count, total), |
| | | normalCount: sum[2].count, |
| | | normalRate: this.rateOf(sum[2].count, total), |
| | | badCount: sum[3].count, |
| | | badRate: this.rateOf(sum[3].count, total), |
| | | veryBadCount: sum[4].count, |
| | | veryBadRate: this.rateOf(sum[4].count, total), |
| | | naCount: sum[5].count, |
| | | naRate: this.rateOf(sum[5].count, total), |
| | | score: this.scoreOfItems(sum), |
| | | }); |
| | | return rows; |
| | | }, |
| | |
| | | }; |
| | | }); |
| | | }, |
| | | // 表äºï¼æé¢ç®æ¨¡ç³æ¥è¯¢ï¼çº¯åç«¯è¿æ»¤ï¼ä¸è¯·æ±åç«¯ï¼ |
| | | filteredQuestionStats() { |
| | | const kw = (this.questionSearch || "").trim().toLowerCase(); |
| | | if (!kw) return this.questionStats; |
| | | return this.questionStats.filter((q) => |
| | | (q.title || "").toLowerCase().indexOf(kw) > -1 |
| | | ); |
| | | }, |
| | | // 表ä¸ï¼æç»´åº¦ + ç¬ç«æ¡ä»¶è¿æ»¤åçè¡ |
| | | table3Rows() { |
| | | const list = this.statDimension === 'dept' ? this.deptComparison : this.wardComparison; |
| | | const f = this.statFilter(); |
| | | if (!f) return list; |
| | | const [type, name] = f.split(':'); |
| | | if (type !== this.statDimension) return list; |
| | | return list.filter((r) => r.name === name); |
| | | const comp = |
| | | this.statDimension === "dept" |
| | | ? this.deptComparison |
| | | : this.wardComparison; |
| | | const list = (comp && comp.rows) || []; |
| | | const names = this.statFilterNames(); |
| | | if (!names || !names.length) return list; |
| | | return list.filter((r) => names.indexOf(r.name) > -1); |
| | | }, |
| | | // 表ä¸ï¼å½å维度ä¸çé¢ç®åï¼å¨æåï¼ |
| | | table3Questions() { |
| | | const comp = |
| | | this.statDimension === "dept" |
| | | ? this.deptComparison |
| | | : this.wardComparison; |
| | | return (comp && comp.questions) || []; |
| | | }, |
| | | }, |
| | | mounted() { |
| | | created() { |
| | | if (!this.queryParams.dateRange || !this.queryParams.dateRange.length) { |
| | | this.queryParams.dateRange = this.defaultRange(); |
| | | } |
| | | this.queryParams.serviceTypeList = this.defaultServiceTypes(); |
| | | }, |
| | | mounted() { |
| | | this.fetchData(); |
| | | }, |
| | | methods: { |
| | | // 表ä¸ç¬ç«æ¡ä»¶ï¼'inherit' æ¶æ²¿ç¨é¡¶é¨æ¡ä»¶ |
| | | statFilter() { |
| | | const v = this.statDeptWard === 'inherit' ? this.queryParams.deptWard : this.statDeptWard; |
| | | return v || ''; |
| | | // é»è®¤éä¸çæå¡ç±»åï¼æ label å¹é
ï¼åä¸å°å°±è¿å空æ°ç» = ä¸éï¼ |
| | | defaultServiceTypes() { |
| | | const hit = DEFAULT_SERVICE_LABELS.map((label) => { |
| | | const item = this.serviceTypeOptions.find((o) => o.label === label); |
| | | return item ? item.value : null; |
| | | }).filter((v) => v != null); |
| | | return Array.from(new Set(hit)); |
| | | }, |
| | | // 表ä¸ç¬ç«æ¡ä»¶ï¼'inherit' æ¶æ²¿ç¨é¡¶é¨æéï¼è¿åéä¸çåç§°æ°ç»ï¼æ¥å£åªååç§°ï¼ï¼ç©ºæ°ç»è¡¨ç¤ºä¸é |
| | | statFilterNames() { |
| | | const opts = |
| | | this.statDimension === "dept" ? this.deptOptions : this.wardOptions; |
| | | const nameOf = (code) => { |
| | | const hit = opts.find((o) => String(o.value) === String(code)); |
| | | return hit ? hit.label : null; |
| | | }; |
| | | if (this.statDeptWard === "inherit") { |
| | | const codes = |
| | | this.statDimension === "dept" |
| | | ? this.queryParams.deptCodes |
| | | : this.queryParams.wardCodes; |
| | | return (codes || []).map(nameOf).filter(Boolean); |
| | | } |
| | | // åæ¢ç»´åº¦åï¼è¥å·²éæ¡ä»¶ä¸å±äºå½å维度åè§ä¸ºä¸é |
| | | if (this.statDeptWard.startsWith(this.statDimension + ":")) { |
| | | const name = nameOf(this.statDeptWard.slice(this.statDimension.length + 1)); |
| | | return name ? [name] : []; |
| | | } |
| | | return []; |
| | | }, |
| | | onStatDimensionChange() { |
| | | // åæ¢ç»´åº¦åï¼è¥å½å已鿡件ä¸å±äºæ°ç»´åº¦ï¼åæ¢å¤â沿ç¨é¡¶é¨â |
| | | if (this.statDeptWard !== 'inherit' && !this.statDeptWard.startsWith(this.statDimension + ':')) { |
| | | this.statDeptWard = 'inherit'; |
| | | if ( |
| | | this.statDeptWard !== "inherit" && |
| | | !this.statDeptWard.startsWith(this.statDimension + ":") |
| | | ) { |
| | | this.statDeptWard = "inherit"; |
| | | } |
| | | }, |
| | | handleReset() { |
| | | this.queryParams.dateRange = this.defaultRange(); |
| | | this.queryParams.deptWard = ''; |
| | | this.queryParams.deptCodes = []; |
| | | this.queryParams.wardCodes = []; |
| | | this.queryParams.statMode = "ward"; |
| | | this.statDimension = "ward"; |
| | | this.statDeptWard = "inherit"; |
| | | this.queryParams.serviceTypeList = this.defaultServiceTypes(); |
| | | this.fetchData(); |
| | | }, |
| | | // 夿é¢ç®é项æ¯å¦ä¸ºåºå®æ»¡æåº¦äºé¡¹ |
| | | // 忢ç»è®¡ç»´åº¦ï¼ç§å®¤/ç
åºï¼æ¶æ¸
空å¦ä¸ç»´åº¦çéæ©ï¼ä¿è¯äºæ¥ |
| | | onStatModeChange() { |
| | | if (this.queryParams.statMode === "dept") { |
| | | this.queryParams.wardCodes = []; |
| | | } else { |
| | | this.queryParams.deptCodes = []; |
| | | } |
| | | // åå忥å°ãåç§å®¤/ç
åºæ»¡æåº¦è¯å对æ¯ã表ï¼é¡¶é¨ â è¡¨ä¸ |
| | | this.statDimension = this.queryParams.statMode; |
| | | this.onStatDimensionChange(); |
| | | }, |
| | | // 夿é¢ç®æ¯å¦ä¸ºæ»¡æåº¦å
项é项é¢ï¼ææé项é½è½å¨åºå®å
项å
å³å½è¡¨ä¸ |
| | | isSatisfactionQuestion(q) { |
| | | if (q.options.length !== FIXED_OPTIONS.length) return false; |
| | | const set = q.options.map((o) => o.option); |
| | | return FIXED_OPTIONS.every((o) => set.includes(o)); |
| | | if (!q.options || !q.options.length) return false; |
| | | return q.options.every((o) => FIXED_OPTIONS.includes(o.option)); |
| | | }, |
| | | questionTotal(q) { |
| | | if (q.total != null) return q.total; |
| | | return q.options.reduce((s, o) => s + o.count, 0); |
| | | }, |
| | | rateOf(count, total) { |
| | | if (!total) return '0.00%'; |
| | | return ((count / total) * 100).toFixed(2) + '%'; |
| | | if (!total) return "0.00%"; |
| | | return ((count / total) * 100).toFixed(2) + "%"; |
| | | }, |
| | | // 综åå¾åï¼é常满æ5åãæ»¡æ4åãä¸è¬3åã䏿»¡æ2åï¼æ¢ç®ç¾åå¶ï¼ä¸éç¨ä¸è®¡å
¥ï¼ââå ä½å
¬å¼ï¼æ¥å£å°±ç»ªå坿å端å£å¾æ¿æ¢ |
| | | scoreOf(counts) { |
| | | const [a, b, c, d] = counts; |
| | | const total = a + b + c + d; |
| | | if (!total) return '0.00'; |
| | | return (((a * 5 + b * 4 + c * 3 + d * 2) / total) * 20).toFixed(2); |
| | | /** |
| | | * 综åå¾åï¼çå®å£å¾ï¼ï¼Î£(åé项åå¼ Ã å¡«æ¥é) / Σ(å¡«æ¥é) |
| | | * items: [{ count, score }]ï¼score 忥å£è¿åç score åæ®µ |
| | | * æ åå¼é项ï¼å¦"æªç»å"ï¼é»è®¤ä¸è®¡å
¥ååä¸åæ¯ï¼é¿å
æä½å¾å |
| | | */ |
| | | scoreOfItems(items) { |
| | | let numerator = 0; |
| | | let denominator = 0; |
| | | items.forEach((it) => { |
| | | const count = Number(it && it.count) || 0; |
| | | const score = Number(it && it.score); |
| | | const hasScore = !isNaN(score); |
| | | if (!hasScore && !NO_SCORE_IN_DENOMINATOR) return; |
| | | numerator += (hasScore ? score : 0) * count; |
| | | denominator += count; |
| | | }); |
| | | if (!denominator) return "0.00"; |
| | | return (numerator / denominator).toFixed(2); |
| | | }, |
| | | defaultRange() { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setDate(start.getDate() - 29); |
| | | start.setDate(start.getDate() - 91); |
| | | const f = (d) => { |
| | | const y = d.getFullYear(); |
| | | const m = String(d.getMonth() + 1).padStart(2, '0'); |
| | | const day = String(d.getDate()).padStart(2, '0'); |
| | | const m = String(d.getMonth() + 1).padStart(2, "0"); |
| | | const day = String(d.getDate()).padStart(2, "0"); |
| | | return `${y}-${m}-${day}`; |
| | | }; |
| | | return [f(start), f(end)]; |
| | | }, |
| | | dateRangeDays(range) { |
| | | if (Array.isArray(range) && range.length === 2 && range[0] && range[1]) { |
| | | const ms = new Date(range[1]).getTime() - new Date(range[0]).getTime(); |
| | | return Math.max(1, Math.round(ms / 86400000)); |
| | | // æç¤ºä¿¡æ¯ï¼å
¼å®¹ $modal ä¸ $messageï¼ |
| | | notify(msg, type) { |
| | | const map = { |
| | | warning: ["msgWarning", "warning"], |
| | | error: ["msgError", "error"], |
| | | success: ["msgSuccess", "success"], |
| | | }; |
| | | const [modalFn, msgFn] = map[type] || map.success; |
| | | if (this.$modal && this.$modal[modalFn]) { |
| | | this.$modal[modalFn](msg); |
| | | } else if (this.$message && this.$message[msgFn]) { |
| | | this.$message[msgFn](msg); |
| | | } |
| | | return 30; |
| | | }, |
| | | // æåæ°æ®ï¼å½åä¸ºæ¨¡ææ°æ®ï¼æ¥å£å°±ç»ªåæ¿æ¢ä¸ºçå®è¯·æ±ï¼ |
| | | fetchData() { |
| | | const data = this.mockFetch(this.queryParams); |
| | | this.questionList = data.questionList; |
| | | this.deptComparison = data.deptComparison; |
| | | this.wardComparison = data.wardComparison; |
| | | }, |
| | | mockFetch(params) { |
| | | const seed = hashString(JSON.stringify(params)); |
| | | const rnd = mulberry32(seed); |
| | | const days = this.dateRangeDays(params.dateRange); |
| | | const timeFactor = Math.max(0.05, days / 30); |
| | | const scopeFactor = params.deptWard ? 0.18 : 1; |
| | | const jitter = () => 0.9 + rnd() * 0.2; |
| | | // æå满æåº¦ç»è®¡æ°æ®ï¼æ¥å£ï¼/smartor/serviceSubtaskDetail/sltdMydTotalByScoreï¼ |
| | | async fetchData() { |
| | | const range = this.queryParams.dateRange || []; |
| | | if (range.length !== 2 || !range[0] || !range[1]) { |
| | | this.notify("请å
éæ©åºé¢æ¥æèå´", "warning"); |
| | | return; |
| | | } |
| | | |
| | | const questionList = RAW_QUESTIONS.map((q) => { |
| | | const options = q.options.map((o) => ({ |
| | | option: o.option, |
| | | count: Math.round(o.count * timeFactor * scopeFactor * jitter()), |
| | | })); |
| | | const item = { title: q.title, type: q.type, options }; |
| | | if (q.type === 'multiple' && q.total != null) { |
| | | item.total = Math.round(q.total * timeFactor * scopeFactor); |
| | | // ç
åº => leavehospitaldistrictcodesï¼ç§å®¤ => leaveldeptcodes |
| | | // ç§å®¤/ç
åºäºæ¥ï¼æç
åºåªä¼ leavehospitaldistrictcodesï¼æç§å®¤åªä¼ leaveldeptcodes |
| | | const wards = this.queryParams.wardCodes || []; |
| | | const depts = this.queryParams.deptCodes || []; |
| | | |
| | | const payload = { |
| | | deptOrDistrict: this.queryParams.deptOrDistrict || "1", |
| | | startFinishTime: range[0], |
| | | endFinishTime: range[1], |
| | | }; |
| | | if (this.queryParams.statMode === "dept") { |
| | | payload.leaveldeptcodes = depts.length |
| | | ? Array.from(new Set(depts)) |
| | | : this.defaultDeptCodes; |
| | | } else { |
| | | payload.leavehospitaldistrictcodes = wards.length |
| | | ? Array.from(new Set(wards)) |
| | | : this.defaultWardCodes; |
| | | } |
| | | return item; |
| | | // æå¡ç±»åå¤éï¼éå·åéï¼æ¥å£å段为 serviceType åç¬¦ä¸²ï¼ |
| | | const serviceTypes = this.queryParams.serviceTypeList || []; |
| | | if (serviceTypes.length) payload.serviceType = serviceTypes.join(","); |
| | | payload.serviceTypeList = serviceTypes; |
| | | this.loading = true; |
| | | try { |
| | | const res = await sltdMydTotalByScore(payload); |
| | | // ææ¥ç¨ï¼æå°æ¥å£åå§è¿åï¼ä¾¿äºæ ¸å¯¹å段åï¼ç¡®è®¤æ 误åå¯å é¤ï¼ |
| | | console.log( |
| | | "[sltdMydTotalByScore] code=", |
| | | res && res.code, |
| | | "data=", |
| | | JSON.stringify(res && res.data).slice(0, 2000) |
| | | ); |
| | | if (res && res.code === 200) { |
| | | this.questionList = normalizeQuestions(res.data); |
| | | if (!this.questionList.length) |
| | | this.notify("å½åæ¡ä»¶ä¸ææ ç»è®¡æ°æ®", "warning"); |
| | | } else { |
| | | this.questionList = []; |
| | | this.notify((res && res.msg) || "ç»è®¡æ°æ®è·å失败", "error"); |
| | | } |
| | | // 表ä¸ï¼åç§å®¤/ç
åºæ»¡æåº¦è¯å对æ¯ï¼ç宿¥å£ï¼å
é¨èªè¡å¤çéè¯¯ï¼ |
| | | await this.fetchComparison(); |
| | | } catch (e) { |
| | | this.questionList = []; |
| | | this.notify("ç»è®¡æ°æ®è¯·æ±å¤±è´¥ï¼è¯·ç¨åéè¯", "error"); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | // æååç§å®¤/ç
åºæ»¡æåº¦è¯å对æ¯ï¼æ¥å£ï¼/smartor/serviceSubtaskDetail/statQuestionOptionByKsOrBqï¼ |
| | | async fetchComparison() { |
| | | const range = this.queryParams.dateRange || []; |
| | | if (range.length !== 2 || !range[0] || !range[1]) { |
| | | this.deptComparison = { rows: [], questions: [] }; |
| | | this.wardComparison = { rows: [], questions: [] }; |
| | | return; |
| | | } |
| | | const base = { |
| | | deptOrDistrict: this.queryParams.deptOrDistrict || "1", |
| | | startFinishTime: range[0], |
| | | endFinishTime: range[1], |
| | | }; |
| | | try { |
| | | // æç§å®¤ç»è®¡ï¼leaveldeptcodes ä¼å
ï¼ä¸æç
åºç»è®¡ï¼leavehospitaldistrictcodesï¼åæ¥ä¸æ¬¡ |
| | | const [deptRes, wardRes] = await Promise.all([ |
| | | statQuestionOptionByKsOrBq({ ...base, leaveldeptcodes: this.defaultDeptCodes }), |
| | | statQuestionOptionByKsOrBq({ ...base, leavehospitaldistrictcodes: this.defaultWardCodes }), |
| | | ]); |
| | | // ææ¥ç¨ï¼æå°æ¥å£åå§è¿åï¼ä¾¿äºæ ¸å¯¹ä¸¤çº§åµå¥ Map ç»æï¼ç¡®è®¤æ 误åå¯å é¤ï¼ |
| | | console.log( |
| | | "[statQuestionOptionByKsOrBq] dept code=", |
| | | deptRes && deptRes.code, |
| | | "data=", |
| | | JSON.stringify(deptRes && deptRes.data).slice(0, 2000), |
| | | "| ward code=", |
| | | wardRes && wardRes.code, |
| | | "data=", |
| | | JSON.stringify(wardRes && wardRes.data).slice(0, 2000) |
| | | ); |
| | | this.deptComparison = this.buildComparison( |
| | | deptRes && deptRes.code === 200 ? deptRes.data : {}, |
| | | "dept" |
| | | ); |
| | | this.wardComparison = this.buildComparison( |
| | | wardRes && wardRes.code === 200 ? wardRes.data : {}, |
| | | "ward" |
| | | ); |
| | | } catch (e) { |
| | | this.deptComparison = { rows: [], questions: [] }; |
| | | this.wardComparison = { rows: [], questions: [] }; |
| | | console.error("è·åç§å®¤/ç
åºè¯å对æ¯å¤±è´¥:", e); |
| | | } |
| | | }, |
| | | // ç»è£
ä¸ºè¡¨ä¸æéçè¡/åç»æï¼è¡=ç§å®¤/ç
åºï¼å=é¢ç®Ãé项 + å¾å + 综åå¾å |
| | | // æ°æ¥å£è¿å两级åµå¥ Mapï¼{ ç§å®¤/ç
åºåç§°: { é¢ç®å
容: [QuestionCountKsOrBqDTO] } } |
| | | // å
¼å®¹æ§æå¹³æ°ç»ï¼[{ questionText, deptname, leavehospitaldistrictname, targetvalue, answerCount, singleScore }] |
| | | buildComparison(data, mode) { |
| | | const questions = []; |
| | | const qMap = new Map(); |
| | | const rowMap = new Map(); |
| | | |
| | | // å°ä¸æ¡ (åç§°, é¢ç®, é项, æ°é, å¾å) æç»ç´¯å è¿è¡/åç»æ |
| | | const collect = (name, title, option, count, single) => { |
| | | if (!title || !name) return; |
| | | let q = qMap.get(title); |
| | | if (!q) { |
| | | q = { title, options: [] }; |
| | | qMap.set(title, q); |
| | | questions.push(q); |
| | | } |
| | | if (option && q.options.indexOf(option) === -1) q.options.push(option); |
| | | |
| | | let row = rowMap.get(name); |
| | | if (!row) { |
| | | row = { name, code: this.codeFor(mode, name), cells: {} }; |
| | | rowMap.set(name, row); |
| | | } |
| | | if (!row.cells[title]) row.cells[title] = {}; |
| | | const cell = row.cells[title][option] || { count: 0, score: 0 }; |
| | | cell.count += count; |
| | | cell.score += single; |
| | | row.cells[title][option] = cell; |
| | | }; |
| | | |
| | | if (Array.isArray(data)) { |
| | | // æ§ç»æï¼æå¹³æ°ç» |
| | | data.forEach((it) => { |
| | | const title = it.questionText || it.qeustionText || ""; |
| | | const name = |
| | | mode === "dept" |
| | | ? it.deptname || "" |
| | | : it.leavehospitaldistrictname || ""; |
| | | const option = it.targetvalue || it.asrtext || ""; |
| | | collect(name, title, option, Number(it.answerCount) || 0, Number(it.singleScore) || 0); |
| | | }); |
| | | } else if (data && typeof data === "object") { |
| | | // æ°ç»æï¼ä¸¤çº§åµå¥ Mapï¼ç¬¬ä¸å± key=ç§å®¤/ç
åºåç§°ï¼ç¬¬äºå± key=é¢ç®ï¼value=é项æç»å表 |
| | | Object.keys(data).forEach((name) => { |
| | | const questionMap = data[name] || {}; |
| | | Object.keys(questionMap).forEach((title) => { |
| | | const list = Array.isArray(questionMap[title]) ? questionMap[title] : []; |
| | | list.forEach((it) => { |
| | | const option = it.targetvalue || it.asrtext || ""; |
| | | collect(name, title, option, Number(it.answerCount) || 0, Number(it.singleScore) || 0); |
| | | }); |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | const rows = Array.from(rowMap.values()); |
| | | rows.forEach((row) => { |
| | | let totalCount = 0; |
| | | let totalScore = 0; |
| | | questions.forEach((q) => { |
| | | const cells = row.cells[q.title] || {}; |
| | | let qCount = 0; |
| | | let qScore = 0; |
| | | q.options.forEach((opt) => { |
| | | const c = cells[opt]; |
| | | if (c) { |
| | | qCount += c.count; |
| | | qScore += c.score; |
| | | } |
| | | }); |
| | | // 该é¢ç®å æå¹³ååï¼Î£ singleScore / Σ answerCount |
| | | cells._score = qCount ? (qScore / qCount).toFixed(2) : "0.00"; |
| | | totalCount += qCount; |
| | | totalScore += qScore; |
| | | row.cells[q.title] = cells; |
| | | }); |
| | | row.totalScore = totalCount ? (totalScore / totalCount).toFixed(2) : "0.00"; |
| | | }); |
| | | |
| | | const deptComparison = DEPTS.map((d) => this.genCompareRow(d, rnd)); |
| | | const wardComparison = WARDS.map((w) => this.genCompareRow(w, rnd)); |
| | | |
| | | return { questionList, deptComparison, wardComparison }; |
| | | return { rows, questions }; |
| | | }, |
| | | genCompareRow(name, rnd) { |
| | | const r = (lo, hi) => Math.round(lo + rnd() * (hi - lo)); |
| | | const q1VeryGood = r(20, 180); |
| | | const q1Good = r(5, 55); |
| | | const q1Normal = r(0, 4); |
| | | const q1Bad = r(0, 3); |
| | | const q2VeryGood = r(18, 175); |
| | | const q2Good = r(5, 55); |
| | | const q2Normal = r(0, 4); |
| | | const q2Bad = r(0, 3); |
| | | return { |
| | | name, |
| | | q1VeryGood, q1Good, q1Normal, q1Bad, |
| | | q1Score: this.scoreOf([q1VeryGood, q1Good, q1Normal, q1Bad]), |
| | | q2VeryGood, q2Good, q2Normal, q2Bad, |
| | | q2Score: this.scoreOf([q2VeryGood, q2Good, q2Normal, q2Bad]), |
| | | totalScore: this.scoreOf([ |
| | | q1VeryGood + q2VeryGood, |
| | | q1Good + q2Good, |
| | | q1Normal + q2Normal, |
| | | q1Bad + q2Bad, |
| | | ]), |
| | | }; |
| | | // åç§° â ç¼ç ï¼ç¨äºè¡¨ä¸æé¡¶é¨æéç¼ç è¿æ»¤ï¼ |
| | | codeFor(mode, name) { |
| | | const opts = mode === "dept" ? this.deptOptions : this.wardOptions; |
| | | const hit = opts.find((o) => String(o.label) === String(name)); |
| | | return hit ? hit.value : name; |
| | | }, |
| | | exportTable(tableId) { |
| | | const tableNames = { table1: 'åæå¡é¡¹ç®æ»¡æåº¦ç»è®¡', table2: 'åéé¢å¤éé¢ç»è®¡', table3: 'åç§å®¤æ»¡æåº¦è¯å对æ¯' }; |
| | | const name = tableNames[tableId] || 'ç»è®¡æ°æ®'; |
| | | const tableNames = { |
| | | table1: "åæå¡é¡¹ç®æ»¡æåº¦ç»è®¡", |
| | | table2: "åéé¢å¤éé¢ç»è®¡", |
| | | table3: "åç§å®¤æ»¡æåº¦è¯å对æ¯", |
| | | }; |
| | | const name = tableNames[tableId] || "ç»è®¡æ°æ®"; |
| | | const table = document.getElementById(tableId); |
| | | if (!table) return; |
| | | |
| | |
| | | // ä»è¡¨æ ¼æåæ°æ®æå»ºå¸¦æ ·å¼ç Excel |
| | | const wb = XLSX.utils.book_new(); |
| | | const data = []; |
| | | table.querySelectorAll('tr').forEach((tr) => { |
| | | table.querySelectorAll("tr").forEach((tr) => { |
| | | const row = []; |
| | | tr.querySelectorAll('th,td').forEach((td) => { |
| | | row.push((td.innerText || '').trim()); |
| | | tr.querySelectorAll("th,td").forEach((td) => { |
| | | row.push((td.innerText || "").trim()); |
| | | }); |
| | | if (row.length) data.push(row); |
| | | }); |
| | |
| | | const ws = XLSX.utils.aoa_to_sheet(data); |
| | | // 设置å宽 |
| | | const colWidths = data[0] ? data[0].map(() => ({ wch: 16 })) : []; |
| | | ws['!cols'] = colWidths; |
| | | ws["!cols"] = colWidths; |
| | | |
| | | XLSX.utils.book_append_sheet(wb, ws, 'Sheet1'); |
| | | XLSX.writeFile(wb, name + '.xlsx'); |
| | | XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); |
| | | XLSX.writeFile(wb, name + ".xlsx"); |
| | | } catch (e) { |
| | | // fallback: CSV |
| | | let csv = ''; |
| | | table.querySelectorAll('tr').forEach((tr) => { |
| | | let csv = ""; |
| | | table.querySelectorAll("tr").forEach((tr) => { |
| | | const row = []; |
| | | tr.querySelectorAll('th,td').forEach((td) => row.push('"' + (td.innerText || '').replace(/"/g, '""') + '"')); |
| | | csv += row.join(',') + '\n'; |
| | | tr.querySelectorAll("th,td").forEach((td) => |
| | | row.push('"' + (td.innerText || "").replace(/"/g, '""') + '"') |
| | | ); |
| | | csv += row.join(",") + "\n"; |
| | | }); |
| | | const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); |
| | | const link = document.createElement('a'); |
| | | const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" }); |
| | | const link = document.createElement("a"); |
| | | link.href = URL.createObjectURL(blob); |
| | | link.download = name + '.csv'; |
| | | link.download = name + ".csv"; |
| | | link.click(); |
| | | } |
| | | }, |
| | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .data-overview { .overview-card { margin-bottom: 20px; } } |
| | | .filter-card { .filter-form { margin-bottom: -10px; } .filter-select { width: 200px; } } |
| | | .card-header { display: flex; justify-content: space-between; align-items: center; } |
| | | .card-title { font-size: 16px; font-weight: 600; color: #303133; } |
| | | .header-right { display: flex; align-items: center; .stat-select { width: 180px; margin: 0 12px; } } |
| | | .question-block { margin-bottom: 24px; |
| | | .q-title { margin: 0 0 12px 0; font-size: 14px; color: #606266; } |
| | | .q-footer { margin-top: 8px; font-size: 13px; color: #909399; text-align: right; } |
| | | .data-overview { |
| | | .overview-card { |
| | | margin-bottom: 20px; |
| | | } |
| | | } |
| | | .filter-card { |
| | | .filter-form { |
| | | margin-bottom: -10px; |
| | | } |
| | | .filter-select { |
| | | width: 220px; |
| | | } |
| | | .filter-select-sm { |
| | | width: 150px; |
| | | } |
| | | } |
| | | .empty-tip { |
| | | padding: 40px 0; |
| | | text-align: center; |
| | | color: #909399; |
| | | font-size: 13px; |
| | | } |
| | | .table2-scroll { |
| | | max-height: 560px; |
| | | overflow-y: auto; |
| | | } |
| | | .card-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | .card-title { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | .header-right { |
| | | display: flex; |
| | | align-items: center; |
| | | .stat-select { |
| | | width: 180px; |
| | | margin: 0 12px; |
| | | } |
| | | .search-input { |
| | | width: 200px; |
| | | margin-right: 12px; |
| | | } |
| | | } |
| | | .question-block { |
| | | margin-bottom: 24px; |
| | | .q-title { |
| | | margin: 0 0 12px 0; |
| | | font-size: 14px; |
| | | color: #606266; |
| | | } |
| | | .q-footer { |
| | | margin-top: 8px; |
| | | font-size: 13px; |
| | | color: #909399; |
| | | text-align: right; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | statisticaltype: 1, |
| | | leavehospitaldistrictcodes: ["all"], |
| | | deptcodes: [], |
| | | serviceType: [], |
| | | serviceType: [2], |
| | | dateRange: [], |
| | | pageNum: 1, |
| | | pageSize: 20, |
| | |
| | | |
| | | // æå¡ç±»åé项 |
| | | options: [ |
| | | { |
| | | value: 6, |
| | | label: "ä½é¢æ»¡æåº¦", |
| | | raw: { |
| | | cssClass: "", |
| | | listClass: "", |
| | | }, |
| | | }, |
| | | // { |
| | | // value: 6, |
| | | // label: "ä½é¢æ»¡æåº¦", |
| | | // raw: { |
| | | // cssClass: "", |
| | | // listClass: "", |
| | | // }, |
| | | // }, |
| | | |
| | | { |
| | | value: 14, |
| | | label: "é¨è¯æ»¡æåº¦", |
| | | raw: { |
| | | cssClass: "", |
| | | listClass: "", |
| | | }, |
| | | }, |
| | | // { |
| | | // value: 14, |
| | | // label: "é¨è¯æ»¡æåº¦", |
| | | // raw: { |
| | | // cssClass: "", |
| | | // listClass: "", |
| | | // }, |
| | | // }, |
| | | ], |
| | | |
| | | // è¡¨æ ¼æ°æ® |
| | |
| | | // è·åç§å®¤æ |
| | | getDeptTree() { |
| | | // è·åæå¡ç±»å |
| | | // this.options = this.$store.getters.tasktypes || []; |
| | | this.options = this.$store.getters.tasktypes || []; |
| | | |
| | | // è·åç§å®¤å表 |
| | | this.flatArraydept = (this.$store.getters.belongDepts || []).map( |
| | |
| | | |
| | | <div |
| | | id="satisfactionBarChart" |
| | | v-loading="loading" |
| | | element-loading-text="ç»è®¡å è½½ä¸..." |
| | | style="width: 100%; height: 400px" |
| | | ></div> |
| | | </div> |
| | |
| | | } |
| | | return this.wardList.map((ward) => ward.value); |
| | | }, |
| | | |
| | | // é®é¢ç»´åº¦éåï¼ä» dimensionality_type åå
¸å维度ç¼ç ï¼æ¥ç»´åº¦æ¶å¿
ä¼ |
| | | dimensionList() { |
| | | const dict = this.dict && this.dict.type && this.dict.type.dimensionality_type; |
| | | return dict ? dict.map((d) => String(d.value)) : []; |
| | | }, |
| | | }, |
| | | |
| | | mounted() { |
| | |
| | | deptcodes: this.deptCodes, // 使ç¨è®¡ç®å±æ§ |
| | | hospitaldistrictcodes: this.hospitalDistrictCodes, // 使ç¨è®¡ç®å±æ§ |
| | | templateid: this.templateId, |
| | | questionType: this.queryParams.type || null, |
| | | serviceTypes: this.defaultServiceTypes, |
| | | dimensionList: this.dimensionList, // é®é¢ç»´åº¦éåï¼æ¥ç»´åº¦æ¶å¿
ä¼ |
| | | }; |
| | | |
| | | const response = await satisfactionGraphDimension(params); |
| | |
| | | return { |
| | | scriptContent: item.scriptContent || "", |
| | | scriptType: 1, |
| | | answerPerson: item.answerPerson || 0, |
| | | noAnswerPerson: item.noAnswerPerson || 0, |
| | | answerCount: item.answerPerson || 0, |
| | | averageScore: item.averageScore || 0, |
| | | maxScore: item.maxScore || 0, |
| | | minScore: item.minScore || 0, |
| | | answerRate: item.answerRate || 0, |
| | | totalCount: (item.answerPerson || 0) + (item.noAnswerPerson || 0), |
| | | answerPerson: Number(item.answerPerson) || 0, |
| | | noAnswerPerson: Number(item.noAnswerPerson) || 0, |
| | | answerCount: Number(item.answerPerson) || 0, |
| | | averageScore: Number(item.averageScore) || 0, |
| | | maxScore: Number(item.maxScore) || 0, |
| | | minScore: Number(item.minScore) || 0, |
| | | answerRate: Number(item.answerRate) || 0, |
| | | totalCount: (Number(item.answerPerson) || 0) + (Number(item.noAnswerPerson) || 0), |
| | | options: options, |
| | | }; |
| | | }); |
| | |
| | | templateid: this.templateId, |
| | | questionType: this.queryParams.type || null, |
| | | serviceTypes: this.defaultServiceTypes, |
| | | dimensionList: this.dimensionList, // é®é¢ç»´åº¦éåï¼æ¥ç»´åº¦æ¶å¿
ä¼ |
| | | }; |
| | | |
| | | const response = await statisticsByDimension(params); |
| | |
| | | dimension: item.dimension || "0", // 维度代ç |
| | | dimensionName: this.getDimensionLabel(item.dimension || "0"), // 维度åç§° |
| | | scriptType: 1, |
| | | answerPerson: item.answerPerson || 0, |
| | | noAnswerPerson: item.noAnswerPerson || 0, |
| | | answerCount: item.answerPerson || 0, |
| | | averageScore: item.averageScore || 0, |
| | | maxScore: item.maxScore || 0, |
| | | minScore: item.minScore || 0, |
| | | answerRate: item.answerRate || 0, |
| | | totalCount: (item.answerPerson || 0) + (item.noAnswerPerson || 0), |
| | | answerPerson: Number(item.answerPerson) || 0, |
| | | noAnswerPerson: Number(item.noAnswerPerson) || 0, |
| | | answerCount: Number(item.answerPerson) || 0, |
| | | averageScore: Number(item.averageScore) || 0, |
| | | maxScore: Number(item.maxScore) || 0, |
| | | minScore: Number(item.minScore) || 0, |
| | | answerRate: Number(item.answerRate) || 0, |
| | | totalCount: (Number(item.answerPerson) || 0) + (Number(item.noAnswerPerson) || 0), |
| | | options: options, |
| | | }; |
| | | }); |
| | |
| | | this.getList(1); |
| | | }, |
| | | onthatday() { |
| | | this.topqueryParams.startSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.sendstateView = 1; // å¾
é访 |
| | | this.topqueryParams.sendstate = null; |
| | | this.topqueryParams.startSendDateTime = null; |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); // å¼å§éè®¿æ¥æ <= ä»å¤© |
| | | this.getList(1); |
| | | }, |
| | | getCurrentDate() { |
| | |
| | | return now.toISOString().slice(0, 10); // æªåå10个å符ï¼å³ YYYY-MM-DD |
| | | }, |
| | | buidegetTasklist(type) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | // ç¨æ·æé䏿æå¾
é访任å¡ï¼ä¼ éå
¨é¨ç§å®¤åç
åº |
| | | this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | // æ¥åå¼å¸¸è·³è½¬ |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | sendstateView: 1, |
| | | leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | | buidegetTasklist(obj).then((response) => { |
| | |
| | | }); |
| | | }, |
| | | buidegetTasklist(type) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | // ç¨æ·æé䏿æå¾
é访任å¡ï¼ä¼ éå
¨é¨ç§å®¤åç
åº |
| | | this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | // æ¥åå¼å¸¸è·³è½¬ |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | sendstateView: 1, |
| | | leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | | buidegetTasklist(obj).then((response) => { |
| | |
| | | }); |
| | | }, |
| | | onthatday() { |
| | | this.topqueryParams.startSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.sendstateView = 1; // å¾
é访 |
| | | this.topqueryParams.sendstate = null; |
| | | this.topqueryParams.startSendDateTime = null; |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); // å¼å§éè®¿æ¥æ <= ä»å¤© |
| | | this.getList(1); |
| | | }, |
| | | getCurrentDate() { |
| | |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <!-- <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | | <el-button |
| | |
| | | > |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-col> --> |
| | | <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | |
| | | topqueryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | sendstateView:2, |
| | | sendstateView:1, |
| | | sort: localStorage.getItem("orgname") == "丽水å¸ä¸å»é¢" ? 8 : 2, //0 æå¡æ¶é´(æ£åº) 1 æå¡æ¶é´(ååº) 2 åéæ¶é´(æ£åº) 3 åéæ¶é´(ååº) 7åºéè®¿æ¥æ(ååº) åºéè®¿æ¥æ(æ£åº) |
| | | serviceType: 3, |
| | | searchscope: 3, |
| | |
| | | this.getList(1); |
| | | }, |
| | | onthatday() { |
| | | this.topqueryParams.startSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.sendstateView = 1; // å¾
é访 |
| | | this.topqueryParams.sendstate = null; |
| | | this.topqueryParams.startSendDateTime = null; |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); // å¼å§éè®¿æ¥æ <= ä»å¤© |
| | | this.getList(1); |
| | | }, |
| | | getCurrentDate() { |
| | |
| | | return now.toISOString().slice(0, 10); // æªåå10个å符ï¼å³ YYYY-MM-DD |
| | | }, |
| | | buidegetTasklist(type) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | // ç¨æ·æé䏿æå¾
é访任å¡ï¼ä¼ éå
¨é¨ç§å®¤åç
åº |
| | | this.topqueryParams.visitDeptCodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | | // this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | | // (obj) => obj.deptCode |
| | | // ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | // æ¥åå¼å¸¸è·³è½¬ |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | sendstateView: 1, |
| | | visitDeptCodes: this.topqueryParams.visitDeptCodes, |
| | | // leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | |
| | | resetQuery() { |
| | | this.dateRange = []; |
| | | this.dateRangefs = []; |
| | | this.serviceStatusValue = 10; |
| | | |
| | | this.topqueryParams = { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | sendstateView:2, |
| | | sendstateView:1, |
| | | sort: 2, //0 æå¡æ¶é´(æ£åº) 1 æå¡æ¶é´(ååº) 2 åéæ¶é´(æ£åº) 3 åéæ¶é´(ååº) |
| | | serviceType: 3, |
| | | searchscope: 3, |
| | |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <!-- <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | | <el-button |
| | |
| | | > |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-col> --> |
| | | <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | |
| | | topqueryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | sendstateView:2, |
| | | sendstateView:1, |
| | | sort: localStorage.getItem("orgname") == "丽水å¸ä¸å»é¢" ? 8 : 2, //0 å»¶ç»æ¤çæ¶é´(æ£åº) 1 å»¶ç»æ¤çæ¶é´(ååº) 2 åéæ¶é´(æ£åº) 3 åéæ¶é´(ååº) 7åºéè®¿æ¥æ(ååº) åºéè®¿æ¥æ(æ£åº) |
| | | serviceType: 3, |
| | | searchscope: 3, |
| | |
| | | this.getList(1); |
| | | }, |
| | | onthatday() { |
| | | this.topqueryParams.startSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.sendstateView = 1; // å¾
é访 |
| | | this.topqueryParams.sendstate = null; |
| | | this.topqueryParams.startSendDateTime = null; |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); // å¼å§éè®¿æ¥æ <= ä»å¤© |
| | | this.getList(1); |
| | | }, |
| | | getCurrentDate() { |
| | |
| | | return now.toISOString().slice(0, 10); // æªåå10个å符ï¼å³ YYYY-MM-DD |
| | | }, |
| | | buidegetTasklist(type) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | // ç¨æ·æé䏿æå¾
é访任å¡ï¼ä¼ éå
¨é¨ç§å®¤åç
åº |
| | | this.topqueryParams.visitDeptCodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | |
| | | ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | // æ¥åå¼å¸¸è·³è½¬ |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | sendstateView: 1, |
| | | visitDeptCodes: this.topqueryParams.visitDeptCodes, |
| | | leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | |
| | | resetQuery() { |
| | | this.dateRange = []; |
| | | this.dateRangefs = []; |
| | | this.serviceStatusValue = 10; |
| | | |
| | | this.topqueryParams = { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | sendstateView:2, |
| | | sendstateView:1, |
| | | sort: 2, //0 å»¶ç»æ¤çæ¶é´(æ£åº) 1 å»¶ç»æ¤çæ¶é´(ååº) 2 åéæ¶é´(æ£åº) 3 åéæ¶é´(ååº) |
| | | serviceType: 3, |
| | | searchscope: 3, |
| | |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <!-- <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | | <el-button |
| | |
| | | > |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-col> --> |
| | | <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | |
| | | }, |
| | | ], |
| | | loading: false, |
| | | serviceStatusValue: 10, |
| | | cascaderProps: { |
| | | expandTrigger: "hover", // æ¬åå±å¼ |
| | | checkStrictly: true, // â
å
³é®ï¼å
许éä¸ä»»æä¸çº§ |
| | | emitPath: false, // â
åªè¿åéä¸çå¼ï¼ä¸è¿åè·¯å¾æ°ç» |
| | | }, |
| | | // éè®¿ç¶æçº§èéæ©å¨ |
| | | serviceStatusOptions: [ |
| | | { |
| | |
| | | topqueryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | sendstateView:2, |
| | | sendstateView:1, |
| | | sort: localStorage.getItem("orgname") == "丽水å¸ä¸å»é¢" ? 8 : 2, //0 åºé¢æ¶é´(æ£åº) 1 åºé¢æ¶é´(ååº) 2 åéæ¶é´(æ£åº) 3 åéæ¶é´(ååº) 7åºéè®¿æ¥æ(ååº) åºéè®¿æ¥æ(æ£åº) |
| | | serviceType: 18, |
| | | searchscope: 3, |
| | |
| | | this.getList(1); |
| | | }, |
| | | onthatday() { |
| | | this.topqueryParams.startSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.sendstateView = 1; // å¾
é访 |
| | | this.topqueryParams.sendstate = null; |
| | | this.topqueryParams.startSendDateTime = null; |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); // å¼å§éè®¿æ¥æ <= ä»å¤© |
| | | this.getList(1); |
| | | }, |
| | | getCurrentDate() { |
| | |
| | | return now.toISOString().slice(0, 10); // æªåå10个å符ï¼å³ YYYY-MM-DD |
| | | }, |
| | | buidegetTasklist(type) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | // ç¨æ·æé䏿æå¾
é访任å¡ï¼ä¼ éå
¨é¨ç§å®¤åç
åº |
| | | this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | // æ¥åå¼å¸¸è·³è½¬ |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | sendstateView: 1, |
| | | leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | | buidegetTasklist(obj).then((response) => { |
| | |
| | | resetQuery() { |
| | | this.dateRange = []; |
| | | this.dateRangefs = []; |
| | | this.serviceStatusValue = 10; |
| | | |
| | | this.topqueryParams = { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | sendstateView:2, |
| | | sendstateView:1, |
| | | sort: 2, //0 åºé¢æ¶é´(æ£åº) 1 åºé¢æ¶é´(ååº) 2 åéæ¶é´(æ£åº) 3 åéæ¶é´(ååº) |
| | | serviceType: 18, |
| | | searchscope: 3, |
| | |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <!-- <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | | <el-button |
| | |
| | | > |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-col> --> |
| | | <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | |
| | | this.getList(1); |
| | | }, |
| | | onthatday() { |
| | | this.topqueryParams.startSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.sendstateView = 1; // å¾
é访 |
| | | this.topqueryParams.sendstate = null; |
| | | this.topqueryParams.startSendDateTime = null; |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); // å¼å§éè®¿æ¥æ <= ä»å¤© |
| | | this.getList(1); |
| | | }, |
| | | getCurrentDate() { |
| | |
| | | return now.toISOString().slice(0, 10); // æªåå10个å符ï¼å³ YYYY-MM-DD |
| | | }, |
| | | buidegetTasklist(type) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | // ç¨æ·æé䏿æå¾
é访任å¡ï¼ä¼ éå
¨é¨ç§å®¤åç
åº |
| | | this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | // æ¥åå¼å¸¸è·³è½¬ |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | sendstateView: 1, |
| | | leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | | buidegetTasklist(obj).then((response) => { |
| | |
| | | </div> |
| | | </el-col> |
| | | <div class="color-legend"> |
| | | <span class="legend-item" v-if="orgname == 'çç«åå¾·ç¿ èé¢åº'"> |
| | | <span class="legend-item" v-if="orgname == 'åå大å¦éå±ç¬¬ä¸å»é¢'"> |
| | | <span class="legend-block legend-blue"></span>æªå°é访æ¶é´ |
| | | </span> |
| | | <span class="legend-item"> |
| | |
| | | value: dept.districtCode, |
| | | }; |
| | | }); |
| | | // å
ç»ç´è¾¾ï¼æ ¹æ®ç§å®¤/ç
åºç¼ç é¢å¡«æ£è
èå´ |
| | | this.applyFollowUpScope(); |
| | | if (this.errtype == 1) { |
| | | this.toleadExport(2); |
| | | } else if (this.errtype == 2) { |
| | |
| | | onthatday() { |
| | | this.resetQuerykj(); |
| | | |
| | | this.topqueryParams.startSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.sendstateView = 1; // å¾
é访 |
| | | this.topqueryParams.sendstate = null; |
| | | this.topqueryParams.startSendDateTime = null; |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); // å¼å§éè®¿æ¥æ <= ä»å¤© |
| | | this.getList(1); |
| | | }, |
| | | getCurrentDate() { |
| | |
| | | }, |
| | | |
| | | buidegetTasklist(type) { |
| | | if (type) { |
| | | this.resetQuerykj(); |
| | | } |
| | | this.applyDeptWardScope(); |
| | | // ç¨æ·æé䏿æå¾
é访任å¡ï¼ä¼ éå
¨é¨ç§å®¤åç
åº |
| | | this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | // æ¥åå¼å¸¸è·³è½¬ |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | sendstateView: 1, |
| | | leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | | buidegetTasklist(obj).then((response) => { |
| | |
| | | /** æç´¢æé®æä½ */ |
| | | handleQuery(refresh) { |
| | | this.applyDeptWardScope(); |
| | | this.clearAllSelection(); |
| | | this.topqueryParams.pageNum = 1; |
| | | // 夿æ¯ä¸æ¯å·¥ä½å°å¿«æ·æ¥è¯¢ |
| | | if (this.errtype != 2) { |
| | |
| | | } |
| | | this.getList(refresh); |
| | | }, |
| | | // å
ç»ç´è¾¾ï¼æ ¹æ®è·¯ç±ä¸çç§å®¤/ç
åºç¼ç é¢å¡«æ£è
èå´ |
| | | applyFollowUpScope() { |
| | | const deptCode = this.$route.query.followUpDeptCode; |
| | | const wardCode = this.$route.query.followUpWardCode; |
| | | if (!deptCode && !wardCode) return; |
| | | const scope = []; |
| | | if (deptCode) scope.push([1, deptCode]); |
| | | if (wardCode) scope.push([2, wardCode]); |
| | | this.topqueryParams.scopetype = scope; |
| | | this.lastScopeType = deptCode ? 1 : 2; |
| | | }, |
| | | // æ£è
èå´å¤çï¼ä»å¤é级è scopetype è§£æç§å®¤/ç
åº |
| | | applyDeptWardScope() { |
| | | const value = this.topqueryParams.scopetype || []; |
| | |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <!-- <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | | <el-button |
| | |
| | | > |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-col> --> |
| | | <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | |
| | | this.getList(1); |
| | | }, |
| | | onthatday() { |
| | | this.topqueryParams.startSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.sendstateView = 1; // å¾
é访 |
| | | this.topqueryParams.sendstate = null; |
| | | this.topqueryParams.startSendDateTime = null; |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); // å¼å§éè®¿æ¥æ <= ä»å¤© |
| | | this.getList(1); |
| | | }, |
| | | getCurrentDate() { |
| | |
| | | return now.toISOString().slice(0, 10); // æªåå10个å符ï¼å³ YYYY-MM-DD |
| | | }, |
| | | buidegetTasklist(type) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | // ç¨æ·æé䏿æå¾
é访任å¡ï¼ä¼ éå
¨é¨ç§å®¤åç
åº |
| | | this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | // æ¥åå¼å¸¸è·³è½¬ |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | sendstateView: 1, |
| | | leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | | buidegetTasklist(obj).then((response) => { |
| | |
| | | resetQuery() { |
| | | this.dateRange = []; |
| | | this.dateRangefs = []; |
| | | this.serviceStatusValue = 10; |
| | | |
| | | this.topqueryParams = { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | sendstateView:2, |
| | | sendstateView:1, |
| | | sort: 2, //0 åºé¢æ¶é´(æ£åº) 1 åºé¢æ¶é´(ååº) 2 åéæ¶é´(æ£åº) 3 åéæ¶é´(ååº) |
| | | serviceType: 3, |
| | | searchscope: 3, |
| | |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <!-- <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | | <el-button |
| | |
| | | > |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-col> --> |
| | | <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | |
| | | this.getList(1); |
| | | }, |
| | | onthatday() { |
| | | this.topqueryParams.startSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.sendstateView = 1; // å¾
é访 |
| | | this.topqueryParams.sendstate = null; |
| | | this.topqueryParams.startSendDateTime = null; |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); // å¼å§éè®¿æ¥æ <= ä»å¤© |
| | | this.getList(1); |
| | | }, |
| | | getCurrentDate() { |
| | |
| | | return now.toISOString().slice(0, 10); // æªåå10个å符ï¼å³ YYYY-MM-DD |
| | | }, |
| | | buidegetTasklist(type) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | // ç¨æ·æé䏿æå¾
é访任å¡ï¼ä¼ éå
¨é¨ç§å®¤åç
åº |
| | | this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | // æ¥åå¼å¸¸è·³è½¬ |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | sendstateView: 1, |
| | | leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | | buidegetTasklist(obj).then((response) => { |
| | |
| | | topqueryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | sendstateView:2, |
| | | sendstateView:1, |
| | | sort: localStorage.getItem("orgname") == "丽水å¸ä¸å»é¢" ? 8 : 2, //0 ææ¯å®ææ¶é´(æ£åº) 1 ææ¯å®ææ¶é´(ååº) 2 åéæ¶é´(æ£åº) 3 åéæ¶é´(ååº) 7åºéè®¿æ¥æ(ååº) åºéè®¿æ¥æ(æ£åº) |
| | | serviceType: 19, |
| | | searchscope: 3, |
| | |
| | | this.getList(1); |
| | | }, |
| | | onthatday() { |
| | | this.topqueryParams.startSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.sendstateView = 1; // å¾
é访 |
| | | this.topqueryParams.sendstate = null; |
| | | this.topqueryParams.startSendDateTime = null; |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); // å¼å§éè®¿æ¥æ <= ä»å¤© |
| | | this.getList(1); |
| | | }, |
| | | getCurrentDate() { |
| | |
| | | return now.toISOString().slice(0, 10); // æªåå10个å符ï¼å³ YYYY-MM-DD |
| | | }, |
| | | buidegetTasklist(type) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | // ç¨æ·æé䏿æå¾
é访任å¡ï¼ä¼ éå
¨é¨ç§å®¤åç
åº |
| | | this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | // æ¥åå¼å¸¸è·³è½¬ |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | sendstateView: 1, |
| | | leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | | buidegetTasklist(obj).then((response) => { |
| | |
| | | resetQuery() { |
| | | this.dateRange = []; |
| | | this.dateRangefs = []; |
| | | this.serviceStatusValue = 10; |
| | | |
| | | this.topqueryParams = { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | sendstateView:2, |
| | | sendstateView:1, |
| | | sort: 2, //0 ææ¯å®ææ¶é´(æ£åº) 1 ææ¯å®ææ¶é´(ååº) 2 åéæ¶é´(æ£åº) 3 åéæ¶é´(ååº) |
| | | serviceType: 19, |
| | | searchscope: 3, |
| | |
| | | <div class="collapse-section"> |
| | | <el-collapse v-model="collapseActive" accordion> |
| | | <el-collapse-item title="æ£è
æ¡£æ¡ä¿¡æ¯" name="patient"> |
| | | <el-form ref="userform2" :model="userform" label-width="90px" size="small"> |
| | | <el-form |
| | | ref="userform2" |
| | | :model="userform" |
| | | label-width="90px" |
| | | size="small" |
| | | > |
| | | <el-row :gutter="16"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ£è
å§å"> |
| | | <el-input v-model="userform.name" placeholder="请è¾å
¥å§å" maxlength="30"></el-input> |
| | | <el-input |
| | | v-model="userform.name" |
| | | placeholder="请è¾å
¥å§å" |
| | | maxlength="30" |
| | | ></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ§å«"> |
| | | <el-select v-model="userform.sex" placeholder="è¯·éæ©" style="width: 100%"> |
| | | <el-select |
| | | v-model="userform.sex" |
| | | placeholder="è¯·éæ©" |
| | | style="width: 100%" |
| | | > |
| | | <el-option label="ç·" :value="1"></el-option> |
| | | <el-option label="女" :value="2"></el-option> |
| | | </el-select> |
| | |
| | | <el-row :gutter="16"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¹´é¾"> |
| | | <el-input v-model="userform.age" placeholder="请è¾å
¥å¹´é¾" maxlength="20"></el-input> |
| | | <el-input |
| | | v-model="userform.age" |
| | | placeholder="请è¾å
¥å¹´é¾" |
| | | maxlength="20" |
| | | ></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èç³»æ¹å¼"> |
| | | <el-input v-model="userform.telcode" placeholder="请è¾å
¥èç³»æ¹å¼" maxlength="20"></el-input> |
| | | <el-input |
| | | v-model="userform.telcode" |
| | | placeholder="请è¾å
¥èç³»æ¹å¼" |
| | | maxlength="20" |
| | | ></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="16"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="亲å±çµè¯"> |
| | | <el-input v-model="userform.relativetelcode" placeholder="请è¾å
¥äº²å±èç³»æ¹å¼" maxlength="20"></el-input> |
| | | <el-input |
| | | v-model="userform.relativetelcode" |
| | | placeholder="请è¾å
¥äº²å±èç³»æ¹å¼" |
| | | maxlength="20" |
| | | ></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="16"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="è¯æåç§°"> |
| | | <el-input v-model="form.leavediagname" placeholder="请è¾å
¥è¯æ" maxlength="50"></el-input> |
| | | <el-input |
| | | v-model="form.leavediagname" |
| | | placeholder="请è¾å
¥è¯æ" |
| | | maxlength="50" |
| | | ></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="16"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="åºçå°"> |
| | | <el-input v-model="userform.birthplace" placeholder="å½ãçãå°å¸ãåºå¿ãè¡éç" maxlength="50"></el-input> |
| | | <el-input |
| | | v-model="userform.birthplace" |
| | | placeholder="å½ãçãå°å¸ãåºå¿ãè¡éç" |
| | | maxlength="50" |
| | | ></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="16"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å±
ä½å°"> |
| | | <el-input v-model="userform.placeOfResidence" placeholder="å½ãçãå°å¸ãåºå¿ãè¡éç" maxlength="50"></el-input> |
| | | <el-input |
| | | v-model="userform.placeOfResidence" |
| | | placeholder="å½ãçãå°å¸ãåºå¿ãè¡éç" |
| | | maxlength="50" |
| | | ></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </el-collapse-item> |
| | | <el-collapse-item title="æè¯å»ºè®®" name="advice" v-if="orgname=='ç¼äºå¿äººæ°å»é¢'"> |
| | | <el-collapse-item |
| | | title="æè¯å»ºè®®" |
| | | name="advice" |
| | | v-if="orgname == 'ç¼äºå¿äººæ°å»é¢'" |
| | | > |
| | | <AdviceList :subid="taskid" :taskid="id" :patid="patid" /> |
| | | </el-collapse-item> |
| | | </el-collapse> |
| | | </div> |
| | | |
| | | |
| | | |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | .map((obj) => obj.targetvalue) |
| | | .join("&"); |
| | | } |
| | | console.log(item.targetvalue,'item.targetvalue'); |
| | | console.log(item.targetvalue, "item.targetvalue"); |
| | | |
| | | if (item.targetvalue) { |
| | | item.scriptResult = item.targetvalue.split("&"); |
| | | } |
| | | console.log(item.scriptResult); |
| | | |
| | | }); |
| | | } |
| | | }); |
| | |
| | | this.$modal.msgSuccess("æå¡ä¿åæå"); |
| | | this.Editsingletasksonyic(this.serviceStates); |
| | | const orgName = localStorage.getItem("orgname"); |
| | | |
| | | if (this.form.isVisitAgain != 1 || this.visitAgain == 1) { |
| | | if ( |
| | | this.form.isVisitAgain != 1 || |
| | | orgName == "丽水å¸ä¸å»é¢" || |
| | | this.visitAgain == 1 |
| | | ) { |
| | | this.Torouter(); |
| | | return; |
| | | } |
| | |
| | | savequestiondetail(obj).then((res) => { |
| | | if (res.code == 200) { |
| | | this.$modal.msgSuccess("æå¡ä¿åæå"); |
| | | // this.Torouter(); |
| | | |
| | | if ( |
| | | this.form.isVisitAgain != 1 || |
| | | orgName == "丽水å¸ä¸å»é¢" || |
| | |
| | | this.Torouter(); |
| | | return; |
| | | } |
| | | |
| | | this.$modal |
| | | .confirm( |
| | | 'ä»»å¡ä¿åæåæ¯å¦é对æ£è
ï¼"' + |
| | |
| | | // åæ¶éç½®ä¸é项ç¸å
³çç¶æ |
| | | // questionItem.isabnormal = false; |
| | | questionItem.showAppendInput = false; |
| | | questionItem.score = null; // åæ¶éä¸åæ¸
空é¢ç®åæ° |
| | | // 注æï¼åæ¶é䏿¶ï¼æä»¬é常ä¸å¸æè§¦åé¢ç®è·³è½¬é»è¾ï¼æä»¥ç´æ¥è¿å |
| | | // 妿éè¦ï¼å¯ä»¥å¨è¿éæ·»å åæ¶éä¸åçç¹å®é»è¾ï¼ä¾å¦éç½®é¢ç®åºå |
| | | } else { |
| | |
| | | // å¤çå¼å¸¸ç¶æé«äº® |
| | | this.tableDatatop[questionIndex].isabnormal = |
| | | selectedOptionObj.isabnormal; |
| | | |
| | | // å¤çåæ°ï¼æéä¸é项ç score 带å°é¢ç® score ä¸ |
| | | this.tableDatatop[questionIndex].score = selectedOptionObj.score; |
| | | |
| | | // å¤çéå è¾å
¥æ¡æ¾ç¤º |
| | | |
| | |
| | | if (obj.isabnormal) { |
| | | this.tableDatatop[index].isabnormal = obj.isabnormal; |
| | | } |
| | | // åæ¾åéé¢ç®åæ°ï¼æå·²éä¸é项ç score 带å°é¢ç® score ä¸ |
| | | if (obj.score !== undefined && obj.score !== null) { |
| | | this.tableDatatop[index].score = obj.score; |
| | | } |
| | | this.$forceUpdate(); |
| | | } |
| | | }); |
| | |
| | | |
| | | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; |
| | | }, |
| | | updateScore(a, b, c) {}, |
| | | // å¤éï¼æéä¸é项çåæ°ç´¯å å°é¢ç® score ä¸ |
| | | updateScore(selectedValues, questionIndex, question) { |
| | | const options = question.svyTaskTemplateTargetoptions || []; |
| | | const score = options.reduce((sum, opt) => { |
| | | if (selectedValues && selectedValues.includes(opt.optioncontent)) { |
| | | return sum + (Number(opt.score) || 0); |
| | | } |
| | | return sum; |
| | | }, 0); |
| | | question.score = score; |
| | | this.$forceUpdate(); |
| | | }, |
| | | // åå¹¶ä¿®æ¹ç¸å
³============================= |
| | | toggleMergeMode() { |
| | | this.isMergeMode = !this.isMergeMode; |
| | |
| | | return `${year}-${month}-${day}`; |
| | | }, |
| | | buidegetTasklist(type) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | // ç¨æ·æé䏿æå¾
é访任å¡ï¼ä¼ éå
¨é¨ç§å®¤åç
åº |
| | | this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | // æ¥åå¼å¸¸è·³è½¬ |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | sendstateView: 1, |
| | | leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | | buidegetTasklist(obj).then((response) => { |
| | |
| | | }); |
| | | }, |
| | | onthatday() { |
| | | this.topqueryParams.startSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.sendstateView = 1; // å¾
é访 |
| | | this.topqueryParams.sendstate = null; |
| | | this.topqueryParams.startSendDateTime = null; |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); // å¼å§éè®¿æ¥æ <= ä»å¤© |
| | | this.getList(1); |
| | | }, |
| | | getCurrentDate() { |
| | |
| | | }); |
| | | }, |
| | | buidegetTasklist(type) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | // ç¨æ·æé䏿æå¾
é访任å¡ï¼ä¼ éå
¨é¨ç§å®¤åç
åº |
| | | this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | // æ¥åå¼å¸¸è·³è½¬ |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | sendstateView: 1, |
| | | leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | | buidegetTasklist(obj).then((response) => { |
| | |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <!-- <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | | <el-button |
| | |
| | | > |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-col> --> |
| | | <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | |
| | | topqueryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | sendstateView:2, |
| | | sendstateView:1, |
| | | sort: localStorage.getItem("orgname") == "丽水å¸ä¸å»é¢" ? 8 : 2, //0 åºé¢æ¶é´(æ£åº) 1 åºé¢æ¶é´(ååº) 2 åéæ¶é´(æ£åº) 3 åéæ¶é´(ååº) 7åºéè®¿æ¥æ(ååº) åºéè®¿æ¥æ(æ£åº) |
| | | serviceType: 13, |
| | | searchscope: 3, |
| | |
| | | this.getList(1); |
| | | }, |
| | | onthatday() { |
| | | this.topqueryParams.startSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); |
| | | this.topqueryParams.sendstateView = 1; // å¾
é访 |
| | | this.topqueryParams.sendstate = null; |
| | | this.topqueryParams.startSendDateTime = null; |
| | | this.topqueryParams.endSendDateTime = this.getCurrentDate(); // å¼å§éè®¿æ¥æ <= ä»å¤© |
| | | this.getList(1); |
| | | }, |
| | | getCurrentDate() { |
| | |
| | | return now.toISOString().slice(0, 10); // æªåå10个å符ï¼å³ YYYY-MM-DD |
| | | }, |
| | | buidegetTasklist(type) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | // ç¨æ·æé䏿æå¾
é访任å¡ï¼ä¼ éå
¨é¨ç§å®¤åç
åº |
| | | this.topqueryParams.visitDeptCodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | |
| | | ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | // æ¥åå¼å¸¸è·³è½¬ |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | sendstateView: 1, |
| | | visitDeptCodes: this.topqueryParams.visitDeptCodes, |
| | | leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | |
| | | this.topqueryParams = { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | sendstateView:2, |
| | | sendstateView:1, |
| | | sort: 2, //0 åºé¢æ¶é´(æ£åº) 1 åºé¢æ¶é´(ååº) 2 åéæ¶é´(æ£åº) 3 åéæ¶é´(ååº) |
| | | serviceType: 13, |
| | | searchscope: 3, |
| | |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <!-- <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | | <el-button |
| | |
| | | > |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-col> --> |
| | | <el-col :span="1.5"> |
| | | <div class="documentf"> |
| | | <div class="document"> |
| | |
| | | return now.toISOString().slice(0, 10); // æªåå10个å符ï¼å³ YYYY-MM-DD |
| | | }, |
| | | buidegetTasklist(type) { |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | // ç¨æ·æé䏿æå¾
é访任å¡ï¼ä¼ éå
¨é¨ç§å®¤åç
åº |
| | | this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | } |
| | | // æ¥åå¼å¸¸è·³è½¬ |
| | | if (this.errtype) { |
| | | this.topqueryParams.leavehospitaldistrictcodes.push( |
| | |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | sendstateView: 1, |
| | | leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | | buidegetTasklist(obj).then((response) => { |
| | |
| | | type="text" |
| | | auto-complete="off" |
| | | placeholder="è´¦å·" |
| | | @blur="handleUsernameBlur" |
| | | > |
| | | <svg-icon |
| | | slot="prefix" |
| | |
| | | } |
| | | }); |
| | | }, |
| | | // è¾å
¥å®è´¦å·åï¼æ£ç´¢å¯éæºææ¯å¦å
å«âååéä¸âï¼è¥æåèªå¨å¡«å
å¯ç |
| | | handleUsernameBlur() { |
| | | if (!this.loginForm.username) return; |
| | | const hasNanhua = this.options.some((item) => { |
| | | const label = item.label || ""; |
| | | return label.includes("åå") && label.includes("éä¸"); |
| | | }); |
| | | if (hasNanhua) { |
| | | this.loginForm.password = "nhfy@0230"; |
| | | } |
| | | }, |
| | | getCookie() { |
| | | const username = Cookies.get("username"); |
| | | const password = Cookies.get("password"); |
| | |
| | | id, |
| | | Voicetype, |
| | | visitCount, |
| | | followUpDeptCode, |
| | | followUpWardCode, |
| | | } = params; |
| | | console.log( |
| | | token, |
| | |
| | | deptCode, |
| | | redirect, |
| | | campusid, |
| | | followUpDeptCode, |
| | | followUpWardCode, |
| | | "åæ°æ¥å¿" |
| | | ); |
| | | |
| | |
| | | visitCount: visitCount || "", |
| | | }; |
| | | console.log("使ç¨taskid跳转å°è¯¦æ
页:", redirectPath, redirectQuery); |
| | | } else if (followUpDeptCode || followUpWardCode) { |
| | | // 7.2 æºå¸¦ç§å®¤/ç
åºç¼ç ï¼è·³è½¬å°åºé¢é访å表并æç§å®¤/ç
åºæ¥è¯¢ |
| | | redirectPath = "/followvisit/discharge"; |
| | | redirectQuery = { |
| | | followUpDeptCode: followUpDeptCode || "", |
| | | followUpWardCode: followUpWardCode || "", |
| | | }; |
| | | console.log("使ç¨ç§å®¤/ç
åºç¼ç 跳转å°åºé¢é访å表:", redirectPath, redirectQuery); |
| | | } else if (redirect) { |
| | | // 7.2 å¦æä¼ å
¥çredirectåå¨ï¼ä½¿ç¨ä¼ å
¥çéå®åè·¯å¾ |
| | | // 7.3 å¦æä¼ å
¥çredirectåå¨ï¼ä½¿ç¨ä¼ å
¥çéå®åè·¯å¾ |
| | | try { |
| | | redirectPath = decodeURIComponent(redirect); |
| | | console.log("使ç¨ä¼ å
¥çéå®åè·¯å¾:", redirectPath); |
| | |
| | | redirectPath = this.getDefaultRedirectPath(); |
| | | } |
| | | } else { |
| | | // 7.3 使ç¨é»è®¤è·¯å¾ |
| | | // 7.4 使ç¨é»è®¤è·¯å¾ |
| | | redirectPath = this.getDefaultRedirectPath(); |
| | | } |
| | | |
| | |
| | | <template v-if="archive"> |
| | | <div class="action-bar"> |
| | | <el-button @click="$router.go(-1)" icon="el-icon-back">è¿å</el-button> |
| | | <el-button :type="editing ? 'success' : 'primary'" :icon="editing ? 'el-icon-check' : 'el-icon-edit'" @click="toggleEdit">{{ editing ? 'ä¿å' : 'ç¼è¾' }}</el-button> |
| | | <el-tag :type="subTypeTag(archive.subType)" style="margin-left:12px">{{ archive.subTypeLabel }}</el-tag> |
| | | <el-button :type="editing ? 'success' : 'primary'" :icon="editing ? 'el-icon-check' : 'el-icon-edit'" @click="toggleEdit"> |
| | | {{ editing ? 'ä¿å' : 'ç¼è¾' }} |
| | | </el-button> |
| | | <el-button v-if="archive.closeStatus != 1" type="danger" plain icon="el-icon-circle-close" @click="handleCloseCase">ç»æ¡</el-button> |
| | | <el-tag :type="archive.closeStatus == 1 ? 'info' : 'success'" style="margin-left:12px"> |
| | | {{ archive.closeStatus == 1 ? 'å·²ç»æ¡' : 'æªç»æ¡' }} |
| | | </el-tag> |
| | | <el-tag :type="subTypeTag(archive.subType)" style="margin-left:8px">{{ archive.subTypeLabel }}</el-tag> |
| | | </div> |
| | | |
| | | <el-tabs v-model="mainTab" type="border-card"> |
| | | <el-tab-pane label="æ¡£æ¡è¯¦æ
" name="detail"> |
| | | |
| | | <!-- æ£è
åºæ¬ä¿¡æ¯ --> |
| | | <el-card class="info-card" shadow="never"> |
| | |
| | | <el-row :gutter="20" style="margin-top:10px"> |
| | | <el-col :span="6"><InfoField label="ç§å®¤" :value="archive.deptname" /></el-col> |
| | | <el-col :span="6"><InfoField label="è¯æ" :value="archive.diagname" /></el-col> |
| | | <el-col :span="6"><InfoField label="主治å»ç" :value="archive.drname" /></el-col> |
| | | <el-col :span="6"><InfoField label="æ¥æº" :value="sourceLabel" /></el-col> |
| | | </el-row> |
| | | </el-card> |
| | |
| | | <!-- å®¶é¿ä¿¡æ¯ --> |
| | | <el-card class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"><span>å®¶é¿/çæ¤äººä¿¡æ¯</span></div> |
| | | <el-form :model="parentInfo" label-width="110px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="6"> |
| | | <InfoField label="å®¶é¿å§å" :value="parentInfo.parentName" :editing="editing" v-model="parentInfo.parentName" /> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <InfoField label="ä¸å¿ç«¥å
³ç³»" :value="relationLabel" :editing="editing" type="select" :options="relationOptions" @change="v => parentInfo.relation = v" /> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <InfoField label="èç³»çµè¯" :value="parentInfo.parentPhone" :editing="editing" v-model="parentInfo.parentPhone" /> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <InfoField label="身份è¯å·" :value="parentInfo.parentIdCard" :editing="editing" v-model="parentInfo.parentIdCard" /> |
| | | </el-col> |
| | | <el-col :span="8"><el-form-item label="å®¶é¿å§å"><el-input v-model="parentInfo.parentName" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ä¸å¿ç«¥å
³ç³»"> |
| | | <el-select v-model="parentInfo.relation" class="w-sm"> |
| | | <el-option v-for="o in relationOptions" :key="o.value" :label="o.label" :value="o.value" /> |
| | | </el-select> |
| | | </el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="èç³»çµè¯"><el-input v-model="parentInfo.parentPhone" class="w-sm" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20" style="margin-top:10px"> |
| | | <el-col :span="12"> |
| | | <InfoField label="èç³»å°å" :value="parentInfo.address" :editing="editing" v-model="parentInfo.address" /> |
| | | </el-col> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="身份è¯å·"><el-input v-model="parentInfo.parentIdCard" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="16"><el-form-item label="èç³»å°å"><el-input v-model="parentInfo.address" class="w-full" /></el-form-item></el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </el-card> |
| | | |
| | | <!-- æ¡£æ¡åºæ¬ä¿¡æ¯ --> |
| | | <!-- æ¡£æ¡ä¿¡æ¯ï¼å¯ç¼è¾ï¼ --> |
| | | <el-card class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"> |
| | | <span>æ¡£æ¡åºæ¬ä¿¡æ¯</span> |
| | | <span>æ¡£æ¡ä¿¡æ¯</span> |
| | | <span class="header-sub">{{ archive.createTime ? archive.createTime.substring(0,10) : '-' }} 建档</span> |
| | | </div> |
| | | <el-form :model="archive" label-width="110px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><InfoField label="建档类å" :value="archive.subTypeLabel" /></el-col> |
| | | <el-col :span="8"><InfoField label="建档å»ç" :value="archive.archiveForm.doctorName" :editing="editing" v-model="archive.archiveForm.doctorName" /></el-col> |
| | | <el-col :span="8"><InfoField label="建档æ¶é´" :value="archive.createTime" /></el-col> |
| | | <el-col :span="8"><el-form-item label="åºçæ¥æ"><el-date-picker v-model="archive.birthday" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="åºçä½é"><el-input v-model="archive.birthWeight" class="w-xs" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="åºçåå¨"><el-input v-model="archive.gestationalWeek" class="w-xs" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="è¯ææ¥æ"><el-date-picker v-model="archive.diagnosisDate" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="主治å»ç"><el-input v-model="archive.attendingDoctor" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ç»ç®¡å»ç"><el-input v-model="archive.managingDoctor" class="w-sm" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="ç»è®°äººå"><el-input v-model="archive.registrant" class="w-sm" /></el-form-item></el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </el-card> |
| | | |
| | | <!-- é«å±å¿ä¸æ¡ â å¯ç¼è¾è¡¨æ ¼ --> |
| | | <el-card v-if="archive.subType === 'highRisk'" class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"><span>é«å±å¿ä¸æ¡ç®¡ç</span></div> |
| | | <el-form :model="archive" label-width="110px" size="small" :disabled="!editing" inline> |
| | | <el-form-item label="é«å±å¿åç±»"><el-input v-model="archive.highRiskCategory" class="w-md" /></el-form-item> |
| | | <el-form-item label="é«å±å¿åç§°"><el-input v-model="archive.highRiskName" class="w-lg" /></el-form-item> |
| | | <el-form-item label="æéè®¿æ¥æ"><el-date-picker v-model="archive.followupDate" value-format="yyyy-MM-dd" class="w-md" /></el-form-item> |
| | | </el-form> |
| | | <el-tabs v-model="activeTab" type="border-card"> |
| | | <el-tab-pane label="çé¿åè²çæµ" name="growth"> |
| | | <EditableTable :data.sync="growthData" :editing="editing" :columns="growthColumns" /> |
| | |
| | | <!-- è¥å
»æ§ç¾ç
䏿¡ â å¯ç¼è¾è¡¨æ ¼ --> |
| | | <el-card v-if="archive.subType === 'nutrition'" class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"><span>è¥å
»æ§ç¾ç
䏿¡ç®¡ç</span></div> |
| | | <el-form :model="archive" label-width="130px" size="small" :disabled="!editing" inline> |
| | | <el-form-item label="è¥å
»æ§ç¾ç
åç§°"><el-input v-model="archive.nutritionName" class="w-lg" /></el-form-item> |
| | | </el-form> |
| | | <el-tabs v-model="activeTab" type="border-card"> |
| | | <el-tab-pane label="使 ¼æµé" name="measure"> |
| | | <EditableTable :data.sync="measureData" :editing="editing" :columns="measureColumns" /> |
| | |
| | | <!-- å¦ä¹ å°é¾ä¸æ¡ â åä¸è¡¨å --> |
| | | <el-card v-if="archive.subType === 'learning'" class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"><span>å¦ä¹ å°é¾ä¸æ¡ç®¡ç</span></div> |
| | | <el-form :model="archive" label-width="110px" size="small" :disabled="!editing" inline> |
| | | <el-form-item label="é¢çº¦æ
åµ"><el-input v-model="archive.appointmentStatus" class="w-lg" /></el-form-item> |
| | | </el-form> |
| | | <el-form :model="form" label-width="130px" size="small" :disabled="!editing"> |
| | | <el-divider content-position="left">å¦ä¹ è½åè¯ä¼°</el-divider> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="è¯ä¼°æ¥æ"><el-date-picker v-model="form.assessDate" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="æµè¯å·¥å
·"><el-input v-model="form.testName" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¯ä¼°æ¥æ"><el-date-picker v-model="form.assessDate" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="æµè¯å·¥å
·"><el-input v-model="form.testName" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="æºå(IQ)"><el-input-number v-model="form.iq" :min="40" :max="160" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="é
读è½å"><el-select v-model="form.reading" style="width:100%"><el-option v-for="o in gradeOptions" :key="o" :label="o" :value="o" /></el-select></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="书åè½å"><el-select v-model="form.writing" style="width:100%"><el-option v-for="o in gradeOptions" :key="o" :label="o" :value="o" /></el-select></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="计ç®è½å"><el-select v-model="form.math" style="width:100%"><el-option v-for="o in gradeOptions" :key="o" :label="o" :value="o" /></el-select></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="é
读è½å"><el-select v-model="form.reading" class="w-sm"><el-option v-for="o in gradeOptions" :key="o" :label="o" :value="o" /></el-select></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="书åè½å"><el-select v-model="form.writing" class="w-sm"><el-option v-for="o in gradeOptions" :key="o" :label="o" :value="o" /></el-select></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="计ç®è½å"><el-select v-model="form.math" class="w-sm"><el-option v-for="o in gradeOptions" :key="o" :label="o" :value="o" /></el-select></el-form-item></el-col> |
| | | </el-row> |
| | | <el-form-item label="综åç»è®º"><el-input v-model="form.result" type="textarea" :rows="2" /></el-form-item> |
| | | |
| | | <el-divider content-position="left">è¡ä¸ºè¯ä¼°</el-divider> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="è¯ä¼°æ¥æ"><el-date-picker v-model="form.behaviorDate" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¯ä¼°æ¥æ"><el-date-picker v-model="form.behaviorDate" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="4"><el-form-item label="注æå"><el-input-number v-model="form.attention" :min="0" :max="36" /></el-form-item></el-col> |
| | | <el-col :span="4"><el-form-item label="å¤å¨"><el-input-number v-model="form.hyperactivity" :min="0" :max="36" /></el-form-item></el-col> |
| | | <el-col :span="4"><el-form-item label="å²å¨"><el-input-number v-model="form.impulsivity" :min="0" :max="36" /></el-form-item></el-col> |
| | |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="æ»å"><el-input-number v-model="form.totalScore" disabled /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¯ä»·"><el-select v-model="form.evaluation" style="width:100%"><el-option label="æ£å¸¸èå´" value="æ£å¸¸èå´" /><el-option label="轻度å¼å¸¸" value="轻度å¼å¸¸" /><el-option label="ä¸åº¦å¼å¸¸" value="ä¸åº¦å¼å¸¸" /></el-select></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¯ä»·"><el-select v-model="form.evaluation" class="w-sm"><el-option label="æ£å¸¸èå´" value="æ£å¸¸èå´" /><el-option label="轻度å¼å¸¸" value="轻度å¼å¸¸" /><el-option label="ä¸åº¦å¼å¸¸" value="ä¸åº¦å¼å¸¸" /></el-select></el-form-item></el-col> |
| | | </el-row> |
| | | |
| | | <el-divider content-position="left">å¹²é¢è®ç»è®°å½</el-divider> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="è®ç»æ¥æ"><el-date-picker v-model="form.trainDate" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è®ç»ç±»å"><el-input v-model="form.trainingType" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è®ç»æ¥æ"><el-date-picker v-model="form.trainDate" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è®ç»ç±»å"><el-input v-model="form.trainingType" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="æ¶é¿(åé)"><el-input-number v-model="form.duration" :min="10" :max="120" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-form-item label="è®ç»å
容"><el-input v-model="form.trainContent" type="textarea" :rows="2" /></el-form-item> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="è®ç»å¸"><el-input v-model="form.trainer" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¿å±"><el-select v-model="form.progress" style="width:100%"><el-option label="è¯å¥½" value="è¯å¥½" /><el-option label="ä¸è¬" value="ä¸è¬" /><el-option label="ç¼æ
¢" value="ç¼æ
¢" /></el-select></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è®ç»å¸"><el-input v-model="form.trainer" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¿å±"><el-select v-model="form.progress" class="w-sm"><el-option label="è¯å¥½" value="è¯å¥½" /><el-option label="ä¸è¬" value="ä¸è¬" /><el-option label="ç¼æ
¢" value="ç¼æ
¢" /></el-select></el-form-item></el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </el-card> |
| | | |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="æå¡è®°å½" name="service"> |
| | | <ServiceRecords :patid="archive.patid" /> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </template> |
| | | <div v-else class="empty-wrap">æ¡£æ¡ä¸å卿已å é¤</div> |
| | | </div> |
| | |
| | | <script> |
| | | import EditableTable from "../components/EditableTable.vue"; |
| | | import InfoField from "./InfoField.vue"; |
| | | import ServiceRecords from "../components/ServiceRecords.vue"; |
| | | import { loadArchives, saveArchives } from "../types"; |
| | | |
| | | export default { |
| | | name: "ChildHealthArchiveDetail", |
| | | components: { EditableTable, InfoField }, |
| | | components: { EditableTable, InfoField, ServiceRecords }, |
| | | data() { |
| | | return { |
| | | loading: false, archive: null, editing: false, activeTab: "growth", |
| | | loading: false, archive: null, editing: true, activeTab: "growth", mainTab: "detail", |
| | | relationOptions: [ |
| | | { label:"ç¶äº²", value:"father" },{ label:"æ¯äº²", value:"mother" },{ label:"ç¥ç¶", value:"grandfather" },{ label:"ç¥æ¯", value:"grandmother" },{ label:"å
¶ä»", value:"other" }, |
| | | ], |
| | |
| | | const map = { standalone:"ç¬ç«å»ºæ¡£", outpatient:"é¨è¯è®°å½", inpatient:"å¨é¢è®°å½" }; |
| | | return map[this.archive?.sourcePage] || this.archive?.sourcePage || "-"; |
| | | }, |
| | | relationLabel() { |
| | | const r = this.relationOptions.find(o => o.value === (this.archive?.parentInfo?.relation)); |
| | | return r ? r.label : "-"; |
| | | }, |
| | | }, |
| | | created() { |
| | | const id = this.$route.query.id; |
| | | if (id) this.loadArchive(id); |
| | | if (id) this.loadArchive(id, this.$route.query.edit == 1); |
| | | }, |
| | | methods: { |
| | | loadArchive(id) { |
| | | loadArchive(id, autoEdit) { |
| | | this.loading = true; |
| | | const all = JSON.parse(localStorage.getItem("patientArchives") || "[]"); |
| | | this.archive = all.find(item => item.id === id) || null; |
| | | this.archive = loadArchives().find((item) => item.id === id) || null; |
| | | if (this.archive) { |
| | | if (!this.archive.parentInfo) this.archive.parentInfo = {}; |
| | | if (this.archive.subType === 'highRisk') { |
| | | this.activeTab = "growth"; |
| | | this.growthData = this.archive.growthData || getDefaultGrowthData(); |
| | |
| | | Object.assign(this.form, this.archive.archiveForm.learningData); |
| | | } |
| | | } |
| | | if (autoEdit) this.editing = true; |
| | | this.loading = false; |
| | | }, |
| | | toggleEdit() { |
| | |
| | | this.archive.planData = JSON.parse(JSON.stringify(this.planData)); |
| | | } |
| | | this.archive.updateTime = new Date().toISOString().replace("T"," ").substring(0,19); |
| | | const all = JSON.parse(localStorage.getItem("patientArchives") || "[]"); |
| | | const all = loadArchives(); |
| | | const idx = all.findIndex(item => item.id === this.archive.id); |
| | | if (idx >= 0) all[idx] = JSON.parse(JSON.stringify(this.archive)); |
| | | localStorage.setItem("patientArchives", JSON.stringify(all)); |
| | | saveArchives(all); |
| | | this.$message.success("ä¿åæå"); |
| | | } |
| | | this.editing = !this.editing; |
| | | }, |
| | | handleCloseCase() { |
| | | this.$modal.confirm("确认å°è¯¥æ¡£æ¡ç»æ¡ï¼").then(() => { |
| | | this.archive.closeStatus = 1; |
| | | this.archive.updateTime = new Date().toISOString().replace("T"," ").substring(0,19); |
| | | const all = loadArchives(); |
| | | const idx = all.findIndex(item => item.id === this.archive.id); |
| | | if (idx >= 0) all[idx] = JSON.parse(JSON.stringify(this.archive)); |
| | | saveArchives(all); |
| | | this.$message.success("å·²ç»æ¡"); |
| | | }).catch(() => {}); |
| | | }, |
| | | subTypeTag(type) { const m={highRisk:"danger",nutrition:"warning",learning:"info"}; return m[type]||""; }, |
| | | }, |
| | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | // è¾å
¥æ¡å®½åº¦ï¼æå段é¿çåºåï¼ |
| | | .w-xs { width: 90px; } |
| | | .w-sm { width: 150px; } |
| | | .w-md { width: 200px; } |
| | | .w-lg { width: 280px; } |
| | | .w-full { width: 100%; } |
| | | |
| | | .action-bar { margin-bottom: 16px; } |
| | | .info-card { margin-bottom: 0; } |
| | | .card-header { display: flex; justify-content: space-between; align-items: center; font-size: 16px; font-weight: 600; } |
| | |
| | | <template> |
| | | <el-dialog |
| | | :title="dialogTitle" |
| | | :title="standalone ? 'æ°å»ºå»ºæ¡£' : 'éæ©å»ºæ¡£ç±»å'" |
| | | :visible.sync="dialogVisible" |
| | | width="750px" |
| | | width="640px" |
| | | :close-on-click-modal="false" |
| | | append-to-body |
| | | @close="handleClose" |
| | | top="3vh" |
| | | > |
| | | <!-- 已鿣è
é¢è§ï¼å
³è建档模å¼ï¼ --> |
| | | <div class="archive-section" v-if="selectedPatients.length > 0"> |
| | | <div class="archive-section" v-if="!standalone && selectedPatients.length > 0"> |
| | | <div class="section-title">已鿣è
ï¼{{ selectedPatients.length }}人ï¼</div> |
| | | <el-table :data="selectedPatients" border size="small" max-height="180"> |
| | | <el-table-column prop="patname" label="å§å" width="80" align="center" /> |
| | |
| | | <el-divider /> |
| | | </div> |
| | | |
| | | <!-- å¿ä¿ç§ï¼å®¶é¿ä¿¡æ¯ï¼å¿
å¡«ï¼ --> |
| | | <div class="archive-section" v-if="mainCategory === 'child'"> |
| | | <div class="section-title">å®¶é¿/çæ¤äººä¿¡æ¯</div> |
| | | <el-form :model="parentInfo" label-width="100px" size="small" inline> |
| | | <el-form-item label="å®¶é¿å§å" required> |
| | | <el-input v-model="parentInfo.parentName" placeholder="请è¾å
¥" style="width:150px" /> |
| | | </el-form-item> |
| | | <el-form-item label="ä¸å¿ç«¥å
³ç³»"> |
| | | <el-select v-model="parentInfo.relation" style="width:120px"> |
| | | <el-option label="ç¶äº²" value="father" /> |
| | | <el-option label="æ¯äº²" value="mother" /> |
| | | <el-option label="ç¥ç¶" value="grandfather" /> |
| | | <el-option label="ç¥æ¯" value="grandmother" /> |
| | | <el-option label="å
¶ä»" value="other" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="èç³»çµè¯" required> |
| | | <el-input v-model="parentInfo.parentPhone" placeholder="èç³»çµè¯" style="width:150px" /> |
| | | </el-form-item> |
| | | <el-form-item label="身份è¯å·"> |
| | | <el-input v-model="parentInfo.parentIdCard" placeholder="身份è¯å·" style="width:200px" /> |
| | | </el-form-item> |
| | | <el-form-item label="èç³»å°å"> |
| | | <el-input v-model="parentInfo.address" placeholder="èç³»å°å" style="width:300px" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-divider /> |
| | | </div> |
| | | |
| | | <!-- 建档主åç±» --> |
| | | <!-- 䏿¡ç±»åéæ© --> |
| | | <div class="archive-section"> |
| | | <div class="section-title">éæ©å»ºæ¡£ç±»å</div> |
| | | <el-radio-group v-model="mainCategory" size="medium" @change="onMainCategoryChange"> |
| | | <el-radio-button label="child">å¿ä¿ç§å»ºæ¡£</el-radio-button> |
| | | <el-radio-button label="maternal">å¦ä¿ç§å»ºæ¡£</el-radio-button> |
| | | </el-radio-group> |
| | | </div> |
| | | |
| | | <!-- åç±»å --> |
| | | <div class="archive-section" v-if="mainCategory"> |
| | | <div class="section-title">鿩䏿¡ç±»å</div> |
| | | <el-radio-group v-model="subType" size="small" @change="onSubTypeChange"> |
| | | <template v-if="mainCategory === 'child'"> |
| | | <el-radio-button label="highRisk">é«å±å¿ä¸æ¡ç®¡ç</el-radio-button> |
| | | <el-radio-button label="nutrition">è¥å
»æ§ç¾ç
䏿¡ç®¡ç</el-radio-button> |
| | | <el-radio-button label="learning">å¦ä¹ å°é¾ä¸æ¡ç®¡ç</el-radio-button> |
| | | </template> |
| | | <template v-else> |
| | | <el-radio-button label="pregnancy">åå¦é访</el-radio-button> |
| | | <el-radio-button label="menopause">æ´å¹´æé访</el-radio-button> |
| | | </template> |
| | | <el-radio-group v-model="subType" size="medium"> |
| | | <el-radio-button v-for="t in typeOptions" :key="t.key" :label="t.key">{{ t.entryLabel }}</el-radio-button> |
| | | </el-radio-group> |
| | | </div> |
| | | |
| | | <!-- 建档ä¸å±å段 --> |
| | | <div class="archive-section" v-if="subType"> |
| | | <div class="section-title">建档信æ¯</div> |
| | | <el-form :model="archiveForm" label-width="120px" size="small"> |
| | | <!-- å¿ä¿ç§ - é«å±å¿ --> |
| | | <template v-if="mainCategory === 'child' && subType === 'highRisk'"> |
| | | <el-form-item label="é«å±å ç´ "> |
| | | <el-select v-model="archiveForm.riskFactor" multiple placeholder="å¯å¤é" style="width:100%"> |
| | | <el-option label="æ©äº§/ä½ä½é" value="preterm" /> |
| | | <el-option label="çªæ¯å²" value="asphyxia" /> |
| | | <el-option label="é¢
å
åºè¡" value="ich" /> |
| | | <el-option label="é«èçº¢ç´ è¡ç" value="hyperbilirubinemia" /> |
| | | <el-option label="宫å
ææ" value="intrauterine" /> |
| | | <el-option label="å
天ç¸å½¢" value="malformation" /> |
| | | <el-option label="å
¶ä»" value="other" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="åºçä½é(g)"> |
| | | <el-input-number v-model="archiveForm.birthWeight" :min="500" :max="6000" /> |
| | | </el-form-item> |
| | | <el-form-item label="åºçåå¨"> |
| | | <el-input-number v-model="archiveForm.gestationalWeek" :min="22" :max="42" :precision="1" /> å¨ |
| | | </el-form-item> |
| | | <el-form-item label="建档å»ç"> |
| | | <el-input v-model="archiveForm.doctorName" placeholder="请è¾å
¥å»ºæ¡£å»ç" /> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨"> |
| | | <el-input v-model="archiveForm.remark" type="textarea" :rows="2" /> |
| | | </el-form-item> |
| | | </template> |
| | | |
| | | <!-- å¿ä¿ç§ - è¥å
»æ§ç¾ç
--> |
| | | <template v-if="mainCategory === 'child' && subType === 'nutrition'"> |
| | | <el-form-item label="è¥å
»è¯æ" required> |
| | | <el-select v-model="archiveForm.nutritionDiagnosis" placeholder="è¯·éæ©" style="width:100%"> |
| | | <el-option label="è¥å
»ä¸è¯" value="malnutrition" /> |
| | | <el-option label="è¶
é" value="overweight" /> |
| | | <el-option label="è¥è" value="obesity" /> |
| | | <el-option label="å¾®éå
ç´ ç¼ºä¹" value="micronutrient" /> |
| | | <el-option label="åå
»å°é¾" value="feeding" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="建档å»ç"> |
| | | <el-input v-model="archiveForm.doctorName" placeholder="请è¾å
¥å»ºæ¡£å»ç" /> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨"> |
| | | <el-input v-model="archiveForm.remark" type="textarea" :rows="2" /> |
| | | </el-form-item> |
| | | </template> |
| | | |
| | | <!-- å¿ä¿ç§ - å¦ä¹ å°é¾ --> |
| | | <template v-if="mainCategory === 'child' && subType === 'learning'"> |
| | | <el-form-item label="å¦ä¹ é®é¢" required> |
| | | <el-select v-model="archiveForm.learningIssue" placeholder="è¯·éæ©" style="width:100%"> |
| | | <el-option label="é
读éç¢" value="dyslexia" /> |
| | | <el-option label="书åéç¢" value="dysgraphia" /> |
| | | <el-option label="计ç®éç¢" value="dyscalculia" /> |
| | | <el-option label="注æå缺é·" value="adhd" /> |
| | | <el-option label="æ··åå" value="mixed" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="建档å»ç"> |
| | | <el-input v-model="archiveForm.doctorName" placeholder="请è¾å
¥å»ºæ¡£å»ç" /> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨"> |
| | | <el-input v-model="archiveForm.remark" type="textarea" :rows="2" /> |
| | | </el-form-item> |
| | | </template> |
| | | |
| | | <!-- å¦ä¿ç§ - åå¦é访 --> |
| | | <template v-if="mainCategory === 'maternal' && subType === 'pregnancy'"> |
| | | <el-form-item label="æ«æ¬¡æç»"> |
| | | <el-date-picker v-model="archiveForm.lmp" type="date" value-format="yyyy-MM-dd" placeholder="éæ©æ¥æ" style="width:100%" /> |
| | | </el-form-item> |
| | | <el-row :gutter="12"> |
| | | <el-col :span="8"><el-form-item label="åå¨"><el-input-number v-model="archiveForm.gestationalWeek" :min="1" :max="42" :precision="1" /> å¨</el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="忬¡"><el-input-number v-model="archiveForm.gravidity" :min="1" :max="20" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="产次"><el-input-number v-model="archiveForm.parity" :min="0" :max="20" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-form-item label="é¢äº§æ"> |
| | | <el-date-picker v-model="archiveForm.edd" type="date" value-format="yyyy-MM-dd" placeholder="éæ©é¢äº§æ" style="width:100%" /> |
| | | </el-form-item> |
| | | <el-form-item label="é«å±å¦å¨ "> |
| | | <el-switch v-model="archiveForm.highRiskPregnancy" active-text="æ¯" inactive-text="å¦" /> |
| | | </el-form-item> |
| | | <el-form-item label="建档å»ç"> |
| | | <el-input v-model="archiveForm.doctorName" placeholder="请è¾å
¥å»ºæ¡£å»ç" /> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨"> |
| | | <el-input v-model="archiveForm.remark" type="textarea" :rows="2" /> |
| | | </el-form-item> |
| | | </template> |
| | | |
| | | <!-- å¦ä¿ç§ - æ´å¹´æé访 --> |
| | | <template v-if="mainCategory === 'maternal' && subType === 'menopause'"> |
| | | <el-form-item label="æç»ç¶æ"> |
| | | <el-select v-model="archiveForm.menstrualStatus" placeholder="è¯·éæ©" style="width:100%"> |
| | | <el-option label="æç»ç´ä¹±" value="irregular" /> |
| | | <el-option label="éç»ï¼<12个æï¼" value="amenorrhea_short" /> |
| | | <el-option label="ç»ç»ï¼â¥12个æï¼" value="menopause" /> |
| | | <el-option label="人工ç»ç»" value="surgical" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æ«æ¬¡æç»"> |
| | | <el-date-picker v-model="archiveForm.lmp" type="date" value-format="yyyy-MM-dd" placeholder="éæ©æ¥æ" style="width:100%" /> |
| | | </el-form-item> |
| | | <el-form-item label="建档å»ç"> |
| | | <el-input v-model="archiveForm.doctorName" placeholder="请è¾å
¥å»ºæ¡£å»ç" /> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨"> |
| | | <el-input v-model="archiveForm.remark" type="textarea" :rows="2" /> |
| | | </el-form-item> |
| | | </template> |
| | | </el-form> |
| | | </div> |
| | | |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="dialogVisible = false">å æ¶</el-button> |
| | | <el-button type="primary" :loading="submitting" @click="handleSubmit" :disabled="!canSubmit"> |
| | | 确认建档 |
| | | </el-button> |
| | | <el-button type="primary" :loading="submitting" @click="handleSubmit" :disabled="!canSubmit">确认建档</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script> |
| | | import { ARCHIVE_TYPES, loadArchives, saveArchives, buildArchiveRecord } from "../types"; |
| | | |
| | | export default { |
| | | name: "ArchiveDialog", |
| | | props: { |
| | |
| | | data() { |
| | | return { |
| | | dialogVisible: false, |
| | | mainCategory: "", |
| | | subType: "", |
| | | submitting: false, |
| | | standalonePatient: { patname: "", sex: 2, age: "", telcode: "", deptname: "", diagname: "" }, |
| | | parentInfo: { parentName: "", relation: "", parentPhone: "", parentIdCard: "", address: "" }, |
| | | archiveForm: { |
| | | riskFactor: [], birthWeight: null, gestationalWeek: null, |
| | | nutritionDiagnosis: "", learningIssue: "", |
| | | gravidity: 1, parity: 0, edd: "", lmp: "", |
| | | highRiskPregnancy: false, menstrualStatus: "", |
| | | doctorName: "", remark: "", |
| | | }, |
| | | }; |
| | | }, |
| | | computed: { |
| | | dialogTitle() { |
| | | return this.standalone ? "æ°å»ºå»ºæ¡£" : "æ£è
建档"; |
| | | }, |
| | | typeOptions() { return ARCHIVE_TYPES; }, |
| | | canSubmit() { |
| | | if (!this.subType) return false; |
| | | if (this.mainCategory === 'child' && !this.parentInfo.parentName) return false; |
| | | if (this.standalone && !this.standalonePatient.patname) return false; |
| | | if (!this.standalone && this.selectedPatients.length === 0) return false; |
| | | return true; |
| | | }, |
| | | selectedPatients() { |
| | | return this.patients || []; |
| | | }, |
| | | selectedPatients() { return this.patients || []; }, |
| | | }, |
| | | watch: { |
| | | visible(val) { |
| | |
| | | }, |
| | | methods: { |
| | | resetForm() { |
| | | this.mainCategory = ""; |
| | | this.subType = ""; |
| | | this.standalonePatient = { patname: "", sex: 2, age: "", telcode: "", deptname: "", diagname: "" }; |
| | | this.parentInfo = { parentName: "", relation: "", parentPhone: "", parentIdCard: "", address: "" }; |
| | | this.archiveForm = { |
| | | riskFactor: [], birthWeight: null, gestationalWeek: null, |
| | | nutritionDiagnosis: "", learningIssue: "", |
| | | gravidity: 1, parity: 0, edd: "", lmp: "", |
| | | highRiskPregnancy: false, menstrualStatus: "", |
| | | doctorName: "", remark: "", |
| | | }; |
| | | }, |
| | | onMainCategoryChange() { this.subType = ""; }, |
| | | onSubTypeChange() {}, |
| | | |
| | | getSubTypeLabel() { |
| | | const map = { highRisk: "é«å±å¿ä¸æ¡ç®¡ç", nutrition: "è¥å
»æ§ç¾ç
䏿¡ç®¡ç", learning: "å¦ä¹ å°é¾ä¸æ¡ç®¡ç", pregnancy: "åå¦é访", menopause: "æ´å¹´æé访" }; |
| | | return map[this.subType] || ""; |
| | | }, |
| | | getMainCategoryLabel() { |
| | | return this.mainCategory === "child" ? "å¿ä¿ç§å»ºæ¡£" : "å¦ä¿ç§å»ºæ¡£"; |
| | | }, |
| | | |
| | | handleSubmit() { |
| | | if (!this.subType) { this.$message.warning("è¯·éæ©ä¸æ¡ç±»å"); return; } |
| | | if (this.standalone && !this.standalonePatient.patname) { this.$message.warning("请è¾å
¥å§å"); return; } |
| | | if (!this.standalone && this.selectedPatients.length === 0) { this.$message.warning("è¯·éæ©æ£è
"); return; } |
| | | this.submitting = true; |
| | | |
| | | const archives = JSON.parse(localStorage.getItem("patientArchives") || "[]"); |
| | | const now = new Date().toISOString().replace("T", " ").substring(0, 19); |
| | | |
| | | // ç¡®å®æ£è
å表 |
| | | const patientList = this.standalone |
| | | ? [{ ...this.standalonePatient, patid: "sa_" + Date.now() }] |
| | | : this.selectedPatients; |
| | | |
| | | patientList.forEach((patient) => { |
| | | archives.push({ |
| | | id: "arc_" + Date.now() + "_" + Math.random().toString(36).substr(2, 6), |
| | | patientId: patient.patid || patient.id, |
| | | patname: patient.patname, |
| | | sex: patient.sex, |
| | | age: patient.age, |
| | | telcode: patient.telcode || patient.phone || "", |
| | | deptname: patient.deptname || "", |
| | | diagname: patient.diagname || "", |
| | | inhospno: patient.inhospno || "", |
| | | outhospno: patient.outhospno || "", |
| | | bedNo: patient.bedNo || "", |
| | | drname: patient.drname || "", |
| | | nurseName: patient.nurseName || "", |
| | | starttime: patient.starttime || patient.admitdate || "", |
| | | mainCategory: this.mainCategory, |
| | | mainCategoryLabel: this.getMainCategoryLabel(), |
| | | subType: this.subType, |
| | | subTypeLabel: this.getSubTypeLabel(), |
| | | archiveForm: JSON.parse(JSON.stringify(this.archiveForm)), |
| | | parentInfo: this.mainCategory === 'child' ? JSON.parse(JSON.stringify(this.parentInfo)) : {}, |
| | | sourcePage: this.standalone ? "standalone" : this.sourcePage, |
| | | status: "active", |
| | | createTime: now, |
| | | updateTime: now, |
| | | }); |
| | | }); |
| | | |
| | | localStorage.setItem("patientArchives", JSON.stringify(archives)); |
| | | const patientList = this.standalone ? [this.standalonePatient] : this.selectedPatients; |
| | | const sourcePage = this.standalone ? "standalone" : this.sourcePage; |
| | | const records = patientList.map((p) => buildArchiveRecord(p, this.subType, sourcePage)); |
| | | saveArchives([...loadArchives(), ...records]); |
| | | |
| | | this.submitting = false; |
| | | this.dialogVisible = false; |
| | | this.$message.success(`æåå建 ${patientList.length} æ¡å»ºæ¡£è®°å½`); |
| | | this.$message.success(`æåå建 ${records.length} æ¡å»ºæ¡£è®°å½`); |
| | | this.$emit("created"); |
| | | |
| | | // 跳转 |
| | | const routePath = this.mainCategory === "child" |
| | | ? "/filing/childHealth" |
| | | : "/filing/maternalHealth"; |
| | | this.$router.push({ path: routePath }); |
| | | // è¿å
¥è¯¦æ
页ï¼ç¼è¾æï¼ |
| | | const first = records[0]; |
| | | const type = ARCHIVE_TYPES.find((t) => t.key === this.subType); |
| | | if (first && type) { |
| | | this.$router.push({ path: type.detailRoute, query: { id: first.id, edit: 1 } }); |
| | | } |
| | | }, |
| | | handleClose() { this.resetForm(); }, |
| | | }, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px"> |
| | | <el-form-item label="å§å"> |
| | | <el-input v-model="queryParams.patname" placeholder="请è¾å
¥å§å" clearable @keyup.enter.native="handleQuery" style="width:180px" /> |
| | | </el-form-item> |
| | | <el-form-item label="è¯æ"> |
| | | <el-input v-model="queryParams.diagname" placeholder="请è¾å
¥è¯æ" clearable @keyup.enter.native="handleQuery" style="width:180px" /> |
| | | </el-form-item> |
| | | <el-form-item label="å»ºæ¡£æ¥æ"> |
| | | <el-date-picker v-model="dateRange" style="width:240px" value-format="yyyy-MM-dd" type="daterange" |
| | | range-separator="-" start-placeholder="å¼å§æ¥æ" end-placeholder="ç»ææ¥æ" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="medium" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="el-icon-refresh" size="medium" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="el-icon-plus" size="medium" @click="handleCreate">æ°å»ºå»ºæ¡£</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="el-icon-delete" size="medium" :disabled="multiple" @click="handleDelete">å é¤</el-button> |
| | | </el-col> |
| | | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" /> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="displayList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="50" align="center" /> |
| | | <el-table-column |
| | | v-for="col in typeConfig.columns" |
| | | :key="col.prop" |
| | | :label="col.label" |
| | | align="center" |
| | | show-overflow-tooltip |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-tag v-if="col.type === 'closeStatus'" :type="scope.row.closeStatus == 1 ? 'info' : 'success'" size="mini"> |
| | | {{ cellValue(scope.row, col) }} |
| | | </el-tag> |
| | | <span v-else>{{ cellValue(scope.row, col) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" fixed="right" width="120"> |
| | | <template slot-scope="scope"> |
| | | <el-button size="medium" type="text" @click="goDetail(scope.row)"> |
| | | <span class="button-textsc"><i class="el-icon-zoom-in" />æ¥ç</span> |
| | | </el-button> |
| | | <el-button size="medium" type="text" @click="handleSingleDelete(scope.row)"> |
| | | <span style="color:#f56c6c"><i class="el-icon-delete" />å é¤</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" /> |
| | | |
| | | <OutpatientPicker :visible.sync="pickerVisible" :type="type" @picked="onPicked" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import OutpatientPicker from "./OutpatientPicker.vue"; |
| | | import { getTypeByKey, loadArchives, saveArchives } from "../types"; |
| | | |
| | | export default { |
| | | name: "ArchiveList", |
| | | components: { OutpatientPicker }, |
| | | props: { |
| | | type: { type: String, default: "" }, |
| | | }, |
| | | data() { |
| | | return { |
| | | loading: false, showSearch: true, multiple: true, ids: [], dateRange: [], |
| | | total: 0, allList: [], displayList: [], pickerVisible: false, |
| | | queryParams: { pageNum: 1, pageSize: 10, patname: "", diagname: "" }, |
| | | }; |
| | | }, |
| | | computed: { |
| | | typeConfig() { |
| | | return getTypeByKey(this.type) || { columns: [], detailRoute: "/filing/maternalDetail" }; |
| | | }, |
| | | }, |
| | | created() { this.getList(); }, |
| | | methods: { |
| | | getList() { |
| | | this.loading = true; |
| | | const all = loadArchives().filter((item) => item.subType === this.type); |
| | | let filtered = [...all]; |
| | | if (this.queryParams.patname) filtered = filtered.filter((i) => i.patname && i.patname.includes(this.queryParams.patname)); |
| | | if (this.queryParams.diagname) filtered = filtered.filter((i) => i.diagname && i.diagname.includes(this.queryParams.diagname)); |
| | | if (this.dateRange && this.dateRange.length === 2) { |
| | | filtered = filtered.filter((i) => { |
| | | const d = (i.createTime || "").substring(0, 10); |
| | | return d >= this.dateRange[0] && d <= this.dateRange[1]; |
| | | }); |
| | | } |
| | | this.total = filtered.length; |
| | | const start = (this.queryParams.pageNum - 1) * this.queryParams.pageSize; |
| | | this.displayList = filtered.slice(start, start + this.queryParams.pageSize); |
| | | this.loading = false; |
| | | }, |
| | | handleQuery() { this.queryParams.pageNum = 1; this.getList(); }, |
| | | resetQuery() { |
| | | this.dateRange = []; |
| | | this.queryParams = { pageNum: 1, pageSize: 10, patname: "", diagname: "" }; |
| | | this.getList(); |
| | | }, |
| | | handleSelectionChange(s) { this.ids = s.map((i) => i.id); this.multiple = !s.length; }, |
| | | handleDelete() { |
| | | if (this.ids.length === 0) { this.$modal.msgWarning("请è³å°éæ©ä¸æ¡"); return; } |
| | | this.$modal.confirm("确认å é¤é䏿¡£æ¡ï¼").then(() => { |
| | | const remaining = loadArchives().filter((item) => !this.ids.includes(item.id)); |
| | | saveArchives(remaining); |
| | | this.$modal.msgSuccess("å 餿å"); |
| | | this.getList(); |
| | | }).catch(() => {}); |
| | | }, |
| | | handleSingleDelete(row) { this.ids = [row.id]; this.handleDelete(); }, |
| | | handleCreate() { this.pickerVisible = true; }, |
| | | onPicked(record) { |
| | | this.getList(); |
| | | this.$router.push({ path: this.typeConfig.detailRoute, query: { id: record.id, edit: 1 } }); |
| | | }, |
| | | goDetail(row) { |
| | | this.$router.push({ path: this.typeConfig.detailRoute, query: { id: row.id } }); |
| | | }, |
| | | getProp(obj, path) { |
| | | if (!path) return ""; |
| | | return path.split(".").reduce((o, k) => (o == null ? o : o[k]), obj); |
| | | }, |
| | | cellValue(row, col) { |
| | | const val = this.getProp(row, col.prop); |
| | | if (col.type === "sex") return val == 1 ? "ç·" : "女"; |
| | | if (col.type === "date") return val ? String(val).substring(0, 10) : "-"; |
| | | if (col.type === "closeStatus") return val == 1 ? "å·²ç»æ¡" : "æªç»æ¡"; |
| | | return val || "-"; |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .button-textsc { color: #3664d9; } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog |
| | | title="éæ©é¨è¯è®°å½" |
| | | :visible.sync="dialogVisible" |
| | | width="85%" |
| | | append-to-body |
| | | top="4vh" |
| | | :close-on-click-modal="false" |
| | | @close="handleClose" |
| | | > |
| | | <el-form :inline="true" size="small" label-width="56px"> |
| | | <el-form-item label="å§å"> |
| | | <el-input v-model="queryParams.patname" placeholder="请è¾å
¥å§å" clearable style="width:160px" @keyup.enter.native="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="è¯æ"> |
| | | <el-input v-model="queryParams.diagname" placeholder="请è¾å
¥è¯æ" clearable style="width:160px" @keyup.enter.native="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="el-icon-refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="list" |
| | | border |
| | | highlight-current-row |
| | | style="width: 100%" |
| | | @current-change="handleCurrentChange" |
| | | > |
| | | <el-table-column label="å°±è¯æ¶é´" align="center" width="140"> |
| | | <template slot-scope="scope">{{ formatTime(scope.row.admitdate) }}</template> |
| | | </el-table-column> |
| | | <el-table-column label="ç
æ¡å·" align="center" prop="outhospno" width="110" /> |
| | | <el-table-column label="å§å" align="center" prop="patname" width="100" /> |
| | | <el-table-column label="æ§å«" align="center" width="60"> |
| | | <template slot-scope="scope">{{ scope.row.sex == 1 ? "ç·" : "女" }}</template> |
| | | </el-table-column> |
| | | <el-table-column label="å¹´é¾" align="center" prop="age" width="60" /> |
| | | <el-table-column label="èç³»çµè¯" align="center" prop="telcode" width="120" /> |
| | | <el-table-column label="è¯æ" align="center" prop="diagname" show-overflow-tooltip /> |
| | | <el-table-column label="å°±è¯ç§å®¤" align="center" prop="deptname" show-overflow-tooltip /> |
| | | <el-table-column label="æ¥è¯å»ç" align="center" prop="drname" width="100" /> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | :page.sync="queryParams.pageNum" |
| | | :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="dialogVisible = false">å æ¶</el-button> |
| | | <el-button type="primary" :disabled="!currentRow" @click="handleConfirm">ç¡®å®</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script> |
| | | import { listPatouthosp } from "@/api/smartor/patouthosp"; |
| | | import { loadArchives, saveArchives, buildArchiveRecord } from "../types"; |
| | | import store from "@/store"; |
| | | |
| | | export default { |
| | | name: "OutpatientPicker", |
| | | props: { |
| | | visible: { type: Boolean, default: false }, |
| | | type: { type: String, default: "" }, |
| | | sourcePage: { type: String, default: "outpatient" }, |
| | | }, |
| | | data() { |
| | | return { |
| | | dialogVisible: false, |
| | | loading: false, |
| | | list: [], |
| | | total: 0, |
| | | currentRow: null, |
| | | queryParams: { pageNum: 1, pageSize: 10, patname: "", diagname: "", searchscope: 3, deptcodes: [] }, |
| | | }; |
| | | }, |
| | | watch: { |
| | | visible(val) { |
| | | this.dialogVisible = val; |
| | | if (val) { |
| | | this.currentRow = null; |
| | | this.getList(); |
| | | } |
| | | }, |
| | | dialogVisible(val) { |
| | | if (!val) this.$emit("update:visible", false); |
| | | }, |
| | | }, |
| | | methods: { |
| | | getList() { |
| | | this.loading = true; |
| | | if (this.queryParams.searchscope == 3) { |
| | | this.queryParams.deptcodes = store.getters.belongDepts.map((obj) => obj.deptCode); |
| | | } |
| | | listPatouthosp(this.queryParams) |
| | | .then((response) => { |
| | | this.list = response.rows || []; |
| | | this.total = response.total || 0; |
| | | }) |
| | | .finally(() => { this.loading = false; }); |
| | | }, |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1; |
| | | this.getList(); |
| | | }, |
| | | resetQuery() { |
| | | this.queryParams = { pageNum: 1, pageSize: 10, patname: "", diagname: "", searchscope: 3, deptcodes: [] }; |
| | | this.currentRow = null; |
| | | this.getList(); |
| | | }, |
| | | handleCurrentChange(row) { |
| | | this.currentRow = row; |
| | | }, |
| | | formatTime(time) { |
| | | if (!time) return "-"; |
| | | return String(time).substring(0, 19).replace("T", " "); |
| | | }, |
| | | handleConfirm() { |
| | | if (!this.currentRow) return; |
| | | const record = buildArchiveRecord(this.currentRow, this.type, this.sourcePage); |
| | | const all = loadArchives(); |
| | | all.push(record); |
| | | saveArchives(all); |
| | | this.dialogVisible = false; |
| | | this.$emit("picked", record); |
| | | }, |
| | | handleClose() { |
| | | this.currentRow = null; |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .dialog-footer { |
| | | text-align: right; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-card class="service-records" shadow="never" style="margin-top: 14px"> |
| | | <div slot="header" class="card-header"><span>æå¡è®°å½</span></div> |
| | | <div v-loading="loading"> |
| | | <div v-if="record.length === 0" class="empty-mini">ææ æå¡è®°å½</div> |
| | | <div v-else class="service-record"> |
| | | <div class="service-item" v-for="(item, idx) in record" :key="idx"> |
| | | <el-card shadow="never" class="service-card"> |
| | | <!-- æ é¢è¡ï¼æå¡ç±»å + ä»»å¡åç§° + éè®¿ç¶æ + å¼å¸¸ç¶æ --> |
| | | <div class="service-card__header"> |
| | | <div class="service-card__title"> |
| | | <span class="service-badge">{{ typeName(item.serviceType) }}</span> |
| | | <span class="service-name">{{ item.taskName || item.templatename || "-" }}</span> |
| | | </div> |
| | | <div class="service-card__tags"> |
| | | <el-tag v-if="item.sendstateView == 1" type="primary" size="small" effect="dark">å¾
é访</el-tag> |
| | | <el-tag v-else-if="item.sendstateView == 2" type="success" size="small" effect="dark">已宿</el-tag> |
| | | <el-tag v-else-if="item.sendstateView == 3" type="warning" size="small" effect="dark">æ éé访</el-tag> |
| | | <span class="service-status" :class="item.excep == 0 ? 'is-ok' : 'is-bad'"> |
| | | {{ item.excep == 0 ? "æå¡æ£å¸¸" : item.excep == 2 ? "è¦å" : "å¼å¸¸" }} |
| | | </span> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- æ¶é´çº¿ï¼åºé¢ â åºè®¿ â 宿 --> |
| | | <div class="service-card__timeline"> |
| | | <span><em>åºé¢</em>{{ fmtTime(item.endtime) }}</span> |
| | | <i>â</i> |
| | | <span><em>åºè®¿</em>{{ fmtTime(item.visitTime) }}</span> |
| | | <i>â</i> |
| | | <span><em>宿</em>{{ fmtTime(item.finishtime) }}</span> |
| | | </div> |
| | | |
| | | <!-- 䏿 ä¸»ä½ --> |
| | | <div class="service-card__columns"> |
| | | <!-- â æ£è
ä¿¡æ¯ --> |
| | | <div class="svc-block svc-block--blue"> |
| | | <div class="svc-block__title"><i class="el-icon-user-solid"></i>æ£è
ä¿¡æ¯</div> |
| | | <div class="svc-block__row"> |
| | | <span class="svc-name">{{ item.sendname || "-" }}</span> |
| | | <span class="svc-sub">{{ sexName(item.sex) }}</span> |
| | | <span class="svc-sub">{{ item.phone || "-" }}</span> |
| | | <span class="svc-sub" v-if="item.endtime">åºé¢{{ endDay(item.endtime) }}天</span> |
| | | </div> |
| | | <div class="svc-block__row svc-sub" v-if="item.sfzh">身份è¯ï¼{{ item.sfzh }}</div> |
| | | <div class="svc-block__row" v-if="item.leavediagname"><span class="svc-diag">è¯æ</span>{{ item.leavediagname }}</div> |
| | | </div> |
| | | |
| | | <!-- â¡ ç§å®¤ç
åº Â· 廿¤ --> |
| | | <div class="svc-block svc-block--green"> |
| | | <div class="svc-block__title"><i class="el-icon-office-building"></i>ç§å®¤ç
åº Â· 廿¤</div> |
| | | <div class="svc-block__row">ç§å®¤ï¼{{ item.deptname || "-" }} / ç
åºï¼{{ item.leavehospitaldistrictname || "-" }}</div> |
| | | <div class="svc-block__row"> |
| | | 主治ï¼{{ item.drname || "-" }} |
| | | <span class="svc-sub">ç»ç®¡ï¼{{ item.managementDoctor || "-" }}</span> |
| | | <span class="svc-sub">æ¤å£«ï¼{{ item.nurseName || "-" }}</span> |
| | | </div> |
| | | <div class="svc-block__row svc-sub">é访人åï¼{{ item.updateBy || "-" }}</div> |
| | | <div class="svc-block__row svc-sub">è´è´£äººï¼{{ item.createBy || "-" }}</div> |
| | | </div> |
| | | |
| | | <!-- ⢠æ§è¡è¯¦æ
--> |
| | | <div class="svc-block svc-block--gray"> |
| | | <div class="svc-block__title"><i class="el-icon-s-management"></i>æ§è¡è¯¦æ
</div> |
| | | <div class="svc-meta"> |
| | | <span v-if="item.sendstate || item.sendstate === 0"><em>ç¶æ</em>{{ sendStateName(item.sendstate) }}</span> |
| | | <span v-if="preach(item.preachform)"><em>æ§è¡</em>{{ preach(item.preachform) }}</span> |
| | | <span v-if="item.templatename"><em>模æ¿</em>{{ item.templatename }}</span> |
| | | <span v-if="item.suggest !== undefined && item.suggest !== null && item.suggest !== ''"><em>æè§</em><dict-tag :options="dict.type.sys_suggest" :value="item.suggest" /></span> |
| | | <span v-if="item.remark"><em>说æ</em>{{ item.remark }}</span> |
| | | <span v-if="item.createTime"><em>å建</em>{{ fmtTime(item.createTime) }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getTaskservelist } from "@/api/AiCentre/index"; |
| | | |
| | | export default { |
| | | name: "ServiceRecords", |
| | | dicts: ["sys_suggest"], |
| | | props: { |
| | | patid: { default: "" }, |
| | | }, |
| | | data() { |
| | | return { loading: false, record: [] }; |
| | | }, |
| | | watch: { |
| | | patid: { immediate: true, handler(v) { if (v) this.load(v); } }, |
| | | }, |
| | | methods: { |
| | | load(patid) { |
| | | this.loading = true; |
| | | getTaskservelist({ patid }) |
| | | .then((res) => { |
| | | if (res.code === 200 && res.rows && res.rows[0]) { |
| | | this.record = res.rows[0].serviceSubtaskList || []; |
| | | } else { |
| | | this.record = []; |
| | | } |
| | | }) |
| | | .catch(() => { this.record = []; }) |
| | | .finally(() => { this.loading = false; }); |
| | | }, |
| | | typeName(t) { |
| | | if (t == 1) return "å¿çµé访"; |
| | | if (t == 2) return "åºé¢é访"; |
| | | if (t == 3) return "å½±åé访"; |
| | | if (t == 4) return "宣æå
³æ"; |
| | | return "å
¶ä»æå¡"; |
| | | }, |
| | | sexName(s) { |
| | | if (s == 1) return "ç·"; |
| | | if (s == 2) return "女"; |
| | | return "-"; |
| | | }, |
| | | sendStateName(s) { |
| | | const map = { 1: "å·²é¢å", 2: "å¾
é访", 3: "å·²åé", 4: "䏿§è¡", 5: "失败", 6: "已宿", 7: "è¶
æ¶" }; |
| | | return map[s] || "-"; |
| | | }, |
| | | fmtTime(t) { |
| | | if (!t) return "-"; |
| | | const s = String(t).replace("T", " "); |
| | | return s.length > 16 ? s.substring(0, 16) : s.substring(0, 10); |
| | | }, |
| | | endDay(t) { |
| | | if (!t) return "-"; |
| | | const d = new Date(String(t).replace("T", " ").replace(/-/g, "/")); |
| | | const diff = Date.now() - d.getTime(); |
| | | return Math.round(diff / (1000 * 3600 * 24)); |
| | | }, |
| | | preach(v) { |
| | | if (!v) return ""; |
| | | return Array.isArray(v) ? v.join("ã") : String(v); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | $primary: #3f6ef0; |
| | | |
| | | .service-records { |
| | | .card-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | } |
| | | } |
| | | |
| | | .empty-mini { |
| | | padding: 30px 0; |
| | | text-align: center; |
| | | color: #c0c4cc; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .service-record { |
| | | .service-item { |
| | | margin-bottom: 16px; |
| | | |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | } |
| | | |
| | | .service-card { |
| | | border-radius: 12px; |
| | | box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); |
| | | |
| | | ::v-deep .el-card__body { |
| | | padding: 20px 24px; |
| | | } |
| | | } |
| | | |
| | | .service-card__header { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding-bottom: 14px; |
| | | border-bottom: 1px dashed #eef0f4; |
| | | } |
| | | |
| | | .service-card__title { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 12px; |
| | | min-width: 0; |
| | | } |
| | | |
| | | .service-card__tags { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | .service-badge { |
| | | display: inline-block; |
| | | padding: 4px 12px; |
| | | font-size: 13px; |
| | | font-weight: 600; |
| | | color: $primary; |
| | | background: #eef4ff; |
| | | border-radius: 6px; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .service-name { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .service-status { |
| | | padding: 4px 12px; |
| | | font-size: 13px; |
| | | border-radius: 999px; |
| | | |
| | | &.is-ok { |
| | | color: #12a182; |
| | | background: #e8f7f1; |
| | | } |
| | | |
| | | &.is-bad { |
| | | color: #e0564c; |
| | | background: #fdeeee; |
| | | } |
| | | } |
| | | |
| | | .service-card__timeline { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | flex-wrap: wrap; |
| | | padding: 12px 0; |
| | | font-size: 13px; |
| | | color: #606266; |
| | | |
| | | em { |
| | | font-style: normal; |
| | | color: #909399; |
| | | margin-right: 2px; |
| | | } |
| | | |
| | | i { |
| | | color: #c0c4cc; |
| | | font-style: normal; |
| | | } |
| | | } |
| | | |
| | | .service-card__columns { |
| | | display: flex; |
| | | gap: 12px; |
| | | } |
| | | |
| | | .svc-block { |
| | | flex: 1; |
| | | min-width: 0; |
| | | border-radius: 6px; |
| | | padding: 10px 12px; |
| | | font-size: 13px; |
| | | |
| | | &--blue { |
| | | background: #ecf5ff; |
| | | .svc-block__title { color: #409eff; } |
| | | } |
| | | |
| | | &--green { |
| | | background: #edf7f0; |
| | | .svc-block__title { color: #67c23a; } |
| | | } |
| | | |
| | | &--gray { |
| | | background: #f5f7fa; |
| | | .svc-block__title { color: #909399; } |
| | | } |
| | | } |
| | | |
| | | .svc-block__title { |
| | | font-size: 12px; |
| | | font-weight: 600; |
| | | margin-bottom: 6px; |
| | | |
| | | i { margin-right: 4px; } |
| | | } |
| | | |
| | | .svc-block__row { |
| | | color: #303133; |
| | | line-height: 1.7; |
| | | font-size: 13px; |
| | | word-break: break-all; |
| | | } |
| | | |
| | | .svc-sub { |
| | | color: #909399; |
| | | font-size: 12px; |
| | | margin-left: 8px; |
| | | } |
| | | |
| | | .svc-name { |
| | | color: #409eff; |
| | | font-weight: 600; |
| | | cursor: default; |
| | | } |
| | | |
| | | .svc-diag { |
| | | display: inline-block; |
| | | font-size: 11px; |
| | | color: #e6a23c; |
| | | background: #fdf6ec; |
| | | padding: 1px 6px; |
| | | border-radius: 3px; |
| | | margin-right: 6px; |
| | | } |
| | | |
| | | .svc-meta { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 4px 12px; |
| | | font-size: 12px; |
| | | color: #606266; |
| | | |
| | | span { white-space: normal; } |
| | | |
| | | em { |
| | | font-style: normal; |
| | | color: #909399; |
| | | margin-right: 2px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <ArchiveList type="highRisk" /> |
| | | </template> |
| | | |
| | | <script> |
| | | import ArchiveList from "../components/ArchiveList.vue"; |
| | | |
| | | export default { |
| | | name: "HighRiskArchiveList", |
| | | components: { ArchiveList }, |
| | | }; |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <ArchiveList type="learning" /> |
| | | </template> |
| | | |
| | | <script> |
| | | import ArchiveList from "../components/ArchiveList.vue"; |
| | | |
| | | export default { |
| | | name: "LearningArchiveList", |
| | | components: { ArchiveList }, |
| | | }; |
| | | </script> |
| | |
| | | <template v-if="archive"> |
| | | <div class="action-bar"> |
| | | <el-button @click="$router.go(-1)" icon="el-icon-back">è¿å</el-button> |
| | | <el-button :type="editing ? 'success' : 'primary'" :icon="editing ? 'el-icon-check' : 'el-icon-edit'" @click="toggleEdit">{{ editing ? 'ä¿å' : 'ç¼è¾' }}</el-button> |
| | | <el-tag :type="archive.subType === 'pregnancy' ? 'success' : 'warning'" style="margin-left:12px">{{ archive.subTypeLabel }}</el-tag> |
| | | <el-button :type="editing ? 'success' : 'primary'" :icon="editing ? 'el-icon-check' : 'el-icon-edit'" @click="toggleEdit"> |
| | | {{ editing ? 'ä¿å' : 'ç¼è¾' }} |
| | | </el-button> |
| | | <el-button v-if="archive.closeStatus != 1" type="danger" plain icon="el-icon-circle-close" @click="handleCloseCase">ç»æ¡</el-button> |
| | | <el-tag :type="archive.closeStatus == 1 ? 'info' : 'success'" style="margin-left:12px"> |
| | | {{ archive.closeStatus == 1 ? 'å·²ç»æ¡' : 'æªç»æ¡' }} |
| | | </el-tag> |
| | | <el-tag :type="archive.subType === 'pregnancy' ? 'success' : 'warning'" style="margin-left:8px">{{ archive.subTypeLabel }}</el-tag> |
| | | </div> |
| | | |
| | | <el-tabs v-model="mainTab" type="border-card"> |
| | | <el-tab-pane label="æ¡£æ¡è¯¦æ
" name="detail"> |
| | | <!-- æ£è
åºæ¬ä¿¡æ¯ --> |
| | | <el-card class="info-card" shadow="never"> |
| | | <div slot="header" class="card-header"><span>æ£è
åºæ¬ä¿¡æ¯</span></div> |
| | |
| | | <el-col :span="6"><InfoField label="å§å" :value="archive.patname" /></el-col> |
| | | <el-col :span="6"><InfoField label="æ§å«" :value="archive.sex == 1 ? 'ç·' : '女'" /></el-col> |
| | | <el-col :span="6"><InfoField label="å¹´é¾" :value="archive.age" /></el-col> |
| | | <el-col :span="6"><InfoField label="çµè¯" :value="archive.telcode" /></el-col> |
| | | <el-col :span="6"><InfoField label="èç³»çµè¯" :value="archive.telcode" /></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20" style="margin-top:10px"> |
| | | <el-col :span="6"><InfoField label="ç§å®¤" :value="archive.deptname" /></el-col> |
| | | <el-col :span="6"><InfoField label="è¯æ" :value="archive.diagname" /></el-col> |
| | | <el-col :span="6"><InfoField label="主治å»ç" :value="archive.drname" /></el-col> |
| | | <el-col :span="6"><InfoField label="æ¥æº" :value="sourceLabel" /></el-col> |
| | | </el-row> |
| | | </el-card> |
| | | |
| | | <!-- æ¡£æ¡åºæ¬ä¿¡æ¯ --> |
| | | <el-card class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"> |
| | | <span>æ¡£æ¡åºæ¬ä¿¡æ¯</span> |
| | | <span class="header-sub">{{ archive.createTime ? archive.createTime.substring(0,10) : '-' }} 建档</span> |
| | | </div> |
| | | <!-- ===== åå¦éè®¿ï¼æ¡£æ¡ä¿¡æ¯ + é¦è¯ä¿¡æ¯ + å¦å¨ æ
åµ åå¹¶åºå ===== --> |
| | | <el-card v-if="archive.subType === 'pregnancy'" class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div class="sub-section"> |
| | | <div class="sub-title">æ¡£æ¡ä¿¡æ¯</div> |
| | | <el-form :model="archive" label-width="110px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><InfoField label="建档类å" :value="archive.subTypeLabel" /></el-col> |
| | | <el-col :span="8"><InfoField label="建档å»ç" :value="archive.archiveForm.doctorName" :editing="editing" v-model="archive.archiveForm.doctorName" /></el-col> |
| | | <el-col :span="8"><InfoField label="建档æ¶é´" :value="archive.createTime" /></el-col> |
| | | <el-col :span="8"><el-form-item label="身份è¯å·"><el-input v-model="archive.idcardno" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="åºçæ¥æ"><el-date-picker v-model="archive.birthday" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¯ææ¥æ"><el-date-picker v-model="archive.diagnosisDate" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | </el-row> |
| | | <!-- åå¦ä¸å± --> |
| | | <el-row v-if="archive.subType === 'pregnancy'" :gutter="20" style="margin-top:10px"> |
| | | <el-col :span="6"><InfoField label="åå¨" :value="archive.archiveForm.gestationalWeek" :editing="editing" v-model="archive.archiveForm.gestationalWeek" type="number" /></el-col> |
| | | <el-col :span="6"><InfoField label="忬¡/产次" :value="'G'+(archive.archiveForm.gravidity||1)+'P'+(archive.archiveForm.parity||0)" /></el-col> |
| | | <el-col :span="6"><InfoField label="é¢äº§æ" :value="archive.archiveForm.edd" /></el-col> |
| | | <el-col :span="6"><InfoField label="é«å±å¦å¨ " :value="archive.archiveForm.highRiskPregnancy ? 'æ¯' : 'å¦'" /></el-col> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="主治å»ç"><el-input v-model="archive.attendingDoctor" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ç»ç®¡å»ç"><el-input v-model="archive.managingDoctor" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ç»è®°äººå"><el-input v-model="archive.registrant" class="w-sm" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row v-if="archive.subType === 'menopause'" :gutter="20" style="margin-top:10px"> |
| | | <el-col :span="8"><InfoField label="æç»ç¶æ" :value="menstrualLabel" /></el-col> |
| | | <el-col :span="8"><InfoField label="æ«æ¬¡æç»" :value="archive.archiveForm.lmp" /></el-col> |
| | | </el-form> |
| | | </div> |
| | | |
| | | <div class="sub-section"> |
| | | <div class="sub-title">åå¦é¦è¯ä¿¡æ¯ç»è®°</div> |
| | | <el-form :model="pregForm.firstVisit" label-width="120px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="å°±è¯å·"><el-input v-model="pregForm.firstVisit.visitNo" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="æ¬äººèç³»æ¹å¼"><el-input v-model="pregForm.firstVisit.selfPhone" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ç
åºå§å"><el-input v-model="pregForm.firstVisit.wardName" class="w-sm" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="è系人èç³»æ¹å¼"><el-input v-model="pregForm.firstVisit.contactPhone" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="身份è¯å·"><el-input v-model="pregForm.firstVisit.idcardno" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="é¦è¯å»ç"><el-input v-model="pregForm.firstVisit.firstDoctor" class="w-sm" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="è¯æåç§°"><el-input v-model="pregForm.firstVisit.diagname" class="w-full" /></el-form-item></el-col> |
| | | <el-col :span="16"><el-form-item label="å±
ä½å°å"><el-input v-model="pregForm.firstVisit.address" class="w-full" /></el-form-item></el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </div> |
| | | |
| | | <div class="sub-section"> |
| | | <div class="sub-title">å¦å¨ æ
åµ</div> |
| | | <el-form label-width="0" size="small" :disabled="!editing"> |
| | | <el-row :gutter="24" class="preg-cascade"> |
| | | <el-col :span="8"> |
| | | <div class="cascade-col"> |
| | | <div class="cascade-label">å¦å¨ æ
åµ</div> |
| | | <el-radio-group v-model="pregForm.pregnancy.status" @change="onPregnancyStatusChange"> |
| | | <el-radio v-for="(opt, key) in PREGNANCY_OPTIONS" :key="key" :label="key">{{ opt.label }}</el-radio> |
| | | </el-radio-group> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <div class="cascade-col"> |
| | | <div class="cascade-label">å
·ä½æ
åµ</div> |
| | | <el-checkbox-group v-model="pregForm.pregnancy.details" :disabled="!pregForm.pregnancy.status"> |
| | | <el-checkbox v-for="d in pregnancySubOptions" :key="d" :label="d">{{ d }}</el-checkbox> |
| | | </el-checkbox-group> |
| | | <div v-if="!pregForm.pregnancy.status" class="cascade-empty">请å
éæ©å¦å¨ æ
åµ</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <div class="cascade-col"> |
| | | <div class="cascade-label">å¤ç建议</div> |
| | | <el-checkbox-group v-model="pregForm.pregnancy.hint" :disabled="!pregForm.pregnancy.status"> |
| | | <el-checkbox v-for="h in pregnancyHintOptions" :key="h" :label="h">{{ h }}</el-checkbox> |
| | | </el-checkbox-group> |
| | | <div v-if="!pregForm.pregnancy.status" class="cascade-empty">请å
éæ©å¦å¨ æ
åµ</div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </div> |
| | | </el-card> |
| | | |
| | | <!-- ===== åå¦é访ï¼3个表å ===== --> |
| | | <template v-if="archive.subType === 'pregnancy'"> |
| | | <!-- æ¯å¦å»ºåï¼åå¦éè®¿ï¼ --> |
| | | <el-card v-if="archive.subType === 'pregnancy'" class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"><span>æ¯å¦å»ºå</span></div> |
| | | <el-form :model="pregForm.registration" label-width="120px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="æ¯å¦å»ºå"> |
| | | <el-radio-group v-model="pregForm.registration.isRegistered"> |
| | | <el-radio label="æ¯">æ¯</el-radio><el-radio label="å¦">å¦</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="é¢äº§æ"><el-date-picker v-model="pregForm.registration.edd" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è®°å½è
"><el-input v-model="pregForm.registration.recorder" class="w-sm" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-form-item v-if="pregForm.registration.isRegistered === 'å¦'" label="æªå»ºæ¡£åå "> |
| | | <el-input v-model="pregForm.registration.unregisteredReason" type="textarea" :rows="2" class="w-lg" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | |
| | | <!-- ===== å´ç»ç»æMHIï¼æ¡£æ¡ä¿¡æ¯ï¼å«éè®¿å¨ææ¬¡æ°ï¼ ===== --> |
| | | <el-card v-if="archive.subType === 'menopause'" class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"> |
| | | <span>æ¡£æ¡ä¿¡æ¯</span> |
| | | <span class="header-sub">{{ archive.createTime ? archive.createTime.substring(0,10) : '-' }} 建档</span> |
| | | </div> |
| | | <el-form :model="archive" label-width="110px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="身份è¯å·"><el-input v-model="archive.idcardno" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="åºçæ¥æ"><el-date-picker v-model="archive.birthday" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¯ææ¥æ"><el-date-picker v-model="archive.diagnosisDate" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="主治å»ç"><el-input v-model="archive.attendingDoctor" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ç»ç®¡å»ç"><el-input v-model="archive.managingDoctor" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ç»è®°äººå"><el-input v-model="archive.registrant" class="w-sm" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="éè®¿å¨æ(次æ°)"><el-input v-model="archive.followupCycles" class="w-xs" /></el-form-item></el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </el-card> |
| | | |
| | | <!-- ===== åå¦éè®¿ï¼æ©åé访表 + è¯å表ï¼éä¸ãç»å¨è¯¢æå¯¼åç»§ç»å¦å¨ å¹¶å¨äº§ç§å»ºæ¡£ãååºç°ï¼ ===== --> |
| | | <template v-if="archive.subType === 'pregnancy' && showFollowUp"> |
| | | <el-card class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"><span>åå¦é访管ç</span></div> |
| | | <el-tabs v-model="activeTab" type="border-card"> |
| | | <!-- 1. åå¦é访系ç»é®é¢ --> |
| | | <el-tab-pane label="åå¦é访系ç»é®é¢" name="sysQ"> |
| | | <el-form :model="form.pregSysQ" label-width="150px" size="small" :disabled="!editing"> |
| | | <div slot="header" class="card-header"><span>æ©åé访表</span></div> |
| | | <el-form :model="pregForm.earlyFollow" label-width="140px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="填忥æ"><el-date-picker v-model="form.pregSysQ.date" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="åå¨"><el-input-number v-model="form.pregSysQ.gestWeek" :min="1" :max="42" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="å§å"><el-input v-model="pregForm.earlyFollow.name" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="å¹´é¾"><el-input v-model="pregForm.earlyFollow.age" class="w-xs" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="å°±è¯å·"><el-input v-model="pregForm.earlyFollow.visitNo" class="w-sm" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="ä½é(kg)"><el-input-number v-model="form.pregSysQ.weight" :precision="1" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¡å"><el-input v-model="form.pregSysQ.bloodPressure" placeholder="æ¶ç¼©å/èå¼ å" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="宫é«(cm)"><el-input-number v-model="form.pregSysQ.fundalHeight" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="èç³»æ¹å¼(微信)"><el-input v-model="pregForm.earlyFollow.wechat" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="æ·ç±"><el-input v-model="pregForm.earlyFollow.household" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="å产å²"><el-input v-model="pregForm.earlyFollow.gravidaPara" placeholder="G_P_" class="w-xs" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="èå¿(次/å)"><el-input-number v-model="form.pregSysQ.fetalHeart" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="æ°´è¿"><el-select v-model="form.pregSysQ.edema" style="width:100%"><el-option label="æ " value="æ " /><el-option label="+" value="+" /><el-option label="++" value="++" /><el-option label="+++" value="+++" /></el-select></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="å°¿èç½"><el-select v-model="form.pregSysQ.urineProtein" style="width:100%"><el-option label="-" value="-" /><el-option label="±" value="±" /><el-option label="+" value="+" /><el-option label="++" value="++" /></el-select></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="å©å§»ç¶åµ"> |
| | | <el-select v-model="pregForm.earlyFollow.maritalStatus" class="w-sm"> |
| | | <el-option label="æªå©" value="æªå©" /><el-option label="å·²å©" value="å·²å©" /><el-option label="ä¸è¯¦" value="ä¸è¯¦" /> |
| | | </el-select> |
| | | </el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="å»ºè¡¨æ¥æ"><el-date-picker v-model="pregForm.earlyFollow.buildDate" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="é¢äº§æ"><el-date-picker v-model="pregForm.earlyFollow.edd" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-form-item label="èªè§çç¶"><el-input v-model="form.pregSysQ.symptoms" type="textarea" :rows="2" placeholder="头æ/ç¼è±/è¸é·/è
¹çç" /></el-form-item> |
| | | <el-form-item label="å¤çæè§"><el-input v-model="form.pregSysQ.advice" type="textarea" :rows="2" /></el-form-item> |
| | | <el-form-item label="䏿¬¡éè®¿æ¥æ"><el-date-picker v-model="form.pregSysQ.nextVisit" value-format="yyyy-MM-dd" style="width:200px" /></el-form-item> |
| | | <el-form-item label="é访å»ç"><el-input v-model="form.pregSysQ.doctor" style="width:200px" /></el-form-item> |
| | | <el-form-item label="è®¡åæµäº§ä¸»è¦åå (å¯å¤é)"> |
| | | <el-checkbox-group v-model="pregForm.earlyFollow.abortionReasons"> |
| | | <el-checkbox label="å·²æå¤å©" /><el-checkbox label="ç»æµå ç´ " /><el-checkbox label="è¯ç©æ´é²" /> |
| | | <el-checkbox label="æªè¾¾ç»å©å¹´é¾" /><el-checkbox label="身ä½å ç´ " /><el-checkbox label="å®¶åºæ¯æä¸è¶³" /> |
| | | <el-checkbox label="èªèº«ä¸æ¿çè²" /><el-checkbox label="å
¶ä»" /> |
| | | </el-checkbox-group> |
| | | <el-input v-if="pregForm.earlyFollow.abortionReasons.includes('å
¶ä»')" v-model="pregForm.earlyFollow.otherReason" placeholder="å
¶ä»åå " class="w-md" style="margin-top:8px" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç»§ç»å¦å¨ "> |
| | | <el-radio-group v-model="pregForm.earlyFollow.continuePregnancy"> |
| | | <el-radio label="æ¯">æ¯</el-radio><el-radio label="å¦">å¦</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="16"><el-form-item label="æ©å建ååä½"><el-input v-model="pregForm.earlyFollow.registrationUnit" class="w-full" /></el-form-item></el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </el-tab-pane> |
| | | |
| | | <!-- 2. åå¦é¦è¯ä¿¡æ¯ç»è®°è¡¨ --> |
| | | <el-tab-pane label="丽水å¦å¹¼ä¿å¥é¢åå¦é¦è¯ä¿¡æ¯ç»è®°è¡¨" name="firstVisit"> |
| | | <el-form :model="form.pregFirst" label-width="160px" size="small" :disabled="!editing"> |
| | | <el-divider content-position="left">åºæ¬ä¿¡æ¯</el-divider> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="å»ºæ¡£æ¥æ"><el-date-picker v-model="form.pregFirst.regDate" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ä¸å¤«å§å"><el-input v-model="form.pregFirst.husbandName" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ä¸å¤«çµè¯"><el-input v-model="form.pregFirst.husbandPhone" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="æ«æ¬¡æç»"><el-date-picker v-model="form.pregFirst.lmp" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="é¢äº§æ"><el-date-picker v-model="form.pregFirst.edd" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="忬¡/产次"><el-input v-model="form.pregFirst.gp" placeholder="G_P_" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-divider content-position="left">æ¢å¾å²</el-divider> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="å宫产å²"><el-select v-model="form.pregFirst.csHistory" style="width:100%"><el-option label="æ " :value="0" /><el-option label="æ" :value="1" /></el-select></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="æµäº§å²"><el-select v-model="form.pregFirst.abortionHistory" style="width:100%"><el-option label="æ " :value="0" /><el-option label="æ" :value="1" /></el-select></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ç¾ç
å²"><el-input v-model="form.pregFirst.diseaseHistory" placeholder="é«è¡å/ç³å°¿ç
/ç²ç¶è
ºç" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-divider content-position="left">æ¬æ¬¡å¦å¨ æ
åµ</el-divider> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="身é«(cm)"><el-input-number v-model="form.pregFirst.height" :precision="1" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ååä½é(kg)"><el-input-number v-model="form.pregFirst.preWeight" :precision="1" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-form-item label="é«å±å ç´ è¯ä¼°"><el-input v-model="form.pregFirst.riskAssessment" type="textarea" :rows="2" /></el-form-item> |
| | | <el-form-item label="建åå»ç"><el-input v-model="form.pregFirst.doctor" style="width:200px" /></el-form-item> |
| | | </el-form> |
| | | </el-tab-pane> |
| | | <div class="sub-section"> |
| | | <div class="sub-title">è¾
导å
容</div> |
| | | <el-table :data="pregForm.counseling" border size="small"> |
| | | <el-table-column label="è¾
导次æ°" width="120" align="center"> |
| | | <template slot-scope="scope">{{ ['ç¬¬ä¸æ¬¡è¾
导','ç¬¬äºæ¬¡è¾
导','ç¬¬ä¸æ¬¡è¾
导','ç¬¬åæ¬¡è¾
导'][scope.$index] }}</template> |
| | | </el-table-column> |
| | | <el-table-column label="è¾
å¯¼æ¥æ" width="160" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-date-picker v-if="editing" v-model="scope.row.date" value-format="yyyy-MM-dd" size="small" style="width:100%" /> |
| | | <span v-else>{{ scope.row.date || '-' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="è¾
导å
容" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-input v-if="editing" v-model="scope.row.content" size="small" /> |
| | | <span v-else>{{ scope.row.content || '-' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="è¾
导人å" width="140" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-input v-if="editing" v-model="scope.row.person" size="small" /> |
| | | <span v-else>{{ scope.row.person || '-' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | |
| | | <!-- 3. æ©åé访ç»è®°è¡¨ --> |
| | | <el-tab-pane label="丽水å¦å¹¼ä¿å¥é¢æ©åé访ç»è®°è¡¨" name="earlyFollow"> |
| | | <el-form :model="form.pregEarly" label-width="150px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="éè®¿æ¥æ"><el-date-picker v-model="form.pregEarly.date" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="åå¨"><el-input-number v-model="form.pregEarly.gestWeek" :min="1" :max="14" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="æ©åååº"><el-select v-model="form.pregEarly.morningSickness" style="width:100%"><el-option label="æ " value="æ " /><el-option label="轻度" value="轻度" /><el-option label="ä¸åº¦" value="ä¸åº¦" /><el-option label="é度" value="é度" /></el-select></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="é´éåºè¡"><el-select v-model="form.pregEarly.bleeding" style="width:100%"><el-option label="æ " value="æ " /><el-option label="æ" value="æ" /></el-select></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è
¹ç"><el-select v-model="form.pregEarly.abdominalPain" style="width:100%"><el-option label="æ " value="æ " /><el-option label="æ" value="æ" /></el-select></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="è¡å¸¸è§"><el-input v-model="form.pregEarly.bloodRoutine" placeholder="Hb/PLTç" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="尿常è§"><el-input v-model="form.pregEarly.urineRoutine" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="Bè¶
æ£æ¥"><el-input v-model="form.pregEarly.ultrasound" placeholder="CRL/NTç" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-form-item label="å¶é
¸è¡¥å
"><el-select v-model="form.pregEarly.folicAcid" style="width:200px"><el-option label="è§å¾æç¨" value="è§å¾æç¨" /><el-option label="å¶å°æç¨" value="å¶å°æç¨" /><el-option label="æªæç¨" value="æªæç¨" /></el-select></el-form-item> |
| | | <el-form-item label="æå¯¼æè§"><el-input v-model="form.pregEarly.advice" type="textarea" :rows="2" /></el-form-item> |
| | | <el-form-item label="é访å»ç"><el-input v-model="form.pregEarly.doctor" style="width:200px" /></el-form-item> |
| | | <div class="sub-section"> |
| | | <div class="sub-title">è¯å表</div> |
| | | <el-form :model="pregForm.score" label-width="140px" size="small" :disabled="!editing" inline> |
| | | <el-form-item label="è¯åæ»å"><el-input-number v-model="pregForm.score.total" :controls="false" style="width:140px" /></el-form-item> |
| | | <el-form-item label="è¯ä¼°ç»æ"><el-input v-model="pregForm.score.result" class="w-lg" /></el-form-item> |
| | | </el-form> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </div> |
| | | </el-card> |
| | | |
| | | <!-- éè®¿å¨æ --> |
| | | <el-card class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"><span>éè®¿å¨æ</span></div> |
| | | <EditableTable :data.sync="pregForm.followupCycle" :editing="editing" :columns="followupColumns" /> |
| | | </el-card> |
| | | |
| | | <!-- å½åæ£è
é访记å½è¡¨ --> |
| | | <el-card class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"><span>å½åæ£è
é访记å½è¡¨</span></div> |
| | | <el-table :data="currentFollowRecords" border size="small"> |
| | | <el-table-column type="index" label="åºå·" width="60" align="center" /> |
| | | <el-table-column prop="planDate" label="æéè®¿æ¥æ" width="130" align="center" /> |
| | | <el-table-column prop="status" label="ç¶åµ" width="100" align="center" /> |
| | | <el-table-column prop="method" label="é访æ¹å¼" width="110" align="center" /> |
| | | <el-table-column prop="situation" label="é访æ
åµ" align="center" show-overflow-tooltip /> |
| | | <el-table-column prop="followDate" label="éè®¿æ¥æ" width="130" align="center" /> |
| | | <el-table-column prop="staff" label="é访人å" width="110" align="center" /> |
| | | </el-table> |
| | | </el-card> |
| | | </template> |
| | | |
| | | <!-- ===== æ´å¹´æé访ï¼6个表å ===== --> |
| | | <!-- ===== å´ç»ç»æMHIï¼6 个é表 tab ===== --> |
| | | <template v-if="archive.subType === 'menopause'"> |
| | | <el-card class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"><span>æ´å¹´æé访管ç</span></div> |
| | | <div slot="header" class="card-header"><span>å´ç»ç»æMHI管ç</span></div> |
| | | <el-tabs v-model="activeTab" type="border-card"> |
| | | <!-- 1. æ´å¹´æé访系ç»é®é¢è¡¨ --> |
| | | <el-tab-pane label="æ´å¹´æé访系ç»é®é¢è¡¨" name="sysQ"> |
| | | <el-form :model="form.menoSysQ" label-width="150px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="填忥æ"><el-date-picker v-model="form.menoSysQ.date" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="填忥æ"><el-date-picker v-model="form.menoSysQ.date" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="å¹´é¾"><el-input-number v-model="form.menoSysQ.age" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="æç»æ
åµ"><el-input v-model="form.menoSysQ.menstruation" placeholder="卿/ç»æ/ç»é" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="æ«æ¬¡æç»"><el-date-picker v-model="form.menoSysQ.lmp" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="æç»æ
åµ"><el-input v-model="form.menoSysQ.menstruation" placeholder="卿/ç»æ/ç»é" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="æ«æ¬¡æç»"><el-date-picker v-model="form.menoSysQ.lmp" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ç»ç»å¹´é¾"><el-input-number v-model="form.menoSysQ.menopauseAge" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | |
| | | </el-row> |
| | | <el-form-item label="å
¶ä»çç¶"><el-input v-model="form.menoSysQ.otherSymptoms" type="textarea" :rows="2" /></el-form-item> |
| | | <el-form-item label="å¤çæè§"><el-input v-model="form.menoSysQ.advice" type="textarea" :rows="2" /></el-form-item> |
| | | <el-form-item label="å»ç"><el-input v-model="form.menoSysQ.doctor" style="width:200px" /></el-form-item> |
| | | <el-form-item label="å»ç"><el-input v-model="form.menoSysQ.doctor" class="w-sm" /></el-form-item> |
| | | </el-form> |
| | | </el-tab-pane> |
| | | |
| | | <!-- 2. MHTé¦è¯ç
å表 --> |
| | | <el-tab-pane label="MHTé¦è¯ç
å表" name="mhtFirst"> |
| | | <el-form :model="form.mhtFirst" label-width="160px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="å°±è¯æ¥æ"><el-date-picker v-model="form.mhtFirst.date" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="主è¯"><el-input v-model="form.mhtFirst.chiefComplaint" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="å°±è¯æ¥æ"><el-date-picker v-model="form.mhtFirst.date" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="主è¯"><el-input v-model="form.mhtFirst.chiefComplaint" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ç»ç»å¹´é"><el-input-number v-model="form.mhtFirst.menopauseYears" :precision="1" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | |
| | | <el-col :span="8"><el-form-item label="BMI"><el-input-number v-model="form.mhtFirst.bmi" :precision="1" disabled /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="è¡å"><el-input v-model="form.mhtFirst.bloodPressure" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¡å"><el-input v-model="form.mhtFirst.bloodPressure" class="w-xs" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¡ç³"><el-input-number v-model="form.mhtFirst.glucose" :precision="1" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¡è"><el-input v-model="form.mhtFirst.lipid" placeholder="TC/TG/LDL/HDL" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¡è"><el-input v-model="form.mhtFirst.lipid" placeholder="TC/TG/LDL/HDL" class="w-md" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-form-item label="æ¢å¾å²"><el-input v-model="form.mhtFirst.pastHistory" type="textarea" :rows="2" placeholder="é«è¡å/ç³å°¿ç
/è¡æ /ä¹³è
ºç/å宫èç¤ç" /></el-form-item> |
| | | <el-form-item label="å¦ç§æ£æ¥"><el-input v-model="form.mhtFirst.gynExam" type="textarea" :rows="2" /></el-form-item> |
| | | <el-form-item label="ä¹³è
ºæ£æ¥"><el-input v-model="form.mhtFirst.breastExam" type="textarea" :rows="2" /></el-form-item> |
| | | <el-form-item label="è¾
婿£æ¥"><el-input v-model="form.mhtFirst.auxExam" type="textarea" :rows="2" placeholder="Bè¶
/骨å¯åº¦/æ¿ç´ æ°´å¹³ç" /></el-form-item> |
| | | <el-form-item label="MHTæ¹æ¡"><el-input v-model="form.mhtFirst.mhtPlan" type="textarea" :rows="2" placeholder="è¯ç©åç§°/åé/ç¨æ³/çç¨" /></el-form-item> |
| | | <el-form-item label="å»ç"><el-input v-model="form.mhtFirst.doctor" style="width:200px" /></el-form-item> |
| | | <el-form-item label="å»ç"><el-input v-model="form.mhtFirst.doctor" class="w-sm" /></el-form-item> |
| | | </el-form> |
| | | </el-tab-pane> |
| | | |
| | | <!-- 3. MHTå¤è¯ç
å表 --> |
| | | <el-tab-pane label="MHTå¤è¯ç
å表" name="mhtFollow"> |
| | | <el-form :model="form.mhtFollow" label-width="160px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="å¤è¯æ¥æ"><el-date-picker v-model="form.mhtFollow.date" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="å¤è¯æ¥æ"><el-date-picker v-model="form.mhtFollow.date" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ç¨è¯ä¾ä»æ§"><el-select v-model="form.mhtFollow.compliance" style="width:100%"><el-option label="è¯å¥½" value="è¯å¥½" /><el-option label="ä¸è¬" value="ä¸è¬" /><el-option label="å·®" value="å·®" /></el-select></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="çç¶æ¹å"><el-select v-model="form.mhtFollow.symptomImprove" style="width:100%"><el-option label="ææ¾" value="ææ¾" /><el-option label="é¨å" value="é¨å" /><el-option label="æ åå" value="æ åå" /></el-select></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ä¸è¯ååº"><el-input v-model="form.mhtFollow.sideEffect" placeholder="å¦ä¹³æ¿èç/é´éåºè¡ç" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="ä¸è¯ååº"><el-input v-model="form.mhtFollow.sideEffect" placeholder="å¦ä¹³æ¿èç/é´éåºè¡ç" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="é´éåºè¡"><el-select v-model="form.mhtFollow.bleeding" style="width:100%"><el-option label="æ " value="æ " /><el-option label="ç¹æ»´" value="ç¹æ»´" /><el-option label="å°é" value="å°é" /><el-option label="ä¸é" value="ä¸é" /></el-select></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="ä½é(kg)"><el-input-number v-model="form.mhtFollow.weight" :precision="1" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¡å"><el-input v-model="form.mhtFollow.bloodPressure" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="è¡å"><el-input v-model="form.mhtFollow.bloodPressure" class="w-xs" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-form-item label="夿¥ç»æ"><el-input v-model="form.mhtFollow.reExamResult" type="textarea" :rows="2" placeholder="Bè¶
/ä¹³è
º/æ¿ç´ çæ£æ¥ç»æ" /></el-form-item> |
| | | <el-form-item label="æ¹æ¡è°æ´"><el-input v-model="form.mhtFollow.planAdjust" type="textarea" :rows="2" /></el-form-item> |
| | | <el-form-item label="䏿¬¡å¤è¯"><el-date-picker v-model="form.mhtFollow.nextVisit" value-format="yyyy-MM-dd" style="width:200px" /></el-form-item> |
| | | <el-form-item label="å»ç"><el-input v-model="form.mhtFollow.doctor" style="width:200px" /></el-form-item> |
| | | <el-form-item label="䏿¬¡å¤è¯"><el-date-picker v-model="form.mhtFollow.nextVisit" value-format="yyyy-MM-dd" class="w-md" /></el-form-item> |
| | | <el-form-item label="å»ç"><el-input v-model="form.mhtFollow.doctor" class="w-sm" /></el-form-item> |
| | | </el-form> |
| | | </el-tab-pane> |
| | | |
| | | <!-- 4. æ¹è¯Kuppermanè¯åæ å表 --> |
| | | <el-tab-pane label="æ¹è¯Kuppermanè¯åæ å表" name="kupperman"> |
| | | <el-form :model="form.kupperman" label-width="160px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="è¯ä¼°æ¥æ"><el-date-picker v-model="form.kupperman.date" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"><el-col :span="8"><el-form-item label="è¯ä¼°æ¥æ"><el-date-picker v-model="form.kupperman.date" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col></el-row> |
| | | <KuppermanScoreTable v-model="form.kupperman" :editing="editing" /> |
| | | </el-form> |
| | | </el-tab-pane> |
| | | |
| | | <!-- 5. æ´å¹´æè¯åé表(MRS) --> |
| | | <el-tab-pane label="æ´å¹´æè¯åé表ï¼MRSï¼" name="mrs"> |
| | | <el-form :model="form.mrs" label-width="160px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="è¯ä¼°æ¥æ"><el-date-picker v-model="form.mrs.date" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"><el-col :span="8"><el-form-item label="è¯ä¼°æ¥æ"><el-date-picker v-model="form.mrs.date" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col></el-row> |
| | | <MRSScoreTable v-model="form.mrs" :editing="editing" /> |
| | | </el-form> |
| | | </el-tab-pane> |
| | | |
| | | <!-- 6. å¹å
¹å ¡ç¡ç è´¨éè¯åé表(PSQI) --> |
| | | <el-tab-pane label="å¹å
¹å ¡ç¡ç è´¨éè¯åé表ï¼PSQIï¼" name="psqi"> |
| | | <el-form :model="form.psqi" label-width="160px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="è¯ä¼°æ¥æ"><el-date-picker v-model="form.psqi.date" value-format="yyyy-MM-dd" style="width:100%" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"><el-col :span="8"><el-form-item label="è¯ä¼°æ¥æ"><el-date-picker v-model="form.psqi.date" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col></el-row> |
| | | <PSQIScoreTable v-model="form.psqi" :editing="editing" /> |
| | | </el-form> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </el-card> |
| | | </template> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="æå¡è®°å½" name="service"> |
| | | <ServiceRecords :patid="archive.patid" /> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </template> |
| | | <div v-else class="empty-wrap">æ¡£æ¡ä¸å卿已å é¤</div> |
| | | </div> |
| | |
| | | |
| | | <script> |
| | | import InfoField from "../childHealth/InfoField.vue"; |
| | | import EditableTable from "../components/EditableTable.vue"; |
| | | import ServiceRecords from "../components/ServiceRecords.vue"; |
| | | import KuppermanScoreTable from "./KuppermanScoreTable.vue"; |
| | | import MRSScoreTable from "./MRSScoreTable.vue"; |
| | | import PSQIScoreTable from "./PSQIScoreTable.vue"; |
| | | import { loadArchives, saveArchives } from "../types"; |
| | | |
| | | const PREGNANCY_OPTIONS = { |
| | | planBirth: { label: "é¦è¯æçè²", details: ["å
å
æµäº§"], hints: ["å»å¦å¤ç½®åç»§ç»å¦å¨ å¹¶å¨äº§ç§å»ºæ¡£"] }, |
| | | earlyAbnormal: { label: "é¦è¯æ©åå¼å¸¸", details: ["èªç¶æµäº§", "èèåè²"], hints: ["为女æ§å次å¦å¨ æä¾å¤åæå¯¼"] }, |
| | | planAbortion: { label: "é¦è¯æäººå·¥æµäº§", details: ["è¯ç©æµäº§", "ææ¯æµäº§"], hints: ["ç»å¨è¯¢æå¯¼åç»§ç»å¦å¨ å¹¶å¨äº§ç§å»ºæ¡£"] }, |
| | | }; |
| | | |
| | | export default { |
| | | name: "MaternalHealthArchiveDetail", |
| | | components: { InfoField, KuppermanScoreTable, MRSScoreTable, PSQIScoreTable }, |
| | | components: { InfoField, EditableTable, ServiceRecords, KuppermanScoreTable, MRSScoreTable, PSQIScoreTable }, |
| | | data() { |
| | | return { |
| | | loading: false, archive: null, editing: false, activeTab: "sysQ", |
| | | PREGNANCY_OPTIONS, |
| | | loading: false, archive: null, editing: true, activeTab: "sysQ", mainTab: "detail", |
| | | followupColumns: [ |
| | | { prop: "seq", label: "åºå·", width: 60 }, |
| | | { prop: "planDate", label: "æéè®¿æ¥æ", width: 130, type: "date" }, |
| | | { prop: "status", label: "ç¶åµ", width: 100, type: "select", options: ["已宿", "æªå®æ"] }, |
| | | { prop: "method", label: "é访æ¹å¼", width: 110 }, |
| | | { prop: "situation", label: "é访æ
åµ", minWidth: 160 }, |
| | | { prop: "followDate", label: "éè®¿æ¥æ", width: 130, type: "date" }, |
| | | { prop: "staff", label: "é访人å", width: 110 }, |
| | | ], |
| | | pregForm: { |
| | | firstVisit: { visitNo: "", selfPhone: "", wardName: "", contactPhone: "", idcardno: "", address: "", diagname: "", firstDoctor: "" }, |
| | | pregnancy: { status: "", details: [], hint: [] }, |
| | | earlyFollow: { name: "", age: "", visitNo: "", wechat: "", household: "", gravidaPara: "", maritalStatus: "", buildDate: "", abortionReasons: [], otherReason: "", continuePregnancy: "", edd: "", registrationUnit: "" }, |
| | | counseling: [ |
| | | { date: "", content: "", person: "" }, { date: "", content: "", person: "" }, |
| | | { date: "", content: "", person: "" }, { date: "", content: "", person: "" }, |
| | | ], |
| | | score: { total: null, result: "" }, |
| | | registration: { isRegistered: "", unregisteredReason: "", edd: "", recorder: "" }, |
| | | followupCycle: [], |
| | | }, |
| | | form: { |
| | | pregSysQ: { date:"", gestWeek:null, weight:null, bloodPressure:"", fundalHeight:null, fetalHeart:null, edema:"æ ", urineProtein:"-", symptoms:"", advice:"", nextVisit:"", doctor:"" }, |
| | | pregFirst: { regDate:"", husbandName:"", husbandPhone:"", lmp:"", edd:"", gp:"", csHistory:0, abortionHistory:0, diseaseHistory:"", height:null, preWeight:null, riskAssessment:"", doctor:"" }, |
| | | pregEarly: { date:"", gestWeek:null, morningSickness:"æ ", bleeding:"æ ", abdominalPain:"æ ", bloodRoutine:"", urineRoutine:"", ultrasound:"", folicAcid:"è§å¾æç¨", advice:"", doctor:"" }, |
| | | menoSysQ: { date:"", age:null, menstruation:"", lmp:"", menopauseAge:null, hotFlash:0, insomnia:0, mood:0, fatigue:0, jointPain:0, palpitation:0, dryness:0, libido:0, otherSymptoms:"", advice:"", doctor:"" }, |
| | | mhtFirst: { date:"", chiefComplaint:"", menopauseYears:null, height:null, weight:null, bmi:null, bloodPressure:"", glucose:null, lipid:"", pastHistory:"", gynExam:"", breastExam:"", auxExam:"", mhtPlan:"", doctor:"" }, |
| | | mhtFollow: { date:"", compliance:"è¯å¥½", symptomImprove:"é¨å", sideEffect:"", bleeding:"æ ", weight:null, bloodPressure:"", reExamResult:"", planAdjust:"", nextVisit:"", doctor:"" }, |
| | |
| | | }, |
| | | computed: { |
| | | sourceLabel() { const m={standalone:"ç¬ç«å»ºæ¡£",outpatient:"é¨è¯è®°å½",inpatient:"å¨é¢è®°å½"}; return m[this.archive?.sourcePage]||this.archive?.sourcePage||"-"; }, |
| | | menstrualLabel() { const m={irregular:"æç»ç´ä¹±",amenorrhea_short:"éç»ï¼<12个æï¼",menopause:"ç»ç»ï¼â¥12个æï¼",surgical:"人工ç»ç»"}; return m[this.archive?.archiveForm?.menstrualStatus]||"-"; }, |
| | | pregnancySubOptions() { |
| | | const opt = PREGNANCY_OPTIONS[this.pregForm.pregnancy.status]; |
| | | return opt ? opt.details : []; |
| | | }, |
| | | pregnancyHintOptions() { |
| | | const opt = PREGNANCY_OPTIONS[this.pregForm.pregnancy.status]; |
| | | return opt ? opt.hints : []; |
| | | }, |
| | | showFollowUp() { |
| | | return this.pregForm.pregnancy.status === "planAbortion" && |
| | | this.pregForm.pregnancy.hint.includes("ç»å¨è¯¢æå¯¼åç»§ç»å¦å¨ å¹¶å¨äº§ç§å»ºæ¡£"); |
| | | }, |
| | | currentFollowRecords() { |
| | | return (this.pregForm.followupCycle || []).filter((r) => r.status === "已宿"); |
| | | }, |
| | | }, |
| | | created() { |
| | | const id = this.$route.query.id; |
| | | if (id) this.loadArchive(id); |
| | | if (id) this.loadArchive(id, this.$route.query.edit == 1); |
| | | }, |
| | | methods: { |
| | | loadArchive(id) { |
| | | loadArchive(id, autoEdit) { |
| | | this.loading = true; |
| | | const all = JSON.parse(localStorage.getItem("patientArchives") || "[]"); |
| | | this.archive = all.find(item => item.id === id) || null; |
| | | this.archive = loadArchives().find((item) => item.id === id) || null; |
| | | if (this.archive) { |
| | | if (this.archive.subType === 'pregnancy') this.activeTab = "sysQ"; |
| | | else if (this.archive.subType === 'menopause') this.activeTab = "sysQ"; |
| | | if (this.archive.subType === "pregnancy") { |
| | | if (this.archive.pregFormData) { |
| | | const saved = JSON.parse(JSON.stringify(this.archive.pregFormData)); |
| | | this.pregForm = Object.assign({}, this.pregForm, saved); |
| | | if (!this.pregForm.pregnancy) this.pregForm.pregnancy = { status: "", details: [], hint: [] }; |
| | | } |
| | | } else if (this.archive.subType === "menopause") { |
| | | if (this.archive.formData) { |
| | | Object.keys(this.form).forEach(k => { |
| | | Object.keys(this.form).forEach((k) => { |
| | | if (this.archive.formData[k]) Object.assign(this.form[k], this.archive.formData[k]); |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | if (autoEdit) this.editing = true; |
| | | this.loading = false; |
| | | }, |
| | | onPregnancyStatusChange() { |
| | | this.pregForm.pregnancy.details = []; |
| | | this.pregForm.pregnancy.hint = []; |
| | | const opt = PREGNANCY_OPTIONS[this.pregForm.pregnancy.status]; |
| | | if (this.archive) this.archive.pregnancyStatus = opt ? opt.label : ""; |
| | | }, |
| | | toggleEdit() { |
| | | if (this.editing) { |
| | | this.archive.formData = JSON.parse(JSON.stringify(this.form)); |
| | | if (this.archive.subType === "pregnancy") this.archive.pregFormData = JSON.parse(JSON.stringify(this.pregForm)); |
| | | if (this.archive.subType === "menopause") this.archive.formData = JSON.parse(JSON.stringify(this.form)); |
| | | this.archive.updateTime = new Date().toISOString().replace("T"," ").substring(0,19); |
| | | const all = JSON.parse(localStorage.getItem("patientArchives") || "[]"); |
| | | const idx = all.findIndex(item => item.id === this.archive.id); |
| | | const all = loadArchives(); |
| | | const idx = all.findIndex((item) => item.id === this.archive.id); |
| | | if (idx >= 0) all[idx] = JSON.parse(JSON.stringify(this.archive)); |
| | | localStorage.setItem("patientArchives", JSON.stringify(all)); |
| | | saveArchives(all); |
| | | this.$message.success("ä¿åæå"); |
| | | } |
| | | this.editing = !this.editing; |
| | | }, |
| | | handleCloseCase() { |
| | | this.$modal.confirm("确认å°è¯¥æ¡£æ¡ç»æ¡ï¼ç»æ¡åå¯å¨å表页æ¥çç»æ¡ç¶æã").then(() => { |
| | | this.archive.closeStatus = 1; |
| | | this.archive.updateTime = new Date().toISOString().replace("T", " ").substring(0, 19); |
| | | const all = loadArchives(); |
| | | const idx = all.findIndex((item) => item.id === this.archive.id); |
| | | if (idx >= 0) all[idx] = JSON.parse(JSON.stringify(this.archive)); |
| | | saveArchives(all); |
| | | this.$message.success("å·²ç»æ¡"); |
| | | }).catch(() => {}); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | $primary: #3f6ef0; |
| | | |
| | | // è¾å
¥æ¡å®½åº¦ï¼æå段é¿çåºåï¼ |
| | | .w-xs { width: 90px; } |
| | | .w-sm { width: 150px; } |
| | | .w-md { width: 200px; } |
| | | .w-lg { width: 280px; } |
| | | .w-full { width: 100%; } |
| | | |
| | | .action-bar { margin-bottom: 16px; } |
| | | .info-card { margin-bottom: 0; } |
| | | .card-header { display: flex; justify-content: space-between; align-items: center; font-size: 16px; font-weight: 600; } |
| | | .header-sub { font-size: 13px; color: #909399; font-weight: normal; } |
| | | .empty-wrap { text-align: center; padding: 100px 0; color: #c0c4cc; font-size: 16px; } |
| | | |
| | | // èè²åå²çº¿ + å°æ é¢ |
| | | .sub-section { |
| | | & + .sub-section { |
| | | margin-top: 24px; |
| | | } |
| | | } |
| | | .sub-title { |
| | | position: relative; |
| | | padding-left: 12px; |
| | | margin-bottom: 16px; |
| | | font-size: 15px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | line-height: 1.2; |
| | | |
| | | &::before { |
| | | content: ""; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 1px; |
| | | bottom: 1px; |
| | | width: 3px; |
| | | border-radius: 2px; |
| | | background: $primary; |
| | | } |
| | | |
| | | &::after { |
| | | content: ""; |
| | | position: absolute; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: -7px; |
| | | border-bottom: 1px solid #dbe5ff; |
| | | } |
| | | } |
| | | |
| | | // å¦å¨ æ
åµ ä¸çº§å¾é |
| | | .preg-cascade { |
| | | .cascade-col { |
| | | padding: 14px 16px; |
| | | min-height: 120px; |
| | | border: 1px solid #e6ecfb; |
| | | border-radius: 8px; |
| | | background: #fafbff; |
| | | |
| | | .el-radio-group, |
| | | .el-checkbox-group { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: flex-start; |
| | | |
| | | .el-radio, |
| | | .el-checkbox { |
| | | margin-right: 0; |
| | | margin-bottom: 8px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .cascade-label { |
| | | margin-bottom: 10px; |
| | | font-size: 13px; |
| | | font-weight: 600; |
| | | color: $primary; |
| | | } |
| | | |
| | | .cascade-empty { |
| | | padding: 10px 0; |
| | | font-size: 12px; |
| | | color: #c0c4cc; |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <ArchiveList type="menopause" /> |
| | | </template> |
| | | |
| | | <script> |
| | | import ArchiveList from "../components/ArchiveList.vue"; |
| | | |
| | | export default { |
| | | name: "MenopauseArchiveList", |
| | | components: { ArchiveList }, |
| | | }; |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <ArchiveList type="nutrition" /> |
| | | </template> |
| | | |
| | | <script> |
| | | import ArchiveList from "../components/ArchiveList.vue"; |
| | | |
| | | export default { |
| | | name: "NutritionArchiveList", |
| | | components: { ArchiveList }, |
| | | }; |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <ArchiveList type="pregnancy" /> |
| | | </template> |
| | | |
| | | <script> |
| | | import ArchiveList from "../components/ArchiveList.vue"; |
| | | |
| | | export default { |
| | | name: "PregnancyArchiveList", |
| | | components: { ArchiveList }, |
| | | }; |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // å¦ä¿/å¿ä¿ 5 ç§ç¹æ®æ£è
䏿¡æ³¨å表ï¼å䏿°æ®æºï¼ |
| | | // category: maternal=å¦ä¿ç§ / child=å¿ä¿ç§ |
| | | // entryLabel: å
¥å£ï¼é¨è¯è®°å½é¡µé䏿¡ï¼æé®å |
| | | // label: å表页/详æ
页æ é¢ |
| | | // columns: å表页åå®ä¹ { label, prop, type } |
| | | // type åå¼ï¼text(é»è®¤) | sex | date | closeStatus |
| | | export const ARCHIVE_TYPES = [ |
| | | { |
| | | key: "pregnancy", |
| | | category: "maternal", |
| | | entryLabel: "æ©åå
³ç±", |
| | | label: "åå¦é访", |
| | | subTypeLabel: "åå¦é访", |
| | | route: "/filing/pregnancy", |
| | | detailRoute: "/filing/maternalDetail", |
| | | columns: [ |
| | | { label: "å§å", prop: "patname" }, |
| | | { label: "åºçæ¥æ", prop: "birthday", type: "date" }, |
| | | { label: "身份è¯å·", prop: "idcardno" }, |
| | | { label: "èç³»çµè¯", prop: "telcode" }, |
| | | { label: "è¯ææ¥æ", prop: "diagnosisDate", type: "date" }, |
| | | { label: "å»ºæ¡£æ¥æ", prop: "createTime", type: "date" }, |
| | | { label: "è¯æ", prop: "diagname" }, |
| | | { label: "å¦å¨ æ
åµ", prop: "pregnancyStatus" }, |
| | | { label: "主治å»ç", prop: "attendingDoctor" }, |
| | | { label: "ç»ç®¡å»ç", prop: "managingDoctor" }, |
| | | { label: "ç»æ¡ç¶æ", prop: "closeStatus", type: "closeStatus" }, |
| | | { label: "ç»è®°äººå", prop: "registrant" }, |
| | | ], |
| | | }, |
| | | { |
| | | key: "menopause", |
| | | category: "maternal", |
| | | entryLabel: "å´ç»ç»æMHI", |
| | | label: "å´ç»ç»æMHI", |
| | | subTypeLabel: "å´ç»ç»æMHI", |
| | | route: "/filing/menopause", |
| | | detailRoute: "/filing/maternalDetail", |
| | | columns: [ |
| | | { label: "å§å", prop: "patname" }, |
| | | { label: "åºçæ¥æ", prop: "birthday", type: "date" }, |
| | | { label: "身份è¯å·", prop: "idcardno" }, |
| | | { label: "èç³»çµè¯", prop: "telcode" }, |
| | | { label: "è¯ææ¥æ", prop: "diagnosisDate", type: "date" }, |
| | | { label: "å»ºæ¡£æ¥æ", prop: "createTime", type: "date" }, |
| | | { label: "è¯æ", prop: "diagname" }, |
| | | { label: "éè®¿å¨æï¼æ¬¡æ°ï¼", prop: "followupCycles" }, |
| | | { label: "主治å»ç", prop: "attendingDoctor" }, |
| | | { label: "ç»ç®¡å»ç", prop: "managingDoctor" }, |
| | | { label: "ç»æ¡ç¶æ", prop: "closeStatus", type: "closeStatus" }, |
| | | { label: "ç»è®°äººå", prop: "registrant" }, |
| | | ], |
| | | }, |
| | | { |
| | | key: "highRisk", |
| | | category: "child", |
| | | entryLabel: "é«å±å¿ä¸æ¡", |
| | | label: "é«å±å¿ä¸æ¡", |
| | | subTypeLabel: "é«å±å¿ä¸æ¡ç®¡ç", |
| | | route: "/filing/highRisk", |
| | | detailRoute: "/filing/childDetail", |
| | | columns: [ |
| | | { label: "å¿ç«¥å§å", prop: "patname" }, |
| | | { label: "å®¶é¿å§å", prop: "parentInfo.parentName" }, |
| | | { label: "æéè®¿æ¥æ", prop: "followupDate", type: "date" }, |
| | | { label: "èç³»çµè¯", prop: "telcode" }, |
| | | { label: "è¯ææ¥æ", prop: "diagnosisDate", type: "date" }, |
| | | { label: "å»ºæ¡£æ¥æ", prop: "createTime", type: "date" }, |
| | | { label: "åºçåå¨", prop: "gestationalWeek" }, |
| | | { label: "æ§å«", prop: "sex", type: "sex" }, |
| | | { label: "åºçæ¥æ", prop: "birthday", type: "date" }, |
| | | { label: "åºçä½é", prop: "birthWeight" }, |
| | | { label: "é«å±å¿åç±»", prop: "highRiskCategory" }, |
| | | { label: "é«å±å¿åç§°", prop: "highRiskName" }, |
| | | { label: "ç»è®°äººå", prop: "registrant" }, |
| | | ], |
| | | }, |
| | | { |
| | | key: "nutrition", |
| | | category: "child", |
| | | entryLabel: "è¥å
»æ§ç¾ç
", |
| | | label: "è¥å
»æ§ç¾ç
", |
| | | subTypeLabel: "è¥å
»æ§ç¾ç
䏿¡ç®¡ç", |
| | | route: "/filing/nutrition", |
| | | detailRoute: "/filing/childDetail", |
| | | columns: [ |
| | | { label: "å¿ç«¥å§å", prop: "patname" }, |
| | | { label: "å®¶é¿å§å", prop: "parentInfo.parentName" }, |
| | | { label: "åºçæ¥æ", prop: "birthday", type: "date" }, |
| | | { label: "èç³»çµè¯", prop: "telcode" }, |
| | | { label: "è¯ææ¥æ", prop: "diagnosisDate", type: "date" }, |
| | | { label: "å»ºæ¡£æ¥æ", prop: "createTime", type: "date" }, |
| | | { label: "åºçåå¨", prop: "gestationalWeek" }, |
| | | { label: "æ§å«", prop: "sex", type: "sex" }, |
| | | { label: "åºçä½é", prop: "birthWeight" }, |
| | | { label: "è¥å
»æ§ç¾ç
åç§°", prop: "nutritionName" }, |
| | | { label: "ç»è®°äººå", prop: "registrant" }, |
| | | ], |
| | | }, |
| | | { |
| | | key: "learning", |
| | | category: "child", |
| | | entryLabel: "å¦ä¹ å°é¾", |
| | | label: "å¦ä¹ å°é¾", |
| | | subTypeLabel: "å¦ä¹ å°é¾ä¸æ¡ç®¡ç", |
| | | route: "/filing/learning", |
| | | detailRoute: "/filing/childDetail", |
| | | columns: [ |
| | | { label: "å¿ç«¥å§å", prop: "patname" }, |
| | | { label: "å®¶é¿å§å", prop: "parentInfo.parentName" }, |
| | | { label: "åºçæ¥æ", prop: "birthday", type: "date" }, |
| | | { label: "èç³»çµè¯", prop: "telcode" }, |
| | | { label: "è¯ææ¥æ", prop: "diagnosisDate", type: "date" }, |
| | | { label: "å»ºæ¡£æ¥æ", prop: "createTime", type: "date" }, |
| | | { label: "æ§å«", prop: "sex", type: "sex" }, |
| | | { label: "é¢çº¦æ
åµ", prop: "appointmentStatus" }, |
| | | ], |
| | | }, |
| | | ]; |
| | | |
| | | export function getTypeByKey(key) { |
| | | return ARCHIVE_TYPES.find((t) => t.key === key); |
| | | } |
| | | |
| | | // 读å localStorage æ¡£æ¡å表 |
| | | export function loadArchives() { |
| | | try { |
| | | return JSON.parse(localStorage.getItem("patientArchives") || "[]"); |
| | | } catch (e) { |
| | | return []; |
| | | } |
| | | } |
| | | |
| | | export function saveArchives(list) { |
| | | localStorage.setItem("patientArchives", JSON.stringify(list)); |
| | | } |
| | | |
| | | // ç±ä¸æ¡æ£è
è®°å½ï¼é¨è¯/ä½é¢/ç¬ç«å½å
¥ï¼çææä¸æ¡çæ¡£æ¡è稿 |
| | | export function buildArchiveRecord(patient, typeKey, sourcePage) { |
| | | const type = getTypeByKey(typeKey); |
| | | const now = new Date().toISOString().replace("T", " ").substring(0, 19); |
| | | const patid = patient.patid || patient.id || "sa_" + Date.now(); |
| | | return { |
| | | id: "arc_" + Date.now() + "_" + Math.random().toString(36).substr(2, 6), |
| | | patientId: patid, |
| | | patid: patid, |
| | | patname: patient.patname || patient.name || "", |
| | | sex: patient.sex, |
| | | age: patient.age, |
| | | telcode: patient.telcode || patient.phone || "", |
| | | deptname: patient.deptname || "", |
| | | diagname: patient.diagname || "", |
| | | outhospno: patient.outhospno || "", |
| | | inhospno: patient.inhospno || "", |
| | | bedNo: patient.bedNo || "", |
| | | drname: patient.drname || "", |
| | | nurseName: patient.nurseName || "", |
| | | starttime: patient.starttime || patient.admitdate || "", |
| | | mainCategory: type.category, |
| | | mainCategoryLabel: type.category === "child" ? "å¿ä¿ç§å»ºæ¡£" : "å¦ä¿ç§å»ºæ¡£", |
| | | subType: type.key, |
| | | subTypeLabel: type.subTypeLabel, |
| | | archiveForm: { doctorName: "" }, |
| | | parentInfo: {}, |
| | | sourcePage: sourcePage || "outpatient", |
| | | status: "active", |
| | | closeStatus: 0, |
| | | // å表页æ°å¢å段 |
| | | idcardno: patient.idcardno || "", |
| | | birthday: patient.birthday || patient.goday || "", |
| | | birthWeight: "", |
| | | gestationalWeek: "", |
| | | diagnosisDate: patient.diagnosisDate || patient.admitdate || "", |
| | | attendingDoctor: patient.drname || "", |
| | | managingDoctor: "", |
| | | registrant: localStorage.getItem("YongHuXM") || "", |
| | | pregnancyStatus: "", |
| | | followupCycles: "", |
| | | highRiskCategory: "", |
| | | highRiskName: "", |
| | | nutritionName: "", |
| | | appointmentStatus: "", |
| | | followupDate: "", |
| | | createTime: now, |
| | | updateTime: now, |
| | | }; |
| | | } |
| | |
| | | æ·»å å»¶ç»æ¤çä»»å¡ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <!-- <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | |
| | | > |
| | | æ£è
建档</el-button |
| | | > |
| | | </el-col> |
| | | </el-col> --> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <!-- 头é¨çå --> |
| | | <div class="personages"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="18"> |
| | | <div class="headportrait"> |
| | | <div class="text-center"> |
| | | <!-- æ£è
ä¿¡æ¯å¤´é¨ --> |
| | | <div class="profile-header"> |
| | | <div class="profile-header__avatar"> |
| | | <img |
| | | v-imgError="require('@/assets/images/shoushuzhudaoyisheng.png')" |
| | | src="" |
| | | /> |
| | | </div> |
| | | <div style="margin-left: 10px">{{ userform.name }}</div> |
| | | <div style="margin-left: 10px" class="text-title"> |
| | | {{ userform.sex == 1 ? "ç·" : "女" }} |
| | | <div class="profile-header__info"> |
| | | <div class="profile-header__name">{{ userform.name }}</div> |
| | | <div class="profile-header__chips"> |
| | | <span class="chip">{{ userform.sex == 1 ? "ç·" : "女" }}</span> |
| | | <span class="chip">{{ userform.age }}å²</span> |
| | | <span class="chip">{{ userform.birthdate }}</span> |
| | | <span class="chip">{{ userform.nation }}</span> |
| | | <span class="chip">{{ userform.birthplace }}</span> |
| | | </div> |
| | | <div style="margin-left: 10px" class="text-title"> |
| | | {{ userform.age }}å² |
| | | </div> |
| | | <div style="margin-left: 10px" class="text-title"> |
| | | {{ userform.birthdate }} |
| | | </div> |
| | | <div style="margin-left: 10px" class="text-title"> |
| | | {{ userform.nation }} |
| | | </div> |
| | | <div style="margin-left: 10px" class="text-title"> |
| | | {{ userform.birthplace }} |
| | | </div> |
| | | </div></el-col |
| | | > |
| | | </el-row> |
| | | </div> |
| | | |
| | | <el-tabs type="border-card" v-model="activeName" @tab-click="handleClick"> |
| | |
| | | |
| | | <!-- å¥åº·æ¡£æ¡æ¨¡å --> |
| | | <div class="information-content" v-if="activeName == 'health'"> |
| | | <div class="top-message"> |
| | | <div class="headlines"> |
| | | <div>åºç¡ä¿¡æ¯</div> |
| | | <el-button type="primary" @click="savefile">ä¿åæ£è
æ¡£æ¡</el-button> |
| | | <div class="section-card"> |
| | | <div class="section-card__header"> |
| | | <span class="section-title">åºç¡ä¿¡æ¯</span> |
| | | <el-button type="primary" size="small" @click="savefile">ä¿åæ£è
æ¡£æ¡</el-button> |
| | | </div> |
| | | <div class="detailed"> |
| | | <div class="section-card__body"> |
| | | <el-form |
| | | ref="userform" |
| | | :model="userform" |
| | | :rules="rules" |
| | | label-width="150px" |
| | | label-width="110px" |
| | | class="profile-form" |
| | | > |
| | | <el-row :gutter="20"> |
| | | <el-row :gutter="24"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ£è
å§å" prop="name"> |
| | | <el-input |
| | | v-model="userform.name" |
| | | placeholder="请è¾å
¥å§å" |
| | | maxlength="30" |
| | | ></el-input> </el-form-item |
| | | ></el-col> |
| | | </el-row> |
| | | <el-row > |
| | | <el-col :span="12" |
| | | ><el-form-item label="èç³»æ¹å¼" prop="telcode"> |
| | | <el-input |
| | | v-model="userform.telcode" |
| | | placeholder="请è¾å
¥èç³»æ¹å¼" |
| | | maxlength="30" |
| | | /> </el-form-item |
| | | ></el-col> |
| | | <el-input v-model="userform.name" placeholder="请è¾å
¥å§å" maxlength="30"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èç³»æ¹å¼" prop="telcode"> |
| | | <el-input v-model="userform.telcode" placeholder="请è¾å
¥èç³»æ¹å¼" maxlength="30"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="亲å±èç³»æ¹å¼" prop="name"> |
| | | <el-input |
| | | v-model="userform.telcodewx" |
| | | placeholder="请è¾å
¥å§å" |
| | | maxlength="30" |
| | | ></el-input> </el-form-item |
| | | ></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-input v-model="userform.telcodewx" placeholder="请è¾å
¥å§å" maxlength="30"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="åºçå°" prop="birthplace"> |
| | | <el-input |
| | | v-model="userform.birthplace" |
| | | placeholder="å½ãçãå°å¸ãåºå¿ãè¡éç详ç»ä¿¡æ¯" |
| | | maxlength="50" |
| | | /> </el-form-item |
| | | ></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="24" |
| | | ><el-form-item label="å±
ä½å°" prop="placeOfResidence"> |
| | | <el-input |
| | | v-model="userform.placeOfResidence" |
| | | placeholder="å½ãçãå°å¸ãåºå¿ãè¡éç详ç»ä¿¡æ¯" |
| | | maxlength="50" |
| | | /> </el-form-item |
| | | ></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-input v-model="userform.birthplace" placeholder="å½ãçãå°å¸ãåºå¿ãè¡éç详ç»ä¿¡æ¯" maxlength="50"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å±
ä½å°" prop="placeOfResidence"> |
| | | <el-input v-model="userform.placeOfResidence" placeholder="å½ãçãå°å¸ãåºå¿ãè¡éç详ç»ä¿¡æ¯" maxlength="50"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="æ ç¾" prop="desc"> |
| | | <div class="xinz-inf"> |
| | |
| | | > |
| | | </el-option> |
| | | </el-select> |
| | | |
| | | <el-button |
| | | v-else |
| | | class="button-new-tag" |
| | |
| | | </el-form> |
| | | </div> |
| | | </div> |
| | | <!-- <div class="top-message"> |
| | | <div class="headline">ç
å²</div> |
| | | <div class="detailed"> |
| | | <el-form :model="form" label-width="100px"> |
| | | <el-row> |
| | | <div class="section-card"> |
| | | <div class="section-card__header"> |
| | | <span class="section-title">ç
å²</span> |
| | | </div> |
| | | <div class="section-card__body"> |
| | | <el-form :model="form" label-width="110px" class="profile-form"> |
| | | <el-row :gutter="24"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="è¿å¾ç¾ç
" prop="name"> |
| | | <el-input |
| | | v-model="form.pastIllnesses" |
| | | placeholder="请è¾å
¥" |
| | | maxlength="30" |
| | | /> |
| | | <el-input v-model="form.pastIllnesses" placeholder="请è¾å
¥" maxlength="30" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="è¯ç©è¿æ" prop="sex"> |
| | | <el-input |
| | | v-model="form.drugAllergy" |
| | | placeholder="请è¾å
¥å
·ä½è¯ç©/æ " |
| | | maxlength="30" |
| | | /> |
| | | <el-input v-model="form.drugAllergy" placeholder="请è¾å
¥å
·ä½è¯ç©/æ " maxlength="30" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="å®¶æç
å²" prop="age"> |
| | | <el-input |
| | | v-model="form.familyHistory" |
| | | placeholder="请è¾å
¥å
·ä½ç¾ç
/æ " |
| | | maxlength="30" |
| | | /> |
| | | <el-input v-model="form.familyHistory" placeholder="请è¾å
¥å
·ä½ç¾ç
/æ " maxlength="30" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="8"> |
| | | <el-form-item label="ææ¯å²" prop="name"> |
| | | <el-input |
| | | v-model="form.surgicalHistory" |
| | | placeholder="请è¾å
¥ææ¯/æ " |
| | | maxlength="30" |
| | | /> |
| | | <el-input v-model="form.surgicalHistory" placeholder="请è¾å
¥ææ¯/æ " maxlength="30" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="çè²å²" prop="age"> |
| | | <el-input |
| | | v-model="form.reproductiveHistory" |
| | | placeholder="请è¾å
¥èæ°/æ " |
| | | maxlength="30" |
| | | /> |
| | | <el-input v-model="form.reproductiveHistory" placeholder="请è¾å
¥èæ°/æ " maxlength="30" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="8"> |
| | | <el-form-item label="å¸çæ
åµ" prop="smoking"> |
| | | <el-radio-group v-model="form.smoking"> |
| | |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="饮飿
åµ" prop="diet"> |
| | | <el-radio-group v-model="form.diet"> |
| | |
| | | <el-radio label="2">æ£å¸¸é¥®é£</el-radio> |
| | | <el-radio label="3">飿¬²ä¸æ¯</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> </el-col |
| | | ><el-col :span="12"> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¿çæ
åµ" prop="psychology"> |
| | | <el-radio-group v-model="form.psychology"> |
| | | <el-radio label="1">å¿æ
ææ¦</el-radio> |
| | |
| | | </el-row> |
| | | </el-form> |
| | | </div> |
| | | </div> --> |
| | | <!-- èç³»çµè¯ --> |
| | | <div class="bottom-message"> |
| | | <div class="headline"> |
| | | 亲å±å·ç ç»´æ¤<span style="margin-right: 60px"> </span> |
| | | <el-button type="primary" @click="addcompiletb">+æ°å¢</el-button> |
| | | </div> |
| | | <div class="Table-screen"> |
| | | <!-- 亲å±å·ç ç»´æ¤ --> |
| | | <div class="section-card"> |
| | | <div class="section-card__header"> |
| | | <span class="section-title">亲å±å·ç ç»´æ¤</span> |
| | | <el-button type="primary" size="small" icon="el-icon-plus" @click="addcompiletb">æ°å¢</el-button> |
| | | </div> |
| | | <div class="section-card__body"> |
| | | <el-table |
| | | :data="tableData" |
| | | style="width: 100%" |
| | | :row-class-name="tableRowClassName" |
| | | stripe |
| | | border |
| | | > |
| | | <el-table-column prop="id" label="åºå·" width="180"> |
| | | </el-table-column> |
| | |
| | | size="small" |
| | | >ç¼è¾</el-button |
| | | > |
| | | |
| | | <el-button @click="deltb(scope.row)" type="danger" size="small" |
| | | >å é¤</el-button |
| | | > |
| | |
| | | <div class="medical-record" v-else-if="activeName == 'medical'"> |
| | | <!-- é¨è¯ --> |
| | | <div v-if="sonactiveName == 'outpatient'"> |
| | | <el-table :data="serviceData" style="width: 100%"> |
| | | <el-table :data="serviceData" style="width: 100%" stripe border> |
| | | <el-table-column |
| | | label="å°±è¯æ¶é´" |
| | | align="center" |
| | |
| | | </div> |
| | | <!-- ä½é¢ --> |
| | | <div v-if="sonactiveName == 'inhospital'"> |
| | | <el-table :data="serviceDatary" style="width: 100%"> |
| | | <el-table :data="serviceDatary" style="width: 100%" stripe border> |
| | | <el-table-column |
| | | label="ä½é¢å·" |
| | | align="center" |
| | |
| | | </div> |
| | | <!-- åºé¢ --> |
| | | <div v-if="sonactiveName == 'checkout'"> |
| | | <el-table :data="serviceDatacy" style="width: 100%"> |
| | | <el-table :data="serviceDatacy" style="width: 100%" stripe border> |
| | | <el-table-column |
| | | label="ä½é¢å·" |
| | | align="center" |
| | |
| | | </div> |
| | | |
| | | <!-- æå¡è®°å½ --> |
| | | <div |
| | | class="medical-recordc" |
| | | style="margin-top: 20px; font-size: 20px !important" |
| | | v-else-if="activeName == 'serve'" |
| | | > |
| | | <div style="margin-bottom: 15px" v-for="item in record"> |
| | | <el-card class="box-card"> |
| | | <div |
| | | style=" |
| | | font-size: 22px; |
| | | padding-left: 5px; |
| | | margin: 15px 0; |
| | | border-left: 4px solid rgb(190, 65, 134); |
| | | " |
| | | > |
| | | <span v-if="item.serviceType == 2">åºé¢é访</span> |
| | | <span v-if="item.serviceType == 1">å¿çµé访</span> |
| | | <span v-if="item.serviceType == 3">å½±åé访</span> |
| | | <span v-if="item.serviceType == 4">宣æå
³æ</span> |
| | | </div> |
| | | <el-divider></el-divider> |
| | | <div style="margin-top: 10px"> |
| | | æå¡åç§°ï¼<span style="color: #2775b6">{{ |
| | | item.templatename |
| | | }}</span> |
| | | </div> |
| | | <div style="margin-top: 10px"> |
| | | å建æ¶é´ï¼<span style="color: #2775b6">{{ item.createTime }}</span> |
| | | </div> |
| | | <div style="margin-top: 10px"> |
| | | 宿æ¶é´ï¼<span style="color: #2775b6">{{ item.finishtime }}</span> |
| | | </div> |
| | | <div style="margin-top: 10px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12" |
| | | >ç§å®¤ï¼ |
| | | <span style="color: #2775b6">{{ item.deptname }}</span></el-col |
| | | > |
| | | <el-col :span="12" |
| | | >ç
åºï¼ |
| | | <span style="color: #2775b6">{{ |
| | | item.leavehospitaldistrictname |
| | | }}</span></el-col |
| | | > |
| | | </el-row> |
| | | </div> |
| | | |
| | | <div |
| | | style=" |
| | | font-size: 20px; |
| | | padding-left: 5px; |
| | | margin: 15px 0; |
| | | border-left: 4px solid rgb(65, 161, 190); |
| | | " |
| | | > |
| | | äººå·¥è®°å½ |
| | | </div> |
| | | <div style="margin-top: 10px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="6" |
| | | >è´è´£äººï¼ |
| | | <span style="color: #2775b6">{{ item.createBy }}</span></el-col |
| | | > |
| | | <el-col :span="6" |
| | | >主治å»çï¼ |
| | | <span style="color: #2775b6">{{ item.drname }}</span></el-col |
| | | > |
| | | <el-col :span="6" |
| | | >责任æ¤å£« |
| | | <span style="color: #2775b6">{{ item.nurseName }}</span></el-col |
| | | > |
| | | </el-row> |
| | | </div> |
| | | <div style="margin-top: 10px"> |
| | | ç»æç¶æï¼ |
| | | <span style="color: #2775b6" v-if="item.excep == 0">æå¡æ£å¸¸</span> |
| | | <span style="color: #b55e54" v-if="item.excep == 1">å¼å¸¸</span> |
| | | </div> |
| | | <!-- <div style="margin-top: 10px"> |
| | | 夿³¨ï¼ |
| | | <span style="color: #2775b6">æé注æé¥®é£å¥åº·</span> |
| | | </div> --> |
| | | </el-card> |
| | | </div> |
| | | </div> |
| | | <ServiceRecords v-else-if="activeName == 'serve'" :patid="id" /> |
| | | <!-- å¥åº·çæµ --> |
| | | <!-- <div class="medical-record" v-show="activeName == 'monitor'"> |
| | | <div v-show="sontwoactiveName == 'blood'" style="display: flex"> |
| | |
| | | Patientclinic, |
| | | } from "@/api/patient/homepage"; |
| | | |
| | | import { getsearchrResults, getTaskservelist } from "@/api/AiCentre/index"; |
| | | import { getsearchrResults } from "@/api/AiCentre/index"; |
| | | import ServiceRecords from "@/views/patient/archives/components/ServiceRecords.vue"; |
| | | import { listPatouthosp } from "@/api/smartor/patouthosp"; |
| | | import { listpatient } from "@/api/patient/record"; |
| | | |
| | | export default { |
| | | name: "Profile", |
| | | components: { userAvatar, userInfo, resetPwd, SFtable }, |
| | | components: { userAvatar, userInfo, resetPwd, SFtable, ServiceRecords }, |
| | | data() { |
| | | return { |
| | | userform: {}, |
| | |
| | | handleClick(tab, event) { |
| | | if (tab.index == "1") { |
| | | this.getList(1); |
| | | } else if (tab.index == "2") { |
| | | this.handleClickfw(); |
| | | } |
| | | }, |
| | | handleClickson(tab, event) { |
| | | console.log(tab, "son"); |
| | | this.getList(tab.index); |
| | | }, |
| | | // æ¥è¯¢æå¡è®°å½ |
| | | handleClickfw() { |
| | | |
| | | getTaskservelist({ |
| | | patid: this.id, |
| | | }).then((res) => { |
| | | if (res.code == 200) { |
| | | this.record = res.rows[0].serviceSubtaskList; |
| | | } |
| | | }); |
| | | }, |
| | | // èç³»æ¹å¼æ°å¢ |
| | | Addanumber() {}, |
| | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .personages { |
| | | height: 88px; |
| | | width: 100%; |
| | | background-color: #5e86f9; |
| | | border-radius: 5px; |
| | | padding: 20px; |
| | | margin-bottom: 10px; |
| | | line-height: 48px; |
| | | font-size: 25px; |
| | | font-weight: 600; |
| | | color: #ffffff; |
| | | .headportrait { |
| | | $primary: #3f6ef0; |
| | | |
| | | // ===== æ£è
ä¿¡æ¯å¤´é¨ ===== |
| | | .profile-header { |
| | | position: relative; |
| | | display: flex; |
| | | .text-center { |
| | | width: 55px; |
| | | height: 55px; |
| | | margin-right: 10px; |
| | | align-items: center; |
| | | padding: 26px 32px; |
| | | margin-bottom: 16px; |
| | | border-radius: 14px; |
| | | overflow: hidden; |
| | | color: #fff; |
| | | background: linear-gradient(120deg, #3f6ef0 0%, #5b8cff 55%, #78a9ff 100%); |
| | | box-shadow: 0 8px 24px rgba(63, 110, 240, 0.26); |
| | | |
| | | &::before { |
| | | content: ""; |
| | | position: absolute; |
| | | right: -70px; |
| | | top: -90px; |
| | | width: 280px; |
| | | height: 280px; |
| | | border-radius: 50%; |
| | | background: rgba(255, 255, 255, 0.09); |
| | | } |
| | | &::after { |
| | | content: ""; |
| | | position: absolute; |
| | | right: 90px; |
| | | bottom: -130px; |
| | | width: 230px; |
| | | height: 230px; |
| | | border-radius: 50%; |
| | | background: rgba(255, 255, 255, 0.06); |
| | | } |
| | | |
| | | &__avatar { |
| | | position: relative; |
| | | z-index: 1; |
| | | width: 76px; |
| | | height: 76px; |
| | | flex-shrink: 0; |
| | | border-radius: 50%; |
| | | padding: 3px; |
| | | background: rgba(255, 255, 255, 0.4); |
| | | box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18); |
| | | |
| | | img { |
| | | width: 100%; |
| | | height: 100%; |
| | | border-radius: 50%; |
| | | object-fit: cover; |
| | | background: #eef2fb; |
| | | } |
| | | } |
| | | .text-title { |
| | | font-size: 20px; |
| | | |
| | | &__info { |
| | | position: relative; |
| | | z-index: 1; |
| | | margin-left: 22px; |
| | | min-width: 0; |
| | | } |
| | | |
| | | &__name { |
| | | font-size: 24px; |
| | | font-weight: 700; |
| | | letter-spacing: 1px; |
| | | line-height: 1.3; |
| | | } |
| | | |
| | | &__chips { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 10px; |
| | | margin-top: 12px; |
| | | |
| | | .chip { |
| | | padding: 4px 14px; |
| | | font-size: 13px; |
| | | font-weight: 500; |
| | | color: #ecfcfc; |
| | | border-radius: 999px; |
| | | background: rgba(255, 255, 255, 0.2); |
| | | border: 1px solid rgba(255, 255, 255, 0.3); |
| | | color: #f5f8ff; |
| | | line-height: 1.5; |
| | | } |
| | | } |
| | | } |
| | | .xinz-inf { |
| | | font-size: 18px; |
| | | // white-space: nowrap; |
| | | |
| | | // ===== Tabs ===== |
| | | ::v-deep .el-tabs--border-card { |
| | | border: none; |
| | | border-radius: 12px; |
| | | box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | |
| | | line-height: 48px; |
| | | > .el-tabs__header { |
| | | margin: 0; |
| | | background: #fff; |
| | | border-bottom: 1px solid #eef0f4; |
| | | |
| | | .el-tag + .el-tag { |
| | | margin-left: 10px; |
| | | .el-tabs__nav { |
| | | border: none; |
| | | |
| | | .el-tabs__item { |
| | | height: 54px; |
| | | line-height: 54px; |
| | | font-size: 15px; |
| | | color: #606266; |
| | | border: none !important; |
| | | |
| | | .mulsz { |
| | | font-size: 15px; |
| | | } |
| | | |
| | | &.is-active { |
| | | color: $primary; |
| | | font-weight: 600; |
| | | background: #f3f7ff; |
| | | box-shadow: inset 0 -3px 0 $primary; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | > .el-tabs__content { |
| | | padding: 0; |
| | | } |
| | | } |
| | | |
| | | // ===== å¥åº·æ¡£æ¡å¡ç ===== |
| | | .information-content { |
| | | margin-top: 16px; |
| | | } |
| | | |
| | | .section-card { |
| | | margin-bottom: 16px; |
| | | background: #fff; |
| | | border-radius: 12px; |
| | | box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); |
| | | overflow: hidden; |
| | | |
| | | &__header { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding: 16px 24px; |
| | | border-bottom: 1px solid #f0f2f5; |
| | | |
| | | .section-title { |
| | | position: relative; |
| | | padding-left: 12px; |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | |
| | | &::before { |
| | | content: ""; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 50%; |
| | | transform: translateY(-50%); |
| | | width: 4px; |
| | | height: 16px; |
| | | border-radius: 2px; |
| | | background: $primary; |
| | | } |
| | | } |
| | | } |
| | | |
| | | &__body { |
| | | padding: 20px 24px 4px; |
| | | } |
| | | } |
| | | |
| | | // 表å |
| | | .profile-form { |
| | | .el-form-item { |
| | | margin-bottom: 18px; |
| | | } |
| | | |
| | | ::v-deep .el-form-item__label { |
| | | color: #606266; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | ::v-deep .el-input__inner { |
| | | border-radius: 6px; |
| | | } |
| | | } |
| | | |
| | | // æ ç¾ |
| | | .xinz-inf { |
| | | line-height: 40px; |
| | | |
| | | .el-tag { |
| | | margin-bottom: 6px; |
| | | border-radius: 4px; |
| | | |
| | | & + .el-tag { |
| | | margin-left: 8px; |
| | | } |
| | | } |
| | | |
| | | .button-new-tag { |
| | | margin-left: 10px; |
| | | margin-left: 8px; |
| | | height: 32px; |
| | | line-height: 30px; |
| | | padding-top: 0; |
| | | padding-bottom: 0; |
| | | } |
| | | |
| | | .input-new-tag { |
| | | width: 90px; |
| | | margin-left: 10px; |
| | | margin-left: 8px; |
| | | vertical-align: bottom; |
| | | } |
| | | } |
| | | .el-tabs--border-card { |
| | | // font-size: 25px; |
| | | .mulsz { |
| | | font-size: 25px; |
| | | margin-top: 20px; |
| | | |
| | | // ===== å»çæ¡£æ¡è¡¨æ ¼ ===== |
| | | .medical-record { |
| | | margin-top: 16px; |
| | | padding: 24px; |
| | | background: #fff; |
| | | border-radius: 12px; |
| | | box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); |
| | | |
| | | ::v-deep .el-table { |
| | | th.el-table__cell { |
| | | background: #f5f7fb; |
| | | color: #303133; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .el-table__row td { |
| | | padding: 10px 0; |
| | | } |
| | | .information-content { |
| | | margin-top: 20px; |
| | | background: #ffffff; |
| | | border: 1px solid #dcdfe6; |
| | | -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), |
| | | 0 0 6px 0 rgba(0, 0, 0, 0.04); |
| | | .top-message { |
| | | margin-top: 25px; |
| | | margin-left: 100px; |
| | | .detailed { |
| | | width: 88%; |
| | | border-radius: 8px; |
| | | padding: 30px; |
| | | margin-bottom: 30px; |
| | | background-color: #ddf0f8; |
| | | .bg-purple { |
| | | margin-bottom: 20px; |
| | | |
| | | .el-table__row--striped td { |
| | | background: #fafbfd; |
| | | } |
| | | .spanvalue { |
| | | display: inline-block; |
| | | min-width: 200px; |
| | | border-bottom: 1px solid rgb(172, 172, 172); |
| | | |
| | | .el-table__row:hover > td { |
| | | background: #f3f7ff !important; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .headline { |
| | | font-size: 25px; |
| | | padding-left: 5px; |
| | | margin-bottom: 10px; |
| | | border-left: 8px solid rgb(65, 161, 190); |
| | | // å¡çå
è¡¨æ ¼ï¼äº²å±å·ç ï¼ |
| | | .section-card__body { |
| | | ::v-deep .el-table { |
| | | th.el-table__cell { |
| | | background: #f5f7fb; |
| | | color: #303133; |
| | | font-weight: 600; |
| | | } |
| | | .headlines { |
| | | font-size: 25px; |
| | | } |
| | | } |
| | | |
| | | // ===== æå¡è®°å½ ===== |
| | | .service-record { |
| | | margin-top: 16px; |
| | | |
| | | .service-item { |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .service-card { |
| | | border-radius: 12px; |
| | | box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); |
| | | |
| | | ::v-deep .el-card__body { |
| | | padding: 20px 24px; |
| | | } |
| | | } |
| | | |
| | | .service-card__header { |
| | | display: flex; |
| | | width: 88%; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding-left: 5px; |
| | | margin-bottom: 10px; |
| | | border-left: 8px solid rgb(65, 161, 190); |
| | | padding-bottom: 14px; |
| | | border-bottom: 1px dashed #eef0f4; |
| | | } |
| | | .bottom-message { |
| | | margin-bottom: 25px; |
| | | margin-left: 100px; |
| | | .Table-screen { |
| | | width: 88%; |
| | | padding: 30px; |
| | | margin-bottom: 30px; |
| | | border-radius: 8px; |
| | | background-color: #ddf0f8; |
| | | font-size: 20px !important; |
| | | |
| | | .service-card__title { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 12px; |
| | | } |
| | | |
| | | .service-badge { |
| | | display: inline-block; |
| | | padding: 4px 12px; |
| | | font-size: 13px; |
| | | font-weight: 600; |
| | | color: $primary; |
| | | background: #eef4ff; |
| | | border-radius: 6px; |
| | | } |
| | | |
| | | .service-name { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | |
| | | .service-status { |
| | | padding: 4px 12px; |
| | | font-size: 13px; |
| | | border-radius: 999px; |
| | | |
| | | &.is-ok { |
| | | color: #12a182; |
| | | background: #e8f7f1; |
| | | } |
| | | |
| | | &.is-bad { |
| | | color: #e0564c; |
| | | background: #fdeeee; |
| | | } |
| | | } |
| | | |
| | | .service-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(4, 1fr); |
| | | gap: 18px 24px; |
| | | padding-top: 16px; |
| | | } |
| | | |
| | | .service-cell { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 4px; |
| | | |
| | | .s-label { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | } |
| | | |
| | | .s-value { |
| | | font-size: 14px; |
| | | color: #303133; |
| | | } |
| | | } |
| | | } |
| | | .medical-record { |
| | | margin-top: 20px; |
| | | margin: 20px; |
| | | padding: 30px; |
| | | background: #ffffff; |
| | | border: 1px solid #dcdfe6; |
| | | -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), |
| | | 0 0 6px 0 rgba(0, 0, 0, 0.04); |
| | | } |
| | | .sontwoactiveName { |
| | | margin: 0 auto; |
| | | } |
| | | |
| | | // é»è®¤èç³»æ¹å¼é«äº®è¡ |
| | | ::v-deep.el-table .warning-row { |
| | | background: oldlace; |
| | | background: #fff7e6; |
| | | } |
| | | </style> |
| | |
| | | icon="el-icon-plus" |
| | | size="medium" |
| | | @click="handleAdd" |
| | | |
| | | >æ°å¢</el-button |
| | | > |
| | | </el-col> |
| | |
| | | size="medium" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | |
| | | >å é¤</el-button |
| | | > |
| | | </el-col> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | |
| | | <!-- <el-table-column |
| | | label="æ£å¸¸å¼èå´" |
| | | align="center" |
| | |
| | | size="medium" |
| | | type="text" |
| | | @click="illnessUpdate(scope.row)" |
| | | |
| | | ><span class="button-textxg" |
| | | ><i class="el-icon-date"></i>详æ
</span |
| | | ></el-button |
| | |
| | | size="medium" |
| | | type="text" |
| | | @click="handleUpdate(scope.row)" |
| | | |
| | | ><span class="button-textxg" |
| | | ><i class="el-icon-edit"></i>ä¿®æ¹</span |
| | | ></el-button |
| | |
| | | size="medium" |
| | | type="text" |
| | | @click="handleDelete(scope.row)" |
| | | |
| | | ><span class="button-textsc" |
| | | ><i class="el-icon-delete"></i>å é¤</span |
| | | ></el-button |
| | |
| | | <el-input |
| | | v-model="indexform.targetname" |
| | | placeholder="请è¾å
¥ææ åç§°" |
| | | maxlength="40" |
| | | maxlength="100" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ææ åç±»" prop="assortid"> |
| | | <el-select |
| | | style="width: 300px;" |
| | | style="width: 300px" |
| | | v-model="indexform.assortid" |
| | | size="medium" |
| | | filterable |
| | |
| | | </el-option-group> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | </el-col> |
| | | </el-row> |
| | | <el-row v-if="!measurement"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="ææ æè¿°" prop="targetdesc"> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="2" |
| | | v-model="indexform.targetdesc" |
| | | placeholder="请è¾å
¥ææ æè¿°" |
| | | id="targetdesc" |
| | | @focus="currentInputId = 'targetdesc'" |
| | | maxlength="40" |
| | | maxlength="400" |
| | | /> |
| | | </el-form-item> </el-col |
| | | ></el-row> |
| | |
| | | { value: careData.inProgress, name: "æ¤çè¿è¡ä¸" }, |
| | | { value: careData.notStarted, name: "æ¤çæªå¼å§" }, |
| | | ]; |
| | | } else if (this.activeTab === "combined") { |
| | | legendData = ["å¾
é访", "é访æå", "é访失败"]; |
| | | const followUpData = { |
| | | pending: 0, |
| | | success: 0, |
| | | fail: 0, |
| | | }; |
| | | |
| | | this.data.forEach((item) => { |
| | | followUpData.pending += |
| | | (item.pendingFollowUp || 0) + (item.pendingFollowUpAgain || 0); |
| | | followUpData.success += |
| | | (item.followUpSuccess || 0) + (item.followUpSuccessAgain || 0); |
| | | followUpData.fail += |
| | | (item.followUpFail || 0) + (item.followUpFailAgain || 0); |
| | | }); |
| | | |
| | | seriesData = [ |
| | | { value: followUpData.pending, name: "å¾
é访" }, |
| | | { value: followUpData.success, name: "é访æå" }, |
| | | { value: followUpData.fail, name: "é访失败" }, |
| | | ]; |
| | | } |
| | | |
| | | return { legendData, seriesData }; |
| | |
| | | }, |
| | | }, |
| | | ]; |
| | | } else if (this.activeTab === "combined") { |
| | | title = "综åé访"; |
| | | yAxisName1 = "人次"; |
| | | legendData = ["åºé¢äººæ¬¡", "馿¬¡å®æ", "忬¡å®æ", "é访ç(%)", "æ¨éç(%)"]; |
| | | colors = ["#5470C6", "#91CC75", "#FAC858", "#EE6666", "#9A60B4"]; |
| | | |
| | | const dischargeData = this.data.map((item) => item.dischargeCount || 0); |
| | | const firstSuccessData = this.data.map( |
| | | (item) => item.followUpSuccess || 0 |
| | | ); |
| | | const againSuccessData = this.data.map( |
| | | (item) => item.followUpSuccessAgain || 0 |
| | | ); |
| | | const followUpRateData = this.data.map((item) => { |
| | | const success = Number(item.followUpSuccess) || 0; |
| | | const nonFollowUp = Number(item.nonFollowUp) || 0; |
| | | const followUpNeeded = Number(item.followUpNeeded) || 0; |
| | | const denominator = followUpNeeded + nonFollowUp; |
| | | return denominator > 0 |
| | | ? Number((((success + nonFollowUp) / denominator) * 100).toFixed(2)) |
| | | : 0; |
| | | }); |
| | | const pushRateData = this.data.map((item) => { |
| | | const successAgain = Number(item.followUpSuccessAgain) || 0; |
| | | const nonFollowUp = Number(item.nonFollowUp) || 0; |
| | | const followUpNeeded = Number(item.followUpNeeded) || 0; |
| | | const denominator = followUpNeeded + nonFollowUp; |
| | | return denominator > 0 |
| | | ? Number(((successAgain / denominator) * 100).toFixed(2)) |
| | | : 0; |
| | | }); |
| | | |
| | | series = [ |
| | | { |
| | | name: "åºé¢äººæ¬¡", |
| | | type: "bar", |
| | | barWidth: "25%", |
| | | data: dischargeData, |
| | | itemStyle: { borderRadius: [4, 4, 0, 0] }, |
| | | }, |
| | | { |
| | | name: "馿¬¡å®æ", |
| | | type: "bar", |
| | | barWidth: "25%", |
| | | data: firstSuccessData, |
| | | itemStyle: { borderRadius: [4, 4, 0, 0] }, |
| | | }, |
| | | { |
| | | name: "忬¡å®æ", |
| | | type: "bar", |
| | | barWidth: "25%", |
| | | data: againSuccessData, |
| | | itemStyle: { borderRadius: [4, 4, 0, 0] }, |
| | | }, |
| | | { |
| | | name: "é访ç(%)", |
| | | type: "line", |
| | | yAxisIndex: 1, |
| | | data: followUpRateData, |
| | | symbolSize: 8, |
| | | lineStyle: { width: 3 }, |
| | | }, |
| | | { |
| | | name: "æ¨éç(%)", |
| | | type: "line", |
| | | yAxisIndex: 1, |
| | | data: pushRateData, |
| | | symbolSize: 8, |
| | | lineStyle: { width: 3, type: "dotted" }, |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | return { |
| | |
| | | }, |
| | | |
| | | // ===================== å¯¼åº ===================== |
| | | getServiceTypeLabel() { |
| | | const val = this.queryParams.serviceType; |
| | | if (val == null) return ""; |
| | | const values = Array.isArray(val) ? val : [val]; |
| | | const list = |
| | | this.options && this.options.length ? this.options : this.tasktypes; |
| | | const labels = values |
| | | .map((v) => (list.find((o) => o.value === v) || {}).label) |
| | | .filter(Boolean); |
| | | return labels.join("/"); |
| | | }, |
| | | |
| | | async exportTable() { |
| | | try { |
| | | let dateRangeString = ""; |
| | |
| | | dateRangeString = isLishuiHospital ? `${now.getFullYear()}å¹´${now.getMonth() + 1}æ` : `${now.getMonth() + 1}æ`; |
| | | } |
| | | |
| | | const excelName = `综åé访ç»è®¡è¡¨_${dateRangeString}.xlsx`; |
| | | const serviceTypeLabel = this.getServiceTypeLabel(); |
| | | const serviceTypeSuffix = serviceTypeLabel ? `_${serviceTypeLabel}` : ""; |
| | | const excelName = `综åé访ç»è®¡è¡¨${serviceTypeSuffix}_${dateRangeString}.xlsx`; |
| | | if (!this.tableData || this.tableData.length === 0) { |
| | | this.$message.warning("ææ æ°æ®å¯å¯¼åº"); |
| | | return false; |
| | |
| | | |
| | | const workbook = new ExcelJS.Workbook(); |
| | | const worksheet = workbook.addWorksheet("综åç»è®¡"); |
| | | this.buildExportSheet(worksheet, dateRangeString); |
| | | this.buildExportSheet(worksheet, dateRangeString, serviceTypeSuffix); |
| | | const buffer = await workbook.xlsx.writeBuffer(); |
| | | const blob = new Blob([buffer], { |
| | | type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", |
| | |
| | | } |
| | | }, |
| | | |
| | | buildExportSheet(worksheet, dateRangeString) { |
| | | buildExportSheet(worksheet, dateRangeString, serviceTypeSuffix = "") { |
| | | // å®ä¹æ ·å¼ |
| | | const titleStyle = { |
| | | font: { name: "微软é
é»", size: 16, bold: true }, |
| | |
| | | |
| | | // æ é¢è¡ |
| | | worksheet.mergeCells(1, 1, 1, 20); |
| | | worksheet.getCell(1, 1).value = `综åé访ç»è®¡è¡¨_${dateRangeString}`; |
| | | worksheet.getCell(1, 1).value = `综åé访ç»è®¡è¡¨${serviceTypeSuffix}_${dateRangeString}`; |
| | | worksheet.getCell(1, 1).style = titleStyle; |
| | | worksheet.getRow(1).height = 35; |
| | | |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | v-if="isTargetHospital" |
| | | label="人工" |
| | | align="center" |
| | | > |
| | | <el-table-column |
| | | label="åé宿" |
| | | align="center" |
| | | key="manualSuccess" |
| | | prop="manualSuccess" |
| | | :render-header="Tooltipfswc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'manualSuccessInfo', |
| | | 'åéå®æäººå·¥é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ scope.row.manualSuccess }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æç»å®æ" |
| | | align="center" |
| | | key="manualAgainSuccess" |
| | | prop="manualAgainSuccess" |
| | | :render-header="Tooltipzzwc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'manualAgainSuccessInfo', |
| | | 'æç»å®æäººå·¥é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ |
| | | scope.row.manualAgainSuccess |
| | | }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | <el-table-column |
| | | v-if="isTargetHospital" |
| | | label="è¯é³" |
| | | align="center" |
| | | > |
| | | <el-table-column |
| | | label="åé宿" |
| | | align="center" |
| | | key="voiceSuccess" |
| | | prop="voiceSuccess" |
| | | :render-header="Tooltipfswc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'voiceSuccessInfo', |
| | | 'åé宿è¯é³é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ scope.row.voiceSuccess }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æç»å®æ" |
| | | align="center" |
| | | key="voiceAgainSuccess" |
| | | prop="voiceAgainSuccess" |
| | | :render-header="Tooltipzzwc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'voiceAgainSuccessInfo', |
| | | 'æç»å®æè¯é³é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ |
| | | scope.row.voiceAgainSuccess |
| | | }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | <el-table-column |
| | | v-if="isTargetHospital" |
| | | label="çä¿¡" |
| | | align="center" |
| | | > |
| | | <el-table-column |
| | | label="åé宿" |
| | | align="center" |
| | | key="smsSuccess" |
| | | prop="smsSuccess" |
| | | :render-header="Tooltipfswc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'smsSuccessInfo', |
| | | 'åé宿çä¿¡é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ scope.row.smsSuccess }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æç»å®æ" |
| | | align="center" |
| | | key="smsAgainSuccess" |
| | | prop="smsAgainSuccess" |
| | | :render-header="Tooltipzzwc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'smsAgainSuccessInfo', |
| | | 'æç»å®æçä¿¡é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ |
| | | scope.row.smsAgainSuccess |
| | | }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | <el-table-column |
| | | v-if="isTargetHospital" |
| | | label="微信" |
| | | align="center" |
| | | > |
| | | <el-table-column |
| | | label="åé宿" |
| | | align="center" |
| | | key="weChatSuccess" |
| | | prop="weChatSuccess" |
| | | :render-header="Tooltipfswc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'wechatSuccessInfo', |
| | | 'åéå®æå¾®ä¿¡é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ scope.row.weChatSuccess }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æç»å®æ" |
| | | align="center" |
| | | key="weChatAgainSuccess" |
| | | prop="weChatAgainSuccess" |
| | | :render-header="Tooltipzzwc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'wechatAgainSuccessInfo', |
| | | 'æç»å®æå¾®ä¿¡é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ |
| | | scope.row.weChatAgainSuccess |
| | | }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | <el-table-column |
| | | v-if="!isTargetHospital" |
| | | label="人工" |
| | | align="center" |
| | | key="manual" |
| | |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="è¯é³" align="center" key="voice" prop="voice"> |
| | | <el-table-column |
| | | v-if="!isTargetHospital" |
| | | label="è¯é³" |
| | | align="center" |
| | | key="voice" |
| | | prop="voice" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="çä¿¡" align="center" key="sms" prop="sms"> |
| | | <el-table-column |
| | | v-if="!isTargetHospital" |
| | | label="çä¿¡" |
| | | align="center" |
| | | key="sms" |
| | | prop="sms" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | v-if="!isTargetHospital" |
| | | label="微信" |
| | | align="center" |
| | | key="weChat" |
| | |
| | | patientqueryParams: { pn: 1, ps: 10 }, |
| | | tasktypes: store.getters.tasktypes, |
| | | }; |
| | | }, |
| | | computed: { |
| | | isTargetHospital() { |
| | | return ( |
| | | this.orgname == "第ä¸äººæ°å»é¢æ¹æ»¨é¢åº" || |
| | | this.orgname == "第ä¸äººæ°å»é¢å´å±±é¢åº" |
| | | ); |
| | | }, |
| | | }, |
| | | methods: { |
| | | loadData() { |
| | |
| | | [h("span", column.label)] |
| | | ); |
| | | }, |
| | | Tooltipfswc(h, { column }) { |
| | | return h( |
| | | "el-tooltip", |
| | | { |
| | | props: { |
| | | content: "馿¬¡å鿣è
å³å¡«æ¥æåçæ°é", |
| | | placement: "top", |
| | | effect: "dark", |
| | | }, |
| | | }, |
| | | [h("span", column.label)] |
| | | ); |
| | | }, |
| | | Tooltipzzwc(h, { column }) { |
| | | return h( |
| | | "el-tooltip", |
| | | { |
| | | props: { |
| | | content: "馿¬¡æªå®æäºæ¬¡æä¸æ¬¡è¡¥å¿æ¨éæ¬æ¹å¼çå®ææ¬¡æ°", |
| | | placement: "top", |
| | | effect: "dark", |
| | | }, |
| | | }, |
| | | [h("span", column.label)] |
| | | ); |
| | | }, |
| | | getInnerSummaries(param) { |
| | | const { columns, data } = param; |
| | | const sums = []; |
| | |
| | | } |
| | | } |
| | | |
| | | // æ ¹æ® serviceType çæé访类ååç§° |
| | | // æ ¹æ® serviceType çæé访类ååç§°ï¼å
¼å®¹åé/å¤éï¼ |
| | | const serviceTypes = Array.isArray(this.queryParams.serviceType) |
| | | ? this.queryParams.serviceType |
| | | : this.queryParams.serviceType |
| | | ? [this.queryParams.serviceType] |
| | | : []; |
| | | |
| | | let serviceTypeName = "馿¬¡åºé¢é访"; // æä»¶å使ç¨çåç§° |
| | | let sheetTypeName = "馿¬¡é访"; // å·¥ä½è¡¨ä½¿ç¨çåç§°ï¼ç®åçï¼ |
| | | |
| | | if ( |
| | | this.queryParams.serviceType && |
| | | Array.isArray(this.queryParams.serviceType) && |
| | | this.queryParams.serviceType.length > 0 |
| | | ) { |
| | | if (serviceTypes.length > 0) { |
| | | // ä½¿ç¨ props ä¸ç optionsï¼å³ tasktypesï¼ |
| | | if (this.options && Array.isArray(this.options)) { |
| | | const matchedTypes = this.options.filter((task) => |
| | | this.queryParams.serviceType.includes(task.value) |
| | | serviceTypes.includes(task.value) |
| | | ); |
| | | console.log(matchedTypes, "matchedTypes"); |
| | | |
| | |
| | | serviceTypeName = `馿¬¡${typeNames.join("/")}`; |
| | | // å·¥ä½è¡¨åç®åï¼å第ä¸ä¸ª+âçâï¼ |
| | | sheetTypeName = `馿¬¡${typeNames[0]}ç`; |
| | | } else if (this.queryParams.serviceType.length > 0) { |
| | | } else { |
| | | // æ å¹é
æ¶ä½¿ç¨åå§å¼ |
| | | const typeStr = this.queryParams.serviceType.join("/"); |
| | | const typeStr = serviceTypes.join("/"); |
| | | serviceTypeName = `馿¬¡${typeStr}`; |
| | | sheetTypeName = "馿¬¡é访"; |
| | | } |
| | | } else if (this.queryParams.serviceType.length > 0) { |
| | | const typeStr = this.queryParams.serviceType.join("/"); |
| | | } else { |
| | | const typeStr = serviceTypes.join("/"); |
| | | serviceTypeName = `馿¬¡${typeStr}`; |
| | | sheetTypeName = "馿¬¡é访"; |
| | | } |
| | |
| | | console.log(1); |
| | | |
| | | this.patientqueryParams.serviceTypes = queryParams.serviceType |
| | | ? Array.isArray(queryParams.serviceType) |
| | | ? queryParams.serviceType.join(",") |
| | | : String(queryParams.serviceType) |
| | | : null; |
| | | |
| | | return selectTimelyRate(this.patientqueryParams); |
| | |
| | | :render-header="Tooltipsfl" |
| | | /> |
| | | <el-table-column |
| | | v-if="isTargetHospital" |
| | | label="人工" |
| | | align="center" |
| | | > |
| | | <el-table-column |
| | | label="åé宿" |
| | | align="center" |
| | | key="manualSuccess" |
| | | prop="manualSuccess" |
| | | :render-header="Tooltipfswc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'manualSuccessInfo', |
| | | 'åéå®æäººå·¥é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ scope.row.manualSuccess }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æç»å®æ" |
| | | align="center" |
| | | key="manualAgainSuccess" |
| | | prop="manualAgainSuccess" |
| | | :render-header="Tooltipzzwc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'manualAgainSuccessInfo', |
| | | 'æç»å®æäººå·¥é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ |
| | | scope.row.manualAgainSuccess |
| | | }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | <el-table-column |
| | | v-if="isTargetHospital" |
| | | label="è¯é³" |
| | | align="center" |
| | | > |
| | | <el-table-column |
| | | label="åé宿" |
| | | align="center" |
| | | key="voiceSuccess" |
| | | prop="voiceSuccess" |
| | | :render-header="Tooltipfswc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'voiceSuccessInfo', |
| | | 'åé宿è¯é³é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ scope.row.voiceSuccess }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æç»å®æ" |
| | | align="center" |
| | | key="voiceAgainSuccess" |
| | | prop="voiceAgainSuccess" |
| | | :render-header="Tooltipzzwc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'voiceAgainSuccessInfo', |
| | | 'æç»å®æè¯é³é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ |
| | | scope.row.voiceAgainSuccess |
| | | }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | <el-table-column |
| | | v-if="isTargetHospital" |
| | | label="çä¿¡" |
| | | align="center" |
| | | > |
| | | <el-table-column |
| | | label="åé宿" |
| | | align="center" |
| | | key="smsSuccess" |
| | | prop="smsSuccess" |
| | | :render-header="Tooltipfswc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'smsSuccessInfo', |
| | | 'åé宿çä¿¡é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ scope.row.smsSuccess }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æç»å®æ" |
| | | align="center" |
| | | key="smsAgainSuccess" |
| | | prop="smsAgainSuccess" |
| | | :render-header="Tooltipzzwc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'smsAgainSuccessInfo', |
| | | 'æç»å®æçä¿¡é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ |
| | | scope.row.smsAgainSuccess |
| | | }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | <el-table-column |
| | | v-if="isTargetHospital" |
| | | label="微信" |
| | | align="center" |
| | | > |
| | | <el-table-column |
| | | label="åé宿" |
| | | align="center" |
| | | key="weChatSuccess" |
| | | prop="weChatSuccess" |
| | | :render-header="Tooltipfswc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'wechatSuccessInfo', |
| | | 'åéå®æå¾®ä¿¡é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ scope.row.weChatSuccess }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æç»å®æ" |
| | | align="center" |
| | | key="weChatAgainSuccess" |
| | | prop="weChatAgainSuccess" |
| | | :render-header="Tooltipzzwc" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click=" |
| | | handleViewDetails( |
| | | scope.row, |
| | | 'wechatAgainSuccessInfo', |
| | | 'æç»å®æå¾®ä¿¡é访å表' |
| | | ) |
| | | " |
| | | > |
| | | <span class="button-zx">{{ |
| | | scope.row.weChatAgainSuccess |
| | | }}</span> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | <el-table-column |
| | | v-if="!isTargetHospital" |
| | | label="人工" |
| | | align="center" |
| | | key="manualAgain" |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | v-if="!isTargetHospital" |
| | | label="è¯é³" |
| | | align="center" |
| | | key="voiceAgain" |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | v-if="!isTargetHospital" |
| | | label="çä¿¡" |
| | | align="center" |
| | | key="smsAgain" |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | v-if="!isTargetHospital" |
| | | label="微信" |
| | | align="center" |
| | | key="weChatAgain" |
| | |
| | | tasktypes: store.getters.tasktypes, |
| | | }; |
| | | }, |
| | | computed: { |
| | | isTargetHospital() { |
| | | return ( |
| | | this.orgname == "第ä¸äººæ°å»é¢æ¹æ»¨é¢åº" || |
| | | this.orgname == "第ä¸äººæ°å»é¢å´å±±é¢åº" |
| | | ); |
| | | }, |
| | | }, |
| | | methods: { |
| | | loadData() { |
| | | this.loading = true; |
| | |
| | | { |
| | | props: { |
| | | content: "(é访æå+馿¬¡é访失败)/馿¬¡åºé访", |
| | | placement: "top", |
| | | effect: "dark", |
| | | }, |
| | | }, |
| | | [h("span", column.label)] |
| | | ); |
| | | }, |
| | | Tooltipfswc(h, { column }) { |
| | | return h( |
| | | "el-tooltip", |
| | | { |
| | | props: { |
| | | content: "馿¬¡å鿣è
å³å¡«æ¥æåçæ°é", |
| | | placement: "top", |
| | | effect: "dark", |
| | | }, |
| | | }, |
| | | [h("span", column.label)] |
| | | ); |
| | | }, |
| | | Tooltipzzwc(h, { column }) { |
| | | return h( |
| | | "el-tooltip", |
| | | { |
| | | props: { |
| | | content: "馿¬¡æªå®æäºæ¬¡æä¸æ¬¡è¡¥å¿æ¨éæ¬æ¹å¼çå®ææ¬¡æ°", |
| | | placement: "top", |
| | | effect: "dark", |
| | | }, |
| | |
| | | } |
| | | } |
| | | |
| | | // æ ¹æ® serviceType çæé访类ååç§° |
| | | // æ ¹æ® serviceType çæé访类ååç§°ï¼å
¼å®¹åé/å¤éï¼ |
| | | const serviceTypes = Array.isArray(this.queryParams.serviceType) |
| | | ? this.queryParams.serviceType |
| | | : this.queryParams.serviceType |
| | | ? [this.queryParams.serviceType] |
| | | : []; |
| | | |
| | | let serviceTypeName = "åºé¢é访"; // æä»¶å使ç¨çåç§° |
| | | let sheetTypeName = "忬¡é访"; // å·¥ä½è¡¨ä½¿ç¨çåç§°ï¼ç®åçï¼ |
| | | console.log(this.queryParams.serviceType); |
| | | |
| | | if ( |
| | | this.queryParams.serviceType && |
| | | Array.isArray(this.queryParams.serviceType) && |
| | | this.queryParams.serviceType.length > 0 |
| | | ) { |
| | | if (serviceTypes.length > 0) { |
| | | if (this.tasktypes && Array.isArray(this.tasktypes)) { |
| | | // è¿æ»¤åºå¹é
çé访类å |
| | | const matchedTypes = this.tasktypes.filter((task) => |
| | | this.queryParams.serviceType.includes(task.value) |
| | | serviceTypes.includes(task.value) |
| | | ); |
| | | |
| | | if (matchedTypes.length === 1) { |
| | |
| | | serviceTypeName = typeNames.join("/"); |
| | | |
| | | // å·¥ä½è¡¨åï¼ä½¿ç¨ç¬¬ä¸ä¸ªç±»åæç®ååç§° |
| | | if (matchedTypes.length <= 2) { |
| | | // å¦æåªæ2个类åï¼é½æ¾ç¤º |
| | | sheetTypeName = `${typeNames[0]}ç`; |
| | | } else { |
| | | // 妿è¶
è¿2个类åï¼åªæ¾ç¤ºç¬¬ä¸ä¸ª |
| | | sheetTypeName = `${typeNames[0]}ç`; |
| | | } |
| | | } else if (this.queryParams.serviceType.length > 0) { |
| | | // å¦ææ²¡æå¹é
çï¼ä½¿ç¨åå§å¼ |
| | | const typeStr = this.queryParams.serviceType.join("/"); |
| | | const typeStr = serviceTypes.join("/"); |
| | | serviceTypeName = typeStr; |
| | | sheetTypeName = "忬¡é访"; |
| | | } |
| | | } else if (this.queryParams.serviceType.length > 0) { |
| | | } else { |
| | | // å¦ææ²¡æ tasktypesï¼ä½¿ç¨åå§å¼ |
| | | const typeStr = this.queryParams.serviceType.join("/"); |
| | | const typeStr = serviceTypes.join("/"); |
| | | serviceTypeName = typeStr; |
| | | sheetTypeName = "忬¡é访"; |
| | | } |
| | |
| | | |
| | | <el-form-item label="æå¡ç±»å" prop="userName"> |
| | | <el-select |
| | | v-model="queryParams.serviceType" |
| | | multiple |
| | | v-model="serviceTypeSingle" |
| | | placeholder="è¯·éæ©" |
| | | > |
| | | <el-option |
| | |
| | | }, |
| | | }; |
| | | }, |
| | | computed: { |
| | | // æå¡ç±»ååéï¼UI ç»å®åå¼ï¼å
é¨ä»ä»¥æ°ç»å½¢å¼ä¼ ç»å端 |
| | | serviceTypeSingle: { |
| | | get() { |
| | | const st = this.queryParams.serviceType; |
| | | return Array.isArray(st) ? st[0] : st; |
| | | }, |
| | | set(val) { |
| | | this.queryParams.serviceType = val == null || val === "" ? [] : [val]; |
| | | }, |
| | | }, |
| | | }, |
| | | created() { |
| | | this.getDeptTree(); |
| | | this.loadCurrentTabData(); |
| | |
| | | // 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:8096`, |
| | | // target: `http://192.168.100.10:8094`,//çç«åå¾· |
| | | // target: `http://192.168.100.10:8095`,//æ°å |
| | | // target: `http://192.168.100.10:8098`,//å¸ä¸ |
| | | target:`http://localhost:8095`, |
| | | // target:`http://localhost:8095`, |
| | | // target:`http://35z1t16164.qicp.vip`, |
| | | // target: `http://192.168.100.172:8095`, |
| | | // target: `http://192.168.100.10:8089`,//åå |