| | |
| | | "@vue/babel-plugin-jsx": "^1.1.5", |
| | | "@vue/composition-api": "^1.0.0-rc.6", |
| | | "axios": "0.24.0", |
| | | "clipboard": "2.0.8", |
| | | "clipboard": "^2.0.11", |
| | | "codemirror": "^5.65.13", |
| | | "core-js": "^3.25.3", |
| | | "cos-js-sdk-v5": "^1.4.18", |
| | |
| | | "lemon-imui": "^1.7.7", |
| | | "moment": "^2.30.1", |
| | | "nprogress": "0.2.0", |
| | | "qrcode": "^1.5.4", |
| | | "quill": "1.3.7", |
| | | "quill-image-drop-module": "^1.0.3", |
| | | "quill-image-resize": "^3.0.9", |
| | |
| | | "vue-count-to": "1.0.13", |
| | | "vue-cropper": "0.5.5", |
| | | "vue-meta": "2.4.0", |
| | | "vue-qr": "^4.0.9", |
| | | "vue-quill-editor": "^3.0.6", |
| | | "vue-router": "3.4.9", |
| | | "vue-sweetalert2": "^5.0.11", |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æ£è
æ ç¾" prop="tagname"> |
| | | <el-input |
| | | v-model="topqueryParams.tagname" |
| | | placeholder="è¾å
¥è¿è¡æ¨¡ç³æ¥è¯¢" |
| | | maxlength="30" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-input |
| | | v-model="topqueryParams.tagname" |
| | | placeholder="è¾å
¥è¿è¡æ¨¡ç³æ¥è¯¢" |
| | | maxlength="30" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-button |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æ ç¾" |
| | | align="center" |
| | | key="tagname" |
| | | prop="tagname" |
| | | show-overflow-tooltip |
| | | width="180" |
| | | /> |
| | | label="æ ç¾" |
| | | align="center" |
| | | key="tagname" |
| | | prop="tagname" |
| | | show-overflow-tooltip |
| | | width="180" |
| | | /> |
| | | <el-table-column |
| | | label="é访人å" |
| | | align="center" |
| | |
| | | ><i class="el-icon-s-order"></i>æ¥ç详æ
</span |
| | | ></el-button |
| | | > |
| | | <el-button size="medium" type="text" @click="outPathQr(scope.row)" |
| | | ><span class="button-qr" |
| | | ><i class="el-icon-view"></i>äºç»´ç </span |
| | | ></el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | > |
| | | </span> |
| | | </el-dialog> |
| | | <!-- äºç»´ç --> |
| | | <el-dialog |
| | | :title="qrDialog.title" |
| | | :visible.sync="qrDialog.visible" |
| | | width="400px" |
| | | center |
| | | @close="handleQrClose" |
| | | > |
| | | <div class="qrcode-container"> |
| | | <!-- å è½½ç¶æ --> |
| | | <div v-if="qrLoading" class="qrcode-loading"> |
| | | <i class="el-icon-loading"></i> |
| | | <span>äºç»´ç çæä¸...</span> |
| | | </div> |
| | | |
| | | <!-- ææææ°æ®æ¶æ¾ç¤ºäºç»´ç --> |
| | | <div v-else-if="safeQrUrl" class="qrcode-content"> |
| | | <vue-qr |
| | | :text="safeQrUrl" |
| | | :size="280" |
| | | :margin="10" |
| | | :logoSrc="qrDialog.logo" |
| | | :logoScale="0.2" |
| | | colorDark="#191a23" |
| | | colorLight="#ffffff" |
| | | ></vue-qr> |
| | | |
| | | <div class="qrcode-info"> |
| | | <p><strong>æ£è
å§åï¼</strong>{{ qrDialog.patientName }}</p> |
| | | <p><strong>ä»»å¡åç§°ï¼</strong>{{ qrDialog.taskName }}</p> |
| | | </div> |
| | | |
| | | <div class="qrcode-actions"> |
| | | <el-button type="primary" size="small" @click="downloadQrCode"> |
| | | <i class="el-icon-download"></i> ä¸è½½äºç»´ç |
| | | </el-button> |
| | | <el-button type="success" size="small" @click="copyQrUrl"> |
| | | <i class="el-icon-document-copy"></i> å¤å¶é¾æ¥ |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- æ æ°æ®æç¤º --> |
| | | <div v-else class="qrcode-empty"> |
| | | <i class="el-icon-warning"></i> |
| | | <span>ææ ææçäºç»´ç 龿¥</span> |
| | | </div> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import Treeselect from "@riophae/vue-treeselect"; |
| | | import store from "@/store"; |
| | | import "@riophae/vue-treeselect/dist/vue-treeselect.css"; |
| | | |
| | | import VueQr from "vue-qr"; |
| | | import Clipboard from "clipboard"; |
| | | export default { |
| | | name: "Discharge", |
| | | dicts: ["sys_normal_disable", "sys_user_sex", "sys_yujing", "sys_suggest"], |
| | | components: { Treeselect }, |
| | | components: { Treeselect, VueQr }, |
| | | data() { |
| | | return { |
| | | // é®ç½©å± |
| | |
| | | addalteropen: false, |
| | | // ä¿®æ¹åéæ¶é´å¯¹è¯æ¡ |
| | | modificationVisible: false, |
| | | resetQrurl: "", |
| | | // é¨é¨åç§° |
| | | deptName: undefined, |
| | | // é»è®¤å¯ç |
| | |
| | | }, |
| | | value: [], |
| | | list: [], |
| | | |
| | | qrDialog: { |
| | | visible: false, |
| | | title: "é访äºç»´ç ", |
| | | url: "", |
| | | patientName: "", |
| | | taskName: "", |
| | | logo: require("@/assets/logo/logoxh.png"), // å¯éçLogoï¼è¯·ç¡®ä¿è·¯å¾æ£ç¡® |
| | | }, |
| | | qrLoading: false, |
| | | sourcetype: [ |
| | | { |
| | | value: 1, |
| | |
| | | }); |
| | | |
| | | if (store.getters.belongWards.length) { |
| | | this.topqueryParams.leavehospitaldistrictcodes=[store.getters.belongWards[0].districtCode] |
| | | this.topqueryParams.scopetype=[2,store.getters.belongWards[0].districtCode] |
| | | this.topqueryParams.leavehospitaldistrictcodes = [ |
| | | store.getters.belongWards[0].districtCode, |
| | | ]; |
| | | this.topqueryParams.scopetype = [ |
| | | 2, |
| | | store.getters.belongWards[0].districtCode, |
| | | ]; |
| | | } |
| | | if (this.errtype) { |
| | | this.toleadExport(2); |
| | |
| | | }, |
| | | activated() { |
| | | this.getList(1); |
| | | }, |
| | | computed: { |
| | | safeQrUrl() { |
| | | return this.qrDialog.url && this.qrDialog.url !== 'undefined' |
| | | ? this.qrDialog.url.toString() |
| | | : '' |
| | | } |
| | | }, |
| | | methods: { |
| | | /** æ¥è¯¢é¨è¯é访æå¡å表 */ |
| | |
| | | let obj = { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | leavehospitaldistrictcodes: this.topqueryParams.leavehospitaldistrictcodes, |
| | | leavehospitaldistrictcodes: |
| | | this.topqueryParams.leavehospitaldistrictcodes, |
| | | sendstates: [2, 3], |
| | | leaveldeptcodes: this.topqueryParams.leaveldeptcodes, |
| | | }; |
| | |
| | | } |
| | | this.handleQuery(); |
| | | }, |
| | | // æ¾ç¤ºäºç»´ç å¼¹æ¡ |
| | | outPathQr(row) { |
| | | console.log(row); |
| | | |
| | | if (!row || !row.outPath || row.outPath === 'undefined') { |
| | | this.$message.warning('è¯¥è®°å½ææ ææçäºç»´ç 龿¥') |
| | | return |
| | | } |
| | | |
| | | this.qrLoading = true |
| | | this.qrDialog = { |
| | | visible: true, |
| | | title: `${row.sendname || 'æ£è
'}çé访äºç»´ç `, |
| | | url: row.outPath, |
| | | patientName: row.sendname || 'æªç¥', |
| | | taskName: row.taskName || 'æªç¥ä»»å¡', |
| | | logo: require("@/assets/logo/logoxh.png"), |
| | | }; |
| | | // ç¡®ä¿ç»ä»¶æè¶³å¤æ¶é´æ¸²æ |
| | | this.$nextTick(() => { |
| | | this.qrLoading = false |
| | | }) |
| | | }, |
| | | |
| | | // äºç»´ç çæåè° |
| | | qrCodeCallback(dataUrl, id) { |
| | | console.log("äºç»´ç çææå:", id); |
| | | // è¿éå¯ä»¥ä¿ådataUrlç¨äºåç»æä½ |
| | | }, |
| | | |
| | | // ä¸è½½äºç»´ç |
| | | downloadQrCode() { |
| | | try { |
| | | const qrComponent = this.$refs.vueQr; |
| | | // è·åäºç»´ç å¾ççURL |
| | | const qrImageUrl = qrComponent.$el.src; |
| | | |
| | | const downloadLink = document.createElement("a"); |
| | | downloadLink.href = qrImageUrl; |
| | | downloadLink.download = `é访äºç»´ç _${ |
| | | this.qrDialog.patientName |
| | | }_${new Date().getTime()}.png`; |
| | | document.body.appendChild(downloadLink); |
| | | downloadLink.click(); |
| | | document.body.removeChild(downloadLink); |
| | | |
| | | this.$message.success("äºç»´ç ä¸è½½æå"); |
| | | } catch (error) { |
| | | console.error("ä¸è½½å¤±è´¥:", error); |
| | | this.$message.error("ä¸è½½å¤±è´¥ï¼è¯·éè¯"); |
| | | } |
| | | }, |
| | | |
| | | // å¤å¶é¾æ¥ |
| | | copyQrUrl() { |
| | | if (!this.qrDialog.url) { |
| | | this.$message.warning("æ ææé¾æ¥å¯å¤å¶"); |
| | | return; |
| | | } |
| | | |
| | | // æ¹æ³1: 使ç¨clipboardåºï¼å¦æå®è£
äºï¼ |
| | | // this.copyWithClipboard() |
| | | |
| | | // æ¹æ³2: 使ç¨ç°ä»£æµè§å¨çClipboard API |
| | | this.copyWithModernAPI(); |
| | | }, |
| | | |
| | | // 使ç¨ç°ä»£Clipboard APIå¤å¶ |
| | | async copyWithModernAPI() { |
| | | try { |
| | | await navigator.clipboard.writeText(this.qrDialog.url); |
| | | this.$message.success("龿¥å·²å¤å¶å°åªè´´æ¿"); |
| | | } catch (error) { |
| | | // éçº§æ¹æ¡ |
| | | this.copyWithFallback(); |
| | | } |
| | | }, |
| | | |
| | | // å
¼å®¹æ§éçº§æ¹æ¡ |
| | | copyWithFallback() { |
| | | const textArea = document.createElement("textarea"); |
| | | textArea.value = this.qrDialog.url; |
| | | textArea.style.position = "fixed"; |
| | | textArea.style.left = "-999999px"; |
| | | textArea.style.top = "-999999px"; |
| | | document.body.appendChild(textArea); |
| | | textArea.focus(); |
| | | textArea.select(); |
| | | |
| | | try { |
| | | document.execCommand("copy"); |
| | | this.$message.success("龿¥å·²å¤å¶å°åªè´´æ¿"); |
| | | } catch (error) { |
| | | this.$message.warning("æµè§å¨ä¸æ¯æèªå¨å¤å¶ï¼è¯·æå¨å¤å¶é¾æ¥"); |
| | | } finally { |
| | | document.body.removeChild(textArea); |
| | | } |
| | | }, |
| | | |
| | | // å
³éäºç»´ç å¼¹æ¡ |
| | | handleQrClose() { |
| | | this.qrDialog.visible = false; |
| | | this.qrLoading = false |
| | | |
| | | // éç½®æ°æ® |
| | | setTimeout(() => { |
| | | this.qrDialog = { |
| | | visible: false, |
| | | title: "é访äºç»´ç ", |
| | | url: "", |
| | | patientName: "", |
| | | taskName: "", |
| | | logo: require("@/assets/logo/logoxh.png"), |
| | | }; |
| | | }, 300); |
| | | }, |
| | | /** å¯¼åºæé®æä½ */ |
| | | handleExport() { |
| | | this.topqueryParams.pageNum = null; |
| | |
| | | border-radius: 1px; |
| | | color: #ffffff; |
| | | } |
| | | .button-qr { |
| | | background: #6c14a2; |
| | | padding: 5px; |
| | | border-radius: 1px; |
| | | color: #ffffff; |
| | | } |
| | | |
| | | ::v-deep.el-radio-group { |
| | | span { |
| | |
| | | } |
| | | } |
| | | |
| | | // é项å使¾å¤§ |
| | | // ::v-deep.el-checkbox-group { |
| | | // span { |
| | | // font-size: 24px; |
| | | // } |
| | | // } |
| | | /* äºç»´ç å¼¹æ¡æ ·å¼ */ |
| | | .qrcode-container { |
| | | text-align: center; |
| | | padding: 10px; |
| | | } |
| | | |
| | | .qrcode-wrapper { |
| | | margin: 0 auto 20px; |
| | | padding: 15px; |
| | | background: #f8f9fa; |
| | | border-radius: 8px; |
| | | display: inline-block; |
| | | } |
| | | |
| | | .qrcode-info { |
| | | margin: 15px 0; |
| | | padding: 12px; |
| | | background: #f0f2f5; |
| | | border-radius: 6px; |
| | | text-align: left; |
| | | } |
| | | |
| | | .qrcode-info p { |
| | | margin: 8px 0; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .qrcode-actions { |
| | | display: flex; |
| | | justify-content: center; |
| | | gap: 12px; |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | /* ååºå¼è®¾è®¡ */ |
| | | @media (max-width: 480px) { |
| | | .qrcode-actions { |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | |
| | | .qrcode-actions .el-button { |
| | | width: 200px; |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="patient-medication-management"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="24" :xs="24"> |
| | | <!-- æç´¢åºå --> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px"> |
| | | <el-form-item label="æ£è
å§å" prop="patientName"> |
| | | <el-input |
| | | v-model="queryParams.patientName" |
| | | placeholder="请è¾å
¥æ£è
å§å" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="è¯ååç§°" prop="drugName"> |
| | | <el-input |
| | | v-model="queryParams.drugName" |
| | | placeholder="请è¾å
¥è¯ååç§°" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¨è¯ç¶æ" prop="medicationStatus"> |
| | | <el-select v-model="queryParams.medicationStatus" placeholder="è¯·éæ©ç¶æ" clearable style="width: 200px"> |
| | | <el-option |
| | | v-for="item in statusOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </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="handleAssignMedication" |
| | | >åé
ç¨è¯</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="el-icon-close" |
| | | size="medium" |
| | | :disabled="multiple" |
| | | @click="handleStopMedication" |
| | | >忢ç¨è¯</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> |
| | | </el-row> |
| | | |
| | | <!-- æ°æ®è¡¨æ ¼ --> |
| | | <el-table v-loading="loading" :data="medicationList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="50" align="center" /> |
| | | <el-table-column label="è®°å½ID" align="center" prop="id" width="80" /> |
| | | <el-table-column label="æ£è
ä¿¡æ¯" align="center" width="200"> |
| | | <template slot-scope="scope"> |
| | | <div class="patient-info"> |
| | | <div class="patient-name">{{ scope.row.patientName }}</div> |
| | | <div class="patient-details"> |
| | | {{ scope.row.patientAge }}å² / {{ scope.row.patientGender === '1' ? 'ç·' : '女' }} / {{ scope.row.patientNo }} |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="è¿æä¿¡æ¯" align="center" width="120"> |
| | | <template slot-scope="scope"> |
| | | <el-tag |
| | | v-if="scope.row.allergyHistory" |
| | | type="danger" |
| | | size="small" |
| | | @click="showAllergyDetail(scope.row)" |
| | | >æè¿æå²</el-tag> |
| | | <span v-else class="no-allergy">æ </span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="è¯åä¿¡æ¯" align="center" min-width="200"> |
| | | <template slot-scope="scope"> |
| | | <div class="drug-info"> |
| | | <div class="drug-name">{{ scope.row.drugName }} ({{ scope.row.drugSpecification }})</div> |
| | | <div class="dosage-info">{{ scope.row.dosage }} {{ scope.row.dosageUnit }} / 次</div> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¨æ³ç¨é" align="center" width="150"> |
| | | <template slot-scope="scope"> |
| | | <div class="usage-info"> |
| | | <div>{{ scope.row.frequency }}次/æ¥</div> |
| | | <div>{{ scope.row.usageMethod }}</div> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¨è¯æ¶é´" align="center" width="200"> |
| | | <template slot-scope="scope"> |
| | | <div class="time-info"> |
| | | <div>å¼å§: {{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</div> |
| | | <div v-if="scope.row.endTime">ç»æ: {{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</div> |
| | | <div v-else>é¿æç¨è¯</div> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¨è¯ç¶æ" align="center" width="100"> |
| | | <template slot-scope="scope"> |
| | | <el-tag |
| | | :type="getStatusTagType(scope.row.medicationStatus)" |
| | | size="small" |
| | | > |
| | | {{ getStatusText(scope.row.medicationStatus) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½å»ç" align="center" width="120" prop="prescribingDoctor" /> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width" width="200"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-edit" |
| | | @click="handleUpdate(scope.row)" |
| | | >ä¿®æ¹</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-close" |
| | | :class="{ 'stop-button': scope.row.medicationStatus === '1' }" |
| | | @click="handleSingleStop(scope.row)" |
| | | :disabled="scope.row.medicationStatus === '0'" |
| | | >{{ scope.row.medicationStatus === '1' ? '忢' : '已忢' }}</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-view" |
| | | @click="handleViewDetail(scope.row)" |
| | | >详æ
</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" |
| | | /> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <!-- åé
ç¨è¯å¯¹è¯æ¡ --> |
| | | <el-dialog :title="assignTitle" :visible.sync="assignOpen" width="900px" append-to-body> |
| | | <el-form ref="assignForm" :model="assignForm" :rules="assignRules" label-width="100px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éæ©æ£è
" prop="patientId"> |
| | | <el-select |
| | | v-model="assignForm.patientId" |
| | | placeholder="è¯·éæ©æ£è
" |
| | | filterable |
| | | @change="handlePatientChange" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="patient in patientOptions" |
| | | :key="patient.id" |
| | | :label="`${patient.name} (${patient.patientNo})`" |
| | | :value="patient.id" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ£è
ä¿¡æ¯"> |
| | | <div v-if="selectedPatient" class="patient-detail"> |
| | | <div>å§å: {{ selectedPatient.name }}</div> |
| | | <div>å¹´é¾: {{ selectedPatient.age }}å²</div> |
| | | <div>ç
åå·: {{ selectedPatient.patientNo }}</div> |
| | | <div v-if="selectedPatient.allergyHistory" class="allergy-warning"> |
| | | è¿æå²: {{ selectedPatient.allergyHistory }} |
| | | </div> |
| | | </div> |
| | | <span v-else class="placeholder">请å
éæ©æ£è
</span> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è¯ååç§°" prop="drugId"> |
| | | <el-select |
| | | v-model="assignForm.drugId" |
| | | placeholder="è¯·éæ©è¯å" |
| | | filterable |
| | | @change="handleDrugChange" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="drug in drugOptions" |
| | | :key="drug.id" |
| | | :label="drug.name" |
| | | :value="drug.id" |
| | | > |
| | | <span>{{ drug.name }}</span> |
| | | <span style="float: right; color: #8492a6; font-size: 13px"> |
| | | {{ drug.specification }} | åºå: {{ drug.stock }} |
| | | </span> |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è¯åè§æ ¼"> |
| | | <el-input v-model="selectedDrug.specification" readonly /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="忬¡åé" prop="dosage"> |
| | | <el-input-number |
| | | v-model="assignForm.dosage" |
| | | :min="0.1" |
| | | :max="10" |
| | | :step="0.1" |
| | | controls-position="right" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="åéåä½" prop="dosageUnit"> |
| | | <el-select v-model="assignForm.dosageUnit" style="width: 100%"> |
| | | <el-option label="ç" value="ç" /> |
| | | <el-option label="ç²" value="ç²" /> |
| | | <el-option label="mg" value="mg" /> |
| | | <el-option label="ml" value="ml" /> |
| | | <el-option label="g" value="g" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="ç¨è¯é¢æ¬¡" prop="frequency"> |
| | | <el-select v-model="assignForm.frequency" style="width: 100%"> |
| | | <el-option label="æ¯æ¥1次" value="1" /> |
| | | <el-option label="æ¯æ¥2次" value="2" /> |
| | | <el-option label="æ¯æ¥3次" value="3" /> |
| | | <el-option label="æ¯æ¥4次" value="4" /> |
| | | <el-option label="æéæç¨" value="0" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¨è¯æ¹æ³" prop="usageMethod"> |
| | | <el-select v-model="assignForm.usageMethod" style="width: 100%"> |
| | | <el-option label="壿" value="壿" /> |
| | | <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="12"> |
| | | <el-form-item label="ç¨è¯æ¶é´" prop="durationType"> |
| | | <el-radio-group v-model="assignForm.durationType"> |
| | | <el-radio label="1">é¿æç¨è¯</el-radio> |
| | | <el-radio label="2">æå®å¨æ</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20" v-if="assignForm.durationType === '2'"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¼å§æ¶é´" prop="startTime"> |
| | | <el-date-picker |
| | | v-model="assignForm.startTime" |
| | | type="datetime" |
| | | placeholder="éæ©å¼å§æ¶é´" |
| | | style="width: 100%" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»ææ¶é´" prop="endTime"> |
| | | <el-date-picker |
| | | v-model="assignForm.endTime" |
| | | type="datetime" |
| | | placeholder="éæ©ç»ææ¶é´" |
| | | style="width: 100%" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-form-item label="ç¨è¯è¯´æ" prop="instructions"> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="3" |
| | | v-model="assignForm.instructions" |
| | | placeholder="请è¾å
¥ç¨è¯æ³¨æäºé¡¹ãç¹æ®è¯´æç" |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button type="primary" @click="submitAssignForm">ç¡® å®</el-button> |
| | | <el-button @click="cancelAssign">å æ¶</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | |
| | | <!-- 忢ç¨è¯å¯¹è¯æ¡ --> |
| | | <el-dialog :title="stopTitle" :visible.sync="stopOpen" width="600px" append-to-body> |
| | | <el-form ref="stopForm" :model="stopForm" :rules="stopRules" label-width="100px"> |
| | | <el-form-item label="忢åå " prop="stopReason"> |
| | | <el-select v-model="stopForm.stopReason" placeholder="è¯·éæ©åæ¢åå " style="width: 100%"> |
| | | <el-option label="çç¨ç»æ" value="çç¨ç»æ" /> |
| | | <el-option label="ä¸è¯ååº" value="ä¸è¯ååº" /> |
| | | <el-option label="çæä¸ä½³" value="çæä¸ä½³" /> |
| | | <el-option label="æ£è
è¦æ±" value="æ£è
è¦æ±" /> |
| | | <el-option label="å»ç建议" value="å»ç建议" /> |
| | | <el-option label="å
¶ä»åå " value="å
¶ä»" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="详ç»è¯´æ" prop="stopDescription"> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="4" |
| | | v-model="stopForm.stopDescription" |
| | | placeholder="请详ç»è¯´æåæ¢ç¨è¯çåå åæ
åµ" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="忢æ¶é´" prop="stopTime"> |
| | | <el-date-picker |
| | | v-model="stopForm.stopTime" |
| | | type="datetime" |
| | | placeholder="鿩忢æ¶é´" |
| | | style="width: 100%" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button type="primary" @click="submitStopForm">ç¡® å®</el-button> |
| | | <el-button @click="cancelStop">å æ¶</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { parseTime } from '@/utils/ruoyi' |
| | | |
| | | export default { |
| | | name: "PatientMedicationManagement", |
| | | dicts: ['sys_normal_disable'], |
| | | data() { |
| | | return { |
| | | // é®ç½©å± |
| | | loading: false, |
| | | // é䏿°ç» |
| | | ids: [], |
| | | // éå个ç¦ç¨ |
| | | single: true, |
| | | // éå¤ä¸ªç¦ç¨ |
| | | multiple: true, |
| | | // æ¾ç¤ºæç´¢æ¡ä»¶ |
| | | showSearch: true, |
| | | // æ»æ¡æ° |
| | | total: 0, |
| | | // ç¨è¯è®°å½æ°æ® |
| | | medicationList: [ |
| | | { |
| | | id: 1, |
| | | patientId: 'P1001', |
| | | patientName: 'å¼ æ¸
æ¬', |
| | | patientAge: 65, |
| | | patientGender: '1', |
| | | patientNo: '20241209001', |
| | | allergyHistory: 'ééç´ è¿æ', |
| | | drugId: 'D1001', |
| | | drugName: 'é¿å¸å¹æè 溶ç', |
| | | drugSpecification: '100mg*30ç/ç', |
| | | dosage: 1, |
| | | dosageUnit: 'ç', |
| | | frequency: '1', |
| | | usageMethod: '壿', |
| | | startTime: '2024-12-01 08:00:00', |
| | | endTime: '', |
| | | durationType: '1', |
| | | instructions: 'é¥åæç¨ï¼æ³¨æèè éååºãé¿ææç¨éå®ææ£æ¥è¡å¸¸è§ã', |
| | | medicationStatus: '1', |
| | | prescribingDoctor: 'ææç½', |
| | | stopReason: '', |
| | | stopDescription: '' |
| | | }, |
| | | { |
| | | id: 2, |
| | | patientId: 'P1001', |
| | | patientName: 'å¼ æ¸
æ¬', |
| | | patientAge: 65, |
| | | patientGender: '1', |
| | | patientNo: '20241209001', |
| | | allergyHistory: 'ééç´ è¿æ', |
| | | drugId: 'D1002', |
| | | drugName: 'é¿æä¼ä»æ±éç', |
| | | drugSpecification: '20mg*7ç/ç', |
| | | dosage: 1, |
| | | dosageUnit: 'ç', |
| | | frequency: '1', |
| | | usageMethod: '壿', |
| | | startTime: '2024-11-20 20:00:00', |
| | | endTime: '', |
| | | durationType: '1', |
| | | instructions: 'æ¯æç¡åæç¨ã注æçæµèåè½ï¼å¦æèèé
¸çè¯·åæ¶å°±å»ã', |
| | | medicationStatus: '1', |
| | | prescribingDoctor: 'ææç½', |
| | | stopReason: '', |
| | | stopDescription: '' |
| | | }, |
| | | { |
| | | id: 3, |
| | | patientId: 'P2001', |
| | | patientName: 'çè³', |
| | | patientAge: 33, |
| | | patientGender: '0', |
| | | patientNo: '20241115002', |
| | | allergyHistory: 'æ ', |
| | | drugId: 'D1003', |
| | | drugName: '泼尼æ¾ç', |
| | | drugSpecification: '5mg*100ç/ç¶', |
| | | dosage: 2, |
| | | dosageUnit: 'ç', |
| | | frequency: '3', |
| | | usageMethod: '壿', |
| | | startTime: '2024-12-05 09:00:00', |
| | | endTime: '2024-12-20 09:00:00', |
| | | durationType: '2', |
| | | instructions: 'æ©ãä¸ãæé¤åæç¨ãéä¸¥æ ¼éµå»å±éæ¸åéï¼ä¸å¯çªç¶åè¯ã', |
| | | medicationStatus: '0', |
| | | prescribingDoctor: 'åç¿æ ', |
| | | stopReason: 'çç¨ç»æ', |
| | | stopDescription: 'æ åçç¨ç¨è¯å®æ¯ï¼è¡å°æ¿è®¡æ°å·²æ¢å¤æ£å¸¸èå´ã' |
| | | }, |
| | | { |
| | | id: 4, |
| | | patientId: 'P2001', |
| | | patientName: 'çè³', |
| | | patientAge: 33, |
| | | patientGender: '0', |
| | | patientNo: '20241115002', |
| | | allergyHistory: 'æ ', |
| | | drugId: 'D1004', |
| | | drugName: 'å¤ç³éå¤åç©è¶å', |
| | | drugSpecification: '150mg*10ç²/ç', |
| | | dosage: 1, |
| | | dosageUnit: 'ç²', |
| | | frequency: '2', |
| | | usageMethod: '壿', |
| | | startTime: '2024-12-05 09:00:00', |
| | | endTime: '', |
| | | durationType: '1', |
| | | instructions: 'é¤åæç¨ï¼å¯åè½»èè éåºæ¿ãæè¯åå¯è½åºç°é»ä¾¿ï¼å±æ£å¸¸ç°è±¡ã', |
| | | medicationStatus: '1', |
| | | prescribingDoctor: 'åç¿æ ', |
| | | stopReason: '', |
| | | stopDescription: '' |
| | | }, |
| | | { |
| | | id: 5, |
| | | patientId: 'P3001', |
| | | patientName: 'æä¼', |
| | | patientAge: 58, |
| | | patientGender: '1', |
| | | patientNo: '20241022005', |
| | | allergyHistory: '磺èºç±»è¯ç©è¿æ', |
| | | drugId: 'D1005', |
| | | drugName: 'çé
¸äºç²åèç', |
| | | drugSpecification: '0.5g*20ç/æ¿', |
| | | dosage: 1, |
| | | dosageUnit: 'ç', |
| | | frequency: '2', |
| | | usageMethod: '壿', |
| | | startTime: '2024-10-22 08:00:00', |
| | | endTime: '', |
| | | durationType: '1', |
| | | instructions: 'é餿é¤åç«å³æç¨ï¼ä»¥åå°èè éä¸éã', |
| | | medicationStatus: '1', |
| | | prescribingDoctor: 'å¼ åæ¶µ', |
| | | stopReason: '', |
| | | stopDescription: '' |
| | | }, |
| | | { |
| | | id: 6, |
| | | patientId: 'P4001', |
| | | patientName: 'èµµç£', |
| | | patientAge: 70, |
| | | patientGender: '1', |
| | | patientNo: '20241202011', |
| | | allergyHistory: 'æµ·é²è¿æ', |
| | | drugId: 'D1006', |
| | | drugName: 'åå¡ç±³ç', |
| | | drugSpecification: '20mg*100ç/ç¶', |
| | | dosage: 1, |
| | | dosageUnit: 'ç', |
| | | frequency: '1', |
| | | usageMethod: '壿', |
| | | startTime: '2024-12-02 07:00:00', |
| | | endTime: '', |
| | | durationType: '1', |
| | | instructions: 'æ¨èµ·æç¨ï¼é¿å
å¤é´å¤æ¬¡èµ·å¤ã注æçæµçµè§£è´¨æ°´å¹³ã', |
| | | medicationStatus: '1', |
| | | prescribingDoctor: 'å´æç¿°', |
| | | stopReason: '', |
| | | stopDescription: '' |
| | | }, |
| | | { |
| | | id: 7, |
| | | patientId: 'P5001', |
| | | patientName: 'å¨å', |
| | | patientAge: 52, |
| | | patientGender: '0', |
| | | patientNo: '20241128009', |
| | | allergyHistory: 'æ ', |
| | | drugId: 'D1007', |
| | | drugName: 'ç¡è¯å°å¹³æ§éç', |
| | | drugSpecification: '30mg*7ç/ç', |
| | | dosage: 1, |
| | | dosageUnit: 'ç', |
| | | frequency: '1', |
| | | usageMethod: '壿', |
| | | startTime: '2024-11-28 08:00:00', |
| | | endTime: '', |
| | | durationType: '1', |
| | | instructions: 'æ´çåæï¼ä¸å¯å¼ç¢ææ°å¼ã', |
| | | medicationStatus: '1', |
| | | prescribingDoctor: 'éæ¿å©', |
| | | stopReason: '', |
| | | stopDescription: '' |
| | | } |
| | | ], |
| | | // åé
ç¨è¯å¼¹åºå± |
| | | assignOpen: false, |
| | | assignTitle: "", |
| | | // 忢ç¨è¯å¼¹åºå± |
| | | stopOpen: false, |
| | | stopTitle: "", |
| | | // æ¥è¯¢åæ° |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | patientName: undefined, |
| | | drugName: undefined, |
| | | medicationStatus: undefined |
| | | }, |
| | | // åé
ç¨è¯è¡¨å |
| | | assignForm: {}, |
| | | // 忢ç¨è¯è¡¨å |
| | | stopForm: {}, |
| | | // é䏿£è
ä¿¡æ¯ |
| | | selectedPatient: null, |
| | | // éä¸è¯åä¿¡æ¯ |
| | | selectedDrug: {}, |
| | | // æ£è
é项 |
| | | patientOptions: [ |
| | | { |
| | | id: 'P1001', |
| | | name: 'å¼ ä¸', |
| | | age: 65, |
| | | patientNo: '20241209001', |
| | | allergyHistory: 'ééç´ è¿æ' |
| | | } |
| | | ], |
| | | // è¯åé项 |
| | | drugOptions: [ |
| | | { |
| | | id: 'D1001', |
| | | name: 'é¿å¸å¹æ', |
| | | specification: '100mg', |
| | | stock: 150 |
| | | } |
| | | ], |
| | | // ç¶æé项 |
| | | statusOptions: [ |
| | | { value: "1", label: "ç¨è¯ä¸" }, |
| | | { value: "0", label: "已忢" } |
| | | ], |
| | | // è¡¨åæ ¡éª |
| | | assignRules: { |
| | | patientId: [ |
| | | { required: true, message: "è¯·éæ©æ£è
", trigger: "change" } |
| | | ], |
| | | drugId: [ |
| | | { required: true, message: "è¯·éæ©è¯å", trigger: "change" } |
| | | ], |
| | | dosage: [ |
| | | { required: true, message: "请è¾å
¥å次åé", trigger: "blur" } |
| | | ], |
| | | frequency: [ |
| | | { required: true, message: "è¯·éæ©ç¨è¯é¢æ¬¡", trigger: "change" } |
| | | ] |
| | | }, |
| | | stopRules: { |
| | | stopReason: [ |
| | | { required: true, message: "è¯·éæ©åæ¢åå ", trigger: "change" } |
| | | ], |
| | | stopTime: [ |
| | | { required: true, message: "è¯·éæ©åæ¢æ¶é´", trigger: "change" } |
| | | ] |
| | | } |
| | | }; |
| | | }, |
| | | created() { |
| | | this.getList(); |
| | | }, |
| | | methods: { |
| | | parseTime, |
| | | /** æ¥è¯¢ç¨è¯è®°å½å表 */ |
| | | getList() { |
| | | this.loading = true; |
| | | // 模æAPIè°ç¨ |
| | | setTimeout(() => { |
| | | this.loading = false; |
| | | this.total = this.medicationList.length; |
| | | }, 500); |
| | | }, |
| | | /** æç´¢æé®æä½ */ |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1; |
| | | this.getList(); |
| | | }, |
| | | /** éç½®æé®æä½ */ |
| | | resetQuery() { |
| | | this.resetForm("queryForm"); |
| | | this.handleQuery(); |
| | | }, |
| | | // å¤éæ¡é䏿°æ® |
| | | handleSelectionChange(selection) { |
| | | this.ids = selection.map(item => item.id); |
| | | this.single = selection.length !== 1; |
| | | this.multiple = !selection.length; |
| | | }, |
| | | /** åé
ç¨è¯æé®æä½ */ |
| | | handleAssignMedication() { |
| | | this.resetAssignForm(); |
| | | this.assignOpen = true; |
| | | this.assignTitle = "åé
ç¨è¯"; |
| | | }, |
| | | /** 忢ç¨è¯æé®æä½ */ |
| | | handleStopMedication() { |
| | | if (this.ids.length === 0) { |
| | | this.$modal.msgError("请å
éæ©è¦åæ¢çç¨è¯è®°å½"); |
| | | return; |
| | | } |
| | | this.resetStopForm(); |
| | | this.stopOpen = true; |
| | | this.stopTitle = "忢ç¨è¯"; |
| | | }, |
| | | /** åä¸ªåæ¢ç¨è¯ */ |
| | | handleSingleStop(row) { |
| | | this.ids = [row.id]; |
| | | this.resetStopForm(); |
| | | this.stopForm.patientName = row.patientName; |
| | | this.stopForm.drugName = row.drugName; |
| | | this.stopOpen = true; |
| | | this.stopTitle = `忢ç¨è¯ - ${row.patientName}`; |
| | | }, |
| | | /** æäº¤åé
ç¨è¯è¡¨å */ |
| | | submitAssignForm() { |
| | | this.$refs["assignForm"].validate(valid => { |
| | | if (valid) { |
| | | // 模æAPIè°ç¨ |
| | | const newRecord = { |
| | | id: Math.max(...this.medicationList.map(item => item.id)) + 1, |
| | | ...this.assignForm, |
| | | patientName: this.selectedPatient?.name, |
| | | patientAge: this.selectedPatient?.age, |
| | | patientGender: this.selectedPatient?.gender, |
| | | patientNo: this.selectedPatient?.patientNo, |
| | | allergyHistory: this.selectedPatient?.allergyHistory, |
| | | drugName: this.selectedDrug?.name, |
| | | drugSpecification: this.selectedDrug?.specification, |
| | | medicationStatus: '1', |
| | | prescribingDoctor: 'å½åç¨æ·', |
| | | startTime: this.assignForm.startTime || new Date().toISOString().replace('T', ' ').substr(0, 19) |
| | | }; |
| | | |
| | | this.medicationList.unshift(newRecord); |
| | | this.total = this.medicationList.length; |
| | | this.$modal.msgSuccess("åé
æå"); |
| | | this.assignOpen = false; |
| | | } |
| | | }); |
| | | }, |
| | | /** æäº¤åæ¢ç¨è¯è¡¨å */ |
| | | submitStopForm() { |
| | | this.$refs["stopForm"].validate(valid => { |
| | | if (valid) { |
| | | // æ´æ°ç¨è¯è®°å½ç¶æ |
| | | this.medicationList.forEach(item => { |
| | | if (this.ids.includes(item.id)) { |
| | | item.medicationStatus = '0'; |
| | | item.endTime = this.stopForm.stopTime; |
| | | item.stopReason = this.stopForm.stopReason; |
| | | item.stopDescription = this.stopForm.stopDescription; |
| | | } |
| | | }); |
| | | |
| | | this.$modal.msgSuccess("忢ç¨è¯æå"); |
| | | this.stopOpen = false; |
| | | this.getList(); |
| | | } |
| | | }); |
| | | }, |
| | | /** æ£è
éæ©åå */ |
| | | handlePatientChange(patientId) { |
| | | this.selectedPatient = this.patientOptions.find(p => p.id === patientId) || null; |
| | | }, |
| | | /** è¯åéæ©åå */ |
| | | handleDrugChange(drugId) { |
| | | this.selectedDrug = this.drugOptions.find(d => d.id === drugId) || {}; |
| | | }, |
| | | /** æ¥ç详æ
*/ |
| | | handleViewDetail(row) { |
| | | this.$alert( |
| | | `<div> |
| | | <p><strong>æ£è
ä¿¡æ¯ï¼</strong>${row.patientName} (${row.patientNo})</p> |
| | | <p><strong>è¯åä¿¡æ¯ï¼</strong>${row.drugName} ${row.drugSpecification}</p> |
| | | <p><strong>ç¨æ³ç¨éï¼</strong>${row.dosage}${row.dosageUnit}/次ï¼${row.frequency}次/æ¥ï¼${row.usageMethod}</p> |
| | | <p><strong>ç¨è¯æ¶é´ï¼</strong>${this.parseTime(row.startTime, '{y}-{m}-{d}')} - ${row.endTime ? this.parseTime(row.endTime, '{y}-{m}-{d}') : 'é¿æ'}</p> |
| | | <p><strong>ç¨è¯è¯´æï¼</strong>${row.instructions || 'æ '}</p> |
| | | ${row.allergyHistory ? `<p><strong>è¿æå²ï¼</strong><span style="color: red">${row.allergyHistory}</span></p>` : ''} |
| | | </div>`, |
| | | "ç¨è¯è¯¦æ
", |
| | | { |
| | | dangerouslyUseHTMLString: true, |
| | | customClass: "medication-detail-dialog", |
| | | } |
| | | ); |
| | | }, |
| | | /** æ¾ç¤ºè¿æå²è¯¦æ
*/ |
| | | showAllergyDetail(row) { |
| | | if (row.allergyHistory) { |
| | | this.$alert(`æ£è
${row.patientName} çè¿æå²ï¼${row.allergyHistory}`, "è¿æå²è¯¦æ
", { |
| | | confirmButtonText: "ç¡®å®" |
| | | }); |
| | | } |
| | | }, |
| | | /** è·åç¶ææ ç¾ç±»å */ |
| | | getStatusTagType(status) { |
| | | const statusMap = { |
| | | '1': 'success', // ç¨è¯ä¸ |
| | | '0': 'info' // 已忢 |
| | | }; |
| | | return statusMap[status] || 'info'; |
| | | }, |
| | | /** è·åç¶æææ¬ */ |
| | | getStatusText(status) { |
| | | const statusMap = { |
| | | '1': 'ç¨è¯ä¸', |
| | | '0': '已忢' |
| | | }; |
| | | return statusMap[status] || 'æªç¥'; |
| | | }, |
| | | /** éç½®åé
ç¨è¯è¡¨å */ |
| | | resetAssignForm() { |
| | | this.assignForm = { |
| | | patientId: undefined, |
| | | drugId: undefined, |
| | | dosage: 1, |
| | | dosageUnit: 'ç', |
| | | frequency: '3', |
| | | usageMethod: '壿', |
| | | durationType: '1', |
| | | startTime: new Date().toISOString().replace('T', ' ').substr(0, 19), |
| | | endTime: undefined, |
| | | instructions: '' |
| | | }; |
| | | this.selectedPatient = null; |
| | | this.selectedDrug = {}; |
| | | this.resetForm("assignForm"); |
| | | }, |
| | | /** éç½®åæ¢ç¨è¯è¡¨å */ |
| | | resetStopForm() { |
| | | this.stopForm = { |
| | | stopReason: '', |
| | | stopDescription: '', |
| | | stopTime: new Date().toISOString().replace('T', ' ').substr(0, 19) |
| | | }; |
| | | this.resetForm("stopForm"); |
| | | }, |
| | | /** åæ¶åé
ç¨è¯ */ |
| | | cancelAssign() { |
| | | this.assignOpen = false; |
| | | this.resetAssignForm(); |
| | | }, |
| | | /** 忶忢ç¨è¯ */ |
| | | cancelStop() { |
| | | this.stopOpen = false; |
| | | this.resetStopForm(); |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .patient-medication-management { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .patient-info { |
| | | text-align: left; |
| | | .patient-name { |
| | | font-weight: bold; |
| | | margin-bottom: 4px; |
| | | } |
| | | .patient-details { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | } |
| | | } |
| | | |
| | | .drug-info { |
| | | text-align: left; |
| | | .drug-name { |
| | | font-weight: bold; |
| | | margin-bottom: 4px; |
| | | } |
| | | .dosage-info { |
| | | font-size: 12px; |
| | | color: #67C23A; |
| | | } |
| | | } |
| | | |
| | | .usage-info, .time-info { |
| | | font-size: 12px; |
| | | line-height: 1.4; |
| | | } |
| | | |
| | | .allergy-warning { |
| | | color: #F56C6C; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .no-allergy { |
| | | color: #909399; |
| | | font-style: italic; |
| | | } |
| | | |
| | | .patient-detail { |
| | | font-size: 12px; |
| | | line-height: 1.6; |
| | | padding: 8px; |
| | | background: #f5f7fa; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .placeholder { |
| | | color: #c0c4cc; |
| | | font-style: italic; |
| | | } |
| | | |
| | | .stop-button { |
| | | color: #E6A23C; |
| | | &:hover { |
| | | color: #f56c6c; |
| | | } |
| | | } |
| | | |
| | | ::v-deep .medication-detail-dialog { |
| | | width: 500px; |
| | | } |
| | | </style> |
| | |
| | | // æ»æ¡æ° |
| | | total: 0, |
| | | // æç« è¡¨æ ¼æ°æ® |
| | | articleList: [ |
| | | { |
| | | id: 1, |
| | | title: "å¦ä½æé«å端å¼åæç", |
| | | category: "1", |
| | | coverImage: "https://pic.rmb.bdstatic.com/bjh/news/5e5f1b3e7b1a8a7f8a3d6a7d3a6a7d3a.jpeg", |
| | | author: "å¼ ä¸", |
| | | publishTime: "2023-05-10 09:30:00", |
| | | views: 1250, |
| | | status: "1", |
| | | summary: "æ¬æä»ç»äºå ç§æé«å端å¼åæççæ¹æ³åå·¥å
·", |
| | | content: "<p>å端å¼åæççæå对äºé¡¹ç®è¿åº¦è³å
³éè¦...</p>" |
| | | }, |
| | | { |
| | | id: 2, |
| | | title: "Vue3æ°ç¹æ§è§£æ", |
| | | category: "2", |
| | | coverImage: "https://pic.rmb.bdstatic.com/bjh/news/8e5f1b3e7b1a8a7f8a3d6a7d3a6a7d3a.jpeg", |
| | | author: "æå", |
| | | publishTime: "2023-05-15 14:20:00", |
| | | views: 3200, |
| | | status: "1", |
| | | summary: "详ç»è§£æVue3çæ°ç¹æ§å使ç¨åºæ¯", |
| | | content: "<p>Vue3带æ¥äºè®¸å¤ä»¤äººå
´å¥çæ°ç¹æ§...</p>" |
| | | }, |
| | | { |
| | | id: 3, |
| | | title: "Element UIä½¿ç¨æå·§", |
| | | category: "3", |
| | | coverImage: "https://pic.rmb.bdstatic.com/bjh/news/9e5f1b3e7b1a8a7f8a3d6a7d3a6a7d3a.jpeg", |
| | | author: "çäº", |
| | | publishTime: "2023-05-20 10:15:00", |
| | | views: 890, |
| | | status: "0", |
| | | summary: "å享ä¸äºElement UIçé«çº§ä½¿ç¨æå·§", |
| | | content: "<p>Element UIä½ä¸ºæµè¡çUIæ¡æ¶ï¼æè®¸å¤å®ç¨æå·§...</p>" |
| | | }, |
| | | { |
| | | id: 4, |
| | | title: "å端æ§è½ä¼åæå", |
| | | category: "1", |
| | | coverImage: "https://pic.rmb.bdstatic.com/bjh/news/7e5f1b3e7b1a8a7f8a3d6a7d3a6a7d3a.jpeg", |
| | | author: "èµµå
", |
| | | publishTime: "2023-05-25 16:45:00", |
| | | views: 4500, |
| | | status: "1", |
| | | summary: "å
¨é¢çå端æ§è½ä¼åæ¹æ³åå®è·µ", |
| | | content: "<p>æ§è½ä¼åæ¯å端å¼å䏿°¸æçè¯é¢...</p>" |
| | | }, |
| | | { |
| | | id: 5, |
| | | title: "TypeScriptå
¥é¨æç¨", |
| | | category: "2", |
| | | coverImage: "https://pic.rmb.bdstatic.com/bjh/news/6e5f1b3e7b1a8a7f8a3d6a7d3a6a7d3a.jpeg", |
| | | author: "é±ä¸", |
| | | publishTime: "2023-06-01 11:10:00", |
| | | views: 2100, |
| | | status: "1", |
| | | summary: "ä»é¶å¼å§å¦ä¹ TypeScript", |
| | | content: "<p>TypeScriptä½ä¸ºJavaScriptçè¶
éè¶æ¥è¶å欢è¿...</p>" |
| | | } |
| | | ], |
| | | // æ¿æ¢åæçarticleListæ°æ® |
| | | articleList: [ |
| | | { |
| | | id: 1, |
| | | title: "ç³å°¿ç
ç®¡çæ°è¿å±ï¼ä¸ªæ§åæ²»çæ¹æ¡çç ç©¶ä¸åºç¨", |
| | | category: "1", |
| | | coverImage: "https://example.com/images/diabetes-management.jpg", |
| | | author: "ææç½", |
| | | publishTime: "2024-11-15 09:30:00", |
| | | views: 3250, |
| | | status: "1", |
| | | summary: "æ¬æç»¼è¿°äºè¿å¹´æ¥ç³å°¿ç
个æ§åæ²»ççææ°ç ç©¶ææï¼éç¹åæäºåºäºæ£è
åºå ç¹å¾çå®å¶åæ²»çæ¹æ¡ã", |
| | | content: "<p>éçç²¾åå»ççåå±ï¼ç³å°¿ç
æ²»çæ£ä»æ ååå个æ§å转å...</p>" |
| | | }, |
| | | { |
| | | id: 2, |
| | | title: "å¿è¡ç®¡ç¾ç
é¢é²ï¼ä»é£é©è¯ä¼°å°æ©æå¹²é¢", |
| | | category: "2", |
| | | coverImage: "https://example.com/images/cardiovascular-prevention.jpg", |
| | | author: "åç¿æ ", |
| | | publishTime: "2024-11-10 14:20:00", |
| | | views: 4280, |
| | | status: "1", |
| | | summary: "æ¢è®¨å¿è¡ç®¡ç¾ç
çæ°åé£é©è¯ä¼°å·¥å
·åæ©æå¹²é¢çç¥ï¼ä¸ºä¸´åºå®è·µæä¾æå¯¼ã", |
| | | content: "<p>å¿è¡ç®¡ç¾ç
ä»ç¶æ¯å
¨ç主è¦çæ»äº¡åå ï¼æ©æé¢é²è³å
³éè¦...</p>" |
| | | }, |
| | | { |
| | | id: 3, |
| | | title: "è¿ç¤å
ç«æ²»ççä¸è¯ååºç®¡çä¸åºå¯¹çç¥", |
| | | category: "3", |
| | | coverImage: "https://example.com/images/immunotherapy-side-effects.jpg", |
| | | author: "å¼ åæ¶µ", |
| | | publishTime: "2024-11-05 10:15:00", |
| | | views: 2890, |
| | | status: "0", |
| | | summary: "ç³»ç»åæå
ç«æ£æ¥ç¹æå¶åæ²»çä¸å¸¸è§çä¸è¯ååºåå
¶ä¸´åºç®¡çæ¹æ¡ã", |
| | | content: "<p>å
ç«æ²»ç为è¿ç¤æ£è
带æ¥å¸æï¼ä½å
¶ç¬ç¹çä¸è¯ååºéè¦ç¹å«å
³æ³¨...</p>" |
| | | }, |
| | | { |
| | | id: 4, |
| | | title: "人工æºè½å¨å»å¦å½±åè¯æä¸çåºç¨ä¸ææ", |
| | | category: "4", |
| | | coverImage: "https://example.com/images/ai-medical-imaging.jpg", |
| | | author: "å´æç¿°", |
| | | publishTime: "2024-10-28 16:45:00", |
| | | views: 5120, |
| | | status: "1", |
| | | summary: "å顾AIææ¯å¨CTãMRIçå»å¦å½±ååæä¸çææ°è¿å±å临åºåºç¨ä»·å¼ã", |
| | | content: "<p>人工æºè½ææ¯æ£å¨éå¡å»å¦å½±åè¯æçæ ¼å±...</p>" |
| | | }, |
| | | { |
| | | id: 5, |
| | | title: "æ
¢æ§ç¼ççè¯ç©æ²»çä¸éè¯ç©å¹²é¢ç»¼å管ç", |
| | | category: "1", |
| | | coverImage: "https://example.com/images/chronic-pain-management.jpg", |
| | | author: "éæ¿å©", |
| | | publishTime: "2024-10-22 11:10:00", |
| | | views: 1950, |
| | | status: "1", |
| | | summary: "åºäºå¾ªè¯å»å¦è¯æ®ï¼æåºæ
¢æ§ç¼çç综åç®¡çæ¹æ¡ï¼å¹³è¡¡çæä¸å®å
¨æ§ã", |
| | | content: "<p>æ
¢æ§ç¼ç严é影忣è
çæ´»è´¨éï¼éè¦å¤æ¨¡å¼ç»¼åæ²»ç...</p>" |
| | | }, |
| | | { |
| | | id: 6, |
| | | title: "å¿ç§å¼å¸éææçè¯çè§èæ´æ°è§£è¯»", |
| | | category: "2", |
| | | coverImage: "https://example.com/images/pediatric-respiratory.jpg", |
| | | author: "éè¯æ¶µ", |
| | | publishTime: "2024-10-18 13:25:00", |
| | | views: 3670, |
| | | status: "1", |
| | | summary: "ç»åææ°ä¸´åºæåï¼è¯¦ç»è§£è¯»å¿ç«¥å¼å¸éææçè¯ææ ååæ²»çååã", |
| | | content: "<p>å¿ç«¥å¼å¸éæææ¯å¿ç§å¸¸è§ç
ï¼è§èè¯ç对é¢åè³å
³éè¦...</p>" |
| | | }, |
| | | { |
| | | id: 7, |
| | | title: "ç²¾ç¥å«çæ°åçæ³çç°ç¶ä¸æªæ¥åå±", |
| | | category: "3", |
| | | coverImage: "https://example.com/images/digital-mental-health.jpg", |
| | | author: "é»çç«", |
| | | publishTime: "2024-10-12 15:30:00", |
| | | views: 2430, |
| | | status: "2", |
| | | summary: "æ¢è®¨æ°åææ¯å¨ç²¾ç¥å¿çç¾ç
æ²»çä¸çåºç¨åæ¯åé¢ä¸´çææã", |
| | | content: "<p>æ°åçæ³ä¸ºç²¾ç¥å«çé¢å带æ¥äºæ°çæ²»çæ¨¡å¼...</p>" |
| | | }, |
| | | { |
| | | id: 8, |
| | | title: "è年综åè¯ä¼°å¨ä¸´åºå®è·µä¸ç宿½è·¯å¾", |
| | | category: "4", |
| | | coverImage: "https://example.com/images/geriatric-assessment.jpg", |
| | | author: "çæ©é¾", |
| | | publishTime: "2024-10-05 08:45:00", |
| | | views: 1780, |
| | | status: "1", |
| | | summary: "ç³»ç»ä»ç»è年综åè¯ä¼°çå¤ç»´åº¦å
容åå
¶å¨èå¹´æ£è
管çä¸çä»·å¼ã", |
| | | content: "<p>éç人å£èé¾åï¼è年综åè¯ä¼°æä¸ºèå¹´å»å¦çéè¦å·¥å
·...</p>" |
| | | } |
| | | ], |
| | | // å¼¹åºå±æ é¢ |
| | | title: "", |
| | | // æ¯å¦æ¾ç¤ºå¼¹åºå± |
| | |
| | | }, |
| | | // æç« åç±»é项 |
| | | categoryOptions: [ |
| | | { value: "1", label: "ææ¯æç« " }, |
| | | { value: "2", label: "æç¨æå" }, |
| | | { value: "3", label: "ç»éªå享" }, |
| | | { value: "4", label: "è¡ä¸èµè®¯" } |
| | | { value: "1", label: "临åºç ç©¶" }, |
| | | { value: "2", label: "è¯çæå" }, |
| | | { value: "3", label: "è¯ç©è¿å±" }, |
| | | { value: "4", label: "ææ¯åæ²¿" } |
| | | ], |
| | | // ç¶æé项 |
| | | statusOptions: [ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="contract-review-page"> |
| | | <!-- ç鿡件 --> |
| | | <el-card class="search-card" shadow="never"> |
| | | <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="100px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="6"> |
| | | <el-form-item label="æ£è
å§å" prop="patientName"> |
| | | <el-input |
| | | v-model="queryParams.patientName" |
| | | placeholder="请è¾å
¥æ£è
å§å" |
| | | clearable |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="å®¡æ ¸ç¶æ" prop="reviewStatus"> |
| | | <el-select v-model="queryParams.reviewStatus" placeholder="è¯·éæ©ç¶æ" clearable> |
| | | <el-option label="å¾
å®¡æ ¸" value="0" /> |
| | | <el-option label="å®¡æ ¸éè¿" value="1" /> |
| | | <el-option label="å®¡æ ¸é©³å" value="2" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="ç³è¯·æ¶é´" prop="applyDate"> |
| | | <el-date-picker |
| | | v-model="queryParams.applyDate" |
| | | type="daterange" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | value-format="yyyy-MM-dd" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <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-col> |
| | | </el-row> |
| | | </el-form> |
| | | </el-card> |
| | | |
| | | <!-- ç»è®¡ä¿¡æ¯ --> |
| | | <el-row :gutter="20" class="stats-row"> |
| | | <el-col :span="8"> |
| | | <el-card shadow="hover"> |
| | | <div class="stat-item"> |
| | | <div class="stat-number">{{ stats.pending }}</div> |
| | | <div class="stat-label">å¾
å®¡æ ¸ç³è¯·</div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-card shadow="hover"> |
| | | <div class="stat-item"> |
| | | <div class="stat-number" style="color: #67C23A;">{{ stats.approved }}</div> |
| | | <div class="stat-label">å·²éè¿å®¡æ ¸</div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-card shadow="hover"> |
| | | <div class="stat-item"> |
| | | <div class="stat-number" style="color: #F56C6C;">{{ stats.rejected }}</div> |
| | | <div class="stat-label">已驳åç³è¯·</div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <!-- å®¡æ ¸å表 --> |
| | | <el-card shadow="never"> |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="reviewList" |
| | | style="width: 100%" |
| | | :default-sort="{prop: 'applyTime', order: 'descending'}" |
| | | > |
| | | <el-table-column label="æ£è
ä¿¡æ¯" min-width="200" fixed> |
| | | <template slot-scope="scope"> |
| | | <div class="patient-info"> |
| | | <div class="patient-name">{{ scope.row.patientName }}</div> |
| | | <div class="patient-detail"> |
| | | {{ scope.row.gender }} | {{ scope.row.age }}å² | {{ scope.row.phone }} |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç³è¯·å¥é¤" min-width="150"> |
| | | <template slot-scope="scope"> |
| | | <el-tag :type="getPackageType(scope.row.servicePackageId)"> |
| | | {{ scope.row.servicePackage }} |
| | | </el-tag> |
| | | <div style="font-size: 12px; color: #666; margin-top: 4px;"> |
| | | 卿: {{ scope.row.contractPeriod }}年 |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å
嫿å¡" min-width="200"> |
| | | <template slot-scope="scope"> |
| | | <el-tooltip effect="dark" :content="scope.row.services.join('ã')" placement="top"> |
| | | <span>{{ scope.row.services.slice(0, 2).join('ã') }}ç{{ scope.row.services.length }}项</span> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç³è¯·æ¶é´" prop="applyTime" width="160" sortable /> |
| | | <el-table-column label="ææå»ç" prop="expectDoctor" width="120" /> |
| | | <el-table-column label="ç¹æ®è¦æ±" min-width="200"> |
| | | <template slot-scope="scope"> |
| | | <span v-if="scope.row.specialRequirements" :title="scope.row.specialRequirements"> |
| | | {{ scope.row.specialRequirements.substring(0, 30) }}... |
| | | </span> |
| | | <span v-else style="color: #999;">æ ç¹æ®è¦æ±</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å®¡æ ¸ç¶æ" width="100"> |
| | | <template slot-scope="scope"> |
| | | <el-tag :type="getReviewStatusType(scope.row.reviewStatus)" effect="dark"> |
| | | {{ getReviewStatusText(scope.row.reviewStatus) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å®¡æ ¸ä¿¡æ¯" min-width="180"> |
| | | <template slot-scope="scope"> |
| | | <div v-if="scope.row.reviewStatus !== 0"> |
| | | <div style="font-size: 12px;">å®¡æ ¸äºº: {{ scope.row.reviewer }}</div> |
| | | <div style="font-size: 12px;">æ¶é´: {{ scope.row.reviewTime }}</div> |
| | | <div v-if="scope.row.reviewStatus === 2" style="color: #f56c6c; font-size: 12px;"> |
| | | åå : {{ scope.row.rejectReason }} |
| | | </div> |
| | | </div> |
| | | <span v-else style="color: #999;">å¾
å®¡æ ¸</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="180" fixed="right"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | v-if="scope.row.reviewStatus === 0" |
| | | size="mini" |
| | | type="primary" |
| | | @click="handleReview(scope.row, 1)" |
| | | >éè¿</el-button> |
| | | <el-button |
| | | v-if="scope.row.reviewStatus === 0" |
| | | size="mini" |
| | | type="danger" |
| | | @click="handleReview(scope.row, 2)" |
| | | >驳å</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | @click="handleView(scope.row)" |
| | | >详æ
</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" |
| | | /> |
| | | </el-card> |
| | | |
| | | <!-- å®¡æ ¸å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | :title="reviewForm.reviewStatus === 1 ? 'å®¡æ ¸éè¿ç¡®è®¤' : 'å®¡æ ¸é©³å确认'" |
| | | :visible.sync="reviewDialogVisible" |
| | | width="500px" |
| | | > |
| | | <el-form :model="reviewForm" ref="reviewFormRef" label-width="100px"> |
| | | <el-form-item |
| | | v-if="reviewForm.reviewStatus === 2" |
| | | label="驳ååå " |
| | | prop="rejectReason" |
| | | :rules="[{ required: true, message: '请è¾å
¥é©³ååå ', trigger: 'blur' }]" |
| | | > |
| | | <el-input |
| | | type="textarea" |
| | | :rows="3" |
| | | v-model="reviewForm.rejectReason" |
| | | placeholder="请è¾å
¥é©³åçå
·ä½åå ï¼ä¾¿äºæ£è
äºè§£æ
åµ" |
| | | maxlength="200" |
| | | show-word-limit |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="åé
å»ç" prop="assignDoctor"> |
| | | <el-select v-model="reviewForm.assignDoctor" placeholder="è¯·éæ©è´è´£å»ç" clearable> |
| | | <el-option |
| | | v-for="doctor in availableDoctors" |
| | | :key="doctor.id" |
| | | :label="doctor.name" |
| | | :value="doctor.id" |
| | | > |
| | | <span>{{ doctor.name }}</span> |
| | | <span style="float: right; color: #8492a6; font-size: 13px"> |
| | | {{ doctor.department }} |
| | | </span> |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨ä¿¡æ¯"> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="2" |
| | | v-model="reviewForm.remark" |
| | | placeholder="å¯å¡«åé¢å¤ç夿³¨ä¿¡æ¯ï¼å¯éï¼" |
| | | maxlength="100" |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div slot="footer"> |
| | | <el-button @click="reviewDialogVisible = false">åæ¶</el-button> |
| | | <el-button type="primary" @click="submitReview">ç¡®å®</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'ContractReview', |
| | | data() { |
| | | return { |
| | | loading: false, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | patientName: undefined, |
| | | reviewStatus: undefined, |
| | | applyDate: undefined |
| | | }, |
| | | total: 0, |
| | | reviewList: [], |
| | | reviewDialogVisible: false, |
| | | reviewForm: { |
| | | id: undefined, |
| | | reviewStatus: 1, |
| | | rejectReason: undefined, |
| | | assignDoctor: undefined, |
| | | remark: undefined |
| | | }, |
| | | currentRow: null, |
| | | stats: { |
| | | pending: 0, |
| | | approved: 0, |
| | | rejected: 0 |
| | | }, |
| | | availableDoctors: [ |
| | | { id: '1', name: 'çå»ç', department: 'å
ç§' }, |
| | | { id: '2', name: 'æå»ç', department: 'èå¹´ç§' }, |
| | | { id: '3', name: 'å¼ å»ç', department: 'å¦äº§ç§' }, |
| | | { id: '4', name: 'åå»ç', department: 'å¿ç§' }, |
| | | { id: '5', name: 'éå»ç', department: 'å
¨ç§' } |
| | | ], |
| | | servicePackages: { |
| | | '1': { name: 'åºç¡å¥åº·ç®¡çå
', color: 'info' }, |
| | | '2': { name: 'æ
¢æ§ç
管çå
', color: 'success' }, |
| | | '3': { name: 'è年人å¥åº·å
', color: 'warning' }, |
| | | '4': { name: 'å产å¦ä¿å¥å
', color: 'danger' }, |
| | | '5': { name: 'å¿ç«¥ä¿å¥å
', color: 'primary' } |
| | | }, |
| | | rules: { |
| | | rejectReason: [ |
| | | { required: true, message: '驳ååå ä¸è½ä¸ºç©º', trigger: 'blur' } |
| | | ], |
| | | assignDoctor: [ |
| | | { required: true, message: 'è¯·éæ©åé
å»ç', trigger: 'change' } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.getList() |
| | | this.calculateStats() |
| | | }, |
| | | methods: { |
| | | //ä¼ååçæ¨¡ææ°æ®çææ¹æ³ |
| | | generateMockData() { |
| | | const mockData = [] |
| | | |
| | | // ä½¿ç¨æ¨æä¾ççå®å§åå表 |
| | | const patientNames = [ |
| | | 'æèè¬', '墿¨ä»²', 'ææç½', 'æ¹å
ç', 'åç¿æ ', '䏿±è»', 'å´ä½³ç', 'è绿ç®', |
| | | 'å¨ç½è·', 'å¼ å§¿å¦¤', 'å¼ è¹ä¼¦', 'å¨ç¼ç', 'åªæ¡è³', 'éè´µå¦', 'æ¨ä½©è³', '黿æº', |
| | | 'é»çç«', 'é丽é', '许æºäº', 'å¼ åæ¶µ', 'æå°ç±', 'çæ©é¾', 'æ±æ¿å»·', 'éè¯æ¶µ', |
| | | 'éæ¿å©', 'å´ä¿ä¼¯', 'é®é¦¨å¦', 'ç¿æ ç ', 'å´æç¿°', 'æä½©ç²' |
| | | ] |
| | | |
| | | const specialReqs = [ |
| | | '叿å»çè½å®æä¸é¨æ£æ¥', |
| | | 'éè¦å¨æ«æ¶é´æ®µçæå¡', |
| | | '对è¯ç©æè¿æå²ï¼éç¹å«æ³¨æ', |
| | | 'è¡å¨ä¸ä¾¿ï¼éè¦ä¸é¨æå¡', |
| | | 'æ ç¹æ®è¦æ±', |
| | | 'éè¦è±è¯æå¡æ¯æ', |
| | | 'æé«è¡åç
å²ï¼ééç¹å
³æ³¨', |
| | | 'éè¦å®æè¡ç³çæµæå¡', |
| | | '叿æåºå®çå®¶åºå»ç', |
| | | 'éè¦å¿çç导æå¡' |
| | | ] |
| | | |
| | | const rejectReasons = [ |
| | | 'èµæä¸å®æ´ï¼è¯·è¡¥å
å¥åº·æ¡£æ¡', |
| | | 'ä¸ç¬¦åå½åç¾çº¦æ¡ä»¶', |
| | | 'éæ©çå»çæ¡£æå·²æ»¡', |
| | | 'æå¡å¥é¤ä¸ç
æ
ä¸å¹é
', |
| | | 'å¹´é¾ä¸ç¬¦åå¥é¤è¦æ±', |
| | | '请补å
宿´çç
å²èµæ' |
| | | ] |
| | | |
| | | // çæçº¦30æ¡æ°æ®ï¼ä¸å§åæ°éå¹é
ï¼ |
| | | for (let i = 0; i < patientNames.length; i++) { |
| | | const packageId = (i % 5) + 1 + '' |
| | | const reviewStatus = i % 3 // 0:å¾
å®¡æ ¸, 1:éè¿, 2:驳å |
| | | const applyDate = this.generateRandomDate('2024-10-01', '2024-12-08') |
| | | |
| | | // çææ´çå®ççµè¯å·ç |
| | | const phonePrefix = ['138', '139', '150', '151', '152', '186', '187', '188'] |
| | | const phone = `${phonePrefix[i % phonePrefix.length]}${this.padNumber(1000 + i * 37, 4)}${this.padNumber(i % 100, 2)}` |
| | | |
| | | // çæåççå¹´é¾ï¼0-80å²ï¼ |
| | | const age = i % 80 |
| | | const gender = i % 2 === 0 ? 'ç·' : '女' |
| | | |
| | | mockData.push({ |
| | | id: `A${2024000 + i}`, |
| | | patientName: patientNames[i], |
| | | gender: gender, |
| | | age: age, |
| | | phone: phone, |
| | | servicePackageId: packageId, |
| | | servicePackage: this.servicePackages[packageId].name, |
| | | services: this.getServicesByPackage(packageId), |
| | | contractPeriod: [1, 2][i % 2], |
| | | applyTime: `${applyDate} ${this.padNumber(8 + (i % 10), 2)}:${this.padNumber(i % 60, 2)}:${this.padNumber(i % 60, 2)}`, |
| | | expectDoctor: ['çå»ç', 'æå»ç', 'å¼ å»ç', 'åå»ç', 'éå»ç'][i % 5], |
| | | specialRequirements: specialReqs[i % specialReqs.length], |
| | | reviewStatus: reviewStatus, |
| | | reviewer: reviewStatus !== 0 ? ['管çå', 'ç³»ç»ç®¡çå', 'å®¡æ ¸ä¸å'][i % 3] : '', |
| | | reviewTime: reviewStatus !== 0 ? |
| | | `${this.addDays(applyDate, 1 + (i % 3))} 14:${this.padNumber(i % 60, 2)}:00` : '', |
| | | rejectReason: reviewStatus === 2 ? rejectReasons[i % rejectReasons.length] : '' |
| | | }) |
| | | } |
| | | |
| | | return mockData |
| | | }, |
| | | |
| | | // æ ¹æ®å¥é¤è·åæå¡å表 |
| | | getServicesByPackage(packageId) { |
| | | const servicesMap = { |
| | | '1': ['年度å¥åº·è¯ä¼°', 'å¨çº¿å¥åº·å¨è¯¢', 'å¥åº·æ¡£æ¡ç®¡ç', '宿å¥åº·æé'], |
| | | '2': ['ä¸å±å»çæå¡', 'ç¨è¯æå¯¼ç®¡ç', '宿éè®¿çæµ', '个æ§å康å¤è®¡å', 'ç´§æ¥å»çå¨è¯¢'], |
| | | '3': ['è·åé£é©è¯ä¼°', '康å¤è®ç»æå¯¼', 'ç¨è¯å®å
¨ç®¡ç', '宿ä¸é¨è®¿è§', 'ç´§æ¥èç³»æå¡', 'å¿çå¥åº·å
³æ'], |
| | | '4': ['åæå¥åº·ç®¡ç', '产ååº·å¤æå¯¼', 'æ°çå¿æ¤çå¨è¯¢', 'è¥å
»è³é£å»ºè®®', 'å¿çæ
ç»ªæ¯æ'], |
| | | '5': ['çé¿åè²çæµ', 'ç«èæ¥ç§ç®¡ç', '常è§ç
鲿²»', 'è¥å
»æå¯¼', 'æ©ææè²å¨è¯¢'] |
| | | } |
| | | return servicesMap[packageId] || [] |
| | | }, |
| | | |
| | | // è¾
婿¹æ³ï¼çæéæºæ¥æ |
| | | generateRandomDate(start, end) { |
| | | const startDate = new Date(start).getTime() |
| | | const endDate = new Date(end).getTime() |
| | | const randomTime = startDate + Math.random() * (endDate - startDate) |
| | | return new Date(randomTime).toISOString().split('T')[0] |
| | | }, |
| | | |
| | | // è¾
婿¹æ³ï¼æ·»å å¤©æ° |
| | | addDays(date, days) { |
| | | const result = new Date(date) |
| | | result.setDate(result.getDate() + days) |
| | | return result.toISOString().split('T')[0] |
| | | }, |
| | | |
| | | // è¾
婿¹æ³ï¼æ°åè¡¥é¶ |
| | | padNumber(num, length) { |
| | | return num.toString().padStart(length, '0') |
| | | }, |
| | | |
| | | // è·åå®¡æ ¸å表 [1](@ref) |
| | | async getList() { |
| | | this.loading = true |
| | | try { |
| | | await new Promise(resolve => setTimeout(resolve, 500)) |
| | | |
| | | const allData = this.generateMockData() |
| | | let filteredData = allData.filter(item => { |
| | | if (this.queryParams.patientName && |
| | | !item.patientName.includes(this.queryParams.patientName)) { |
| | | return false |
| | | } |
| | | if (this.queryParams.reviewStatus !== undefined && |
| | | item.reviewStatus !== parseInt(this.queryParams.reviewStatus)) { |
| | | return false |
| | | } |
| | | if (this.queryParams.applyDate && this.queryParams.applyDate.length === 2) { |
| | | const applyDate = item.applyTime.split(' ')[0] |
| | | if (applyDate < this.queryParams.applyDate[0] || |
| | | applyDate > this.queryParams.applyDate[1]) { |
| | | return false |
| | | } |
| | | } |
| | | return true |
| | | }) |
| | | |
| | | const start = (this.queryParams.pageNum - 1) * this.queryParams.pageSize |
| | | const end = start + this.queryParams.pageSize |
| | | this.reviewList = filteredData.slice(start, end) |
| | | this.total = filteredData.length |
| | | |
| | | this.calculateStats() |
| | | } catch (error) { |
| | | console.error('è·åå®¡æ ¸å表失败:', error) |
| | | this.$message.error('æ°æ®å 载失败') |
| | | } finally { |
| | | this.loading = false |
| | | } |
| | | }, |
| | | |
| | | // 计ç®ç»è®¡ä¿¡æ¯ |
| | | calculateStats() { |
| | | const allData = this.generateMockData() |
| | | this.stats.pending = allData.filter(item => item.reviewStatus === 0).length |
| | | this.stats.approved = allData.filter(item => item.reviewStatus === 1).length |
| | | this.stats.rejected = allData.filter(item => item.reviewStatus === 2).length |
| | | }, |
| | | |
| | | // è·åå®¡æ ¸ç¶æææ¬ [2](@ref) |
| | | getReviewStatusText(status) { |
| | | const statusMap = { 0: 'å¾
å®¡æ ¸', 1: 'å®¡æ ¸éè¿', 2: 'å®¡æ ¸é©³å' } |
| | | return statusMap[status] || 'æªç¥' |
| | | }, |
| | | |
| | | // è·åå®¡æ ¸ç¶æç±»å |
| | | getReviewStatusType(status) { |
| | | const typeMap = { 0: 'warning', 1: 'success', 2: 'danger' } |
| | | return typeMap[status] || 'info' |
| | | }, |
| | | |
| | | // è·åå¥é¤ç±»å |
| | | getPackageType(packageId) { |
| | | const typeMap = { '1': 'info', '2': 'success', '3': 'warning', '4': 'danger', '5': 'primary' } |
| | | return typeMap[packageId] || 'info' |
| | | }, |
| | | |
| | | // æç´¢æä½ [1](@ref) |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1 |
| | | this.getList() |
| | | }, |
| | | |
| | | // éç½®æç´¢ |
| | | resetQuery() { |
| | | this.queryParams = { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | patientName: undefined, |
| | | reviewStatus: undefined, |
| | | applyDate: undefined |
| | | } |
| | | this.handleQuery() |
| | | }, |
| | | |
| | | // å¤çå®¡æ ¸æä½ [2](@ref) |
| | | handleReview(row, status) { |
| | | this.currentRow = row |
| | | this.reviewForm = { |
| | | id: row.id, |
| | | reviewStatus: status, |
| | | rejectReason: undefined, |
| | | assignDoctor: undefined, |
| | | remark: undefined |
| | | } |
| | | this.reviewDialogVisible = true |
| | | |
| | | // æ¸
é¤è¡¨åéªè¯ |
| | | this.$nextTick(() => { |
| | | if (this.$refs.reviewFormRef) { |
| | | this.$refs.reviewFormRef.clearValidate() |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | // æäº¤å®¡æ ¸ [2,6](@ref) |
| | | async submitReview() { |
| | | try { |
| | | // 表åéªè¯ |
| | | if (this.reviewForm.reviewStatus === 2) { |
| | | if (!this.reviewForm.rejectReason) { |
| | | this.$message.error('请填å驳ååå ') |
| | | return |
| | | } |
| | | } |
| | | |
| | | if (!this.reviewForm.assignDoctor) { |
| | | this.$message.error('è¯·éæ©åé
å»ç') |
| | | return |
| | | } |
| | | |
| | | // 模æAPIè°ç¨ |
| | | await new Promise(resolve => setTimeout(resolve, 1000)) |
| | | |
| | | // æ´æ°å½åè¡çç¶æ |
| | | const currentIndex = this.reviewList.findIndex(item => item.id === this.currentRow.id) |
| | | if (currentIndex !== -1) { |
| | | this.reviewList[currentIndex].reviewStatus = this.reviewForm.reviewStatus |
| | | this.reviewList[currentIndex].reviewer = 'å½åç¨æ·' |
| | | this.reviewList[currentIndex].reviewTime = new Date().toLocaleString() |
| | | this.reviewList[currentIndex].rejectReason = this.reviewForm.rejectReason |
| | | |
| | | // å¦æå®¡æ ¸éè¿ï¼åé
å»ç |
| | | if (this.reviewForm.reviewStatus === 1) { |
| | | const doctor = this.availableDoctors.find(d => d.id === this.reviewForm.assignDoctor) |
| | | this.reviewList[currentIndex].expectDoctor = doctor ? doctor.name : this.reviewList[currentIndex].expectDoctor |
| | | } |
| | | } |
| | | |
| | | this.$message.success(this.reviewForm.reviewStatus === 1 ? 'å®¡æ ¸éè¿æå' : 'å®¡æ ¸é©³åæå') |
| | | this.reviewDialogVisible = false |
| | | this.calculateStats() // éæ°è®¡ç®ç»è®¡ä¿¡æ¯ |
| | | } catch (error) { |
| | | console.error('å®¡æ ¸æä½å¤±è´¥:', error) |
| | | this.$message.error('å®¡æ ¸æä½å¤±è´¥') |
| | | } |
| | | }, |
| | | |
| | | // æ¥ç详æ
|
| | | handleView(row) { |
| | | this.$message.info(`æ¥çæ£è
${row.patientName} çç³è¯·è¯¦æ
`) |
| | | // å®é
å¼åä¸è·³è½¬å°è¯¦æ
页 |
| | | // this.$router.push({ path: '/patient/contract/apply-detail', query: { id: row.id } }) |
| | | }, |
| | | |
| | | // æ¹éå®¡æ ¸éè¿ |
| | | handleBatchApprove() { |
| | | const pendingItems = this.reviewList.filter(item => item.reviewStatus === 0) |
| | | if (pendingItems.length === 0) { |
| | | this.$message.warning('没æå¾
å®¡æ ¸çç³è¯·') |
| | | return |
| | | } |
| | | |
| | | this.$confirm(`ç¡®å®è¦æ¹ééè¿ ${pendingItems.length} 个å¾
å®¡æ ¸ç³è¯·åï¼`, 'æ¹éå®¡æ ¸', { |
| | | type: 'warning' |
| | | }).then(async () => { |
| | | try { |
| | | this.loading = true |
| | | // æ¨¡ææ¹éå®¡æ ¸APIè°ç¨ |
| | | await new Promise(resolve => setTimeout(resolve, 2000)) |
| | | |
| | | // æ´æ°ææå¾
å®¡æ ¸é¡¹çç¶æ |
| | | pendingItems.forEach(item => { |
| | | item.reviewStatus = 1 |
| | | item.reviewer = 'å½åç¨æ·' |
| | | item.reviewTime = new Date().toLocaleString() |
| | | }) |
| | | |
| | | this.$message.success(`æ¹éå®¡æ ¸éè¿æåï¼å
±å¤ç ${pendingItems.length} 个ç³è¯·`) |
| | | this.calculateStats() |
| | | } catch (error) { |
| | | this.$message.error('æ¹éå®¡æ ¸å¤±è´¥') |
| | | } finally { |
| | | this.loading = false |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | // 导åºå®¡æ ¸æ°æ® |
| | | handleExport() { |
| | | const exportData = this.generateMockData() |
| | | // å®é
å¼åä¸è¿éåºè¯¥è°ç¨å¯¼åºAPI |
| | | console.log('å¯¼åºæ°æ®:', exportData) |
| | | this.$message.info('导åºåè½å¼åä¸ï¼æ°æ®å·²æå°å°æ§å¶å°') |
| | | } |
| | | }, |
| | | watch: { |
| | | // çå¬å®¡æ ¸ç¶æååï¼å¨æè®¾ç½®éªè¯è§å [6](@ref) |
| | | 'reviewForm.reviewStatus': function(newVal) { |
| | | this.$nextTick(() => { |
| | | if (this.$refs.reviewFormRef) { |
| | | this.$refs.reviewFormRef.clearValidate() |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | .contract-review-page { |
| | | padding: 20px; |
| | | background: #f5f7fa; |
| | | min-height: calc(100vh - 60px); |
| | | |
| | | .search-card { |
| | | margin-bottom: 20px; |
| | | |
| | | ::v-deep .el-form-item { |
| | | margin-bottom: 0; |
| | | } |
| | | } |
| | | |
| | | .stats-row { |
| | | margin-bottom: 20px; |
| | | |
| | | .stat-item { |
| | | text-align: center; |
| | | padding: 20px; |
| | | |
| | | .stat-number { |
| | | font-size: 32px; |
| | | font-weight: bold; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .stat-label { |
| | | font-size: 14px; |
| | | color: #666; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .patient-info { |
| | | .patient-name { |
| | | font-weight: 600; |
| | | margin-bottom: 4px; |
| | | color: #303133; |
| | | } |
| | | |
| | | .patient-detail { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | } |
| | | } |
| | | |
| | | // å®¡æ ¸ç¶ææ ·å¼ |
| | | .review-status { |
| | | padding: 4px 8px; |
| | | border-radius: 4px; |
| | | font-size: 12px; |
| | | font-weight: 500; |
| | | |
| | | &.status-pending { |
| | | background: #fdf6ec; |
| | | color: #e6a23c; |
| | | } |
| | | |
| | | &.status-approved { |
| | | background: #f0f9e8; |
| | | color: #67c23a; |
| | | } |
| | | |
| | | &.status-rejected { |
| | | background: #fef0f0; |
| | | color: #f56c6c; |
| | | } |
| | | } |
| | | |
| | | // ç¹æ®è¦æ±ææ¬æ ·å¼ |
| | | .special-requirements { |
| | | max-width: 200px; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | |
| | | &:hover { |
| | | white-space: normal; |
| | | overflow: visible; |
| | | background: white; |
| | | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |
| | | padding: 8px; |
| | | border-radius: 4px; |
| | | position: absolute; |
| | | z-index: 1000; |
| | | max-width: 300px; |
| | | } |
| | | } |
| | | |
| | | // è¡¨æ ¼æ ·å¼ |
| | | ::v-deep .el-table { |
| | | .el-table__header-wrapper { |
| | | th { |
| | | background-color: #f5f7fa; |
| | | color: #606266; |
| | | font-weight: 600; |
| | | } |
| | | } |
| | | |
| | | .el-table__body { |
| | | tr { |
| | | transition: all 0.3s ease; |
| | | |
| | | &:hover { |
| | | transform: translateY(-1px); |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | &.pending-row { |
| | | background: #fdf6ec !important; |
| | | |
| | | &:hover { |
| | | background: #faf2e6 !important; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // å®¡æ ¸å¯¹è¯æ¡æ ·å¼ |
| | | .review-dialog { |
| | | ::v-deep .el-dialog { |
| | | border-radius: 8px; |
| | | box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); |
| | | } |
| | | |
| | | .dialog-footer { |
| | | text-align: right; |
| | | margin-top: 20px; |
| | | } |
| | | } |
| | | |
| | | // æä½æé®æ ·å¼ |
| | | .action-buttons { |
| | | display: flex; |
| | | gap: 8px; |
| | | |
| | | .el-button { |
| | | padding: 7px 12px; |
| | | border-radius: 4px; |
| | | font-size: 12px; |
| | | |
| | | &.approve-btn { |
| | | background: #67c23a; |
| | | border-color: #67c23a; |
| | | color: white; |
| | | |
| | | &:hover { |
| | | background: #5daf34; |
| | | border-color: #5daf34; |
| | | } |
| | | } |
| | | |
| | | &.reject-btn { |
| | | background: #f56c6c; |
| | | border-color: #f56c6c; |
| | | color: white; |
| | | |
| | | &:hover { |
| | | background: #e65c5c; |
| | | border-color: #e65c5c; |
| | | } |
| | | } |
| | | |
| | | &.detail-btn { |
| | | color: #409eff; |
| | | border-color: #409eff; |
| | | |
| | | &:hover { |
| | | background: #ecf5ff; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // æ¹éæä½æ |
| | | .batch-actions { |
| | | background: #ecf5ff; |
| | | padding: 12px 20px; |
| | | margin-bottom: 16px; |
| | | border-radius: 4px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | |
| | | .batch-info { |
| | | color: #409eff; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | |
| | | // ç©ºç¶ææ ·å¼ |
| | | .empty-state { |
| | | text-align: center; |
| | | padding: 40px 20px; |
| | | color: #909399; |
| | | |
| | | .empty-icon { |
| | | font-size: 48px; |
| | | margin-bottom: 16px; |
| | | opacity: 0.5; |
| | | } |
| | | |
| | | .empty-text { |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | |
| | | // ååºå¼è®¾è®¡ |
| | | @media (max-width: 768px) { |
| | | padding: 10px; |
| | | |
| | | .stats-row { |
| | | .el-col { |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | |
| | | .action-buttons { |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .batch-actions { |
| | | flex-direction: column; |
| | | gap: 10px; |
| | | align-items: stretch; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="signed-patient-page"> |
| | | <!-- æç´¢çéåºå --> |
| | | <el-card class="search-card" shadow="never"> |
| | | <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="100px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="6"> |
| | | <el-form-item label="æ£è
å§å" prop="patientName"> |
| | | <el-input |
| | | v-model="queryParams.patientName" |
| | | placeholder="请è¾å
¥æ£è
å§å" |
| | | clearable |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="ç¾çº¦ç¶æ" prop="contractStatus"> |
| | | <el-select v-model="queryParams.contractStatus" placeholder="è¯·éæ©ç¶æ" clearable> |
| | | <el-option label="æ£å¸¸æå¡ä¸" value="1" /> |
| | | <el-option label="å³å°å°æ" value="2" /> |
| | | <el-option label="已尿" value="3" /> |
| | | <el-option label="å·²ç»æ¢" value="4" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="æå¡å¥é¤" prop="servicePackage"> |
| | | <el-select v-model="queryParams.servicePackage" placeholder="è¯·éæ©å¥é¤" clearable> |
| | | <el-option label="åºç¡å¥åº·ç®¡çå
" value="1" /> |
| | | <el-option label="æ
¢æ§ç
管çå
" value="2" /> |
| | | <el-option label="è年人å¥åº·å
" value="3" /> |
| | | <el-option label="å产å¦ä¿å¥å
" value="4" /> |
| | | <el-option label="å¿ç«¥ä¿å¥å
" value="5" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <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-col> |
| | | </el-row> |
| | | </el-form> |
| | | </el-card> |
| | | |
| | | <!-- ç»è®¡ä¿¡æ¯å¡ç --> |
| | | <el-row :gutter="20" class="stats-row"> |
| | | <el-col :span="6"> |
| | | <el-card class="stats-card" shadow="hover"> |
| | | <div class="stats-content"> |
| | | <div class="stats-number">{{ stats.total }}</div> |
| | | <div class="stats-label">æ»ç¾çº¦æ£è
</div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-card class="stats-card" shadow="hover"> |
| | | <div class="stats-content"> |
| | | <div class="stats-number" style="color: #67C23A;">{{ stats.active }}</div> |
| | | <div class="stats-label">æ£å¸¸æå¡ä¸</div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-card class="stats-card" shadow="hover"> |
| | | <div class="stats-content"> |
| | | <div class="stats-number" style="color: #E6A23C;">{{ stats.expiring }}</div> |
| | | <div class="stats-label">å³å°å°æ</div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-card class="stats-card" shadow="hover"> |
| | | <div class="stats-content"> |
| | | <div class="stats-number" style="color: #F56C6C;">{{ stats.expired }}</div> |
| | | <div class="stats-label">已尿/ç»æ¢</div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <!-- æ°æ®è¡¨æ ¼ --> |
| | | <el-card shadow="never"> |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="patientList" |
| | | @selection-change="handleSelectionChange" |
| | | style="width: 100%" |
| | | :default-sort="{prop: 'signDate', order: 'descending'}" |
| | | > |
| | | <el-table-column type="selection" width="55" /> |
| | | <el-table-column label="æ£è
ä¿¡æ¯" min-width="180" fixed> |
| | | <template slot-scope="scope"> |
| | | <div class="patient-info"> |
| | | <div class="patient-name">{{ scope.row.patientName }}</div> |
| | | <div class="patient-detail"> |
| | | {{ scope.row.gender }} | {{ scope.row.age }}å² | {{ scope.row.phone }} |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="身份è¯å·" prop="idCard" width="180" /> |
| | | <el-table-column label="ç¾çº¦å»ç" prop="doctorName" width="120" /> |
| | | <el-table-column label="æå¡å¥é¤" min-width="150"> |
| | | <template slot-scope="scope"> |
| | | <el-tag :type="getPackageType(scope.row.servicePackageId)"> |
| | | {{ scope.row.servicePackage }} |
| | | </el-tag> |
| | | <div style="font-size: 12px; color: #666; margin-top: 4px;"> |
| | | 卿: {{ scope.row.contractPeriod }}年 |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å
嫿å¡" min-width="200"> |
| | | <template slot-scope="scope"> |
| | | <el-tooltip effect="dark" :content="scope.row.services.join('ã')" placement="top"> |
| | | <span>{{ scope.row.services.slice(0, 2).join('ã') }}ç{{ scope.row.services.length }}项</span> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¾çº¦æ¶é´" prop="signDate" width="120" sortable /> |
| | | <el-table-column label="å°ææ¶é´" prop="expireDate" width="120" /> |
| | | <el-table-column label="å©ä½å¤©æ°" width="100"> |
| | | <template slot-scope="scope"> |
| | | <span :class="getRemainingDaysClass(scope.row.remainingDays)"> |
| | | {{ scope.row.remainingDays }}天 |
| | | </span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¾çº¦ç¶æ" width="100" fixed="right"> |
| | | <template slot-scope="scope"> |
| | | <el-tag :type="getStatusType(scope.row.contractStatus)" effect="dark"> |
| | | {{ getStatusText(scope.row.contractStatus) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="200" fixed="right"> |
| | | <template slot-scope="scope"> |
| | | <el-button size="mini" type="text" @click="handleView(scope.row)">详æ
</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | @click="handleRenew(scope.row)" |
| | | :disabled="scope.row.contractStatus === 1" |
| | | >ç»çº¦</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | @click="handleTerminate(scope.row)" |
| | | :disabled="scope.row.contractStatus === 4" |
| | | style="color: #F56C6C;" |
| | | >ç»æ¢</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" |
| | | /> |
| | | </el-card> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'SignedPatientList', |
| | | data() { |
| | | return { |
| | | loading: false, |
| | | ids: [], |
| | | stats: { |
| | | total: 0, |
| | | active: 0, |
| | | expiring: 0, |
| | | expired: 0 |
| | | }, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | patientName: undefined, |
| | | contractStatus: undefined, |
| | | servicePackage: undefined |
| | | }, |
| | | total: 0, |
| | | patientList: [], |
| | | // æå¡å¥é¤é
ç½® |
| | | servicePackages: { |
| | | '1': { |
| | | name: 'åºç¡å¥åº·ç®¡çå
', |
| | | services: ['年度å¥åº·è¯ä¼°', 'å¨çº¿å¥åº·å¨è¯¢', 'å¥åº·æ¡£æ¡ç®¡ç', '宿å¥åº·æé'], |
| | | price: 0, |
| | | color: 'info' |
| | | }, |
| | | '2': { |
| | | name: 'æ
¢æ§ç
管çå
', |
| | | services: ['ä¸å±å»çæå¡', 'ç¨è¯æå¯¼ç®¡ç', '宿éè®¿çæµ', '个æ§å康å¤è®¡å', 'ç´§æ¥å»çå¨è¯¢'], |
| | | price: 299, |
| | | color: 'success' |
| | | }, |
| | | '3': { |
| | | name: 'è年人å¥åº·å
', |
| | | services: ['è·åé£é©è¯ä¼°', '康å¤è®ç»æå¯¼', 'ç¨è¯å®å
¨ç®¡ç', '宿ä¸é¨è®¿è§', 'ç´§æ¥èç³»æå¡', 'å¿çå¥åº·å
³æ'], |
| | | price: 499, |
| | | color: 'warning' |
| | | }, |
| | | '4': { |
| | | name: 'å产å¦ä¿å¥å
', |
| | | services: ['åæå¥åº·ç®¡ç', '产ååº·å¤æå¯¼', 'æ°çå¿æ¤çå¨è¯¢', 'è¥å
»è³é£å»ºè®®', 'å¿çæ
ç»ªæ¯æ'], |
| | | price: 399, |
| | | color: 'danger' |
| | | }, |
| | | '5': { |
| | | name: 'å¿ç«¥ä¿å¥å
', |
| | | services: ['çé¿åè²çæµ', 'ç«èæ¥ç§ç®¡ç', '常è§ç
鲿²»', 'è¥å
»æå¯¼', 'æ©ææè²å¨è¯¢'], |
| | | price: 199, |
| | | color: 'primary' |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.getList() |
| | | this.calculateStats() |
| | | }, |
| | | methods: { |
| | | // çææ´çå®çæ¨¡ææ°æ® |
| | | // ç²¾ç®åçæ¨¡ææ°æ®çææ¹æ³ |
| | | // ä¼ååçæ¨¡ææ°æ®çææ¹æ³ |
| | | generateMockData() { |
| | | const mockData = [] |
| | | |
| | | // ä½¿ç¨æ¨æä¾ççå®å§åå表 |
| | | const patientNames = [ |
| | | 'æèè¬', '墿¨ä»²', 'ææç½', 'æ¹å
ç', 'åç¿æ ', '䏿±è»', 'å´ä½³ç', 'è绿ç®', |
| | | 'å¨ç½è·', 'å¼ å§¿å¦¤', 'å¼ è¹ä¼¦', 'å¨ç¼ç', 'åªæ¡è³', 'éè´µå¦', 'æ¨ä½©è³', '黿æº', |
| | | 'é»çç«', 'é丽é', '许æºäº', 'å¼ åæ¶µ', 'æå°ç±', 'çæ©é¾', 'æ±æ¿å»·', 'éè¯æ¶µ', |
| | | 'éæ¿å©', 'å´ä¿ä¼¯', 'é®é¦¨å¦', 'ç¿æ ç ', 'å´æç¿°', 'æä½©ç²' |
| | | ] |
| | | |
| | | const doctors = ['çå»ç', 'æå»ç', 'å¼ å»ç', 'åå»ç', 'éå»ç'] |
| | | const cities = ['å京å¸', '䏿µ·å¸', '广å·å¸', 'æ·±å³å¸', 'æå·å¸', 'å京å¸', 'æé½å¸'] |
| | | const areas = ['æé³åº', 'æµ·æ·åº', 'æµ¦ä¸æ°åº', '黿µ¦åº', '天河åº', 'ç¦ç°åº', '西æ¹åº'] |
| | | |
| | | // çæçº¦20æ¡æ°æ® |
| | | for (let i = 0; i < patientNames.length; i++) { |
| | | const packageId = (i % 5) + 1 + '' |
| | | const packageInfo = this.servicePackages[packageId] |
| | | |
| | | // çææ´åççç¾çº¦æ¶é´ï¼è¿å»1å¹´å
ï¼ |
| | | const signDate = this.generateRandomDate('2023-12-01', '2024-11-30') |
| | | const contractPeriod = [1, 2][i % 2] // 1å¹´æ2å¹´åå |
| | | const expireDate = this.addYears(signDate, contractPeriod) |
| | | const remainingDays = this.calculateRemainingDays(expireDate) |
| | | const contractStatus = this.getContractStatus(expireDate, remainingDays) |
| | | |
| | | // çææ´çå®ççµè¯å·ç å身份è¯å· |
| | | const phonePrefix = ['138', '139', '150', '151', '152', '186', '187', '188'] |
| | | const phone = `${phonePrefix[i % phonePrefix.length]}${this.padNumber(1000 + i * 37, 4)}${this.padNumber(i % 100, 2)}` |
| | | |
| | | // çæåççå¹´é¾ï¼20-80å²ï¼ |
| | | const age = 20 + (i % 60) |
| | | const birthYear = new Date().getFullYear() - age |
| | | const idCard = `11010${birthYear}${this.padNumber(1 + (i % 12), 2)}${this.padNumber(1 + (i % 28), 2)}${this.padNumber(i % 1000, 3)}X` |
| | | |
| | | mockData.push({ |
| | | id: `P${2024000 + i}`, |
| | | patientName: patientNames[i], |
| | | gender: i % 2 === 0 ? 'ç·' : '女', |
| | | age: age, |
| | | phone: phone, |
| | | idCard: idCard, |
| | | doctorName: doctors[i % doctors.length], |
| | | servicePackageId: packageId, |
| | | servicePackage: packageInfo.name, |
| | | services: packageInfo.services, |
| | | contractPeriod: contractPeriod, |
| | | signDate: signDate, |
| | | expireDate: expireDate, |
| | | remainingDays: remainingDays, |
| | | contractStatus: contractStatus, |
| | | address: `${cities[i % cities.length]}${areas[i % areas.length]}${this.generateStreet(i)}` // æ°å¢å°ååæ®µ |
| | | }) |
| | | } |
| | | |
| | | return mockData |
| | | }, |
| | | |
| | | // æ°å¢è¾
婿¹æ³ï¼çæè¡éå°å |
| | | generateStreet(index) { |
| | | const streets = [ |
| | | 'ä¸å±±è·¯123å·', '人æ°è·¯456å·', 'è§£æ¾è·¯789å·', '建设路101å·', 'å平路202å·', |
| | | 'æ°åè·¯303å·', 'å
æè·¯404å·', '幸ç¦è·¯505å·', 'å¢ç»è·¯606å·', 'ææè·¯707å·' |
| | | ] |
| | | return streets[index % streets.length] |
| | | }, |
| | | |
| | | // è¾
婿¹æ³ |
| | | generateRandomDate(start, end) { |
| | | const startDate = new Date(start).getTime() |
| | | const endDate = new Date(end).getTime() |
| | | const randomTime = startDate + Math.random() * (endDate - startDate) |
| | | return new Date(randomTime).toISOString().split('T')[0] |
| | | }, |
| | | |
| | | addYears(date, years) { |
| | | const result = new Date(date) |
| | | result.setFullYear(result.getFullYear() + years) |
| | | return result.toISOString().split('T')[0] |
| | | }, |
| | | |
| | | calculateRemainingDays(expireDate) { |
| | | const today = new Date() |
| | | const expire = new Date(expireDate) |
| | | const diffTime = expire - today |
| | | return Math.ceil(diffTime / (1000 * 60 * 60 * 24)) |
| | | }, |
| | | |
| | | getContractStatus(expireDate, remainingDays) { |
| | | if (remainingDays < 0) return 3 // 已尿 |
| | | if (remainingDays <= 30) return 2 // å³å°å°æ |
| | | return 1 // æ£å¸¸æå¡ä¸ |
| | | }, |
| | | |
| | | padNumber(num, length) { |
| | | return num.toString().padStart(length, '0') |
| | | }, |
| | | |
| | | // è·åæ£è
å表 |
| | | async getList() { |
| | | this.loading = true |
| | | try { |
| | | // 模æAPIè°ç¨å»¶è¿ |
| | | await new Promise(resolve => setTimeout(resolve, 500)) |
| | | |
| | | const allData = this.generateMockData() |
| | | // ç®åçæ¬å°çé |
| | | let filteredData = allData.filter(item => { |
| | | if (this.queryParams.patientName && |
| | | !item.patientName.includes(this.queryParams.patientName)) { |
| | | return false |
| | | } |
| | | if (this.queryParams.contractStatus && |
| | | item.contractStatus !== parseInt(this.queryParams.contractStatus)) { |
| | | return false |
| | | } |
| | | if (this.queryParams.servicePackage && |
| | | item.servicePackageId !== this.queryParams.servicePackage) { |
| | | return false |
| | | } |
| | | return true |
| | | }) |
| | | |
| | | // å页å¤ç |
| | | const start = (this.queryParams.pageNum - 1) * this.queryParams.pageSize |
| | | const end = start + this.queryParams.pageSize |
| | | this.patientList = filteredData.slice(start, end) |
| | | this.total = filteredData.length |
| | | |
| | | this.calculateStats() |
| | | } catch (error) { |
| | | console.error('è·åæ°æ®å¤±è´¥:', error) |
| | | this.$message.error('æ°æ®å 载失败') |
| | | } finally { |
| | | this.loading = false |
| | | } |
| | | }, |
| | | |
| | | // 计ç®ç»è®¡ä¿¡æ¯ |
| | | calculateStats() { |
| | | const allData = this.generateMockData() |
| | | this.stats.total = allData.length |
| | | this.stats.active = allData.filter(item => item.contractStatus === 1).length |
| | | this.stats.expiring = allData.filter(item => item.contractStatus === 2).length |
| | | this.stats.expired = allData.filter(item => item.contractStatus === 3).length |
| | | }, |
| | | |
| | | // ç¶æç¸å
³æ¹æ³ |
| | | getStatusText(status) { |
| | | const statusMap = { 1: 'æ£å¸¸æå¡ä¸', 2: 'å³å°å°æ', 3: '已尿', 4: 'å·²ç»æ¢' } |
| | | return statusMap[status] || 'æªç¥' |
| | | }, |
| | | |
| | | getStatusType(status) { |
| | | const typeMap = { 1: 'success', 2: 'warning', 3: 'danger', 4: 'info' } |
| | | return typeMap[status] || 'info' |
| | | }, |
| | | |
| | | getPackageType(packageId) { |
| | | const typeMap = { '1': 'info', '2': 'success', '3': 'warning', '4': 'danger', '5': 'primary' } |
| | | return typeMap[packageId] || 'info' |
| | | }, |
| | | |
| | | getRemainingDaysClass(days) { |
| | | if (days < 0) return 'expired' |
| | | if (days <= 30) return 'expiring' |
| | | return 'normal' |
| | | }, |
| | | |
| | | // æä½æ¹æ³ |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1 |
| | | this.getList() |
| | | }, |
| | | |
| | | resetQuery() { |
| | | this.queryParams = { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | patientName: undefined, |
| | | contractStatus: undefined, |
| | | servicePackage: undefined |
| | | } |
| | | this.handleQuery() |
| | | }, |
| | | |
| | | handleSelectionChange(selection) { |
| | | this.ids = selection.map(item => item.id) |
| | | }, |
| | | |
| | | handleView(row) { |
| | | this.$message.info(`æ¥çæ£è
${row.patientName} ç详æ
`) |
| | | // å®é
å¼åä¸è·³è½¬å°è¯¦æ
页 |
| | | // this.$router.push({ path: '/patient/contract/detail', query: { id: row.id } }) |
| | | }, |
| | | |
| | | handleRenew(row) { |
| | | this.$confirm(`ç¡®å®è¦ä¸ºæ£è
${row.patientName} åçç»çº¦åï¼`, 'æç¤º', { |
| | | type: 'warning' |
| | | }).then(() => { |
| | | this.$message.success('ç»çº¦æä½æå') |
| | | }) |
| | | }, |
| | | |
| | | handleTerminate(row) { |
| | | this.$confirm(`ç¡®å®è¦ç»æ¢ä¸ ${row.patientName} çç¾çº¦å
³ç³»åï¼æ¤æä½ä¸å¯æ¤éã`, 'è¦å', { |
| | | type: 'error', |
| | | confirmButtonText: 'ç¡®å®ç»æ¢', |
| | | cancelButtonText: 'åæ¶' |
| | | }).then(() => { |
| | | this.$message.success('ç¾çº¦å
³ç³»å·²ç»æ¢') |
| | | this.getList() |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .signed-patient-page { |
| | | padding: 20px; |
| | | |
| | | .search-card { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .stats-row { |
| | | margin-bottom: 20px; |
| | | |
| | | .stats-card { |
| | | .stats-content { |
| | | text-align: center; |
| | | padding: 10px; |
| | | |
| | | .stats-number { |
| | | font-size: 28px; |
| | | font-weight: bold; |
| | | color: #409EFF; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .stats-label { |
| | | font-size: 14px; |
| | | color: #666; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .patient-info { |
| | | .patient-name { |
| | | font-weight: 600; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .patient-detail { |
| | | font-size: 12px; |
| | | color: #666; |
| | | } |
| | | } |
| | | |
| | | .expired { |
| | | color: #F56C6C; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .expiring { |
| | | color: #E6A23C; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .normal { |
| | | color: #67C23A; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <!-- <el-form-item label="æ£è
èå´" prop="tagId"> |
| | | <el-form-item label="æ£è
æ§å«" prop="tagId"> |
| | | <el-select |
| | | v-model="queryParams.searchscope" |
| | | placeholder="è¯·éæ©æ£è
èå´" |
| | | v-model="queryParams.sex" |
| | | placeholder="è¯·éæ©æ£è
æ§å«" |
| | | > |
| | | <el-option |
| | | v-for="item in source" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | > |
| | | </el-option> |
| | | <el-option label="ç·" :value="1"> </el-option> |
| | | <el-option label="女" :value="2"> </el-option> |
| | | </el-select> |
| | | </el-form-item> --> |
| | | </el-form-item> |
| | | <el-form-item label="æ£è
å¹´é¾" prop="telcode"> |
| | | <el-input |
| | | v-model="queryParams.age" |
| | | placeholder="请è¾å
¥æ¥è¯¢å¹´é¾" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="èç³»çµè¯" prop="telcode"> |
| | | <el-input |
| | | v-model="queryParams.telcode" |
| | |
| | | ><i class="el-icon-edit"></i>æ£è
è¿æ»¤</span |
| | | ></el-button |
| | | > |
| | | <!-- <el-button |
| | | <el-button |
| | | size="medium" |
| | | type="text" |
| | | @click="Distributionservice(scope.row)" |
| | | @click="openContractDialog(scope.row)" |
| | | ><span class="button-textxg" |
| | | ><i class="el-icon-menu"></i>æå¡</span |
| | | ><i class="el-icon-menu"></i>æ£è
ç¾çº¦</span |
| | | ></el-button |
| | | > --> |
| | | > |
| | | <!-- <el-button |
| | | size="medium" |
| | | type="text" |
| | |
| | | </div> |
| | | </el-dialog> |
| | | <!-- 跳转æå¡å¯¹è¯æ¡ --> |
| | | <el-dialog title="éæ©æå¡ç±»å" :visible.sync="serviceVisible"> |
| | | <el-card class="box-card"> |
| | | <el-radio-group v-model="serviceradio"> |
| | | <el-radio :label="1">宣æé访</el-radio> |
| | | <el-radio :label="2">é¨è¯æå¡</el-radio> |
| | | <el-radio :label="3">åºé¢æå¡</el-radio> |
| | | <el-radio :label="4">å¤è¯æå¡</el-radio> |
| | | <el-radio :label="5">使£éç¥</el-radio> |
| | | <el-radio :label="6">é®å·æå¡</el-radio> |
| | | <!-- ç®åçæ£è
ç¾çº¦å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | title="æ£è
ç¾çº¦æå¡" |
| | | :visible.sync="contractDialogVisible" |
| | | width="600px" |
| | | > |
| | | <!-- æ¥éª¤æç¤ºå¨ --> |
| | | <el-steps |
| | | :active="contractStep" |
| | | align-center |
| | | simple |
| | | style="margin-bottom: 20px" |
| | | > |
| | | <el-step title="éæ©æå¡" icon="el-icon-document"></el-step> |
| | | <el-step title="确认ç¾çº¦" icon="el-icon-finished"></el-step> |
| | | </el-steps> |
| | | |
| | | <!-- æ¥éª¤1: æå¡éæ© --> |
| | | <div v-if="contractStep === 1" class="step-content"> |
| | | <h4>请为 {{ currentPatient.name }} éæ©ç¾çº¦æå¡å¥é¤ï¼</h4> |
| | | |
| | | <el-radio-group |
| | | v-model="tempContractData.servicePackage" |
| | | style="width: 100%" |
| | | > |
| | | <el-row :gutter="16"> |
| | | <el-col :span="8" v-for="pkg in servicePackages" :key="pkg.id"> |
| | | <el-card |
| | | :class="[ |
| | | 'package-card', |
| | | { active: tempContractData.servicePackage === pkg.id }, |
| | | ]" |
| | | @click.native="tempContractData.servicePackage = pkg.id" |
| | | shadow="hover" |
| | | style="margin-bottom: 16px; cursor: pointer" |
| | | > |
| | | <div style="text-align: center"> |
| | | <h4>{{ pkg.name }}</h4> |
| | | <p style="color: #666; font-size: 12px; margin: 8px 0"> |
| | | {{ pkg.description }} |
| | | </p> |
| | | <p style="color: #e6a23c; font-weight: bold"> |
| | | {{ pkg.price > 0 ? `Â¥${pkg.price}/å¹´` : "å
è´¹" }} |
| | | </p> |
| | | <el-tag |
| | | v-for="feature in pkg.features" |
| | | :key="feature" |
| | | size="mini" |
| | | style="margin: 2px" |
| | | type="info" |
| | | >{{ feature }}</el-tag |
| | | > |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | </el-radio-group> |
| | | </el-card> |
| | | |
| | | <el-form label-width="80px" style="margin-top: 20px"> |
| | | <el-form-item label="ç¾çº¦å¨æ"> |
| | | <el-select |
| | | v-model="tempContractData.contractPeriod" |
| | | placeholder="è¯·éæ©" |
| | | > |
| | | <el-option label="1å¹´" :value="1"></el-option> |
| | | <el-option label="2å¹´" :value="2"></el-option> |
| | | <el-option label="3å¹´" :value="3"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨ä¿¡æ¯"> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="2" |
| | | v-model="tempContractData.remark" |
| | | placeholder="å¯å¡«åç¹æ®å¥åº·éæ±æå¤æ³¨ä¿¡æ¯" |
| | | ></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | |
| | | <!-- æ¥éª¤2: ç¾çº¦ç¡®è®¤ --> |
| | | <div v-if="contractStep === 2" class="step-content"> |
| | | <el-card> |
| | | <h4>ç¾çº¦ä¿¡æ¯ç¡®è®¤</h4> |
| | | <el-descriptions :column="1" border> |
| | | <el-descriptions-item label="æ£è
å§å">{{ |
| | | currentPatient.name |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="æ£è
ç¼å·">{{ |
| | | currentPatient.patientno |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="æå¡å¥é¤"> |
| | | {{ getSelectedPackage().name }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="ç¾çº¦å¨æ" |
| | | >{{ tempContractData.contractPeriod }}å¹´</el-descriptions-item |
| | | > |
| | | <el-descriptions-item label="ç¾çº¦æ¥æ">{{ |
| | | new Date().toLocaleDateString() |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="夿³¨ä¿¡æ¯">{{ |
| | | tempContractData.remark || "æ " |
| | | }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | </el-card> |
| | | </div> |
| | | |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="serviceVisible = false">å æ¶</el-button> |
| | | <el-button type="primary" @click="CreateService">å建æå¡</el-button> |
| | | <el-button @click="prevStep" v-if="contractStep > 1">ä¸ä¸æ¥</el-button> |
| | | <el-button @click="closeContractDialog">åæ¶</el-button> |
| | | <el-button |
| | | type="primary" |
| | | @click="nextStep" |
| | | :disabled="contractStep === 1 && !tempContractData.servicePackage" |
| | | > |
| | | {{ contractStep === 2 ? "确认ç¾çº¦" : "ä¸ä¸æ¥" }} |
| | | </el-button> |
| | | </div> |
| | | </el-dialog> |
| | | <!-- é£é©ç±»å --> |
| | |
| | | serviceradio: 1, |
| | | distributeVisible: false, |
| | | RiskVisible: false, |
| | | tasktopic: "5", //æ°å¢ç±»å |
| | | tasktopic: "2", //æ°å¢ç±»å |
| | | Riskradio: 1, |
| | | RiskObj: {}, |
| | | // æ¥è¯¢åæ° |
| | | topqueryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | type: 2, |
| | | userName: undefined, |
| | | tagid: undefined, |
| | | topic: undefined, |
| | | }, |
| | | // æ¥æèå´ |
| | | dateRange: [], |
| | | taskoptions: [], |
| | | contractDialogVisible: false, // æ§å¶ç¾çº¦å¯¹è¯æ¡æ¾ç¤º |
| | | contractStep: 1, // ç¾çº¦æ¥éª¤ï¼1-éæ©æå¡ 2-ç¡®è®¤ä¿¡æ¯ |
| | | currentPatient: {}, // å½åç¾çº¦çæ£è
ä¿¡æ¯ |
| | | tempContractData: { |
| | | // 临æ¶åå¨çç¾çº¦æ°æ® |
| | | servicePackage: null, // éä¸çæå¡å¥é¤ |
| | | contractPeriod: 1, // ç¾çº¦å¨æï¼å¹´ï¼ |
| | | remark: "", // 夿³¨ä¿¡æ¯ |
| | | }, |
| | | // æ¨¡ææ°æ®ï¼å¯éçç¾çº¦æå¡å¥é¤ |
| | | servicePackages: [ |
| | | { |
| | | id: 1, |
| | | name: "åºç¡å¥åº·ç®¡çå
", |
| | | description: "å
å«å®æå¥åº·è¯ä¼°ãåºæ¬å¨è¯¢", |
| | | price: 0, |
| | | features: ["年度å¥åº·è¯ä¼°", "å¨çº¿å¨è¯¢"], |
| | | }, |
| | | { |
| | | id: 2, |
| | | name: "æ
¢æ§ç
管çå
", |
| | | description: "ä¸ä¸ºæ
¢æ§ç
æ£è
设计", |
| | | price: 299, |
| | | features: ["ä¸å±å»ç", "ç¨è¯æé", "宿é访"], |
| | | }, |
| | | { |
| | | id: 3, |
| | | name: "è年人å¥åº·å
", |
| | | description: "å
³æ³¨è年人å¥åº·é®é¢", |
| | | price: 499, |
| | | features: ["è·åé£é©è¯ä¼°", "åº·å¤æå¯¼", "ç´§æ¥èç³»"], |
| | | }, |
| | | ], |
| | | taskoptions: [ |
| | | // { |
| | | // value: "1", |
| | | // label: "çæµè¯ä¼°", |
| | | // }, |
| | | { |
| | | value: "2", |
| | | label: "åºé¢é访", |
| | | }, |
| | | { |
| | | value: "3", |
| | | label: "é¨è¯é访", |
| | | }, |
| | | { |
| | | value: "4", |
| | | label: "宣æå
³æ", |
| | | }, |
| | | { |
| | | value: "5", |
| | | label: "å¤è¯ç®¡ç", |
| | | }, |
| | | // { |
| | | // value: "6", |
| | | // label: "满æåº¦è°æ¥", |
| | | // }, |
| | | { |
| | | value: "7", |
| | | label: "æ£è
æ¥å", |
| | | }, |
| | | { |
| | | value: "8", |
| | | label: "å
¶ä»éç¥", |
| | | }, |
| | | ], |
| | | paperstypes: [ |
| | | { papersname: "身份è¯" }, |
| | | { papersname: "æ¤ç
§" }, |
| | |
| | | queryParams: { |
| | | pageNum: 1, |
| | | allhosp: "0", |
| | | sex: 1, |
| | | pageSize: 10, |
| | | searchscope: 2, |
| | | notrequiredFlag: 0, |
| | |
| | | created() { |
| | | this.getList(); |
| | | this.gettabList(); |
| | | this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | | (obj) => obj.deptCode |
| | | ); |
| | | this.topqueryParams.leavehospitaldistrictcodes = |
| | | store.getters.belongWards.map((obj) => obj.districtCode); |
| | | //è·åå·²çéåçå¯éä»»å¡ç±»å |
| | | this.taskoptions = store.getters.Serviceauthority; |
| | | }, |
| | | methods: { |
| | | /** æ¥è¯¢æ£è
å表 */ |
| | |
| | | this.loading = false; |
| | | }); |
| | | }, |
| | | Distributionservice(row) { |
| | | this.serviceVisible = true; |
| | | openContractDialog(row) { |
| | | this.currentPatient = { ...row }; // 设置å½åæ£è
|
| | | this.contractDialogVisible = true; |
| | | this.contractStep = 1; |
| | | // éç½®è¡¨åæ°æ® |
| | | this.tempContractData = { |
| | | servicePackage: null, |
| | | contractPeriod: 1, |
| | | remark: "", |
| | | }; |
| | | }, |
| | | // ä¸ä¸æ¥æä½ |
| | | nextStep() { |
| | | if (this.contractStep < 2) { |
| | | this.contractStep++; |
| | | } else { |
| | | this.submitContract(); |
| | | } |
| | | }, |
| | | |
| | | // ä¸ä¸æ¥æä½ |
| | | prevStep() { |
| | | if (this.contractStep > 1) { |
| | | this.contractStep--; |
| | | } |
| | | }, |
| | | // è·åéä¸çæå¡å¥é¤ä¿¡æ¯ |
| | | getSelectedPackage() { |
| | | return ( |
| | | this.servicePackages.find( |
| | | (pkg) => pkg.id === this.tempContractData.servicePackage |
| | | ) || {} |
| | | ); |
| | | }, |
| | | |
| | | // 模ææäº¤ç¾çº¦ä¿¡æ¯ |
| | | submitContract() { |
| | | // è¿éæ¯å端模ææä½ï¼å®é
å¼åä¸åºéè¿APIæäº¤æ°æ® |
| | | const contractInfo = { |
| | | patientId: this.currentPatient.id, |
| | | patientName: this.currentPatient.name, |
| | | package: this.getSelectedPackage(), |
| | | period: this.tempContractData.contractPeriod, |
| | | signDate: new Date().toISOString().split("T")[0], |
| | | remark: this.tempContractData.remark, |
| | | }; |
| | | |
| | | console.log("模æç¾çº¦æ°æ®:", contractInfo); |
| | | |
| | | // 模ææåæç¤º |
| | | this.$message.success( |
| | | `å·²æå为 ${this.currentPatient.name} ç¾çº¦ ${ |
| | | this.getSelectedPackage().name |
| | | }` |
| | | ); |
| | | |
| | | // å
³éå¯¹è¯æ¡ |
| | | this.closeContractDialog(); |
| | | |
| | | // å¯ä»¥å¨è¿é触åå
¶ä»æä½ï¼å¦å·æ°æ£è
å表ç |
| | | }, |
| | | // å
³éå¯¹è¯æ¡å¹¶éç½®ç¶æ |
| | | closeContractDialog() { |
| | | this.contractDialogVisible = false; |
| | | this.contractStep = 1; |
| | | this.tempContractData = { |
| | | servicePackage: null, |
| | | contractPeriod: 1, |
| | | remark: "", |
| | | }; |
| | | }, |
| | | RiskMarker(row) { |
| | | this.RiskVisible = true; |
| | |
| | | pageSize: 10, |
| | | searchscope: 2, |
| | | }; |
| | | this.handleQuery(); |
| | | this.handleQuery(); |
| | | }, |
| | | // å¤éæ¡é䏿°æ® |
| | | handleSelectionChange(selection) { |
| | |
| | | }, |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | handleUpdate(row) { |
| | | const userIds = row.id || this.ids; |
| | | particularpatient(userIds).then((response) => { |
| | | this.form = response.data; |
| | | }); |
| | | this.amendtag = true; |
| | | this.Labelchange = true; |
| | | // const userIds = row.id || this.ids; |
| | | // particularpatient(userIds).then((response) => { |
| | | // this.form = response.data; |
| | | // }); |
| | | // this.amendtag = true; |
| | | // this.Labelchange = true; |
| | | }, |
| | | //ä¿®æ¹/æ°å¢æ£è
|
| | | submitForm() { |
| | |
| | | }, |
| | | distribute() { |
| | | this.distributeVisible = true; |
| | | if (this.tasktopic == 1) { |
| | | this.topqueryParams.type = 3; |
| | | } else if (this.tasktopic == 2) { |
| | | this.topqueryParams.type = 1; |
| | | } else if (this.tasktopic == 3) { |
| | | this.topqueryParams.type = 1; |
| | | } else if (this.tasktopic == 4) { |
| | | this.topqueryParams.type = 1; |
| | | if ( |
| | | this.tasktopic == 2 || |
| | | this.tasktopic == 3 || |
| | | this.tasktopic == 1 || |
| | | this.tasktopic == 7 || |
| | | this.tasktopic == 6 |
| | | ) { |
| | | this.topqueryParams.type = "2"; |
| | | } else if (this.tasktopic == 4 || this.tasktopic == 8) { |
| | | this.topqueryParams.type = "3"; |
| | | } else if (this.tasktopic == 5) { |
| | | this.topqueryParams.type = 1; |
| | | } else if (this.tasktopic == 6) { |
| | | this.topqueryParams.type = 2; |
| | | this.topqueryParams.type = "1"; |
| | | } |
| | | this.topqueryParams.typename = this.findLabelByValue( |
| | | this.taskoptions, |
| | | this.tasktopic |
| | | ); |
| | | this.topqueryParams.serviceType = Number(this.tasktopic); |
| | | getTasklist(this.topqueryParams).then((response) => { |
| | | this.taskuserList = response.rows; |
| | | this.tasktotal = response.total; |
| | |
| | | display: center !important; |
| | | } |
| | | } |
| | | .package-card.active { |
| | | border-color: #409EFF; |
| | | background-color: #f0f9ff; |
| | | } |
| | | |
| | | .step-content { |
| | | min-height: 300px; |
| | | } |
| | | |
| | | .dialog-footer { |
| | | text-align: right; |
| | | } |
| | | .preview-left { |
| | | margin: 20px; |
| | | // margin: 20px; |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <!-- çæ¥æè¦æ¨¡å --> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <div class="screening-summary"> |
| | | <div class="summary-header"> |
| | | <i class="el-icon-search"></i> |
| | | <span>çæ¥æè¦</span> |
| | | <div |
| | | style=" |
| | | margin-left: auto; |
| | | display: flex; |
| | | align-items: center; |
| | | " |
| | | > |
| | | <el-button |
| | | type="primary" |
| | | size="mini" |
| | | @click="addScreening" |
| | | > |
| | | <i class="el-icon-plus"></i> æ°å¢ |
| | | </el-button> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="refreshScreeningData" |
| | | style="margin-left: 10px" |
| | | > |
| | | <i class="el-icon-refresh"></i> å·æ° |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | <div class="summary-content"> |
| | | <el-table |
| | | :data="screeningSummaryData" |
| | | border |
| | | size="mini" |
| | | height="200" |
| | | v-loading="screeningLoading" |
| | | > |
| | | <el-table-column |
| | | prop="screeningType" |
| | | label="çæ¥ç±»å" |
| | | width="100" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-tag |
| | | :type="getScreeningTagType(scope.row.screeningType)" |
| | | > |
| | | {{ scope.row.screeningType }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | prop="screeningDate" |
| | | label="çæ¥æ¥æ" |
| | | width="100" |
| | | > |
| | | <template slot-scope="scope"> |
| | | {{ formatTime(scope.row.screeningDate) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="result" label="ç»æ" width="80"> |
| | | <template slot-scope="scope"> |
| | | <el-tag |
| | | :type=" |
| | | scope.row.result === 'æ£å¸¸' |
| | | ? 'success' |
| | | : scope.row.result === 'å¼å¸¸' |
| | | ? 'danger' |
| | | : 'warning' |
| | | " |
| | | size="small" |
| | | > |
| | | {{ scope.row.result }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | prop="details" |
| | | label="详ç»ç»æ" |
| | | min-width="120" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-tooltip |
| | | :content="scope.row.details" |
| | | placement="top" |
| | | v-if=" |
| | | scope.row.details && scope.row.details.length > 10 |
| | | " |
| | | > |
| | | <span |
| | | >{{ scope.row.details.substring(0, 10) }}...</span |
| | | > |
| | | </el-tooltip> |
| | | <span v-else>{{ scope.row.details }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="150" fixed="right"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | type="primary" |
| | | size="mini" |
| | | @click="editScreening(scope.$index, scope.row)" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | size="mini" |
| | | @click="deleteScreening(scope.$index, scope.row)" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <div class="summary-stats"> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="8"> |
| | | <div class="stat-item"> |
| | | <div class="stat-value" style="color: #67c23a"> |
| | | {{ screeningStats.normal }} |
| | | </div> |
| | | <div class="stat-label">æ£å¸¸</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <div class="stat-item"> |
| | | <div class="stat-value" style="color: #e6a23c"> |
| | | {{ screeningStats.abnormal }} |
| | | </div> |
| | | <div class="stat-label">å¼å¸¸</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <div class="stat-item"> |
| | | <div class="stat-value" style="color: #f56c6c"> |
| | | {{ screeningStats.critical }} |
| | | </div> |
| | | <div class="stat-label">屿¥</div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | |
| | | <!-- æ
¢ç
æè¦æ¨¡å --> |
| | | <el-col :span="12"> |
| | | <div class="chronic-disease-summary"> |
| | | <div class="summary-header"> |
| | | <i class="el-icon-document"></i> |
| | | <span>æ
¢ç
æè¦</span> |
| | | <div |
| | | style=" |
| | | margin-left: auto; |
| | | display: flex; |
| | | align-items: center; |
| | | " |
| | | > |
| | | <el-button |
| | | type="primary" |
| | | size="mini" |
| | | @click="addChronicDisease" |
| | | > |
| | | <i class="el-icon-plus"></i> æ°å¢ |
| | | </el-button> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="refreshChronicData" |
| | | style="margin-left: 10px" |
| | | > |
| | | <i class="el-icon-refresh"></i> å·æ° |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | <div class="summary-content"> |
| | | <el-table |
| | | :data="chronicDiseaseData" |
| | | border |
| | | size="mini" |
| | | height="200" |
| | | v-loading="chronicLoading" |
| | | > |
| | | <el-table-column |
| | | prop="diseaseName" |
| | | label="ç¾ç
åç§°" |
| | | width="120" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-tag |
| | | :type="getDiseaseTagType(scope.row.diseaseName)" |
| | | > |
| | | {{ scope.row.diseaseName }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | prop="diagnoseDate" |
| | | label="ç¡®è¯æ¥æ" |
| | | width="100" |
| | | > |
| | | <template slot-scope="scope"> |
| | | {{ formatTime(scope.row.diagnoseDate) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="status" label="ç¶æ" width="80"> |
| | | <template slot-scope="scope"> |
| | | <el-tag |
| | | :type=" |
| | | scope.row.status === '稳å®' |
| | | ? 'success' |
| | | : scope.row.status === 'æ´»å¨æ' |
| | | ? 'warning' |
| | | : 'danger' |
| | | " |
| | | size="small" |
| | | > |
| | | {{ scope.row.status }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | prop="currentTreatment" |
| | | label="å½åæ²»ç" |
| | | min-width="120" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-tooltip |
| | | :content="scope.row.currentTreatment" |
| | | placement="top" |
| | | v-if=" |
| | | scope.row.currentTreatment && |
| | | scope.row.currentTreatment.length > 10 |
| | | " |
| | | > |
| | | <span |
| | | >{{ |
| | | scope.row.currentTreatment.substring(0, 10) |
| | | }}...</span |
| | | > |
| | | </el-tooltip> |
| | | <span v-else>{{ scope.row.currentTreatment }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="150" fixed="right"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | type="primary" |
| | | size="mini" |
| | | @click="editChronicDisease(scope.$index, scope.row)" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | size="mini" |
| | | @click=" |
| | | deleteChronicDisease(scope.$index, scope.row) |
| | | " |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <div class="summary-stats"> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="6"> |
| | | <div class="stat-item"> |
| | | <div class="stat-value" style="color: #67c23a"> |
| | | {{ chronicStats.stable }} |
| | | </div> |
| | | <div class="stat-label">稳å®</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="stat-item"> |
| | | <div class="stat-value" style="color: #e6a23c"> |
| | | {{ chronicStats.active }} |
| | | </div> |
| | | <div class="stat-label">æ´»å¨æ</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="stat-item"> |
| | | <div class="stat-value" style="color: #f56c6c"> |
| | | {{ chronicStats.severe }} |
| | | </div> |
| | | <div class="stat-label">严é</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="stat-item"> |
| | | <div class="stat-value" style="color: #909399"> |
| | | {{ chronicStats.total }} |
| | | </div> |
| | | <div class="stat-label">æ»æ°</div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </div> |
| | | </div> |
| | |
| | | </div> |
| | | </div> --> |
| | | </div> |
| | | <!-- çæ¥æè¦ç¼è¾å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | :title="screeningEditing ? 'ç¼è¾çæ¥è®°å½' : 'æ°å¢çæ¥è®°å½'" |
| | | :visible.sync="screeningDialogVisible" |
| | | width="600px" |
| | | > |
| | | <el-form :model="screeningForm" label-width="100px"> |
| | | <el-form-item label="çæ¥ç±»å" prop="screeningType" required> |
| | | <el-select |
| | | v-model="screeningForm.screeningType" |
| | | placeholder="è¯·éæ©çæ¥ç±»å" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="item in screeningTypeOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | > |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="çæ¥æ¥æ" prop="screeningDate" required> |
| | | <el-date-picker |
| | | v-model="screeningForm.screeningDate" |
| | | type="datetime" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | placeholder="éæ©çæ¥æ¥æ" |
| | | style="width: 100%" |
| | | > |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="çæ¥ç»æ" prop="result" required> |
| | | <el-select |
| | | v-model="screeningForm.result" |
| | | placeholder="è¯·éæ©ç»æ" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="item in resultOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | > |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="详ç»ç»æ" prop="details"> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="3" |
| | | v-model="screeningForm.details" |
| | | placeholder="请è¾å
¥è¯¦ç»ç»æä¿¡æ¯" |
| | | > |
| | | </el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="screeningDialogVisible = false">åæ¶</el-button> |
| | | <el-button type="primary" @click="saveScreening">ç¡®å®</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | |
| | | <!-- æ
¢ç
æè¦ç¼è¾å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | :title="chronicEditing ? 'ç¼è¾æ
¢ç
è®°å½' : 'æ°å¢æ
¢ç
è®°å½'" |
| | | :visible.sync="chronicDialogVisible" |
| | | width="600px" |
| | | > |
| | | <el-form :model="chronicForm" label-width="100px"> |
| | | <el-form-item label="ç¾ç
åç§°" prop="diseaseName" required> |
| | | <el-select |
| | | v-model="chronicForm.diseaseName" |
| | | placeholder="è¯·éæ©ç¾ç
åç§°" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="item in diseaseOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | > |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="ç¡®è¯æ¥æ" prop="diagnoseDate" required> |
| | | <el-date-picker |
| | | v-model="chronicForm.diagnoseDate" |
| | | type="date" |
| | | value-format="yyyy-MM-dd" |
| | | placeholder="éæ©ç¡®è¯æ¥æ" |
| | | style="width: 100%" |
| | | > |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="å½åç¶æ" prop="status" required> |
| | | <el-select |
| | | v-model="chronicForm.status" |
| | | placeholder="è¯·éæ©ç¶æ" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="item in statusOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | > |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="å½åæ²»ç" prop="currentTreatment"> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="2" |
| | | v-model="chronicForm.currentTreatment" |
| | | placeholder="请è¾å
¥å½åæ²»çæ¹æ¡" |
| | | > |
| | | </el-input> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="é访计å" prop="followUpPlan"> |
| | | <el-input |
| | | v-model="chronicForm.followUpPlan" |
| | | placeholder="请è¾å
¥é访计å" |
| | | > |
| | | </el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="chronicDialogVisible = false">åæ¶</el-button> |
| | | <el-button type="primary" @click="saveChronicDisease">ç¡®å®</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | <el-dialog :title="titletb" :visible.sync="AddanumberVisible"> |
| | | <el-form :model="numberform" label-width="100px"> |
| | | <el-form-item label="å§å"> |
| | |
| | | </el-date-picker> --> |
| | | <el-date-picker |
| | | v-model="borninfoform.generatedTime" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | type="datetime" |
| | | placeholder="éæ©æ¥ææ¶é´" |
| | | > |
| | |
| | | sonactiveName: "inhospital", //å¥åº·çæµå¯¼èª |
| | | sontwoactiveName: "weight", //å»çæ¡£æ¡å¯¼èª |
| | | dynamicTags: [], |
| | | // çæ¥æè¦ç¸å
³æ°æ® |
| | | screeningLoading: false, |
| | | screeningSummaryData: [], |
| | | screeningStats: { |
| | | normal: 0, |
| | | abnormal: 0, |
| | | critical: 0, |
| | | }, |
| | | |
| | | // æ
¢ç
æè¦ç¸å
³æ°æ® |
| | | chronicLoading: false, |
| | | chronicDiseaseData: [], |
| | | chronicStats: { |
| | | stable: 0, |
| | | active: 0, |
| | | severe: 0, |
| | | total: 0, |
| | | }, |
| | | borninforules: { |
| | | height: [ |
| | | { required: true, message: "身é¿ä¸è½ä¸ºç©º", trigger: "blur" }, |
| | |
| | | xtechartdom: {}, |
| | | tzechartdom: {}, |
| | | tableData: [], |
| | | // çæ¥æè¦ç¼è¾ç¸å
³ |
| | | screeningEditing: false, |
| | | screeningEditIndex: -1, |
| | | screeningEditTemp: {}, |
| | | screeningDialogVisible: false, |
| | | screeningForm: { |
| | | screeningType: "", |
| | | screeningDate: "", |
| | | result: "æ£å¸¸", |
| | | details: "", |
| | | }, |
| | | |
| | | // æ
¢ç
æè¦ç¼è¾ç¸å
³ |
| | | chronicEditing: false, |
| | | chronicEditIndex: -1, |
| | | chronicEditTemp: {}, |
| | | chronicDialogVisible: false, |
| | | chronicForm: { |
| | | diseaseName: "", |
| | | diagnoseDate: "", |
| | | status: "稳å®", |
| | | currentTreatment: "", |
| | | followUpPlan: "", |
| | | }, |
| | | |
| | | // çéé项 |
| | | resultOptions: [ |
| | | { label: "æ£å¸¸", value: "æ£å¸¸" }, |
| | | { label: "å¼å¸¸", value: "å¼å¸¸" }, |
| | | { label: "屿¥", value: "屿¥" }, |
| | | ], |
| | | |
| | | statusOptions: [ |
| | | { label: "稳å®", value: "稳å®" }, |
| | | { label: "æ´»å¨æ", value: "æ´»å¨æ" }, |
| | | { label: "严é", value: "严é" }, |
| | | ], |
| | | |
| | | screeningTypeOptions: [ |
| | | { label: "å¿è¡ç®¡", value: "å¿è¡ç®¡" }, |
| | | { label: "ç³å°¿ç
", value: "ç³å°¿ç
" }, |
| | | { label: "è¿ç¤æ å¿", value: "è¿ç¤æ å¿" }, |
| | | { label: "è¾åè½", value: "è¾åè½" }, |
| | | { label: "å¼å¸ç³»ç»", value: "å¼å¸ç³»ç»" }, |
| | | ], |
| | | |
| | | diseaseOptions: [ |
| | | { label: "é«è¡å", value: "é«è¡å" }, |
| | | { label: "2åç³å°¿ç
", value: "2åç³å°¿ç
" }, |
| | | { label: "å å¿ç
", value: "å å¿ç
" }, |
| | | { label: "æ
¢æ§è¾ç
", value: "æ
¢æ§è¾ç
" }, |
| | | ], |
| | | tableDatalist: [ |
| | | { |
| | | id: 12, |
| | |
| | | this.id = this.$route.query.id; |
| | | this.getuserinfo(); |
| | | this.gettabList(); |
| | | // åå§åçæ¥åæ
¢ç
æ°æ® |
| | | this.initScreeningData(); |
| | | this.initChronicDiseaseData(); |
| | | }, |
| | | |
| | | methods: { |
| | |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | /** çæ¥æè¦ - æ°å¢ */ |
| | | addScreening() { |
| | | this.screeningEditing = false; |
| | | this.screeningEditIndex = -1; |
| | | this.screeningForm = { |
| | | screeningType: "", |
| | | screeningDate: new Date().toISOString().split("T")[0] + " 09:00:00", |
| | | result: "æ£å¸¸", |
| | | details: "", |
| | | }; |
| | | this.screeningDialogVisible = true; |
| | | }, |
| | | |
| | | /** çæ¥æè¦ - ç¼è¾ */ |
| | | editScreening(index, row) { |
| | | this.screeningEditing = true; |
| | | this.screeningEditIndex = index; |
| | | this.screeningForm = { ...row }; |
| | | this.screeningDialogVisible = true; |
| | | }, |
| | | |
| | | /** çæ¥æè¦ - ä¿å */ |
| | | saveScreening() { |
| | | if ( |
| | | !this.screeningForm.screeningType || |
| | | !this.screeningForm.screeningDate |
| | | ) { |
| | | this.$message.error("请填åå¿
å¡«åæ®µ"); |
| | | return; |
| | | } |
| | | |
| | | if (this.screeningEditing) { |
| | | // ç¼è¾ç°æè®°å½ |
| | | this.screeningSummaryData.splice(this.screeningEditIndex, 1, { |
| | | ...this.screeningForm, |
| | | id: this.screeningSummaryData[this.screeningEditIndex].id, |
| | | }); |
| | | this.$message.success("çæ¥è®°å½ä¿®æ¹æå"); |
| | | } else { |
| | | // æ°å¢è®°å½ |
| | | const newRecord = { |
| | | id: Date.now(), // 临æ¶ID |
| | | ...this.screeningForm, |
| | | riskLevel: this.getRiskLevelByResult(this.screeningForm.result), |
| | | }; |
| | | this.screeningSummaryData.unshift(newRecord); |
| | | this.$message.success("çæ¥è®°å½æ°å¢æå"); |
| | | } |
| | | |
| | | this.calculateScreeningStats(); |
| | | this.screeningDialogVisible = false; |
| | | }, |
| | | |
| | | /** çæ¥æè¦ - å é¤ */ |
| | | deleteScreening(index, row) { |
| | | this.$confirm("ç¡®å®è¦å é¤è¿æ¡çæ¥è®°å½åï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | this.screeningSummaryData.splice(index, 1); |
| | | this.calculateScreeningStats(); |
| | | this.$message.success("å 餿å"); |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | |
| | | /** æ ¹æ®ç»æè·åé£é©ç级 */ |
| | | getRiskLevelByResult(result) { |
| | | const riskMap = { |
| | | æ£å¸¸: "low", |
| | | å¼å¸¸: "medium", |
| | | 屿¥: "critical", |
| | | }; |
| | | return riskMap[result] || "low"; |
| | | }, |
| | | /** æ
¢ç
æè¦ - æ°å¢ */ |
| | | addChronicDisease() { |
| | | this.chronicEditing = false; |
| | | this.chronicEditIndex = -1; |
| | | this.chronicForm = { |
| | | diseaseName: "", |
| | | diagnoseDate: new Date().toISOString().split("T")[0], |
| | | status: "稳å®", |
| | | currentTreatment: "", |
| | | followUpPlan: "æ¯æå¤è¯ä¸æ¬¡", |
| | | }; |
| | | this.chronicDialogVisible = true; |
| | | }, |
| | | |
| | | /** æ
¢ç
æè¦ - ç¼è¾ */ |
| | | editChronicDisease(index, row) { |
| | | this.chronicEditing = true; |
| | | this.chronicEditIndex = index; |
| | | this.chronicForm = { ...row }; |
| | | this.chronicDialogVisible = true; |
| | | }, |
| | | |
| | | /** æ
¢ç
æè¦ - ä¿å */ |
| | | saveChronicDisease() { |
| | | if (!this.chronicForm.diseaseName || !this.chronicForm.diagnoseDate) { |
| | | this.$message.error("请填åå¿
å¡«åæ®µ"); |
| | | return; |
| | | } |
| | | |
| | | if (this.chronicEditing) { |
| | | // ç¼è¾ç°æè®°å½ |
| | | this.chronicDiseaseData.splice(this.chronicEditIndex, 1, { |
| | | ...this.chronicForm, |
| | | id: this.chronicDiseaseData[this.chronicEditIndex].id, |
| | | }); |
| | | this.$message.success("æ
¢ç
è®°å½ä¿®æ¹æå"); |
| | | } else { |
| | | // æ°å¢è®°å½ |
| | | const newRecord = { |
| | | id: Date.now(), // 临æ¶ID |
| | | ...this.chronicForm, |
| | | }; |
| | | this.chronicDiseaseData.unshift(newRecord); |
| | | this.$message.success("æ
¢ç
è®°å½æ°å¢æå"); |
| | | } |
| | | |
| | | this.calculateChronicStats(); |
| | | this.chronicDialogVisible = false; |
| | | }, |
| | | |
| | | /** æ
¢ç
æè¦ - å é¤ */ |
| | | deleteChronicDisease(index, row) { |
| | | this.$confirm("ç¡®å®è¦å é¤è¿æ¡æ
¢ç
è®°å½åï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | this.chronicDiseaseData.splice(index, 1); |
| | | this.calculateChronicStats(); |
| | | this.$message.success("å 餿å"); |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | checkAgeExists(newAge) { |
| | | // åè®¾å·²ææ°æ®åå¨å¨ this.existingData ä¸ |
| | |
| | | }); |
| | | // èç³»ä¿¡æ¯ |
| | | this.getcontactlist(); |
| | | }, |
| | | /** åå§åçæ¥æè¦æ°æ® */ |
| | | initScreeningData() { |
| | | // 模æçæ¥æè¦æ°æ®[1,4](@ref) |
| | | this.screeningSummaryData = [ |
| | | { |
| | | id: 1, |
| | | screeningType: "å¿è¡ç®¡", |
| | | screeningDate: "2024-11-15 09:00:00", |
| | | result: "å¼å¸¸", |
| | | details: "å¿çµå¾æ¾ç¤ºST段åä½ï¼å»ºè®®è¿ä¸æ¥æ£æ¥", |
| | | riskLevel: "high", |
| | | }, |
| | | { |
| | | id: 2, |
| | | screeningType: "ç³å°¿ç
", |
| | | screeningDate: "2024-11-10 14:30:00", |
| | | result: "æ£å¸¸", |
| | | details: "空è
¹è¡ç³5.6mmol/Lï¼ç³åè¡çº¢èç½5.8%", |
| | | riskLevel: "low", |
| | | }, |
| | | { |
| | | id: 3, |
| | | screeningType: "è¿ç¤æ å¿", |
| | | screeningDate: "2024-11-05 10:15:00", |
| | | result: "屿¥", |
| | | details: "CEA 15.2ng/mLï¼å»ºè®®ç«å³ä¸ç§å°±è¯", |
| | | riskLevel: "critical", |
| | | }, |
| | | { |
| | | id: 4, |
| | | screeningType: "è¾åè½", |
| | | screeningDate: "2024-10-28 16:20:00", |
| | | result: "å¼å¸¸", |
| | | details: "èé
æ¸
é¤çåä½ï¼eGFR 55mL/min", |
| | | riskLevel: "medium", |
| | | }, |
| | | { |
| | | id: 5, |
| | | screeningType: "å¼å¸ç³»ç»", |
| | | screeningDate: "2024-10-20 11:00:00", |
| | | result: "æ£å¸¸", |
| | | details: "èºåè½æ£æ¥æªè§ææ¾å¼å¸¸", |
| | | riskLevel: "low", |
| | | }, |
| | | ]; |
| | | |
| | | // 计ç®ç»è®¡ä¿¡æ¯ |
| | | this.calculateScreeningStats(); |
| | | }, |
| | | |
| | | /** 计ç®çæ¥ç»è®¡ä¿¡æ¯ */ |
| | | calculateScreeningStats() { |
| | | this.screeningStats = { |
| | | normal: this.screeningSummaryData.filter( |
| | | (item) => item.result === "æ£å¸¸" |
| | | ).length, |
| | | abnormal: this.screeningSummaryData.filter( |
| | | (item) => item.result === "å¼å¸¸" |
| | | ).length, |
| | | critical: this.screeningSummaryData.filter( |
| | | (item) => item.result === "屿¥" |
| | | ).length, |
| | | }; |
| | | }, |
| | | |
| | | /** åå§åæ
¢ç
æè¦æ°æ® */ |
| | | initChronicDiseaseData() { |
| | | // 模ææ
¢ç
æè¦æ°æ®[2,5](@ref) |
| | | this.chronicDiseaseData = [ |
| | | { |
| | | id: 1, |
| | | diseaseName: "é«è¡å", |
| | | diagnoseDate: "2020-03-15", |
| | | status: "稳å®", |
| | | currentTreatment: "氨氯å°å¹³ 5mg qdï¼å®æçæµè¡å", |
| | | followUpPlan: "æ¯æå¤è¯ä¸æ¬¡", |
| | | }, |
| | | { |
| | | id: 2, |
| | | diseaseName: "2åç³å°¿ç
", |
| | | diagnoseDate: "2019-08-20", |
| | | status: "æ´»å¨æ", |
| | | currentTreatment: "äºç²åè 500mg bidï¼è°å²ç´ 注å°", |
| | | followUpPlan: "æ¯ä¸¤å¨å¤è¯ä¸æ¬¡", |
| | | }, |
| | | { |
| | | id: 3, |
| | | diseaseName: "å å¿ç
", |
| | | diagnoseDate: "2021-05-10", |
| | | status: "稳å®", |
| | | currentTreatment: "é¿å¸å¹æ 100mg qdï¼é¿æä¼ä»æ± 20mg qd", |
| | | followUpPlan: "æ¯å£åº¦å¤è¯ä¸æ¬¡", |
| | | }, |
| | | { |
| | | id: 4, |
| | | diseaseName: "æ
¢æ§è¾ç
", |
| | | diagnoseDate: "2022-01-30", |
| | | status: "严é", |
| | | currentTreatment: "æ§å¶è¡åãè¡ç³ï¼ä½èç½é¥®é£", |
| | | followUpPlan: "æ¯æä¸ç§é访", |
| | | }, |
| | | ]; |
| | | |
| | | // 计ç®ç»è®¡ä¿¡æ¯ |
| | | this.calculateChronicStats(); |
| | | }, |
| | | |
| | | /** è®¡ç®æ
¢ç
ç»è®¡ä¿¡æ¯ */ |
| | | calculateChronicStats() { |
| | | this.chronicStats = { |
| | | stable: this.chronicDiseaseData.filter((item) => item.status === "稳å®") |
| | | .length, |
| | | active: this.chronicDiseaseData.filter( |
| | | (item) => item.status === "æ´»å¨æ" |
| | | ).length, |
| | | severe: this.chronicDiseaseData.filter((item) => item.status === "严é") |
| | | .length, |
| | | total: this.chronicDiseaseData.length, |
| | | }; |
| | | }, |
| | | |
| | | /** è·åçæ¥ç±»åæ ç¾æ ·å¼ */ |
| | | getScreeningTagType(type) { |
| | | const typeMap = { |
| | | å¿è¡ç®¡: "danger", |
| | | ç³å°¿ç
: "warning", |
| | | è¿ç¤æ å¿: "danger", |
| | | è¾åè½: "warning", |
| | | å¼å¸ç³»ç»: "success", |
| | | }; |
| | | return typeMap[type] || "info"; |
| | | }, |
| | | |
| | | /** è·åç¾ç
åç§°æ ç¾æ ·å¼ */ |
| | | getDiseaseTagType(diseaseName) { |
| | | const diseaseMap = { |
| | | é«è¡å: "warning", |
| | | "2åç³å°¿ç
": "danger", |
| | | å å¿ç
: "danger", |
| | | æ
¢æ§è¾ç
: "danger", |
| | | }; |
| | | return diseaseMap[diseaseName] || "info"; |
| | | }, |
| | | |
| | | /** æ¥ççæ¥è¯¦æ
*/ |
| | | viewScreeningDetail(row) { |
| | | this.$alert( |
| | | `<div> |
| | | <p><strong>çæ¥ç±»åï¼</strong>${row.screeningType}</p> |
| | | <p><strong>çæ¥æ¥æï¼</strong>${this.formatTime(row.screeningDate)}</p> |
| | | <p><strong>çæ¥ç»æï¼</strong><el-tag type="${ |
| | | row.result === "æ£å¸¸" |
| | | ? "success" |
| | | : row.result === "å¼å¸¸" |
| | | ? "danger" |
| | | : "warning" |
| | | }">${row.result}</el-tag></p> |
| | | <p><strong>详ç»ç»æï¼</strong>${row.details}</p> |
| | | <p><strong>é£é©è¯ä¼°ï¼</strong>${this.getRiskLevelText( |
| | | row.riskLevel |
| | | )}</p> |
| | | </div>`, |
| | | "çæ¥è¯¦æ
", |
| | | { |
| | | dangerouslyUseHTMLString: true, |
| | | customClass: "detail-dialog", |
| | | } |
| | | ); |
| | | }, |
| | | |
| | | /** æ¥çæ
¢ç
详æ
*/ |
| | | viewChronicDetail(row) { |
| | | this.$alert( |
| | | `<div> |
| | | <p><strong>ç¾ç
åç§°ï¼</strong>${row.diseaseName}</p> |
| | | <p><strong>ç¡®è¯æ¥æï¼</strong>${this.formatTime(row.diagnoseDate)}</p> |
| | | <p><strong>å½åç¶æï¼</strong><el-tag type="${ |
| | | row.status === "稳å®" |
| | | ? "success" |
| | | : row.status === "æ´»å¨æ" |
| | | ? "warning" |
| | | : "danger" |
| | | }">${row.status}</el-tag></p> |
| | | <p><strong>å½åæ²»çï¼</strong>${row.currentTreatment}</p> |
| | | <p><strong>é访计åï¼</strong>${row.followUpPlan}</p> |
| | | </div>`, |
| | | "æ
¢ç
详æ
", |
| | | { |
| | | dangerouslyUseHTMLString: true, |
| | | customClass: "detail-dialog", |
| | | } |
| | | ); |
| | | }, |
| | | |
| | | /** è·åé£é©ççº§ææ¬ */ |
| | | getRiskLevelText(level) { |
| | | const levelMap = { |
| | | low: "ä½é£é©", |
| | | medium: "ä¸é£é©", |
| | | high: "é«é£é©", |
| | | critical: "屿¥", |
| | | }; |
| | | return levelMap[level] || "æªç¥"; |
| | | }, |
| | | |
| | | /** å·æ°çæ¥æ°æ® */ |
| | | refreshScreeningData() { |
| | | this.screeningLoading = true; |
| | | // 模æå¼æ¥å è½½ |
| | | setTimeout(() => { |
| | | this.initScreeningData(); |
| | | this.screeningLoading = false; |
| | | this.$message.success("çæ¥æ°æ®å·²å·æ°"); |
| | | }, 1000); |
| | | }, |
| | | |
| | | /** å·æ°æ
¢ç
æ°æ® */ |
| | | refreshChronicData() { |
| | | this.chronicLoading = true; |
| | | // 模æå¼æ¥å è½½ |
| | | setTimeout(() => { |
| | | this.initChronicDiseaseData(); |
| | | this.chronicLoading = false; |
| | | this.$message.success("æ
¢ç
æ°æ®å·²å·æ°"); |
| | | }, 1000); |
| | | }, |
| | | // ä¿åæ£è
æ¡£æ¡ |
| | | savefile() { |
| | |
| | | } |
| | | } |
| | | } |
| | | .screening-summary, |
| | | .chronic-disease-summary { |
| | | background: #ffffff; |
| | | border: 1px solid #e6e6e6; |
| | | border-radius: 4px; |
| | | margin-bottom: 20px; |
| | | |
| | | .summary-header { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 12px 15px; |
| | | background: #f5f7fa; |
| | | border-bottom: 1px solid #e6e6e6; |
| | | font-weight: 600; |
| | | color: #333; |
| | | |
| | | i { |
| | | margin-right: 8px; |
| | | color: #409eff; |
| | | } |
| | | } |
| | | |
| | | .summary-content { |
| | | padding: 15px; |
| | | |
| | | .summary-stats { |
| | | margin-top: 15px; |
| | | padding-top: 15px; |
| | | border-top: 1px dashed #e6e6e6; |
| | | |
| | | .stat-item { |
| | | text-align: center; |
| | | |
| | | .stat-value { |
| | | font-size: 24px; |
| | | font-weight: bold; |
| | | margin-bottom: 5px; |
| | | } |
| | | |
| | | .stat-label { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* 详æ
å¯¹è¯æ¡æ ·å¼ */ |
| | | :deep(.detail-dialog) { |
| | | .el-message-box__message { |
| | | p { |
| | | margin: 10px 0; |
| | | line-height: 1.6; |
| | | } |
| | | |
| | | strong { |
| | | color: #333; |
| | | min-width: 80px; |
| | | display: inline-block; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* ååºå¼è®¾è®¡ */ |
| | | @media (max-width: 1200px) { |
| | | .screening-summary, |
| | | .chronic-disease-summary { |
| | | .summary-content { |
| | | .el-table { |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .xinz-inf { |
| | | font-size: 18px; |
| | | // white-space: nowrap; |
| | |
| | | ::v-deep.el-table .warning-row { |
| | | background: oldlace; |
| | | } |
| | | /* æä½æé®ç»æ ·å¼ */ |
| | | .summary-header .el-button-group { |
| | | margin-left: auto; |
| | | } |
| | | |
| | | /* å¯¹è¯æ¡è¡¨åæ ·å¼ */ |
| | | .el-dialog .el-form-item { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | /* ç»è®¡æ°åæ ·å¼ä¼å */ |
| | | .stat-item { |
| | | cursor: pointer; |
| | | transition: all 0.3s; |
| | | } |
| | | |
| | | .stat-item:hover { |
| | | background-color: #f5f7fa; |
| | | border-radius: 4px; |
| | | } |
| | | </style> |
| | |
| | | placeholder="è¯·éæ©ä»»å¡åç§°" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="å¾ååºé´"> |
| | | <el-input |
| | | v-model="topqueryParams.scoreStart" |
| | | placeholder="å¼å§å" |
| | | style="width: 100px" |
| | | ></el-input> |
| | | <span style="margin: 0 10px">-</span> |
| | | <el-input |
| | | v-model="topqueryParams.scoreEnd" |
| | | placeholder="ç»æå" |
| | | style="width: 100px" |
| | | ></el-input> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="çæ¡æ¥è¯¢"> |
| | | <el-input |
| | | v-model="topqueryParams.detailResult" |
| | | placeholder="请è¾å
¥çæ¡å
³é®è¯" |
| | | style="width: 200px" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="åºé¢æ¶é´"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | |
| | | > |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-row :gutter="10" style="margin-bottom: 15px;"> |
| | | <!-- <el-col :span="24"> |
| | | <span style="margin-right: 10px; font-size: 14px; color: #606266;">å¿«ééæ©ï¼</span> |
| | | <el-button-group> |
| | | <el-button size="mini" @click="quickScoreRange('excellent')">ä¼ç§(90-100)</el-button> |
| | | <el-button size="mini" @click="quickScoreRange('good')">è¯å¥½(80-89)</el-button> |
| | | <el-button size="mini" @click="quickScoreRange('medium')">ä¸ç(70-79)</el-button> |
| | | <el-button size="mini" @click="quickScoreRange('pass')">åæ ¼(60-69)</el-button> |
| | | <el-button size="mini" @click="quickScoreRange('fail')">ä¸åæ ¼(0-59)</el-button> |
| | | <el-button size="mini" @click="resetScoreQuery">éç½®</el-button> |
| | | </el-button-group> |
| | | </el-col> --> |
| | | </el-row> |
| | | <el-divider></el-divider> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | |
| | | :options="dict.type.sys_suggest" |
| | | :value="scope.row.suggest" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="å¾å" |
| | | align="center" |
| | | key="score" |
| | | prop="score" |
| | | width="100" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <span>{{ scope.row.score || "-" }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | |
| | | pageSize: 10, |
| | | serviceType: 1, |
| | | searchscope: 3, |
| | | scoreStart: undefined, // å¾åå¼å§ |
| | | scoreEnd: undefined, // å¾åç»æ |
| | | detailResult: undefined, // ç»ææ¥è¯¢ |
| | | scopetype: [], |
| | | leaveldeptcodes: [], |
| | | leavehospitaldistrictcodes: [], |
| | |
| | | methods: { |
| | | /** æ¥è¯¢é¨è¯é访æå¡å表 */ |
| | | getList(refresh) { |
| | | // å¤çå¾ååºé´æ¥è¯¢é»è¾ |
| | | this.handleScoreQuery(); |
| | | // é»è®¤å
¨é¨ |
| | | if (this.topqueryParams.searchscope == 3) { |
| | | this.topqueryParams.leaveldeptcodes = store.getters.belongDepts.map( |
| | |
| | | getTaskservelist(this.topqueryParams).then((response) => { |
| | | this.userList = response.rows[0].serviceSubtaskList; |
| | | this.total = response.total; |
| | | |
| | | if (refresh) { |
| | | this.cardlist[0].value = |
| | | Number(response.rows[0].wzx) + Number(response.rows[0].ysf); |
| | |
| | | this.total = response.total; |
| | | }); |
| | | }, |
| | | /** å¾ååºé´å¿«ééæ© */ |
| | | quickScoreRange(range) { |
| | | const ranges = { |
| | | 'excellent': { start: 90, end: 100 }, |
| | | 'good': { start: 80, end: 89 }, |
| | | 'medium': { start: 70, end: 79 }, |
| | | 'pass': { start: 60, end: 69 }, |
| | | 'fail': { start: 0, end: 59 } |
| | | }; |
| | | |
| | | if (ranges[range]) { |
| | | this.topqueryParams.scoreStart = ranges[range].start; |
| | | this.topqueryParams.scoreEnd = ranges[range].end; |
| | | this.handleQuery(); |
| | | } |
| | | }, |
| | | /** å¤çå¾ååºé´æ¥è¯¢ */ |
| | | handleScoreQuery() { |
| | | // éªè¯å¾ååºé´è¾å
¥ |
| | | if (this.topqueryParams.scoreStart && isNaN(this.topqueryParams.scoreStart)) { |
| | | this.$message.warning('å¼å§åå¿
须为æ°å'); |
| | | this.topqueryParams.scoreStart = undefined; |
| | | return; |
| | | } |
| | | |
| | | if (this.topqueryParams.scoreEnd && isNaN(this.topqueryParams.scoreEnd)) { |
| | | this.$message.warning('ç»æåå¿
须为æ°å'); |
| | | this.topqueryParams.scoreEnd = undefined; |
| | | return; |
| | | } |
| | | |
| | | // ç¡®ä¿å¼å§åä¸å¤§äºç»æå |
| | | if (this.topqueryParams.scoreStart && this.topqueryParams.scoreEnd) { |
| | | if (parseFloat(this.topqueryParams.scoreStart) > parseFloat(this.topqueryParams.scoreEnd)) { |
| | | this.$message.warning('å¼å§åä¸è½å¤§äºç»æå'); |
| | | // 交æ¢å¼ |
| | | [this.topqueryParams.scoreStart, this.topqueryParams.scoreEnd] = |
| | | [this.topqueryParams.scoreEnd, this.topqueryParams.scoreStart]; |
| | | } |
| | | } |
| | | }, |
| | | // æ¥çé¨è¯é访详æ
|
| | | Referencequestion(row) { |
| | | this.previewVisible = true; |
| | |
| | | this.single = selection.length != 1; |
| | | this.multiple = !selection.length; |
| | | }, |
| | | resetScoreQuery() { |
| | | this.topqueryParams.scoreStart = undefined; |
| | | this.topqueryParams.scoreEnd = undefined; |
| | | this.topqueryParams.detailResult = undefined; |
| | | }, |
| | | //å é¤é项 |
| | | handleClose(tag) { |
| | | this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1); |
| | |
| | | font-size: 23px; |
| | | } |
| | | } |
| | | /* å¾ååºé´è¾å
¥æ¡æ ·å¼ */ |
| | | .score-range-input { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | .score-separator { |
| | | margin: 0 10px; |
| | | color: #909399; |
| | | } |
| | | } |
| | | |
| | | /* ç»ææ ç¾æ ·å¼ */ |
| | | .result-tag { |
| | | margin: 2px; |
| | | } |
| | | |
| | | /* å¿«ééæ©æé®æ ·å¼ */ |
| | | .quick-score-buttons { |
| | | margin-bottom: 15px; |
| | | |
| | | .el-button-group { |
| | | margin-left: 10px; |
| | | } |
| | | } |
| | | .uploading { |
| | | margin-top: 20px; |
| | | margin: 20px; |
| | |
| | | <el-tab-pane label="å¢é管ç" name="team"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="24" :xs="24"> |
| | | <el-form :model="teamQueryParams" ref="teamQueryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form |
| | | :model="teamQueryParams" |
| | | ref="teamQueryForm" |
| | | size="small" |
| | | :inline="true" |
| | | v-show="showSearch" |
| | | label-width="68px" |
| | | > |
| | | <el-form-item label="å¢éåç§°" prop="name"> |
| | | <el-input |
| | | v-model="teamQueryParams.name" |
| | |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="å¢éç¶æ" prop="status"> |
| | | <el-select v-model="teamQueryParams.status" placeholder="è¯·éæ©ç¶æ" clearable style="width: 200px"> |
| | | <el-select |
| | | v-model="teamQueryParams.status" |
| | | placeholder="è¯·éæ©ç¶æ" |
| | | clearable |
| | | style="width: 200px" |
| | | > |
| | | <el-option |
| | | v-for="item in teamStatusOptions" |
| | | :key="item.value" |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="medium" @click="handleTeamQuery">æç´¢</el-button> |
| | | <el-button icon="el-icon-refresh" size="medium" @click="resetTeamQuery">éç½®</el-button> |
| | | <el-button |
| | | type="primary" |
| | | icon="el-icon-search" |
| | | size="medium" |
| | | @click="handleTeamQuery" |
| | | >æç´¢</el-button |
| | | > |
| | | <el-button |
| | | icon="el-icon-refresh" |
| | | size="medium" |
| | | @click="resetTeamQuery" |
| | | >éç½®</el-button |
| | | > |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | |
| | | icon="el-icon-plus" |
| | | size="medium" |
| | | @click="handleTeamAdd" |
| | | >æ°å¢å¢é</el-button> |
| | | >æ°å¢å¢é</el-button |
| | | > |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="teamLoading" :data="filteredTeamList" @selection-change="handleTeamSelectionChange"> |
| | | <el-table |
| | | v-loading="teamLoading" |
| | | :data="filteredTeamList" |
| | | @selection-change="handleTeamSelectionChange" |
| | | > |
| | | <el-table-column type="selection" width="50" align="center" /> |
| | | <el-table-column label="å¢éID" align="center" prop="id" width="80" /> |
| | | <el-table-column label="å¢éåç§°" align="center" prop="name" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="å¢éç»é¿" align="center" prop="leader" width="120" /> |
| | | <el-table-column label="å¢éæå" align="center" prop="memberCount" width="100"> |
| | | <template slot-scope="scope"> |
| | | <el-tag>{{ (scope.row.members || []).length }}人</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="160"> |
| | | <el-table-column |
| | | label="å¢éID" |
| | | align="center" |
| | | prop="id" |
| | | width="80" |
| | | /> |
| | | <el-table-column |
| | | label="å¢éåç§°" |
| | | align="center" |
| | | prop="name" |
| | | :show-overflow-tooltip="true" |
| | | /> |
| | | <el-table-column |
| | | label="å¢éç»é¿" |
| | | align="center" |
| | | prop="leader" |
| | | width="120" |
| | | /> |
| | | <el-table-column |
| | | label="å¢éæå" |
| | | align="center" |
| | | prop="memberCount" |
| | | width="100" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> |
| | | <el-tag>{{ (scope.row.members || []).length }}人</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å¢éç¶æ" align="center" prop="status" width="100"> |
| | | <el-table-column |
| | | label="å建æ¶é´" |
| | | align="center" |
| | | prop="createTime" |
| | | width="160" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="teamStatusOptions" :value="scope.row.status"/> |
| | | <span>{{ |
| | | parseTime(scope.row.createTime, "{y}-{m}-{d}") |
| | | }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width" width="180"> |
| | | <el-table-column |
| | | label="å¢éç¶æ" |
| | | align="center" |
| | | prop="status" |
| | | width="100" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <dict-tag |
| | | :options="teamStatusOptions" |
| | | :value="scope.row.status" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æä½" |
| | | align="center" |
| | | class-name="small-padding fixed-width" |
| | | width="180" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-view" |
| | | @click="handleTeamDetail(scope.row)" |
| | | >详æ
</el-button> |
| | | >详æ
</el-button |
| | | > |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-edit" |
| | | @click="handleTeamUpdate(scope.row)" |
| | | >ç¼è¾</el-button> |
| | | >ç¼è¾</el-button |
| | | > |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-delete" |
| | | @click="handleTeamDelete(scope.row)" |
| | | >å é¤</el-button> |
| | | >å é¤</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="teamTotal>0" |
| | | v-show="teamTotal > 0" |
| | | :total="teamTotal" |
| | | :page.sync="teamQueryParams.pageNum" |
| | | :limit.sync="teamQueryParams.pageSize" |
| | |
| | | <el-tab-pane label="人ååç»" name="member"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="24" :xs="24"> |
| | | <el-form :model="memberQueryParams" ref="memberQueryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form |
| | | :model="memberQueryParams" |
| | | ref="memberQueryForm" |
| | | size="small" |
| | | :inline="true" |
| | | v-show="showSearch" |
| | | label-width="68px" |
| | | > |
| | | <el-form-item label="æåå§å" prop="name"> |
| | | <el-input |
| | | v-model="memberQueryParams.name" |
| | |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="æå±å¢é" prop="teamId"> |
| | | <el-select v-model="memberQueryParams.teamId" placeholder="è¯·éæ©å¢é" clearable style="width: 200px"> |
| | | <el-select |
| | | v-model="memberQueryParams.teamId" |
| | | placeholder="è¯·éæ©å¢é" |
| | | clearable |
| | | style="width: 200px" |
| | | > |
| | | <el-option |
| | | v-for="item in teamList" |
| | | :key="item.id" |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æåç¶æ" prop="status"> |
| | | <el-select v-model="memberQueryParams.status" placeholder="è¯·éæ©ç¶æ" clearable style="width: 200px"> |
| | | <el-select |
| | | v-model="memberQueryParams.status" |
| | | placeholder="è¯·éæ©ç¶æ" |
| | | clearable |
| | | style="width: 200px" |
| | | > |
| | | <el-option |
| | | v-for="item in memberStatusOptions" |
| | | :key="item.value" |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="medium" @click="handleMemberQuery">æç´¢</el-button> |
| | | <el-button icon="el-icon-refresh" size="medium" @click="resetMemberQuery">éç½®</el-button> |
| | | <el-button |
| | | type="primary" |
| | | icon="el-icon-search" |
| | | size="medium" |
| | | @click="handleMemberQuery" |
| | | >æç´¢</el-button |
| | | > |
| | | <el-button |
| | | icon="el-icon-refresh" |
| | | size="medium" |
| | | @click="resetMemberQuery" |
| | | >éç½®</el-button |
| | | > |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | |
| | | icon="el-icon-plus" |
| | | size="medium" |
| | | @click="handleMemberAdd" |
| | | >æ°å¢æå</el-button> |
| | | >æ°å¢æå</el-button |
| | | > |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | |
| | | size="medium" |
| | | :disabled="multiple" |
| | | @click="handleMemberDelete" |
| | | >å é¤</el-button> |
| | | >å é¤</el-button |
| | | > |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="memberLoading" :data="filteredMemberList" @selection-change="handleMemberSelectionChange"> |
| | | <el-table |
| | | v-loading="memberLoading" |
| | | :data="filteredMemberList" |
| | | @selection-change="handleMemberSelectionChange" |
| | | > |
| | | <el-table-column type="selection" width="50" align="center" /> |
| | | <el-table-column label="æåID" align="center" prop="id" width="80" /> |
| | | <el-table-column label="æåå§å" align="center" prop="name" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æå±å¢é" align="center" prop="teamName" width="150" /> |
| | | <el-table-column label="èä½" align="center" prop="position" width="120" /> |
| | | <el-table-column label="èç³»çµè¯" align="center" prop="phone" width="150" /> |
| | | <el-table-column label="é®ç®±" align="center" prop="email" width="200" /> |
| | | <el-table-column label="å½åå·¥å" align="center" prop="currentWorkOrder" width="120"> |
| | | <el-table-column |
| | | label="æåID" |
| | | align="center" |
| | | prop="id" |
| | | width="80" |
| | | /> |
| | | <el-table-column |
| | | label="æåå§å" |
| | | align="center" |
| | | prop="name" |
| | | :show-overflow-tooltip="true" |
| | | /> |
| | | <el-table-column |
| | | label="æå±å¢é" |
| | | align="center" |
| | | prop="teamName" |
| | | width="150" |
| | | /> |
| | | <el-table-column |
| | | label="èä½" |
| | | align="center" |
| | | prop="position" |
| | | width="120" |
| | | /> |
| | | <el-table-column |
| | | label="èç³»çµè¯" |
| | | align="center" |
| | | prop="phone" |
| | | width="150" |
| | | /> |
| | | <el-table-column |
| | | label="é®ç®±" |
| | | align="center" |
| | | prop="email" |
| | | width="200" |
| | | /> |
| | | <el-table-column |
| | | label="å½åå·¥å" |
| | | align="center" |
| | | prop="currentWorkOrder" |
| | | width="120" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-tag :type="scope.row.currentWorkOrder ? '' : 'info'"> |
| | | {{ scope.row.currentWorkOrder || '空é²' }} |
| | | {{ scope.row.currentWorkOrder || "空é²" }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æåç¶æ" align="center" prop="status" width="100"> |
| | | <el-table-column |
| | | label="æåç¶æ" |
| | | align="center" |
| | | prop="status" |
| | | width="100" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="memberStatusOptions" :value="scope.row.status"/> |
| | | <dict-tag |
| | | :options="memberStatusOptions" |
| | | :value="scope.row.status" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width" width="180"> |
| | | <el-table-column |
| | | label="æä½" |
| | | align="center" |
| | | class-name="small-padding fixed-width" |
| | | width="180" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-edit" |
| | | @click="handleMemberUpdate(scope.row)" |
| | | >ç¼è¾</el-button> |
| | | >ç¼è¾</el-button |
| | | > |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-delete" |
| | | @click="handleMemberDelete(scope.row)" |
| | | >å é¤</el-button> |
| | | >å é¤</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="memberTotal>0" |
| | | v-show="memberTotal > 0" |
| | | :total="memberTotal" |
| | | :page.sync="memberQueryParams.pageNum" |
| | | :limit.sync="memberQueryParams.pageSize" |
| | |
| | | <el-tab-pane label="工忿´¾" name="workOrder"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="24" :xs="24"> |
| | | <el-form :model="workOrderQueryParams" ref="workOrderQueryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form |
| | | :model="workOrderQueryParams" |
| | | ref="workOrderQueryForm" |
| | | size="small" |
| | | :inline="true" |
| | | v-show="showSearch" |
| | | label-width="68px" |
| | | > |
| | | <el-form-item label="å·¥åç¼å·" prop="id"> |
| | | <el-input |
| | | v-model="workOrderQueryParams.id" |
| | |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥åç¶æ" prop="status"> |
| | | <el-select v-model="workOrderQueryParams.status" placeholder="è¯·éæ©ç¶æ" clearable style="width: 200px"> |
| | | <el-select |
| | | v-model="workOrderQueryParams.status" |
| | | placeholder="è¯·éæ©ç¶æ" |
| | | clearable |
| | | style="width: 200px" |
| | | > |
| | | <el-option |
| | | v-for="item in workOrderStatusOptions" |
| | | :key="item.value" |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å¤ç人" prop="assignee"> |
| | | <el-select v-model="workOrderQueryParams.assignee" placeholder="è¯·éæ©å¤ç人" clearable style="width: 200px"> |
| | | <el-select |
| | | v-model="workOrderQueryParams.assignee" |
| | | placeholder="è¯·éæ©å¤ç人" |
| | | clearable |
| | | style="width: 200px" |
| | | > |
| | | <el-option |
| | | v-for="item in memberList" |
| | | :key="item.id" |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="medium" @click="handleWorkOrderQuery">æç´¢</el-button> |
| | | <el-button icon="el-icon-refresh" size="medium" @click="resetWorkOrderQuery">éç½®</el-button> |
| | | <el-button |
| | | type="primary" |
| | | icon="el-icon-search" |
| | | size="medium" |
| | | @click="handleWorkOrderQuery" |
| | | >æç´¢</el-button |
| | | > |
| | | <el-button |
| | | icon="el-icon-refresh" |
| | | size="medium" |
| | | @click="resetWorkOrderQuery" |
| | | >éç½®</el-button |
| | | > |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | |
| | | icon="el-icon-plus" |
| | | size="medium" |
| | | @click="handleWorkOrderAdd" |
| | | >æ°å»ºå·¥å</el-button> |
| | | >æ°å»ºå·¥å</el-button |
| | | > |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="workOrderLoading" :data="filteredWorkOrderList" @selection-change="handleWorkOrderSelectionChange"> |
| | | <el-table |
| | | v-loading="workOrderLoading" |
| | | :data="filteredWorkOrderList" |
| | | @selection-change="handleWorkOrderSelectionChange" |
| | | > |
| | | <el-table-column type="selection" width="50" align="center" /> |
| | | <el-table-column label="å·¥åç¼å·" align="center" prop="id" width="120" /> |
| | | <el-table-column label="å·¥åæ é¢" align="center" prop="title" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ä¼å
级" align="center" prop="priority" width="100"> |
| | | <el-table-column |
| | | label="å·¥åç¼å·" |
| | | align="center" |
| | | prop="id" |
| | | width="120" |
| | | /> |
| | | <el-table-column |
| | | label="å·¥åæ é¢" |
| | | align="center" |
| | | prop="title" |
| | | :show-overflow-tooltip="true" |
| | | /> |
| | | <el-table-column |
| | | label="ä¼å
级" |
| | | align="center" |
| | | prop="priority" |
| | | width="100" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-tag :type="scope.row.priority === '1' ? 'danger' : scope.row.priority === '2' ? 'warning' : ''"> |
| | | {{ scope.row.priority === '1' ? 'é«' : scope.row.priority === '2' ? 'ä¸' : 'ä½' }} |
| | | <el-tag |
| | | :type=" |
| | | scope.row.priority === '1' |
| | | ? 'danger' |
| | | : scope.row.priority === '2' |
| | | ? 'warning' |
| | | : '' |
| | | " |
| | | > |
| | | {{ |
| | | scope.row.priority === "1" |
| | | ? "é«" |
| | | : scope.row.priority === "2" |
| | | ? "ä¸" |
| | | : "ä½" |
| | | }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="160"> |
| | | <el-table-column |
| | | label="å建æ¶é´" |
| | | align="center" |
| | | prop="createTime" |
| | | width="160" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> |
| | | <span>{{ |
| | | parseTime(scope.row.createTime, "{y}-{m}-{d}") |
| | | }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æªæ¢æ¶é´" align="center" prop="deadline" width="160"> |
| | | <el-table-column |
| | | label="æªæ¢æ¶é´" |
| | | align="center" |
| | | prop="deadline" |
| | | width="160" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.deadline, '{y}-{m}-{d}') }}</span> |
| | | <span>{{ |
| | | parseTime(scope.row.deadline, "{y}-{m}-{d}") |
| | | }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å¤ç人" align="center" prop="assigneeName" width="120" /> |
| | | <el-table-column label="å·¥åç¶æ" align="center" prop="status" width="120"> |
| | | <el-table-column |
| | | label="å¤ç人" |
| | | align="center" |
| | | prop="assigneeName" |
| | | width="120" |
| | | /> |
| | | <el-table-column |
| | | label="å·¥åç¶æ" |
| | | align="center" |
| | | prop="status" |
| | | width="120" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="workOrderStatusOptions" :value="scope.row.status"/> |
| | | <dict-tag |
| | | :options="workOrderStatusOptions" |
| | | :value="scope.row.status" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width" width="180"> |
| | | <el-table-column |
| | | label="æä½" |
| | | align="center" |
| | | class-name="small-padding fixed-width" |
| | | width="180" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-edit" |
| | | @click="handleWorkOrderUpdate(scope.row)" |
| | | >ç¼è¾</el-button> |
| | | >ç¼è¾</el-button |
| | | > |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-delete" |
| | | @click="handleWorkOrderDelete(scope.row)" |
| | | >å é¤</el-button> |
| | | >å é¤</el-button |
| | | > |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-s-promotion" |
| | | @click="handleAssignWorkOrder(scope.row)" |
| | | v-if="scope.row.status === '0'" |
| | | >ææ´¾</el-button> |
| | | >ææ´¾</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="workOrderTotal>0" |
| | | v-show="workOrderTotal > 0" |
| | | :total="workOrderTotal" |
| | | :page.sync="workOrderQueryParams.pageNum" |
| | | :limit.sync="workOrderQueryParams.pageSize" |
| | |
| | | </el-tabs> |
| | | |
| | | <!-- å¢é详æ
å¯¹è¯æ¡ --> |
| | | <el-dialog :title="teamDialogTitle" :visible.sync="teamDialogVisible" width="70%" append-to-body> |
| | | <el-dialog |
| | | :title="teamDialogTitle" |
| | | :visible.sync="teamDialogVisible" |
| | | width="70%" |
| | | append-to-body |
| | | > |
| | | <el-descriptions :column="2" border> |
| | | <el-descriptions-item label="å¢éID">{{ currentTeam.id }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¢éåç§°">{{ currentTeam.name }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¢éç»é¿">{{ currentTeam.leader }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¢éæå">{{ (currentTeam.members || []).length }}人</el-descriptions-item> <el-descriptions-item label="å建æ¶é´">{{ parseTime(currentTeam.createTime, '{y}-{m}-{d} {h}:{i}') }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¢éID">{{ |
| | | currentTeam.id |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¢éåç§°">{{ |
| | | currentTeam.name |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¢éç»é¿">{{ |
| | | currentTeam.leader |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¢éæå" |
| | | >{{ (currentTeam.members || []).length }}人</el-descriptions-item |
| | | > |
| | | <el-descriptions-item label="å建æ¶é´">{{ |
| | | parseTime(currentTeam.createTime, "{y}-{m}-{d} {h}:{i}") |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¢éç¶æ"> |
| | | <dict-tag :options="teamStatusOptions" :value="currentTeam.status"/> |
| | | <dict-tag :options="teamStatusOptions" :value="currentTeam.status" /> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="å¢éæè¿°" :span="2">{{ currentTeam.description || 'æ ' }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¢éæè¿°" :span="2">{{ |
| | | currentTeam.description || "æ " |
| | | }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | |
| | | <div class="team-members" style="margin-top: 20px;"> |
| | | <div class="team-members" style="margin-top: 20px"> |
| | | <div class="headline"> |
| | | <div class="basics">å¢éæå</div> |
| | | </div> |
| | |
| | | <el-table-column prop="currentWorkOrder" label="å½åå·¥å" width="150"> |
| | | <template slot-scope="scope"> |
| | | <el-tag :type="scope.row.currentWorkOrder ? '' : 'info'"> |
| | | {{ scope.row.currentWorkOrder || '空é²' }} |
| | | {{ scope.row.currentWorkOrder || "空é²" }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="status" label="æåç¶æ" width="100"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="memberStatusOptions" :value="scope.row.status"/> |
| | | <dict-tag |
| | | :options="memberStatusOptions" |
| | | :value="scope.row.status" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | |
| | | <div class="team-work-orders" style="margin-top: 20px;"> |
| | | <div class="team-work-orders" style="margin-top: 20px"> |
| | | <div class="headline"> |
| | | <div class="basics">å¢éå·¥å</div> |
| | | </div> |
| | |
| | | <el-table-column prop="title" label="å·¥åæ é¢" /> |
| | | <el-table-column prop="priority" label="ä¼å
级" width="100"> |
| | | <template slot-scope="scope"> |
| | | <el-tag :type="scope.row.priority === '1' ? 'danger' : scope.row.priority === '2' ? 'warning' : ''"> |
| | | {{ scope.row.priority === '1' ? 'é«' : scope.row.priority === '2' ? 'ä¸' : 'ä½' }} |
| | | <el-tag |
| | | :type=" |
| | | scope.row.priority === '1' |
| | | ? 'danger' |
| | | : scope.row.priority === '2' |
| | | ? 'warning' |
| | | : '' |
| | | " |
| | | > |
| | | {{ |
| | | scope.row.priority === "1" |
| | | ? "é«" |
| | | : scope.row.priority === "2" |
| | | ? "ä¸" |
| | | : "ä½" |
| | | }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="assigneeName" label="å¤ç人" width="120" /> |
| | | <el-table-column prop="status" label="å·¥åç¶æ" width="120"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="workOrderStatusOptions" :value="scope.row.status"/> |
| | | <dict-tag |
| | | :options="workOrderStatusOptions" |
| | | :value="scope.row.status" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="createTime" label="å建æ¶é´" width="160"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> |
| | | <span>{{ parseTime(scope.row.createTime, "{y}-{m}-{d}") }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="deadline" label="æªæ¢æ¶é´" width="160"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.deadline, '{y}-{m}-{d}') }}</span> |
| | | <span>{{ parseTime(scope.row.deadline, "{y}-{m}-{d}") }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | |
| | | <!-- å¨å¢é详æ
å¯¹è¯æ¡çå¢éæåè¡¨æ ¼åæ·»å äºç»´ç åºå --> |
| | | <div class="team-qrcode" style="margin-top: 20px"> |
| | | <div class="headline"> |
| | | <div class="basics">å¢éäºç»´ç </div> |
| | | </div> |
| | | <el-divider></el-divider> |
| | | <div class="qrcode-container"> |
| | | <vue-qr |
| | | :text="teamQRContent" |
| | | :size="200" |
| | | :margin="10" |
| | | colorDark="#409EFF" |
| | | :logoScale="0.2" |
| | | :logoSrc="logoUrl" |
| | | ></vue-qr> |
| | | <div class="qrcode-actions"> |
| | | <el-button size="mini" @click="downloadQRCode" |
| | | >ä¸è½½äºç»´ç </el-button |
| | | > |
| | | <el-button size="mini" type="primary" @click="refreshQRCode" |
| | | >å·æ°</el-button |
| | | > |
| | | </div> |
| | | <p class="qrcode-tip">æ«æäºç»´ç æ¥çå¢éä¿¡æ¯ï¼æææ24å°æ¶ï¼</p> |
| | | </div> |
| | | </div> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="teamDialogVisible = false">å
³ é</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | |
| | | <!-- æ°å¢/ç¼è¾å¢éå¯¹è¯æ¡ --> |
| | | <el-dialog :title="teamFormTitle" :visible.sync="teamFormVisible" width="50%" append-to-body> |
| | | <el-form ref="teamForm" :model="teamForm" :rules="teamRules" label-width="80px"> |
| | | <el-dialog |
| | | :title="teamFormTitle" |
| | | :visible.sync="teamFormVisible" |
| | | width="50%" |
| | | append-to-body |
| | | > |
| | | <el-form |
| | | ref="teamForm" |
| | | :model="teamForm" |
| | | :rules="teamRules" |
| | | label-width="80px" |
| | | > |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å¢éåç§°" prop="name"> |
| | |
| | | v-for="dict in teamStatusOptions" |
| | | :key="dict.value" |
| | | :label="dict.value" |
| | | >{{dict.label}}</el-radio> |
| | | >{{ dict.label }}</el-radio |
| | | > |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | :titles="['å¯éæå', 'å¢éæå']" |
| | | :props="{ |
| | | key: 'id', |
| | | label: 'name' |
| | | label: 'name', |
| | | }" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å¢éæè¿°" prop="description"> |
| | | <el-input type="textarea" :rows="3" v-model="teamForm.description" placeholder="请è¾å
¥å¢éæè¿°" /> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="3" |
| | | v-model="teamForm.description" |
| | | placeholder="请è¾å
¥å¢éæè¿°" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | </el-dialog> |
| | | |
| | | <!-- æ°å¢/ç¼è¾æåå¯¹è¯æ¡ --> |
| | | <el-dialog :title="memberFormTitle" :visible.sync="memberFormVisible" width="50%" append-to-body> |
| | | <el-form ref="memberForm" :model="memberForm" :rules="memberRules" label-width="80px"> |
| | | <el-dialog |
| | | :title="memberFormTitle" |
| | | :visible.sync="memberFormVisible" |
| | | width="50%" |
| | | append-to-body |
| | | > |
| | | <el-form |
| | | ref="memberForm" |
| | | :model="memberForm" |
| | | :rules="memberRules" |
| | | label-width="80px" |
| | | > |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æåå§å" prop="name"> |
| | | <el-input v-model="memberForm.name" placeholder="请è¾å
¥æåå§å" /> |
| | | <el-input |
| | | v-model="memberForm.name" |
| | | placeholder="请è¾å
¥æåå§å" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æå±å¢é" prop="teamId"> |
| | | <el-select v-model="memberForm.teamId" placeholder="è¯·éæ©æå±å¢é"> |
| | | <el-select |
| | | v-model="memberForm.teamId" |
| | | placeholder="è¯·éæ©æå±å¢é" |
| | | > |
| | | <el-option |
| | | v-for="item in teamList" |
| | | :key="item.id" |
| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èä½" prop="position"> |
| | | <el-input v-model="memberForm.position" placeholder="请è¾å
¥èä½" /> |
| | | <el-input |
| | | v-model="memberForm.position" |
| | | placeholder="请è¾å
¥èä½" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èç³»çµè¯" prop="phone"> |
| | | <el-input v-model="memberForm.phone" placeholder="请è¾å
¥èç³»çµè¯" /> |
| | | <el-input |
| | | v-model="memberForm.phone" |
| | | placeholder="请è¾å
¥èç³»çµè¯" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | v-for="dict in memberStatusOptions" |
| | | :key="dict.value" |
| | | :label="dict.value" |
| | | >{{dict.label}}</el-radio> |
| | | >{{ dict.label }}</el-radio |
| | | > |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | </el-dialog> |
| | | |
| | | <!-- æ°å¢/ç¼è¾å·¥åå¯¹è¯æ¡ --> |
| | | <el-dialog :title="workOrderFormTitle" :visible.sync="workOrderFormVisible" width="60%" append-to-body> |
| | | <el-form ref="workOrderForm" :model="workOrderForm" :rules="workOrderRules" label-width="80px"> |
| | | <el-dialog |
| | | :title="workOrderFormTitle" |
| | | :visible.sync="workOrderFormVisible" |
| | | width="60%" |
| | | append-to-body |
| | | > |
| | | <el-form |
| | | ref="workOrderForm" |
| | | :model="workOrderForm" |
| | | :rules="workOrderRules" |
| | | label-width="80px" |
| | | > |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å·¥åæ é¢" prop="title"> |
| | | <el-input v-model="workOrderForm.title" placeholder="请è¾å
¥å·¥åæ é¢" /> |
| | | <el-input |
| | | v-model="workOrderForm.title" |
| | | placeholder="请è¾å
¥å·¥åæ é¢" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¼å
级" prop="priority"> |
| | | <el-select v-model="workOrderForm.priority" placeholder="è¯·éæ©ä¼å
级"> |
| | | <el-select |
| | | v-model="workOrderForm.priority" |
| | | placeholder="è¯·éæ©ä¼å
级" |
| | | > |
| | | <el-option |
| | | v-for="item in priorityOptions" |
| | | :key="item.value" |
| | |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å·¥åå
容" prop="content"> |
| | | <el-input type="textarea" :rows="4" v-model="workOrderForm.content" placeholder="请è¾å
¥å·¥åå
容" /> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="4" |
| | | v-model="workOrderForm.content" |
| | | placeholder="请è¾å
¥å·¥åå
容" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | v-for="dict in workOrderStatusOptions" |
| | | :key="dict.value" |
| | | :label="dict.value" |
| | | >{{dict.label}}</el-radio> |
| | | >{{ dict.label }}</el-radio |
| | | > |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="workOrderForm.status === '1'"> |
| | | <el-form-item label="å¤ç人" prop="assignee"> |
| | | <el-select v-model="workOrderForm.assignee" placeholder="è¯·éæ©å¤ç人"> |
| | | <el-select |
| | | v-model="workOrderForm.assignee" |
| | | placeholder="è¯·éæ©å¤ç人" |
| | | > |
| | | <el-option |
| | | v-for="item in memberList" |
| | | :key="item.id" |
| | |
| | | </el-dialog> |
| | | |
| | | <!-- ææ´¾å·¥åå¯¹è¯æ¡ --> |
| | | <el-dialog title="ææ´¾å·¥å" :visible.sync="assignDialogVisible" width="40%" append-to-body> |
| | | <el-dialog |
| | | title="ææ´¾å·¥å" |
| | | :visible.sync="assignDialogVisible" |
| | | width="40%" |
| | | append-to-body |
| | | > |
| | | <el-form :model="assignForm" label-width="80px"> |
| | | <el-form-item label="å·¥åæ é¢"> |
| | | <el-input v-model="assignForm.title" disabled /> |
| | | </el-form-item> |
| | | <el-form-item label="å¤ç人" prop="assignee"> |
| | | <el-select v-model="assignForm.assignee" placeholder="è¯·éæ©å¤ç人" style="width: 100%"> |
| | | <el-select |
| | | v-model="assignForm.assignee" |
| | | placeholder="è¯·éæ©å¤ç人" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="item in availableMembers" |
| | | :key="item.id" |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ä¼å
级" prop="priority"> |
| | | <el-select v-model="assignForm.priority" placeholder="è¯·éæ©ä¼å
级" style="width: 100%"> |
| | | <el-select |
| | | v-model="assignForm.priority" |
| | | placeholder="è¯·éæ©ä¼å
级" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="item in priorityOptions" |
| | | :key="item.value" |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { parseTime } from '@/utils/ruoyi' |
| | | import { parseTime } from "@/utils/ruoyi"; |
| | | import VueQr from "vue-qr"; |
| | | |
| | | export default { |
| | | name: "TeamManagement", |
| | | dicts: ['sys_normal_disable', 'sys_user_sex'], |
| | | dicts: ["sys_normal_disable", "sys_user_sex"], |
| | | components: { VueQr }, |
| | | data() { |
| | | return { |
| | | // å½åæ¿æ´»çæ ç¾é¡µ |
| | | activeTab: 'team', |
| | | activeTab: "team", |
| | | // æ¾ç¤ºæç´¢æ¡ä»¶ |
| | | showSearch: true, |
| | | |
| | | // å¢é管çç¸å
³æ°æ® |
| | | teamLoading: false, |
| | | multiple: false, // è¿éæ·»å |
| | | multiple: false, // è¿éæ·»å |
| | | // æ¿æ¢åæçteamListæ°æ® |
| | | teamList: [ |
| | | { |
| | | id: 1, |
| | | name: "å端å¼åå¢é", |
| | | leader: "å¼ ä¸", |
| | | name: "å¿è¡ç®¡å
ç§å¢é", |
| | | leader: "ææç½", |
| | | members: [ |
| | | { id: 1, name: "å¼ ä¸", position: "å端ç»é¿", phone: "13800138001", email: "zhangsan@example.com", currentWorkOrder: "WO20230001", status: "1" }, |
| | | { id: 2, name: "æå", position: "é«çº§å端", phone: "13800138002", email: "lisi@example.com", currentWorkOrder: "", status: "1" }, |
| | | { id: 3, name: "çäº", position: "å端å¼å", phone: "13800138003", email: "wangwu@example.com", currentWorkOrder: "WO20230002", status: "1" } |
| | | { |
| | | id: 1, |
| | | name: "ææç½", |
| | | position: "主任å»å¸", |
| | | phone: "13800138001", |
| | | email: "lichengbai@hospital.com", |
| | | currentWorkOrder: "MED20230001", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 2, |
| | | name: "åç¿æ ", |
| | | position: "å¯ä¸»ä»»å»å¸", |
| | | phone: "13800138002", |
| | | email: "liuyihui@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 3, |
| | | name: "å¼ åæ¶µ", |
| | | position: "主治å»å¸", |
| | | phone: "13800138003", |
| | | email: "zhangmenghan@hospital.com", |
| | | currentWorkOrder: "MED20230002", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 9, |
| | | name: "å´æç¿°", |
| | | position: "ä½é¢å»å¸", |
| | | phone: "13800138009", |
| | | email: "wusihan@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | ], |
| | | createTime: "2023-01-15 09:30:00", |
| | | createTime: "2024-01-15 09:30:00", |
| | | status: "1", |
| | | description: "è´è´£å
¬å¸ææå端项ç®çå¼ååç»´æ¤" |
| | | description: "è´è´£å¿è¡ç®¡ç¾ç
çè¯æãæ²»çåææ¯ï¼æ
é¿å å¿ç
ä»å
¥æ²»ç", |
| | | }, |
| | | { |
| | | id: 2, |
| | | name: "å端å¼åå¢é", |
| | | leader: "èµµå
", |
| | | name: "è¿ç¤ç§æ²»çå¢é", |
| | | leader: "éæ¿å©", |
| | | members: [ |
| | | { id: 4, name: "èµµå
", position: "å端ç»é¿", phone: "13800138004", email: "zhaoliu@example.com", currentWorkOrder: "WO20230003", status: "1" }, |
| | | { id: 5, name: "é±ä¸", position: "é«çº§å端", phone: "13800138005", email: "qianqi@example.com", currentWorkOrder: "", status: "1" }, |
| | | { id: 6, name: "åå
«", position: "å端å¼å", phone: "13800138006", email: "sunba@example.com", currentWorkOrder: "", status: "1" } |
| | | { |
| | | id: 4, |
| | | name: "éæ¿å©", |
| | | position: "è¿ç¤ç§ä¸»ä»»", |
| | | phone: "13800138004", |
| | | email: "chenzhengqian@hospital.com", |
| | | currentWorkOrder: "MED20230003", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 5, |
| | | name: "éè¯æ¶µ", |
| | | position: "æ¾çå»å¸", |
| | | phone: "13800138005", |
| | | email: "dengshihan@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 6, |
| | | name: "é»çç«", |
| | | position: "åçå»å¸", |
| | | phone: "13800138006", |
| | | email: "huangshengmei@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | ], |
| | | createTime: "2023-01-20 14:20:00", |
| | | createTime: "2024-02-10 14:20:00", |
| | | status: "1", |
| | | description: "è´è´£å
¬å¸ææå端æå¡çå¼ååç»´æ¤" |
| | | description: "䏿³¨äºè¿ç¤çç»¼åæ²»çï¼å
æ¬åçãæ¾çåé¶åæ²»ç", |
| | | }, |
| | | { |
| | | id: 3, |
| | | name: "æµè¯å¢é", |
| | | leader: "å¨ä¹", |
| | | name: "å¿ç§è¯çå¢é", |
| | | leader: "çæ©é¾", |
| | | members: [ |
| | | { id: 7, name: "å¨ä¹", position: "æµè¯ç»ç", phone: "13800138007", email: "zhoujiu@example.com", currentWorkOrder: "WO20230004", status: "1" }, |
| | | { id: 8, name: "å´å", position: "æµè¯å·¥ç¨å¸", phone: "13800138008", email: "wushi@example.com", currentWorkOrder: "", status: "1" } |
| | | { |
| | | id: 7, |
| | | name: "çæ©é¾", |
| | | position: "å¿ç§ä¸»ä»»", |
| | | phone: "13800138007", |
| | | email: "wagenlong@hospital.com", |
| | | currentWorkOrder: "MED20230004", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 8, |
| | | name: "æ±æ¿å»·", |
| | | position: "å¿ç§å»å¸", |
| | | phone: "13800138008", |
| | | email: "zhuzhengting@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 10, |
| | | name: "æä½©ç²", |
| | | position: "å¿ç§æ¤å£«é¿", |
| | | phone: "13800138010", |
| | | email: "linpeiling@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | ], |
| | | createTime: "2023-02-10 10:15:00", |
| | | createTime: "2024-03-05 10:15:00", |
| | | status: "1", |
| | | description: "è´è´£å
¬å¸ææé¡¹ç®çæµè¯å·¥ä½" |
| | | } |
| | | description: "è´è´£å¿ç«¥å¸¸è§ç
ãå¤åç
çè¯çåé¢é²ä¿å¥å·¥ä½", |
| | | }, |
| | | { |
| | | id: 4, |
| | | name: "æ¥è¯æ¢æå¢é", |
| | | leader: "å´ä¿ä¼¯", |
| | | members: [ |
| | | { |
| | | id: 11, |
| | | name: "å´ä¿ä¼¯", |
| | | position: "æ¥è¯ç§ä¸»ä»»", |
| | | phone: "13800138011", |
| | | email: "wujunbo@hospital.com", |
| | | currentWorkOrder: "MED20230005", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 12, |
| | | name: "é®é¦¨å¦", |
| | | position: "æ¥è¯å»å¸", |
| | | phone: "13800138012", |
| | | email: "ruanxinxue@hospital.com", |
| | | currentWorkOrder: "MED20230006", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 13, |
| | | name: "ç¿æ ç ", |
| | | position: "æ¥è¯æ¤å£«", |
| | | phone: "13800138013", |
| | | email: "wenghuizhu@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | ], |
| | | createTime: "2024-03-20 16:45:00", |
| | | status: "1", |
| | | description: "24å°æ¶å¾
å½ï¼è´è´£æ¥å±éçæ£è
çæ¢æåæ²»ç", |
| | | }, |
| | | ], |
| | | teamTotal: 4, |
| | | teamQueryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: undefined, |
| | | status: undefined |
| | | status: undefined, |
| | | }, |
| | | teamTotal: 3, |
| | | teamStatusOptions: [ |
| | | { value: "0", label: "ç¦ç¨" }, |
| | | { value: "1", label: "å¯ç¨" } |
| | | { value: "1", label: "å¯ç¨" }, |
| | | ], |
| | | teamDialogVisible: false, |
| | | teamDialogTitle: "", |
| | | currentTeam: { |
| | | id: undefined, |
| | | name: undefined, |
| | | leader: undefined, |
| | | members: [], // ç¡®ä¿æé»è®¤ç©ºæ°ç» |
| | | createTime: undefined, |
| | | status: undefined, |
| | | description: undefined |
| | | }, |
| | | id: undefined, |
| | | name: undefined, |
| | | leader: undefined, |
| | | members: [], // ç¡®ä¿æé»è®¤ç©ºæ°ç» |
| | | createTime: undefined, |
| | | status: undefined, |
| | | description: undefined, |
| | | }, |
| | | teamFormVisible: false, |
| | | teamFormTitle: "", |
| | | teamForm: { |
| | |
| | | leader: undefined, |
| | | members: [], |
| | | status: "1", |
| | | description: undefined |
| | | description: undefined, |
| | | }, |
| | | teamRules: { |
| | | name: [ |
| | | { required: true, message: "å¢éåç§°ä¸è½ä¸ºç©º", trigger: "blur" } |
| | | { required: true, message: "å¢éåç§°ä¸è½ä¸ºç©º", trigger: "blur" }, |
| | | ], |
| | | leader: [ |
| | | { required: true, message: "å¢éç»é¿ä¸è½ä¸ºç©º", trigger: "change" } |
| | | { required: true, message: "å¢éç»é¿ä¸è½ä¸ºç©º", trigger: "change" }, |
| | | ], |
| | | status: [ |
| | | { required: true, message: "å¢éç¶æä¸è½ä¸ºç©º", trigger: "change" } |
| | | ] |
| | | { required: true, message: "å¢éç¶æä¸è½ä¸ºç©º", trigger: "change" }, |
| | | ], |
| | | }, |
| | | |
| | | // äºç»´ç ç¸å
³æ°æ® |
| | | teamQRContent: "127.0.0.1:8093/wt?p=0BE9L3C2u", |
| | | logoUrl: require("@/assets/logo/logoxh.png"), // å»é¢logo |
| | | currentQRCodeUrl: "", |
| | | // 人ååç»ç¸å
³æ°æ® |
| | | memberLoading: false, |
| | | // æ¿æ¢åæçmemberListæ°æ® |
| | | memberList: [ |
| | | { id: 1, name: "å¼ ä¸", teamId: 1, teamName: "å端å¼åå¢é", position: "å端ç»é¿", phone: "13800138001", email: "zhangsan@example.com", currentWorkOrder: "WO20230001", status: "1" }, |
| | | { id: 2, name: "æå", teamId: 1, teamName: "å端å¼åå¢é", position: "é«çº§å端", phone: "13800138002", email: "lisi@example.com", currentWorkOrder: "", status: "1" }, |
| | | { id: 3, name: "çäº", teamId: 1, teamName: "å端å¼åå¢é", position: "å端å¼å", phone: "13800138003", email: "wangwu@example.com", currentWorkOrder: "WO20230002", status: "1" }, |
| | | { id: 4, name: "èµµå
", teamId: 2, teamName: "å端å¼åå¢é", position: "å端ç»é¿", phone: "13800138004", email: "zhaoliu@example.com", currentWorkOrder: "WO20230003", status: "1" }, |
| | | { id: 5, name: "é±ä¸", teamId: 2, teamName: "å端å¼åå¢é", position: "é«çº§å端", phone: "13800138005", email: "qianqi@example.com", currentWorkOrder: "", status: "1" }, |
| | | { id: 6, name: "åå
«", teamId: 2, teamName: "å端å¼åå¢é", position: "å端å¼å", phone: "13800138006", email: "sunba@example.com", currentWorkOrder: "", status: "1" }, |
| | | { id: 7, name: "å¨ä¹", teamId: 3, teamName: "æµè¯å¢é", position: "æµè¯ç»ç", phone: "13800138007", email: "zhoujiu@example.com", currentWorkOrder: "WO20230004", status: "1" }, |
| | | { id: 8, name: "å´å", teamId: 3, teamName: "æµè¯å¢é", position: "æµè¯å·¥ç¨å¸", phone: "13800138008", email: "wushi@example.com", currentWorkOrder: "", status: "1" } |
| | | // å¿è¡ç®¡å
ç§å¢éæå |
| | | { |
| | | id: 1, |
| | | name: "ææç½", |
| | | teamId: 1, |
| | | teamName: "å¿è¡ç®¡å
ç§å¢é", |
| | | position: "主任å»å¸", |
| | | phone: "13800138001", |
| | | email: "lichengbai@hospital.com", |
| | | currentWorkOrder: "MED20230001", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 2, |
| | | name: "åç¿æ ", |
| | | teamId: 1, |
| | | teamName: "å¿è¡ç®¡å
ç§å¢é", |
| | | position: "å¯ä¸»ä»»å»å¸", |
| | | phone: "13800138002", |
| | | email: "liuyihui@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 3, |
| | | name: "å¼ åæ¶µ", |
| | | teamId: 1, |
| | | teamName: "å¿è¡ç®¡å
ç§å¢é", |
| | | position: "主治å»å¸", |
| | | phone: "13800138003", |
| | | email: "zhangmenghan@hospital.com", |
| | | currentWorkOrder: "MED20230002", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 9, |
| | | name: "å´æç¿°", |
| | | teamId: 1, |
| | | teamName: "å¿è¡ç®¡å
ç§å¢é", |
| | | position: "ä½é¢å»å¸", |
| | | phone: "13800138009", |
| | | email: "wusihan@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | |
| | | // è¿ç¤ç§æ²»çå¢éæå |
| | | { |
| | | id: 4, |
| | | name: "éæ¿å©", |
| | | teamId: 2, |
| | | teamName: "è¿ç¤ç§æ²»çå¢é", |
| | | position: "è¿ç¤ç§ä¸»ä»»", |
| | | phone: "13800138004", |
| | | email: "chenzhengqian@hospital.com", |
| | | currentWorkOrder: "MED20230003", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 5, |
| | | name: "éè¯æ¶µ", |
| | | teamId: 2, |
| | | teamName: "è¿ç¤ç§æ²»çå¢é", |
| | | position: "æ¾çå»å¸", |
| | | phone: "13800138005", |
| | | email: "dengshihan@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 6, |
| | | name: "é»çç«", |
| | | teamId: 2, |
| | | teamName: "è¿ç¤ç§æ²»çå¢é", |
| | | position: "åçå»å¸", |
| | | phone: "13800138006", |
| | | email: "huangshengmei@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | |
| | | // å¿ç§è¯çå¢éæå |
| | | { |
| | | id: 7, |
| | | name: "çæ©é¾", |
| | | teamId: 3, |
| | | teamName: "å¿ç§è¯çå¢é", |
| | | position: "å¿ç§ä¸»ä»»", |
| | | phone: "13800138007", |
| | | email: "wagenlong@hospital.com", |
| | | currentWorkOrder: "MED20230004", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 8, |
| | | name: "æ±æ¿å»·", |
| | | teamId: 3, |
| | | teamName: "å¿ç§è¯çå¢é", |
| | | position: "å¿ç§å»å¸", |
| | | phone: "13800138008", |
| | | email: "zhuzhengting@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 10, |
| | | name: "æä½©ç²", |
| | | teamId: 3, |
| | | teamName: "å¿ç§è¯çå¢é", |
| | | position: "å¿ç§æ¤å£«é¿", |
| | | phone: "13800138010", |
| | | email: "linpeiling@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | |
| | | // æ¥è¯æ¢æå¢éæå |
| | | { |
| | | id: 11, |
| | | name: "å´ä¿ä¼¯", |
| | | teamId: 4, |
| | | teamName: "æ¥è¯æ¢æå¢é", |
| | | position: "æ¥è¯ç§ä¸»ä»»", |
| | | phone: "13800138011", |
| | | email: "wujunbo@hospital.com", |
| | | currentWorkOrder: "MED20230005", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 12, |
| | | name: "é®é¦¨å¦", |
| | | teamId: 4, |
| | | teamName: "æ¥è¯æ¢æå¢é", |
| | | position: "æ¥è¯å»å¸", |
| | | phone: "13800138012", |
| | | email: "ruanxinxue@hospital.com", |
| | | currentWorkOrder: "MED20230006", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 13, |
| | | name: "ç¿æ ç ", |
| | | teamId: 4, |
| | | teamName: "æ¥è¯æ¢æå¢é", |
| | | position: "æ¥è¯æ¤å£«", |
| | | phone: "13800138013", |
| | | email: "wenghuizhu@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | |
| | | // å
¶ä»å»ç人å |
| | | { |
| | | id: 14, |
| | | name: "æ¹å
ç", |
| | | teamId: 1, |
| | | teamName: "å¿è¡ç®¡å
ç§å¢é", |
| | | position: "å¿çµæå¸", |
| | | phone: "13800138014", |
| | | email: "fangzhaoyu@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | { |
| | | id: 15, |
| | | name: "䏿±è»", |
| | | teamId: 2, |
| | | teamName: "è¿ç¤ç§æ²»çå¢é", |
| | | position: "ç
çå»å¸", |
| | | phone: "13800138015", |
| | | email: "dinghanzhen@hospital.com", |
| | | currentWorkOrder: "", |
| | | status: "1", |
| | | }, |
| | | ], |
| | | memberTotal: 15, |
| | | memberQueryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: undefined, |
| | | teamId: undefined, |
| | | status: undefined |
| | | status: undefined, |
| | | }, |
| | | memberTotal: 8, |
| | | memberStatusOptions: [ |
| | | { value: "0", label: "ç¦ç¨" }, |
| | | { value: "1", label: "å¯ç¨" } |
| | | { value: "1", label: "å¯ç¨" }, |
| | | ], |
| | | memberFormVisible: false, |
| | | memberFormTitle: "", |
| | |
| | | position: undefined, |
| | | phone: undefined, |
| | | email: undefined, |
| | | status: "1" |
| | | status: "1", |
| | | }, |
| | | memberRules: { |
| | | name: [ |
| | | { required: true, message: "æåå§åä¸è½ä¸ºç©º", trigger: "blur" } |
| | | { required: true, message: "æåå§åä¸è½ä¸ºç©º", trigger: "blur" }, |
| | | ], |
| | | teamId: [ |
| | | { required: true, message: "æå±å¢éä¸è½ä¸ºç©º", trigger: "change" } |
| | | { required: true, message: "æå±å¢éä¸è½ä¸ºç©º", trigger: "change" }, |
| | | ], |
| | | position: [ |
| | | { required: true, message: "èä½ä¸è½ä¸ºç©º", trigger: "blur" } |
| | | { required: true, message: "èä½ä¸è½ä¸ºç©º", trigger: "blur" }, |
| | | ], |
| | | phone: [ |
| | | { required: true, message: "èç³»çµè¯ä¸è½ä¸ºç©º", trigger: "blur" } |
| | | { required: true, message: "èç³»çµè¯ä¸è½ä¸ºç©º", trigger: "blur" }, |
| | | ], |
| | | email: [ |
| | | { required: true, message: "é®ç®±ä¸è½ä¸ºç©º", trigger: "blur" }, |
| | | { type: 'email', message: '请è¾å
¥æ£ç¡®çé®ç®±å°å', trigger: ['blur', 'change'] } |
| | | { |
| | | type: "email", |
| | | message: "请è¾å
¥æ£ç¡®çé®ç®±å°å", |
| | | trigger: ["blur", "change"], |
| | | }, |
| | | ], |
| | | status: [ |
| | | { required: true, message: "æåç¶æä¸è½ä¸ºç©º", trigger: "change" } |
| | | ] |
| | | { required: true, message: "æåç¶æä¸è½ä¸ºç©º", trigger: "change" }, |
| | | ], |
| | | }, |
| | | |
| | | // 工忿´¾ç¸å
³æ°æ® |
| | | workOrderLoading: false, |
| | | // æ¿æ¢åæçworkOrderListæ°æ® |
| | | workOrderList: [ |
| | | { id: "WO20230001", title: "é¦é¡µæ¹çéæ±å¼å", priority: "1", createTime: "2023-03-01 09:30:00", deadline: "2023-03-15 18:00:00", assignee: 1, assigneeName: "å¼ ä¸", status: "1", content: "宿é¦é¡µæ¹ççææå端å¼åå·¥ä½" }, |
| | | { id: "WO20230002", title: "ç¨æ·ä¸å¿æ¥å£å¼å", priority: "2", createTime: "2023-03-05 14:20:00", deadline: "2023-03-20 18:00:00", assignee: 3, assigneeName: "çäº", status: "1", content: "å¼åç¨æ·ä¸å¿ç¸å
³æ¥å£" }, |
| | | { id: "WO20230003", title: "订åç³»ç»æ§è½ä¼å", priority: "1", createTime: "2023-03-10 10:15:00", deadline: "2023-03-25 18:00:00", assignee: 4, assigneeName: "èµµå
", status: "1", content: "ä¼å订åç³»ç»æ§è½ï¼æé«ååºé度" }, |
| | | { id: "WO20230004", title: "æ¯ä»åè½æµè¯", priority: "3", createTime: "2023-03-15 16:45:00", deadline: "2023-03-30 18:00:00", assignee: 7, assigneeName: "å¨ä¹", status: "1", content: "宿æ¯ä»åè½çå
¨é¢æµè¯" }, |
| | | { id: "WO20230005", title: "æ°æ®æ¥è¡¨å¼å", priority: "2", createTime: "2023-03-20 11:10:00", deadline: "2023-04-05 18:00:00", assignee: undefined, assigneeName: undefined, status: "0", content: "å¼åæ°æ®ç»è®¡æ¥è¡¨åè½" } |
| | | { |
| | | id: "MED20230001", |
| | | title: "å å¿ç
æ£è
PCIææ¯å®æ", |
| | | priority: "1", |
| | | createTime: "2024-11-01 09:30:00", |
| | | deadline: "2024-11-05 18:00:00", |
| | | assignee: 1, |
| | | assigneeName: "ææç½", |
| | | status: "1", |
| | | content: |
| | | "为å å¿ç
æ£è
宿ç»ç®å ç¶å¨èä»å
¥æ²»çææ¯ï¼éè¦æ¯åè¯ä¼°ååå¤", |
| | | }, |
| | | { |
| | | id: "MED20230002", |
| | | title: "é«è¡åæ£è
è¯ç©æ²»çæ¹æ¡è°æ´", |
| | | priority: "2", |
| | | createTime: "2024-11-03 14:20:00", |
| | | deadline: "2024-11-08 18:00:00", |
| | | assignee: 3, |
| | | assigneeName: "å¼ åæ¶µ", |
| | | status: "1", |
| | | content: "æ ¹æ®æ£è
è¡åçæµç»æï¼è°æ´éåè¯ç©ç»åååé", |
| | | }, |
| | | { |
| | | id: "MED20230003", |
| | | title: "èºçæ£è
åç卿宿", |
| | | priority: "1", |
| | | createTime: "2024-11-05 10:15:00", |
| | | deadline: "2024-11-10 18:00:00", |
| | | assignee: 4, |
| | | assigneeName: "éæ¿å©", |
| | | status: "1", |
| | | content: "å¶å®èºçæ£è
æ°ä¸æåçæ¹æ¡ï¼å
æ¬è¯ç©éæ©ååé计ç®", |
| | | }, |
| | | { |
| | | id: "MED20230004", |
| | | title: "å¿ç«¥èºçæ£è
è¯çæ¹æ¡", |
| | | priority: "2", |
| | | createTime: "2024-11-08 16:45:00", |
| | | deadline: "2024-11-12 18:00:00", |
| | | assignee: 7, |
| | | assigneeName: "çæ©é¾", |
| | | status: "1", |
| | | content: "为å¿ç«¥èºçæ£è
å¶å®ä¸ªæ§åæ²»çæ¹æ¡ï¼å
æ¬æçç´ éæ©åé¾åæ²»ç", |
| | | }, |
| | | { |
| | | id: "MED20230005", |
| | | title: "æ¥è¯è¸çæ£è
å¿«éè¯ä¼°", |
| | | priority: "1", |
| | | createTime: "2024-11-10 11:10:00", |
| | | deadline: "2024-11-10 23:00:00", |
| | | assignee: 11, |
| | | assigneeName: "å´ä¿ä¼¯", |
| | | status: "1", |
| | | content: "对æ¥è¯è¸çæ£è
è¿è¡å¿«éè¯ä¼°ï¼æé¤æ¥æ§å¿èæ¢æ»å¯è½", |
| | | }, |
| | | { |
| | | id: "MED20230006", |
| | | title: "å¤ä¼¤æ£è
æ¸
åç¼åå¤ç", |
| | | priority: "2", |
| | | createTime: "2024-11-12 13:25:00", |
| | | deadline: "2024-11-12 20:00:00", |
| | | assignee: 12, |
| | | assigneeName: "é®é¦¨å¦", |
| | | status: "1", |
| | | content: "å¤çæ¥è¯å¤ä¼¤æ£è
ç伤壿¸
ååç¼åå·¥ä½", |
| | | }, |
| | | { |
| | | id: "MED20230007", |
| | | title: "ç³å°¿ç
æ£è
è°å²ç´ è°æ´", |
| | | priority: "2", |
| | | createTime: "2024-11-15 08:45:00", |
| | | deadline: "2024-11-20 18:00:00", |
| | | assignee: undefined, |
| | | assigneeName: undefined, |
| | | status: "0", |
| | | content: "æ ¹æ®æ£è
è¡ç³çæµæ°æ®ï¼è°æ´è°å²ç´ ç¨éåæ³¨å°æ¹æ¡", |
| | | }, |
| | | ], |
| | | workOrderTotal: 7, |
| | | workOrderQueryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | id: undefined, |
| | | status: undefined, |
| | | assignee: undefined |
| | | assignee: undefined, |
| | | }, |
| | | workOrderTotal: 5, |
| | | workOrderStatusOptions: [ |
| | | { value: "0", label: "å¾
ææ´¾" }, |
| | | { value: "1", label: "è¿è¡ä¸" }, |
| | | { value: "2", label: "已宿" }, |
| | | { value: "3", label: "已忶" } |
| | | { value: "3", label: "已忶" }, |
| | | ], |
| | | priorityOptions: [ |
| | | { value: "1", label: "é«" }, |
| | | { value: "2", label: "ä¸" }, |
| | | { value: "3", label: "ä½" } |
| | | { value: "3", label: "ä½" }, |
| | | ], |
| | | workOrderFormVisible: false, |
| | | workOrderFormTitle: "", |
| | |
| | | deadline: undefined, |
| | | assignee: undefined, |
| | | status: "0", |
| | | content: undefined |
| | | content: undefined, |
| | | }, |
| | | workOrderRules: { |
| | | title: [ |
| | | { required: true, message: "å·¥åæ é¢ä¸è½ä¸ºç©º", trigger: "blur" } |
| | | { required: true, message: "å·¥åæ é¢ä¸è½ä¸ºç©º", trigger: "blur" }, |
| | | ], |
| | | priority: [ |
| | | { required: true, message: "ä¼å
级ä¸è½ä¸ºç©º", trigger: "change" } |
| | | { required: true, message: "ä¼å
级ä¸è½ä¸ºç©º", trigger: "change" }, |
| | | ], |
| | | deadline: [ |
| | | { required: true, message: "æªæ¢æ¶é´ä¸è½ä¸ºç©º", trigger: "change" } |
| | | { required: true, message: "æªæ¢æ¶é´ä¸è½ä¸ºç©º", trigger: "change" }, |
| | | ], |
| | | content: [ |
| | | { required: true, message: "å·¥åå
容ä¸è½ä¸ºç©º", trigger: "blur" } |
| | | { required: true, message: "å·¥åå
容ä¸è½ä¸ºç©º", trigger: "blur" }, |
| | | ], |
| | | status: [ |
| | | { required: true, message: "å·¥åç¶æä¸è½ä¸ºç©º", trigger: "change" } |
| | | ] |
| | | { required: true, message: "å·¥åç¶æä¸è½ä¸ºç©º", trigger: "change" }, |
| | | ], |
| | | }, |
| | | |
| | | // ææ´¾å·¥åç¸å
³æ°æ® |
| | |
| | | title: undefined, |
| | | assignee: undefined, |
| | | priority: "2", |
| | | deadline: undefined |
| | | } |
| | | deadline: undefined, |
| | | }, |
| | | }; |
| | | }, |
| | | // å¨watch䏿·»å çæ§ |
| | | watch: { |
| | | teamDialogVisible(newVal) { |
| | | if (newVal) { |
| | | // å¯¹è¯æ¡æ¾ç¤ºæ¶éæ°çæäºç»´ç |
| | | this.$nextTick(() => { |
| | | setTimeout(() => { |
| | | this.generateTeamQRContent(this.currentTeam); |
| | | }, 100); |
| | | }); |
| | | } |
| | | }, |
| | | |
| | | }, |
| | | computed: { |
| | | // å¢éæåé项ï¼ç¨äºç©¿æ¢æ¡ï¼ |
| | | memberOptions() { |
| | | return this.memberList.map(member => ({ |
| | | return this.memberList.map((member) => ({ |
| | | key: member.id, |
| | | label: member.name, |
| | | disabled: member.status === "0" |
| | | disabled: member.status === "0", |
| | | })); |
| | | }, |
| | | // è¿æ»¤åçå¢éå表 |
| | | filteredTeamList() { |
| | | let list = [...this.teamList]; |
| | | if (this.teamQueryParams.name) { |
| | | list = list.filter(item => |
| | | list = list.filter((item) => |
| | | item.name.includes(this.teamQueryParams.name) |
| | | ); |
| | | } |
| | | if (this.teamQueryParams.status) { |
| | | list = list.filter(item => |
| | | item.status === this.teamQueryParams.status |
| | | list = list.filter( |
| | | (item) => item.status === this.teamQueryParams.status |
| | | ); |
| | | } |
| | | return list; |
| | |
| | | filteredMemberList() { |
| | | let list = [...this.memberList]; |
| | | if (this.memberQueryParams.name) { |
| | | list = list.filter(item => |
| | | list = list.filter((item) => |
| | | item.name.includes(this.memberQueryParams.name) |
| | | ); |
| | | } |
| | | if (this.memberQueryParams.teamId) { |
| | | list = list.filter(item => |
| | | item.teamId === this.memberQueryParams.teamId |
| | | list = list.filter( |
| | | (item) => item.teamId === this.memberQueryParams.teamId |
| | | ); |
| | | } |
| | | if (this.memberQueryParams.status) { |
| | | list = list.filter(item => |
| | | item.status === this.memberQueryParams.status |
| | | list = list.filter( |
| | | (item) => item.status === this.memberQueryParams.status |
| | | ); |
| | | } |
| | | return list; |
| | |
| | | filteredWorkOrderList() { |
| | | let list = [...this.workOrderList]; |
| | | if (this.workOrderQueryParams.id) { |
| | | list = list.filter(item => |
| | | list = list.filter((item) => |
| | | item.id.includes(this.workOrderQueryParams.id) |
| | | ); |
| | | } |
| | | if (this.workOrderQueryParams.status) { |
| | | list = list.filter(item => |
| | | item.status === this.workOrderQueryParams.status |
| | | list = list.filter( |
| | | (item) => item.status === this.workOrderQueryParams.status |
| | | ); |
| | | } |
| | | if (this.workOrderQueryParams.assignee) { |
| | | list = list.filter(item => |
| | | item.assignee === this.workOrderQueryParams.assignee |
| | | list = list.filter( |
| | | (item) => item.assignee === this.workOrderQueryParams.assignee |
| | | ); |
| | | } |
| | | return list; |
| | |
| | | // å¢éå·¥åï¼ç¨äºå¢é详æ
ï¼ |
| | | teamWorkOrders() { |
| | | if (!this.currentTeam.id) return []; |
| | | const teamMemberIds = this.currentTeam.members.map(member => member.id); |
| | | return this.workOrderList.filter(order => |
| | | const teamMemberIds = this.currentTeam.members.map((member) => member.id); |
| | | return this.workOrderList.filter((order) => |
| | | teamMemberIds.includes(order.assignee) |
| | | ); |
| | | }, |
| | | // å¯ç¨æåï¼ç¨äºå·¥åææ´¾ï¼ |
| | | availableMembers() { |
| | | return this.memberList.filter(member => |
| | | member.status === "1" && !member.currentWorkOrder |
| | | return this.memberList.filter( |
| | | (member) => member.status === "1" && !member.currentWorkOrder |
| | | ); |
| | | } |
| | | }, |
| | | }, |
| | | methods: { |
| | | // è§£ææ¶é´ |
| | |
| | | handleTeamQuery() { |
| | | this.teamQueryParams.pageNum = 1; |
| | | }, |
| | | // æ¥çå¢é详æ
æ¶çæäºç»´ç |
| | | handleTeamDetail(row) { |
| | | this.currentTeam = row; |
| | | this.teamDialogTitle = "å¢é详æ
- " + row.name; |
| | | this.teamDialogVisible = true; |
| | | |
| | | // 使ç¨nextTickç¡®ä¿DOM渲æå®æ |
| | | this.$nextTick(() => { |
| | | // çæä¸´æ¶äºç»´ç å
容 |
| | | this.generateTeamQRContent(row); |
| | | }); |
| | | }, |
| | | |
| | | // çæå¢éäºç»´ç å
容 |
| | | generateTeamQRContent(team) { |
| | | const timestamp = new Date().getTime(); |
| | | const expireTime = timestamp + 24 * 60 * 60 * 1000; // 24å°æ¶æææ |
| | | |
| | | const qrData = { |
| | | teamId: team.id, |
| | | teamName: team.name, |
| | | leader: team.leader, |
| | | memberCount: team.members.length, |
| | | timestamp: timestamp, |
| | | expireTime: expireTime, |
| | | type: "team_info", |
| | | }; |
| | | |
| | | // ç¡®ä¿å
容æ¯åç¬¦ä¸²æ ¼å¼ |
| | | this.teamQRContent = "127.0.0.1:8093/wt?p=0BE9L3C2u"; |
| | | console.log("çæçäºç»´ç å
容:", this.teamQRContent); |
| | | }, |
| | | |
| | | // äºç»´ç çæåè° |
| | | onQRCodeGenerated(dataURL, id) { |
| | | if (dataURL) { |
| | | this.currentQRCodeUrl = dataURL; |
| | | console.log("äºç»´ç çææå"); |
| | | } else { |
| | | console.error("äºç»´ç çæå¤±è´¥"); |
| | | // å¤ç¨æ¹æ¡ï¼ä½¿ç¨qrcode.jsçæ |
| | | this.generateQRCodeWithQRCodeJS(); |
| | | } |
| | | }, |
| | | // å¤ç¨çææ¹æ¡ |
| | | generateQRCodeWithQRCodeJS() { |
| | | const QRCode = require("qrcode"); |
| | | if (this.teamQRContent) { |
| | | QRCode.toDataURL( |
| | | this.teamQRContent, |
| | | { |
| | | width: 200, |
| | | height: 200, |
| | | margin: 2, |
| | | color: { |
| | | dark: "#409EFF", |
| | | light: "#FFFFFF", |
| | | }, |
| | | }, |
| | | (err, url) => { |
| | | if (err) { |
| | | console.error("å¤ç¨äºç»´ç çæå¤±è´¥:", err); |
| | | return; |
| | | } |
| | | this.currentQRCodeUrl = url; |
| | | console.log("å¤ç¨äºç»´ç çææå"); |
| | | } |
| | | ); |
| | | } |
| | | }, |
| | | // ä¸è½½äºç»´ç |
| | | downloadQRCode() { |
| | | if (!this.currentQRCodeUrl) { |
| | | this.$message.warning("请å
çæäºç»´ç "); |
| | | return; |
| | | } |
| | | |
| | | const a = document.createElement("a"); |
| | | const event = new MouseEvent("click"); |
| | | |
| | | a.download = `å¢éäºç»´ç _${ |
| | | this.currentTeam.name |
| | | }_${new Date().getTime()}.png`; |
| | | a.href = this.currentQRCodeUrl; |
| | | a.dispatchEvent(event); |
| | | }, |
| | | |
| | | // å·æ°äºç»´ç |
| | | refreshQRCode() { |
| | | this.generateTeamQRContent(this.currentTeam); |
| | | this.$message.success("äºç»´ç 已巿°"); |
| | | }, |
| | | |
| | | // å¨å·¥å详æ
ä¸ä¹å¯ä»¥æ·»å äºç»´ç åè½ |
| | | handleWorkOrderDetail(row) { |
| | | // çæå·¥åäºç»´ç |
| | | const qrData = { |
| | | workOrderId: row.id, |
| | | title: row.title, |
| | | priority: row.priority, |
| | | status: row.status, |
| | | timestamp: new Date().getTime(), |
| | | type: "work_order", |
| | | }; |
| | | |
| | | this.workOrderQRContent = JSON.stringify(qrData); |
| | | }, |
| | | // éç½®å¢éæç´¢ |
| | | resetTeamQuery() { |
| | | this.resetForm("teamQueryForm"); |
| | |
| | | }, |
| | | // å¢éå¤é |
| | | handleTeamSelectionChange(selection) { |
| | | this.ids = selection.map(item => item.id); |
| | | this.ids = selection.map((item) => item.id); |
| | | this.single = selection.length !== 1; |
| | | this.multiple = !selection.length; |
| | | }, |
| | | // æ¥çå¢é详æ
|
| | | handleTeamDetail(row) { |
| | | this.currentTeam = row; |
| | | this.teamDialogTitle = "å¢é详æ
- " + row.name; |
| | | this.teamDialogVisible = true; |
| | | }, |
| | | // æ°å¢å¢é |
| | | handleTeamAdd() { |
| | |
| | | // ä¿®æ¹å¢é |
| | | handleTeamUpdate(row) { |
| | | this.resetTeamForm(); |
| | | const team = this.teamList.find(item => item.id === row.id); |
| | | const team = this.teamList.find((item) => item.id === row.id); |
| | | this.teamForm = Object.assign({}, team); |
| | | this.teamForm.members = team.members.map(member => member.id); |
| | | this.teamForm.members = team.members.map((member) => member.id); |
| | | this.teamFormTitle = "ä¿®æ¹å¢é"; |
| | | this.teamFormVisible = true; |
| | | }, |
| | | // å é¤å¢é |
| | | handleTeamDelete(row) { |
| | | const teamIds = row.id || this.ids; |
| | | this.$modal.confirm('æ¯å¦ç¡®è®¤å é¤å¢éå称为"' + row.name + '"çæ°æ®é¡¹ï¼').then(() => { |
| | | // 模æå é¤å¢é |
| | | this.teamList = this.teamList.filter(item => item.id !== teamIds); |
| | | this.teamTotal = this.teamList.length; |
| | | this.$modal.msgSuccess("å 餿å"); |
| | | }).catch(() => {}); |
| | | this.$modal |
| | | .confirm('æ¯å¦ç¡®è®¤å é¤å¢éå称为"' + row.name + '"çæ°æ®é¡¹ï¼') |
| | | .then(() => { |
| | | // 模æå é¤å¢é |
| | | this.teamList = this.teamList.filter((item) => item.id !== teamIds); |
| | | this.teamTotal = this.teamList.length; |
| | | this.$modal.msgSuccess("å 餿å"); |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | // æäº¤å¢é表å |
| | | submitTeamForm() { |
| | | this.$refs["teamForm"].validate(valid => { |
| | | this.$refs["teamForm"].validate((valid) => { |
| | | if (valid) { |
| | | if (this.teamForm.id != null) { |
| | | // 模æä¿®æ¹å¢é |
| | | const index = this.teamList.findIndex(item => item.id === this.teamForm.id); |
| | | const index = this.teamList.findIndex( |
| | | (item) => item.id === this.teamForm.id |
| | | ); |
| | | if (index !== -1) { |
| | | const leader = this.memberList.find(member => member.id === this.teamForm.leader); |
| | | const members = this.memberList.filter(member => |
| | | const leader = this.memberList.find( |
| | | (member) => member.id === this.teamForm.leader |
| | | ); |
| | | const members = this.memberList.filter((member) => |
| | | this.teamForm.members.includes(member.id) |
| | | ); |
| | | |
| | | this.teamList.splice(index, 1, { |
| | | ...this.teamForm, |
| | | leader: leader ? leader.name : '', |
| | | members: members |
| | | leader: leader ? leader.name : "", |
| | | members: members, |
| | | }); |
| | | } |
| | | this.$modal.msgSuccess("ä¿®æ¹æå"); |
| | | } else { |
| | | // æ¨¡ææ°å¢å¢é |
| | | const newId = Math.max(...this.teamList.map(item => item.id)) + 1; |
| | | const leader = this.memberList.find(member => member.id === this.teamForm.leader); |
| | | const members = this.memberList.filter(member => |
| | | const newId = Math.max(...this.teamList.map((item) => item.id)) + 1; |
| | | const leader = this.memberList.find( |
| | | (member) => member.id === this.teamForm.leader |
| | | ); |
| | | const members = this.memberList.filter((member) => |
| | | this.teamForm.members.includes(member.id) |
| | | ); |
| | | |
| | | this.teamList.unshift({ |
| | | ...this.teamForm, |
| | | id: newId, |
| | | leader: leader ? leader.name : '', |
| | | leader: leader ? leader.name : "", |
| | | members: members, |
| | | createTime: new Date().toLocaleString() |
| | | createTime: new Date().toLocaleString(), |
| | | }); |
| | | this.teamTotal = this.teamList.length; |
| | | this.$modal.msgSuccess("æ°å¢æå"); |
| | |
| | | leader: undefined, |
| | | members: [], |
| | | status: "1", |
| | | description: undefined |
| | | description: undefined, |
| | | }; |
| | | this.resetForm("teamForm"); |
| | | }, |
| | |
| | | }, |
| | | // æåå¤é |
| | | handleMemberSelectionChange(selection) { |
| | | this.ids = selection.map(item => item.id); |
| | | this.ids = selection.map((item) => item.id); |
| | | this.single = selection.length !== 1; |
| | | this.multiple = !selection.length; |
| | | }, |
| | |
| | | // ä¿®æ¹æå |
| | | handleMemberUpdate(row) { |
| | | this.resetMemberForm(); |
| | | const member = this.memberList.find(item => item.id === row.id); |
| | | const member = this.memberList.find((item) => item.id === row.id); |
| | | this.memberForm = Object.assign({}, member); |
| | | this.memberFormTitle = "ä¿®æ¹æå"; |
| | | this.memberFormVisible = true; |
| | |
| | | // å 餿å |
| | | handleMemberDelete(row) { |
| | | const memberIds = row.id || this.ids; |
| | | this.$modal.confirm('æ¯å¦ç¡®è®¤å 餿åå§å为"' + row.name + '"çæ°æ®é¡¹ï¼').then(() => { |
| | | // 模æå 餿å |
| | | this.memberList = this.memberList.filter(item => item.id !== memberIds); |
| | | this.memberTotal = this.memberList.length; |
| | | this.$modal.msgSuccess("å 餿å"); |
| | | }).catch(() => {}); |
| | | this.$modal |
| | | .confirm('æ¯å¦ç¡®è®¤å 餿åå§å为"' + row.name + '"çæ°æ®é¡¹ï¼') |
| | | .then(() => { |
| | | // 模æå 餿å |
| | | this.memberList = this.memberList.filter( |
| | | (item) => item.id !== memberIds |
| | | ); |
| | | this.memberTotal = this.memberList.length; |
| | | this.$modal.msgSuccess("å 餿å"); |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | // æäº¤æå表å |
| | | submitMemberForm() { |
| | | this.$refs["memberForm"].validate(valid => { |
| | | this.$refs["memberForm"].validate((valid) => { |
| | | if (valid) { |
| | | if (this.memberForm.id != null) { |
| | | // 模æä¿®æ¹æå |
| | | const index = this.memberList.findIndex(item => item.id === this.memberForm.id); |
| | | const index = this.memberList.findIndex( |
| | | (item) => item.id === this.memberForm.id |
| | | ); |
| | | if (index !== -1) { |
| | | const team = this.teamList.find(item => item.id === this.memberForm.teamId); |
| | | const team = this.teamList.find( |
| | | (item) => item.id === this.memberForm.teamId |
| | | ); |
| | | this.memberList.splice(index, 1, { |
| | | ...this.memberForm, |
| | | teamName: team ? team.name : '' |
| | | teamName: team ? team.name : "", |
| | | }); |
| | | } |
| | | this.$modal.msgSuccess("ä¿®æ¹æå"); |
| | | } else { |
| | | // æ¨¡ææ°å¢æå |
| | | const newId = Math.max(...this.memberList.map(item => item.id)) + 1; |
| | | const team = this.teamList.find(item => item.id === this.memberForm.teamId); |
| | | const newId = |
| | | Math.max(...this.memberList.map((item) => item.id)) + 1; |
| | | const team = this.teamList.find( |
| | | (item) => item.id === this.memberForm.teamId |
| | | ); |
| | | this.memberList.unshift({ |
| | | ...this.memberForm, |
| | | id: newId, |
| | | teamName: team ? team.name : '', |
| | | currentWorkOrder: '' |
| | | teamName: team ? team.name : "", |
| | | currentWorkOrder: "", |
| | | }); |
| | | this.memberTotal = this.memberList.length; |
| | | this.$modal.msgSuccess("æ°å¢æå"); |
| | |
| | | position: undefined, |
| | | phone: undefined, |
| | | email: undefined, |
| | | status: "1" |
| | | status: "1", |
| | | }; |
| | | this.resetForm("memberForm"); |
| | | }, |
| | |
| | | }, |
| | | // å·¥åå¤é |
| | | handleWorkOrderSelectionChange(selection) { |
| | | this.ids = selection.map(item => item.id); |
| | | this.ids = selection.map((item) => item.id); |
| | | this.single = selection.length !== 1; |
| | | this.multiple = !selection.length; |
| | | }, |
| | |
| | | // ä¿®æ¹å·¥å |
| | | handleWorkOrderUpdate(row) { |
| | | this.resetWorkOrderForm(); |
| | | const workOrder = this.workOrderList.find(item => item.id === row.id); |
| | | const workOrder = this.workOrderList.find((item) => item.id === row.id); |
| | | this.workOrderForm = Object.assign({}, workOrder); |
| | | this.workOrderFormTitle = "ç¼è¾å·¥å"; |
| | | this.workOrderFormVisible = true; |
| | |
| | | // å é¤å·¥å |
| | | handleWorkOrderDelete(row) { |
| | | const workOrderIds = row.id || this.ids; |
| | | this.$modal.confirm('æ¯å¦ç¡®è®¤å é¤å·¥åæ é¢ä¸º"' + row.title + '"çæ°æ®é¡¹ï¼').then(() => { |
| | | // 模æå é¤å·¥å |
| | | this.workOrderList = this.workOrderList.filter(item => item.id !== workOrderIds); |
| | | this.workOrderTotal = this.workOrderList.length; |
| | | this.$modal.msgSuccess("å 餿å"); |
| | | }).catch(() => {}); |
| | | this.$modal |
| | | .confirm('æ¯å¦ç¡®è®¤å é¤å·¥åæ é¢ä¸º"' + row.title + '"çæ°æ®é¡¹ï¼') |
| | | .then(() => { |
| | | // 模æå é¤å·¥å |
| | | this.workOrderList = this.workOrderList.filter( |
| | | (item) => item.id !== workOrderIds |
| | | ); |
| | | this.workOrderTotal = this.workOrderList.length; |
| | | this.$modal.msgSuccess("å 餿å"); |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | // ææ´¾å·¥å |
| | | handleAssignWorkOrder(row) { |
| | |
| | | title: row.title, |
| | | assignee: undefined, |
| | | priority: row.priority, |
| | | deadline: row.deadline |
| | | deadline: row.deadline, |
| | | }; |
| | | this.assignDialogVisible = true; |
| | | }, |
| | | // æäº¤å·¥å表å |
| | | submitWorkOrderForm() { |
| | | this.$refs["workOrderForm"].validate(valid => { |
| | | this.$refs["workOrderForm"].validate((valid) => { |
| | | if (valid) { |
| | | if (this.workOrderForm.id != null) { |
| | | // 模æä¿®æ¹å·¥å |
| | | const index = this.workOrderList.findIndex(item => item.id === this.workOrderForm.id); |
| | | const index = this.workOrderList.findIndex( |
| | | (item) => item.id === this.workOrderForm.id |
| | | ); |
| | | if (index !== -1) { |
| | | const assignee = this.memberList.find(member => member.id === this.workOrderForm.assignee); |
| | | const assignee = this.memberList.find( |
| | | (member) => member.id === this.workOrderForm.assignee |
| | | ); |
| | | this.workOrderList.splice(index, 1, { |
| | | ...this.workOrderForm, |
| | | assigneeName: assignee ? assignee.name : undefined |
| | | assigneeName: assignee ? assignee.name : undefined, |
| | | }); |
| | | } |
| | | this.$modal.msgSuccess("ä¿®æ¹æå"); |
| | | } else { |
| | | // æ¨¡ææ°å¢å·¥å |
| | | const newId = "WO" + new Date().getFullYear() + (Math.floor(Math.random() * 90000) + 10000); |
| | | const assignee = this.memberList.find(member => member.id === this.workOrderForm.assignee); |
| | | const newId = |
| | | "WO" + |
| | | new Date().getFullYear() + |
| | | (Math.floor(Math.random() * 90000) + 10000); |
| | | const assignee = this.memberList.find( |
| | | (member) => member.id === this.workOrderForm.assignee |
| | | ); |
| | | this.workOrderList.unshift({ |
| | | ...this.workOrderForm, |
| | | id: newId, |
| | | assigneeName: assignee ? assignee.name : undefined, |
| | | createTime: new Date().toLocaleString() |
| | | createTime: new Date().toLocaleString(), |
| | | }); |
| | | this.workOrderTotal = this.workOrderList.length; |
| | | this.$modal.msgSuccess("æ°å¢æå"); |
| | |
| | | deadline: undefined, |
| | | assignee: undefined, |
| | | status: "0", |
| | | content: undefined |
| | | content: undefined, |
| | | }; |
| | | this.resetForm("workOrderForm"); |
| | | }, |
| | |
| | | } |
| | | |
| | | // æ¨¡æææ´¾å·¥å |
| | | const index = this.workOrderList.findIndex(item => item.id === this.assignForm.id); |
| | | const index = this.workOrderList.findIndex( |
| | | (item) => item.id === this.assignForm.id |
| | | ); |
| | | if (index !== -1) { |
| | | const assignee = this.memberList.find(member => member.id === this.assignForm.assignee); |
| | | const assignee = this.memberList.find( |
| | | (member) => member.id === this.assignForm.assignee |
| | | ); |
| | | if (assignee) { |
| | | // æ´æ°å·¥åç¶æ |
| | | this.workOrderList.splice(index, 1, { |
| | |
| | | assigneeName: assignee.name, |
| | | priority: this.assignForm.priority, |
| | | deadline: this.assignForm.deadline, |
| | | status: "1" |
| | | status: "1", |
| | | }); |
| | | |
| | | // æ´æ°æåå½åå·¥å |
| | | const memberIndex = this.memberList.findIndex(member => member.id === this.assignForm.assignee); |
| | | const memberIndex = this.memberList.findIndex( |
| | | (member) => member.id === this.assignForm.assignee |
| | | ); |
| | | if (memberIndex !== -1) { |
| | | this.memberList.splice(memberIndex, 1, { |
| | | ...this.memberList[memberIndex], |
| | | currentWorkOrder: this.assignForm.id |
| | | currentWorkOrder: this.assignForm.id, |
| | | }); |
| | | } |
| | | |
| | |
| | | this.assignDialogVisible = false; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | |
| | | } |
| | | |
| | | .avatar-uploader ::v-deep .el-upload:hover { |
| | | border-color: #409EFF; |
| | | border-color: #409eff; |
| | | } |
| | | |
| | | .avatar-uploader-icon { |
| | |
| | | display: block; |
| | | } |
| | | |
| | | .team-members, .team-work-orders { |
| | | .team-members, |
| | | .team-work-orders { |
| | | margin-top: 20px; |
| | | } |
| | | </style> |
| | |
| | | // target: `http://192.168.168.60:8095`, |
| | | // target: `http://192.168.144.34:8095`, |
| | | // target: `http://220.66.136.101:8095`, |
| | | target:`http://localhost:8095`, |
| | | target: `http://192.168.100.10:8099`, |
| | | // target:`http://localhost:8095`, |
| | | changeOrigin: true, |
| | | pathRewrite: { |
| | | ['^' + process.env.VUE_APP_BASE_API]: '' |