| src/api/businessApi/followup.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/business/GetWitness/GetWitnessInfo.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/business/GetWitness/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/business/OrganUtilization/OrganUtilizationInfo.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/business/allocation/allocationInfo.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/business/followupVisit/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/business/followupVisit/info.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/project/components/orgselect/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/api/businessApi/followup.js
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,48 @@ import request from '@/utils/request' // æ¡ä¾å表å详æ export function listFollowup(data) { return request({ url: '/project/donatefollowup/list', method: 'post', data: data }) } // åè éè®¿ä¿®æ¹ export function addFollowup(data) { return request({ url: '/project/donatefollowup/add', method: 'post', data: data }) } // åè éè®¿ä¿®æ¹ export function updateFollowup(data) { return request({ url: '/project/donatefollowup/edit', method: 'post', data: data }) } // åè é访详æ export function getFollowup(id) { return request({ url: '/project/donatefollowup/' + id, method: 'get' }) } // å é¤ export function delFollowup(id) { return request({ url: '/project/donatefollowup/remove/' + id, method: 'get' }) } // 导åºåè é访 export function exportFollowup(query) { return request({ url: '/project/donatefollowup/export', method: 'get', params: query }) } src/views/business/GetWitness/GetWitnessInfo.vue
@@ -13,7 +13,6 @@ <el-button type="success" @click="handleProcure" :disabled="form.recordstate === 'completed'" :loading="confirmLoading" > 确认è·å @@ -22,7 +21,6 @@ </div> <el-form :model="form" ref="form" :rules="rules" label-width="120px"> <!-- ææ¯ç¸å ³ä¿¡æ¯ --> <el-divider content-position="left">ææ¯ä¿¡æ¯</el-divider> @@ -39,7 +37,6 @@ type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> @@ -50,7 +47,6 @@ type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> @@ -67,7 +63,6 @@ type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> @@ -81,7 +76,6 @@ type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> @@ -89,30 +83,22 @@ <el-row :gutter="20"> <el-col :span="8"> <el-form-item label="é¨éèæç®¡æ¶é´" prop="portalveincannulatime" > <el-form-item label="é¨éèæç®¡æ¶é´" prop="portalveincannulatime"> <el-date-picker v-model="form.portalveincannulatime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="é¨éèçæ³¨æ¶é´" prop="portalveinperfusiontime" > <el-form-item label="é¨éèçæ³¨æ¶é´" prop="portalveinperfusiontime"> <el-date-picker v-model="form.portalveinperfusiontime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> @@ -122,11 +108,11 @@ <el-divider content-position="left">åè°åä¿¡æ¯</el-divider> <el-row :gutter="20"> <el-col :span="8"> <!-- <el-col :span="8"> <el-form-item label="åè°åå§å" prop="coordinatorName"> <el-input v-model="form.coordinatorName" /> </el-form-item> </el-col> </el-col> --> <el-col :span="8"> <el-form-item label="è¿ææ¯å®¤æ¶é´" prop="coordinatorInOperating"> <el-date-picker @@ -134,7 +120,6 @@ type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> @@ -145,7 +130,6 @@ type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> @@ -164,7 +148,6 @@ type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> @@ -212,33 +195,6 @@ </el-form-item> </el-col> </el-row> <!-- è®°å½ä¿¡æ¯ --> <el-divider content-position="left">è®°å½ä¿¡æ¯</el-divider> <el-row :gutter="20"> <el-col :span="8"> <el-form-item label="ä½é¢å·" prop="donorno"> <el-input v-model="form.donorno" readonly /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="æå¨å»çæºæ" prop="treatmenthospitalname"> <el-input v-model="form.treatmenthospitalname" placeholder="请è¾å ¥å»çæºæåç§°" /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="å»çæºæç¼ç " prop="treatmenthospitalno"> <el-input v-model="form.treatmenthospitalno" placeholder="请è¾å ¥å»çæºæç¼ç " /> </el-form-item> </el-col> </el-row> </el-form> </el-card> @@ -247,13 +203,15 @@ <div slot="header" class="clearfix"> <span class="detail-title">å¨å®è·åè®°å½</span> <div style="float: right;"> <el-tag :type=" form.recordstate === 'completed' ? 'success' : 'warning' " <!-- <el-tag :type="form.witnessState === 'completed' ? 'success' : 'warning'" > {{ form.recordstate === "completed" ? "已宿" : "è¿è¡ä¸" }} </el-tag> {{ form.witnessState === "completed" ? "已宿" : "è¿è¡ä¸" }} </el-tag> --> <dict-tag :options="dict.type.sys_user_sex" :value="form.witnessState" /> </div> </div> @@ -274,7 +232,6 @@ v-for="dict in dict.type.sys_Organ || []" :key="dict.value" :label="dict.value" :disabled="form.recordstate === 'completed'" > {{ dict.label }} </el-checkbox> @@ -323,7 +280,6 @@ type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="éæ©è·åå¼å§æ¶é´" :disabled="form.recordstate === 'completed'" /> </template> </el-table-column> @@ -332,18 +288,17 @@ label="å¨å®ç¦»ä½æ¶é´" align="center" width="180" prop="organGetTime" prop="organgettime" > <template slot-scope="scope"> <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.organGetTime" v-model="scope.row.organgettime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="éæ©å¨å®ç¦»ä½æ¶é´" :disabled="form.recordstate === 'completed'" /> </template> </el-table-column> @@ -352,14 +307,13 @@ label="è·åå»é¢" align="center" width="200" prop="gainHospitalNo" prop="gainhospitalno" > <template slot-scope="scope"> <el-select v-model="scope.row.gainHospitalNo" v-model="scope.row.gainhospitalno" placeholder="è¯·éæ©è·åå»é¢" style="width: 100%" :disabled="form.recordstate === 'completed'" @change="handleHospitalChange(scope.row, $event)" > <el-option @@ -376,18 +330,17 @@ label="è·åå»å¸" align="center" width="120" prop="organGetDoctor" prop="organgetdoct" > <template slot-scope="scope"> <el-input v-model="scope.row.organGetDoctor" v-model="scope.row.organgetdoct" placeholder="è·åå»å¸" :disabled="form.recordstate === 'completed'" /> </template> </el-table-column> <el-table-column <!-- <el-table-column label="婿" align="center" width="120" @@ -397,12 +350,12 @@ <el-input v-model="scope.row.assistant" placeholder="婿" :disabled="form.recordstate === 'completed'" /> </template> </el-table-column> </el-table-column> --> <el-table-column <!-- <el-table-column label="è·åæ¤å£«" align="center" width="120" @@ -412,7 +365,7 @@ <el-input v-model="scope.row.procurementNurse" placeholder="è·åæ¤å£«" :disabled="form.recordstate === 'completed'" /> </template> </el-table-column> @@ -427,41 +380,25 @@ <el-input v-model="scope.row.operatingRoomNurse" placeholder="ææ¯å®¤æ¤å£«" :disabled="form.recordstate === 'completed'" /> </template> </el-table-column> <el-table-column label="麻éå»ç" align="center" width="120" prop="anesthesiologist" > <template slot-scope="scope"> <el-input v-model="scope.row.anesthesiologist" placeholder="麻éå»ç" :disabled="form.recordstate === 'completed'" /> </template> </el-table-column> </el-table-column> --> <el-table-column label="è·åç¶æ" align="center" width="120" prop="organState" prop="organstate" > <template slot-scope="scope"> <el-select v-model="scope.row.organState" v-model="scope.row.organstate" placeholder="è¯·éæ©è·åç¶æ" style="width: 100%" :disabled="form.recordstate === 'completed'" > <el-option v-for="dict in organStateList" v-for="dict in dict.type.Obtain_status" :key="dict.value" :label="dict.label" :value="dict.value" @@ -473,16 +410,15 @@ <el-table-column label="说æ" align="center" prop="notGetReason" prop="notgetreason" min-width="200" > <template slot-scope="scope"> <el-input type="textarea" clearable v-model="scope.row.notGetReason" v-model="scope.row.notgetreason" placeholder="请è¾å ¥æªè·å说æ" :disabled="form.recordstate === 'completed'" /> </template> </el-table-column> @@ -492,7 +428,6 @@ align="center" width="120" class-name="small-padding fixed-width" v-if="form.recordstate !== 'completed'" > <template slot-scope="scope"> <el-button @@ -511,16 +446,22 @@ </el-row> <!-- è·åç»è®¡ä¿¡æ¯ --> <div <!-- <div class="procurement-stats" v-if="procurementData.serviceDonationwitnessorgans && procurementData.serviceDonationwitnessorgans.length > 0" v-if=" procurementData.serviceDonationwitnessorgans && procurementData.serviceDonationwitnessorgans.length > 0 " > <el-row :gutter="20"> <el-col :span="6"> <div class="stat-item"> <span class="stat-label">å·²è·åå¨å®:</span> <span class="stat-value" >{{ procurementData.serviceDonationwitnessorgans.length }} 个</span >{{ procurementData.serviceDonationwitnessorgans.length }} 个</span > </div> </el-col> @@ -542,48 +483,26 @@ <span class="stat-value"> <el-tag :type=" form.recordstate === 'completed' ? 'success' : 'warning' form.witnessState === 'completed' ? 'success' : 'warning' " > {{ form.recordstate === "completed" ? "已宿" : "è¿è¡ä¸" }} {{ form.witnessState === "completed" ? "已宿" : "è¿è¡ä¸" }} </el-tag> </span> </div> </el-col> </el-row> </div> </div> --> <div v-else class="empty-procurement"> <div v-if="!procurementData.serviceDonationwitnessorgans" class="empty-procurement" > <el-empty description="ææ è·åè®°å½" :image-size="80"> <span>请å éæ©è¦è·åçå¨å®</span> </el-empty> </div> </el-form> <div class="dialog-footer" v-if="form.recordstate !== 'completed'"> <el-button type="primary" @click="handleSaveProcurement" :loading="saveLoading" :disabled="!procurementData.serviceDonationwitnessorgans || procurementData.serviceDonationwitnessorgans.length === 0" > ä¿åè·åè®°å½ </el-button> <el-button type="success" @click="handleConfirmProcurement" :loading="confirmLoading" :disabled="incompleteRecords > 0" > ç¡®è®¤å®æè·å </el-button> </div> </el-card> <!-- é件管çé¨åä¼å --> @@ -610,10 +529,7 @@ /> <!-- éä»¶å表å±ç¤º --> <div class="attachment-list" v-if="attachments && attachments.length > 0" > <div class="attachment-list" v-if="attachments && attachments.length > 0"> <div class="list-title">å·²ä¸ä¼ éä»¶ ({{ attachments.length }})</div> <el-table :data="attachments" style="width: 100%" size="small"> <el-table-column label="æä»¶å" min-width="200"> @@ -687,9 +603,9 @@ </el-col> <el-col :span="12"> <el-form-item label="è·åç¶æ"> <el-select v-model="currentRecord.organState" style="width: 100%"> <el-select v-model="currentRecord.organstate" style="width: 100%"> <el-option v-for="dict in organStateList" v-for="dict in dict.type.Obtain_status" :key="dict.value" :label="dict.label" :value="dict.value" @@ -703,7 +619,7 @@ <el-col :span="12"> <el-form-item label="è·åå»å¸"> <el-input v-model="currentRecord.organGetDoctor" v-model="currentRecord.organgetdoct" placeholder="请è¾å ¥è·åå»å¸" /> </el-form-item> @@ -746,12 +662,12 @@ <el-form-item label="æªè·å说æ" v-if="currentRecord.organState === '0'" v-if="currentRecord.organstate === '0'" > <el-input type="textarea" :rows="3" v-model="currentRecord.notGetReason" v-model="currentRecord.notgetreason" placeholder="请è¾å ¥æªè·åçåå 说æ" /> </el-form-item> @@ -772,10 +688,17 @@ > <div v-if="currentPreviewFile"> <div v-if="currentPreviewFile.fileType === 'image'"> <img :src="currentPreviewFile.fileUrl" style="max-width: 100%; max-height: 500px;" /> <img :src="currentPreviewFile.fileUrl" style="max-width: 100%; max-height: 500px;" /> </div> <div v-else-if="currentPreviewFile.fileType === 'pdf'"> <iframe :src="currentPreviewFile.fileUrl" width="100%" height="500px"></iframe> <iframe :src="currentPreviewFile.fileUrl" width="100%" height="500px" ></iframe> </div> <div v-else> <p>䏿¯æé¢è§æ¤æä»¶ç±»åï¼è¯·ä¸è½½æ¥ç</p> @@ -786,7 +709,7 @@ </template> <script> import { witnessList, witnessadd, witnessedit, } from "@/api/businessApi"; import { witnessList, witnessadd, witnessedit } from "@/api/businessApi"; import UploadAttachment from "@/components/UploadAttachment"; import CaseBasicInfo from "@/components/CaseBasicInfo"; import dayjs from "dayjs"; @@ -794,9 +717,15 @@ export default { name: "OrganProcurementDetail", components: { UploadAttachment,CaseBasicInfo UploadAttachment, CaseBasicInfo }, dicts: ["sys_BloodType", "sys_DonationCategory", "sys_Organ"], dicts: [ "sys_BloodType", "sys_DonationCategory", "sys_Organ", "Obtain_status" ], data() { return { caseId: null, @@ -806,7 +735,7 @@ infoid: undefined, name: "", inpatientno: "", recordstate: "pending", witnessState: "2", caseNo: "", donorno: "", treatmenthospitalname: "", @@ -879,12 +808,6 @@ selectedOrgans: [], // å»é¢å表 hospitalList: [], // å¨å®ç¶æå表 organStateList: [ { value: "1", label: "å·²è·å" }, { value: "0", label: "æªè·å" }, { value: "2", label: "é¨åè·å" } ], // è·åè®°å½æ°æ® procurementData: { serviceDonationwitnessorgans: [] @@ -894,7 +817,8 @@ attachmentFileList: [], // éä»¶ç¸å ³é ç½® attachmentLimit: 10, attachmentAccept: ".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt", attachmentAccept: ".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt", // ç¼è¾å¯¹è¯æ¡ editDialogVisible: false, currentRecord: {}, @@ -916,16 +840,16 @@ return this.procurementData.serviceDonationwitnessorgans.filter( record => !record.organStartTime || !record.organGetTime || !record.gainHospitalNo || !record.organGetDoctor !record.organgettime || !record.gainhospitalno || !record.organgetdoct ).length; }, // å¯ä¸å»é¢æ°é uniqueHospitals() { if (!this.procurementData.serviceDonationwitnessorgans) return 0; const hospitals = this.procurementData.serviceDonationwitnessorgans .map(record => record.gainHospitalNo) .map(record => record.gainhospitalno) .filter(Boolean); return new Set(hospitals).size; }, @@ -973,7 +897,7 @@ } this.form.infoid = infoid; this.generateDonorNo(); // this.generateDonorNo(); if (infoid) { this.getDetail(infoid); @@ -982,12 +906,12 @@ this.getHospitalData(); }, // çææç®è ç¼å· generateDonorNo() { const timestamp = Date.now().toString(); this.form.donorno = "D" + timestamp.slice(-8); this.form.caseNo = "CASE" + timestamp.slice(-6); this.form.inpatientno = "IP" + timestamp.slice(-6); }, // generateDonorNo() { // const timestamp = Date.now().toString(); // this.form.donorno = "D" + timestamp.slice(-8); // this.form.caseNo = "CASE" + timestamp.slice(-6); // this.form.inpatientno = "IP" + timestamp.slice(-6); // }, // è·å详æ async getDetail(infoid) { this.loading = true; @@ -999,12 +923,16 @@ response.data.length > 0 ) { const data = response.data[0]; if (!data.witnessState || data.witnessState == 1) { data.witnessState = "2"; } // å¡«å è¡¨åæ°æ® Object.assign(this.form, data); // åå§åéä»¶ if (this.form.attachments) { if (this.form.deathjudgeannex) { this.form.attachments = JSON.parse(this.form.deathjudgeannex); this.attachments = Array.isArray(this.form.attachments) ? [...this.form.attachments] : []; @@ -1122,7 +1050,10 @@ ); } // 妿鿩äº"å·¦è¾"æ"å³è¾"ï¼åæ¶"åè¾"éæ© else if (selectedValues.includes("C64L") || selectedValues.includes("C64R")) { else if ( selectedValues.includes("C64L") || selectedValues.includes("C64R") ) { this.selectedOrgans = selectedValues.filter(item => item !== "C64"); } @@ -1133,7 +1064,10 @@ ); } // 妿鿩äº"å·¦èº"æ"å³èº"ï¼åæ¶"å ¨èº"éæ© else if (selectedValues.includes("C34L") || selectedValues.includes("C34R")) { else if ( selectedValues.includes("C34L") || selectedValues.includes("C34R") ) { this.selectedOrgans = selectedValues.filter(item => item !== "C34"); } }, @@ -1147,16 +1081,16 @@ organname: organName, organno: organValue, organStartTime: "", organGetTime: "", gainHospitalNo: "", gainHospitalName: "", organGetDoctor: "", organgettime: "", gainhospitalno: "", gainhospitalname: "", organgetdoct: "", assistant: "", procurementNurse: "", operatingRoomNurse: "", anesthesiologist: "", organState: "1", notGetReason: "" organstate: "1", notgetreason: "" }); }, @@ -1166,7 +1100,7 @@ item => item.hospitalNo === hospitalNo ); if (hospital) { row.gainHospitalName = hospital.hospitalName; row.gainhospitalname = hospital.hospitalName; } }, // ç¼è¾è·åè®°å½ @@ -1183,7 +1117,9 @@ // 确认ç¼è¾ handleEditConfirm() { if (this.currentEditIndex !== -1) { this.procurementData.serviceDonationwitnessorgans[this.currentEditIndex] = { this.procurementData.serviceDonationwitnessorgans[ this.currentEditIndex ] = { ...this.currentRecord }; this.$message.success("è·åè®°å½æ´æ°æå"); @@ -1194,9 +1130,9 @@ getOrganRowClassName({ row }) { if ( !row.organStartTime || !row.organGetTime || !row.gainHospitalNo || !row.organGetDoctor !row.organgettime || !row.gainhospitalno || !row.organgetdoct ) { return "warning-row"; } @@ -1210,9 +1146,9 @@ try { const saveData = { ...this.form, attachments: this.attachments, deathjudgeannex: JSON.stringify(this.attachments), organdonation: this.selectedOrgans.join(","), serviceDonationwitnessorgans: serviceDonationwitnessorganList: this.procurementData.serviceDonationwitnessorgans || [] }; @@ -1286,11 +1222,13 @@ }) .then(async () => { this.confirmLoading = true; this.form.recordstate = "completed"; this.form.operationendtime = this.form.operationendtime || new Date() .toISOString() .replace("T", " ") .substring(0, 19); this.form.witnessState = "3"; this.form.operationendtime = this.form.operationendtime || new Date() .toISOString() .replace("T", " ") .substring(0, 19); try { const saveData = { @@ -1309,13 +1247,13 @@ this.$message.error( "确认è·å失败ï¼" + (response.msg || "æªç¥é误") ); this.form.recordstate = "pending"; this.form.witnessState = "2"; this.form.operationendtime = ""; } } catch (error) { console.error("确认è·å失败:", error); this.$message.error("确认è·å失败"); this.form.recordstate = "pending"; this.form.witnessState = "2"; this.form.operationendtime = ""; } finally { this.confirmLoading = false; @@ -1415,7 +1353,10 @@ /** è·åæä»¶ç±»å */ getFileType(fileName) { if (!fileName) return "other"; const extension = fileName.split(".").pop().toLowerCase(); const extension = fileName .split(".") .pop() .toLowerCase(); const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"]; const pdfTypes = ["pdf"]; const officeTypes = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"]; @@ -1469,7 +1410,10 @@ /** è·åæä»¶æ©å±å */ getFileExtension(filename) { return filename.split(".").pop().toLowerCase(); return filename .split(".") .pop() .toLowerCase(); }, /** æ ¼å¼åæä»¶å¤§å° */ src/views/business/GetWitness/index.vue
@@ -26,15 +26,19 @@ @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item label="è·åç¶æ" prop="recordstate"> <el-form-item label="è·åç¶æ" prop="witnessState"> <el-select v-model="queryParams.recordstate" v-model="queryParams.witnessState" placeholder="è¯·éæ©è·åç¶æ" clearable style="width: 200px" > <el-option label="å·²è·å" value="1" /> <el-option label="å¾ è·å" value="0" /> <el-option v-for="dict in dict.type.Obtain_status" :key="dict.value" :label="dict.label" :value="dict.value" /> </el-select> </el-form-item> <el-form-item> @@ -108,15 +112,14 @@ <el-table-column label="è·åç¶æ" align="center" prop="recordstate" prop="witnessState" width="100" > <template slot-scope="scope"> <el-tag :type="scope.row.recordstate === '1' ? 'success' : 'warning'" > {{ scope.row.recordstate === "1" ? "å·²è·å" : "å¾ è·å" }} </el-tag> <dict-tag :options="dict.type.Obtain_status" :value="scope.row.witnessState" /> </template> </el-table-column> <el-table-column @@ -191,7 +194,7 @@ export default { name: "OrganProcurementList", components: { Pagination }, dicts: ["sys_user_sex"], dicts: ["sys_user_sex",'Obtain_status'], data() { return { // é®ç½©å± @@ -212,7 +215,7 @@ pageSize: 10, inpatientno: undefined, name: undefined, recordstate: undefined witnessState: undefined } }; }, src/views/business/OrganUtilization/OrganUtilizationInfo.vue
@@ -1,5 +1,7 @@ <template> <div class="organ-utilization-detail"> <case-basic-info :case-id="caseId" :show-attachment="true" /> <!-- åºæ¬ä¿¡æ¯ --> <el-card class="detail-card"> <div slot="header" class="clearfix"> @@ -11,7 +13,8 @@ <el-button type="success" @click="handleComplete" :disabled="form.utilizationStatus === 'completed'" :disabled="form.recordstate === 'completed'" :loading="confirmLoading" > 宿å©ç¨ </el-button> @@ -20,76 +23,9 @@ <el-form :model="form" ref="form" :rules="rules" label-width="120px"> <el-row :gutter="20"> <el-col :span="8"> <el-form-item label="ä½é¢å·" prop="hospitalNo"> <el-input v-model="form.hospitalNo" readonly /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="ä½é¢å·" prop="caseNo"> <el-input v-model="form.caseNo" readonly /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="æç®è å§å" prop="donorName"> <el-input v-model="form.donorName" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="8"> <el-form-item label="æ§å«" prop="gender"> <el-select v-model="form.gender" style="width: 100%"> <el-option label="ç·" value="0" /> <el-option label="女" value="1" /> </el-select> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="å¹´é¾" prop="age"> <el-input v-model="form.age" /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="åºçæ¥æ" prop="birthDate"> <el-date-picker v-model="form.birthDate" type="date" value-format="yyyy-MM-dd" style="width: 100%" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="ç¾ç è¯æ" prop="diagnosis"> <el-input type="textarea" :rows="2" v-model="form.diagnosis" placeholder="请è¾å ¥ç¾ç è¯æä¿¡æ¯" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="åé æ¶é´" prop="allocationTime"> <el-date-picker v-model="form.allocationTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="6"> <el-form-item align="left" label="é使ç®" prop="isBodyDonation"> <el-radio-group v-model="form.isBodyDonation"> <el-form-item align="left" label="é使ç®" prop="isbodydonation"> <el-radio-group v-model="form.isbodydonation"> <el-radio v-for="dict in dict.type.sys_0_1 || []" :key="dict.value" @@ -100,11 +36,11 @@ </el-form-item> </el-col> <el-col :span="18"> <el-form-item align="left" label="æ¥æ¶åä½" prop="receivingUnit"> <el-form-item align="left" label="æ¥æ¶åä½" prop="receivingunit"> <el-input v-model="form.receivingUnit" v-model="form.receivingunit" placeholder="请è¾å ¥æ¥æ¶åä½" :disabled="form.isBodyDonation !== '1'" :disabled="form.isbodydonation !== '1'" /> </el-form-item> </el-col> @@ -112,61 +48,37 @@ <el-row :gutter="20"> <el-col :span="6"> <el-form-item label="è´è´£äºº" prop="responsibleUserId"> <el-select v-model="form.responsibleUserId" placeholder="è¯·éæ©è´è´£äºº" style="width: 100%" > <el-option v-for="item in leaderList" :key="item.reportNo" :label="item.reportName" :value="item.reportNo" /> </el-select> <el-form-item label="è´è´£äºº" prop="responsibleusername"> <el-input v-model="form.responsibleusername" placeholder="请è¾å ¥è´è´£äººå§å" /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="åè°åä¸" prop="coordinatedUserId1"> <el-select v-model="form.coordinatedUserId1" placeholder="è¯·éæ©åè°å" style="width: 100%" > <el-option v-for="item in coordinatorList" :key="item.reportNo" :label="item.reportName" :value="item.reportNo" /> </el-select> <el-form-item label="åè°åä¸" prop="coordinatedusernameo"> <el-input v-model="form.coordinatedusernameo" placeholder="请è¾å ¥åè°åä¸å§å" /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="åè°åäº" prop="coordinatedUserId2"> <el-select v-model="form.coordinatedUserId2" placeholder="è¯·éæ©åè°å" style="width: 100%" > <el-option v-for="item in coordinatorList" :key="item.reportNo" :label="item.reportName" :value="item.reportNo" /> </el-select> <el-form-item label="åè°åäº" prop="coordinatedusernamet"> <el-input v-model="form.coordinatedusernamet" placeholder="请è¾å ¥åè°åäºå§å" /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="宿æ¶é´" prop="completionTime"> <el-form-item label="宿æ¶é´" prop="completetime"> <el-date-picker v-model="form.completionTime" v-model="form.completetime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" :disabled="form.utilizationStatus !== 'completed'" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> @@ -174,14 +86,14 @@ <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="ç»è®°äºº" prop="registrant"> <el-input v-model="form.registrant" /> <el-form-item label="ç»è®°äºº" prop="createBy"> <el-input v-model="form.createBy" readonly /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="ç»è®°æ¶é´" prop="registrationTime"> <el-form-item label="ç»è®°æ¶é´" prop="createTime"> <el-date-picker v-model="form.registrationTime" v-model="form.createTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" @@ -193,13 +105,13 @@ </el-form> </el-card> <!-- å¨å®å©ç¨è®°å½é¨å --> <!-- å¨å®å©ç¨è®°å½é¨å - æ´ååè 详æ --> <el-card class="utilization-card"> <div slot="header" class="clearfix"> <span class="detail-title">å¨å®å©ç¨è®°å½</span> <div style="float: right;"> <el-tag :type="getStatusTagType(form.utilizationStatus)"> {{ getStatusText(form.utilizationStatus) }} <el-tag :type="getStatusTagType(form.recordstate)"> {{ getStatusText(form.recordstate) }} </el-tag> </div> </div> @@ -213,12 +125,15 @@ <el-row> <el-col> <el-form-item label-width="100px" label="ç§»æ¤å¨å®"> <el-checkbox-group v-model="selectedOrgans" @change="handleOrganSelectionChange"> <el-checkbox-group v-model="selectedOrgans" @change="handleOrganSelectionChange" > <el-checkbox v-for="dict in dict.type.sys_Organ || []" :key="dict.value" :label="dict.value" :disabled="form.utilizationStatus === 'completed'" :disabled="form.recordstate === 'completed'" > {{ dict.label }} </el-checkbox> @@ -231,38 +146,236 @@ <el-col> <el-form-item> <el-table :data="utilizationData.records" :data="utilizationData.serviceDonatecomporganList" v-loading="loading" border style="width: 100%" :row-class-name="getOrganRowClassName" :expand-row-keys="expandedRows" @expand-change="handleExpandChange" row-key="organno" > <el-table-column type="expand" width="60"> <template slot-scope="scope"> <!-- å±å¼è¡å 容 - åè 详ç»ä¿¡æ¯ --> <div class="recipient-detail-expand"> <div class="recipient-header"> <span class="recipient-title">åè 详ç»ä¿¡æ¯</span> <el-tag v-if="scope.row.transplantstate === '1'" type="success" size="small" > å·²ç§»æ¤ </el-tag> <el-tag v-else-if="scope.row.transplantstate === '0'" type="warning" size="small" > æªç§»æ¤ </el-tag> <el-tag v-else type="info" size="small"> ç§»æ¤ä¸ </el-tag> </div> <el-form :model="scope.row" label-width="140px" class="recipient-form" > <!-- åºæ¬ä¿¡æ¯é¨å --> <div class="form-section"> <h4 class="section-title">åºæ¬ä¿¡æ¯</h4> <el-row :gutter="20"> <el-col :span="8"> <el-form-item label="åè å§å"> <el-input v-model="scope.row.name" placeholder="请è¾å ¥åè å§å" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="åºçæ¥æ"> <el-date-picker v-model="scope.row.birthday" type="date" value-format="yyyy-MM-dd" placeholder="éæ©åºçæ¥æ" style="width: 100%" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="æ§å«"> <el-select v-model="scope.row.sex" placeholder="è¯·éæ©æ§å«" style="width: 100%" :disabled="form.recordstate === 'completed'" > <el-option label="ç·" value="0" /> <el-option label="女" value="1" /> </el-select> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="8"> <el-form-item label="å¹´é¾"> <el-input v-model="scope.row.age" placeholder="å¹´é¾" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="è¯ä»¶ç±»å"> <el-select v-model="scope.row.idcardtype" placeholder="è¯·éæ©è¯ä»¶ç±»å" style="width: 100%" :disabled="form.recordstate === 'completed'" > <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="8"> <el-form-item label="è¯ä»¶å·ç "> <el-input v-model="scope.row.idcardno" placeholder="è¯ä»¶å·ç " :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> </el-row> </div> <!-- è系信æ¯é¨å --> <div class="form-section"> <h4 class="section-title">è系信æ¯</h4> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="ç§»æ¤ä¸å¿åç§°"> <el-input v-model="scope.row.hospitalname" placeholder="请è¾å ¥ç§»æ¤ä¸å¿åç§°" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="èç³»çµè¯"> <el-input v-model="scope.row.phone" placeholder="èç³»çµè¯" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="24"> <el-form-item label="ç°ä½å°å"> <el-input type="textarea" :rows="2" v-model="scope.row.residenceaddress" placeholder="请è¾å ¥è¯¦ç»å°å" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> </el-row> </div> <!-- ç§»æ¤ä¿¡æ¯é¨å --> <div class="form-section" v-if="scope.row.transplantstate === '1'" > <h4 class="section-title">ç§»æ¤ä¿¡æ¯</h4> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="ç§»æ¤æ¶é´"> <el-date-picker v-model="scope.row.transplanttime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="éæ©ç§»æ¤æ¥æ" style="width: 100%" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="ç§»æ¤å»ç"> <el-input v-model="scope.row.transplantdoct" placeholder="请è¾å ¥ç§»æ¤å»ç" :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> </el-row> </div> <!-- æªç§»æ¤åå --> <div class="form-section" v-if="scope.row.transplantstate === '0'" > <h4 class="section-title">æªç§»æ¤ä¿¡æ¯</h4> <el-row :gutter="20"> <el-col :span="24"> <el-form-item label="æªç§»æ¤åå "> <el-input type="textarea" :rows="3" v-model="scope.row.abandonreason" placeholder="请è¾å ¥æªç§»æ¤åå " :disabled="form.recordstate === 'completed'" /> </el-form-item> </el-col> </el-row> </div> </el-form> </div> </template> </el-table-column> <el-table-column label="å¨å®åç§°" align="center" width="120" prop="organName" prop="organname" > <template slot-scope="scope"> <el-input v-model="scope.row.organName" v-model="scope.row.organname" placeholder="å¨å®åç§°" :disabled="true" /> </template> </el-table-column> <el-table-column label="ç³»ç»ç¼å·" align="center" width="120" prop="caseNo" > <el-table-column label="ç³»ç»ç¼å·" align="center" prop="caseNo"> <template slot-scope="scope"> <el-input v-model="scope.row.caseNo" placeholder="ç³»ç»ç¼å·" :disabled="form.utilizationStatus === 'completed'" /> </template> </el-table-column> @@ -270,15 +383,14 @@ <el-table-column label="ç§»æ¤å»é¢" align="center" width="200" prop="hospitalNo" width="260" prop="hospitalno" > <template slot-scope="scope"> <el-select v-model="scope.row.hospitalNo" v-model="scope.row.hospitalno" placeholder="è¯·éæ©ç§»æ¤å»é¢" style="width: 100%" :disabled="form.utilizationStatus === 'completed'" @change="handleHospitalChange(scope.row, $event)" > <el-option @@ -292,67 +404,16 @@ </el-table-column> <el-table-column label="åä½å§æ°" align="center" width="120" prop="recipientName" > <template slot-scope="scope"> <el-input v-model="scope.row.recipientName" placeholder="åä½å§æ°" :disabled="form.utilizationStatus === 'completed'" /> </template> </el-table-column> <el-table-column label="ç§»æ¤è´è´£äºº" align="center" width="120" prop="transplantDoctor" > <template slot-scope="scope"> <el-input v-model="scope.row.transplantDoctor" placeholder="å»å¸å§å" :disabled="form.utilizationStatus === 'completed'" /> </template> </el-table-column> <el-table-column label="ç§»æ¤æ¶é´" align="center" width="150" prop="transplantTime" > <template slot-scope="scope"> <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.transplantTime" type="date" value-format="yyyy-MM-dd" placeholder="éæ©ç§»æ¤æ¶é´" :disabled="form.utilizationStatus === 'completed'" /> </template> </el-table-column> <el-table-column label="ç§»æ¤ç¶æ" align="center" width="120" prop="transplantStatus" prop="transplantstate" > <template slot-scope="scope"> <el-select v-model="scope.row.transplantStatus" v-model="scope.row.transplantstate" placeholder="è¯·éæ©ç§»æ¤ç¶æ" style="width: 100%" :disabled="form.utilizationStatus === 'completed'" @change="handleTransplantStatusChange(scope.row, $event)" > <el-option v-for="dict in transplantStatusList" @@ -365,18 +426,43 @@ </el-table-column> <el-table-column label="说æ" label="ç§»æ¤æ¶é´" align="center" prop="abandonReason" min-width="200" width="220" prop="transplanttime" > <template slot-scope="scope"> <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.transplanttime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="éæ©ç§»æ¤æ¶é´" /> </template> </el-table-column> <el-table-column label="ç§»æ¤å»ç" align="center" prop="transplantdoct" > <template slot-scope="scope"> <el-input type="textarea" clearable v-model="scope.row.abandonReason" placeholder="请è¾å ¥å¼ç¨è¯´æ" :disabled="form.utilizationStatus === 'completed'" v-model="scope.row.transplantdoct" placeholder="å»å¸å§å" /> </template> </el-table-column> <el-table-column label="åè å§å" align="center" prop="name"> <template slot-scope="scope"> <el-input v-model="scope.row.name" placeholder="åè å§å" :disabled="form.recordstate === 'completed'" /> </template> </el-table-column> @@ -384,9 +470,8 @@ <el-table-column label="æä½" align="center" width="120" class-name="small-padding fixed-width" v-if="form.utilizationStatus !== 'completed'" v-if="form.recordstate !== 'completed'" > <template slot-scope="scope"> <el-button @@ -397,6 +482,16 @@ > ç¼è¾ </el-button> <el-button size="mini" type="text" icon="el-icon-delete" style="color: #F56C6C;" @click="handleRemoveOrgan(scope.$index)" v-if="!scope.row.id" > å é¤ </el-button> </template> </el-table-column> </el-table> @@ -404,279 +499,100 @@ </el-col> </el-row> <!-- å©ç¨ç»è®¡ä¿¡æ¯ --> <div class="utilization-stats" v-if="utilizationData.records.length > 0"> <el-row :gutter="20"> <el-col :span="6"> <div class="stat-item"> <span class="stat-label">å·²å©ç¨å¨å®:</span> <span class="stat-value">{{ utilizationData.records.length }} 个</span> </div> </el-col> <el-col :span="6"> <div class="stat-item"> <span class="stat-label">å¾ å®åä¿¡æ¯:</span> <span class="stat-value">{{ incompleteRecords }} 个</span> </div> </el-col> <el-col :span="6"> <div class="stat-item"> <span class="stat-label">æ¶åå»é¢:</span> <span class="stat-value">{{ uniqueHospitals }} å®¶</span> </div> </el-col> <el-col :span="6"> <div class="stat-item"> <span class="stat-label">å©ç¨ç¶æ:</span> <span class="stat-value"> <el-tag :type="getStatusTagType(form.utilizationStatus)"> {{ getStatusText(form.utilizationStatus) }} </el-tag> </span> </div> </el-col> </el-row> </div> <!-- ç»è®¡ä¿¡æ¯ --> <div v-else class="empty-utilization"> <div v-if=" !utilizationData.serviceDonatecomporganList || utilizationData.serviceDonatecomporganList.length == 0 " class="empty-utilization" > <el-empty description="ææ å©ç¨è®°å½" :image-size="80"> <span>请å éæ©è¦å©ç¨çå¨å®</span> </el-empty> </div> </el-form> <div class="dialog-footer" v-if="form.utilizationStatus !== 'completed'"> <el-button type="primary" @click="handleSaveUtilization" :loading="saveLoading" :disabled="utilizationData.records.length === 0" > ä¿åå©ç¨è®°å½ </el-button> <el-button type="success" @click="handleConfirmUtilization" :loading="confirmLoading" :disabled="incompleteRecords > 0" > ç¡®è®¤å®æå©ç¨ </el-button> </div> </el-card> <!-- åè 详ç»ä¿¡æ¯é¨å --> <el-card class="recipient-card" v-if="utilizationData.records.length > 0"> <div slot="header" class="clearfix"> <span class="detail-title">åè 详ç»ä¿¡æ¯</span> </div> <el-tabs v-model="activeRecipientTab" type="card"> <el-tab-pane v-for="record in utilizationData.records" :key="record.organNo" :label="record.organName" :name="record.organNo" > <el-form :model="record" label-width="140px"> <el-row :gutter="20"> <el-col :span="8"> <el-form-item label="åè å§å"> <el-input v-model="record.recipientName" placeholder="请è¾å ¥åè å§å" /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="åºçå¹´æ"> <el-date-picker v-model="record.recipientBirthDate" type="month" value-format="yyyy-MM" placeholder="éæ©åºçå¹´æ" style="width: 100%" /> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="æ§å«"> <el-select v-model="record.recipientGender" placeholder="è¯·éæ©æ§å«" style="width: 100%"> <el-option label="ç·" value="0" /> <el-option label="女" value="1" /> </el-select> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="ç§»æ¤ä¸å¿åç§°"> <el-input v-model="record.transplantCenter" placeholder="请è¾å ¥ç§»æ¤ä¸å¿åç§°" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="æå¨å°"> <el-input v-model="record.location" placeholder="请è¾å ¥æå¨å°" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="ç§»æ¤æ¥æ"> <el-date-picker v-model="record.transplantTime" type="date" value-format="yyyy-MM-dd" placeholder="éæ©ç§»æ¤æ¥æ" style="width: 100%" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="ååç "> <el-input v-model="record.originalDisease" placeholder="请è¾å ¥ååç " /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="24"> <el-form-item label="æ£æµææ "> <el-input type="textarea" :rows="3" v-model="record.testIndicators" placeholder="请è¾å ¥åç±»å¿ è¦çæ£æµææ " /> </el-form-item> </el-col> </el-row> </el-form> </el-tab-pane> </el-tabs> </el-card> <!-- é访记å½é¨å --> <el-card class="followup-card"> <div slot="header" class="clearfix"> <span class="detail-title">é访记å½</span> <el-button type="primary" size="mini" icon="el-icon-plus" @click="handleAddFollowup" style="float: right;" > æ°å¢é访 </el-button> </div> <el-table :data="followupData.records" v-loading="loading" border> <el-table-column label="å¨å®åç§°" align="center" width="120" prop="organName" /> <el-table-column label="é访æ¶é´" align="center" width="160" prop="followupTime"> <template slot-scope="scope"> <span>{{ parseTime(scope.row.followupTime) }}</span> </template> </el-table-column> <el-table-column label="é访类å" align="center" width="100" prop="followupType"> <template slot-scope="scope"> <el-tag :type="getFollowupTypeTag(scope.row.followupType)"> {{ getFollowupTypeText(scope.row.followupType) }} </el-tag> </template> </el-table-column> <el-table-column label="åè æ åµ" align="center" prop="recipientCondition" min-width="200" show-overflow-tooltip /> <el-table-column label="é访å»ç" align="center" width="120" prop="followupDoctor" /> <el-table-column label="䏿¬¡é访æ¶é´" align="center" width="160" prop="nextFollowupTime"> <template slot-scope="scope"> <span>{{ scope.row.nextFollowupTime || '-' }}</span> </template> </el-table-column> <el-table-column label="æä½" align="center" width="150"> <template slot-scope="scope"> <el-button size="mini" type="text" icon="el-icon-view" @click="handleViewFollowup(scope.row)" >æ¥ç</el-button> <el-button size="mini" type="text" icon="el-icon-edit" @click="handleEditFollowup(scope.row)" >ç¼è¾</el-button> <el-button size="mini" type="text" icon="el-icon-delete" style="color: #F56C6C;" @click="handleDeleteFollowup(scope.row)" >å é¤</el-button> </template> </el-table-column> </el-table> </el-card> <!-- é件管çé¨å --> <!-- é件管çé¨å - ä¼åä¸ºå®æ´åè½ --> <el-card class="attachment-card"> <div slot="header" class="clearfix"> <span class="detail-title">ç¸å ³éä»¶</span> <el-button type="primary" size="mini" icon="el-icon-upload" @click="handleUploadAttachment" <div class="attachment-header"> <i class="el-icon-paperclip"></i> <span class="attachment-title">ç¸å ³éä»¶</span> <span class="attachment-tip" >æ¯æä¸ä¼ å¨å®å©ç¨ç¸å ³æä»¶ (æå¤{{ attachmentLimit }}个)</span > ä¸ä¼ éä»¶ </el-button> </div> <div class="attachment-list"> <el-table :data="attachments" style="width: 100%"> <el-table-column label="æä»¶åç§°" min-width="200"> <!-- ä½¿ç¨ UploadAttachment ç»ä»¶ --> <UploadAttachment ref="uploadAttachment" :file-list="attachmentFileList" :limit="attachmentLimit" :accept="attachmentAccept" :multiple="true" @change="handleAttachmentChange" @upload-success="handleUploadSuccess" @upload-error="handleUploadError" @remove="handleAttachmentRemove" /> <!-- éä»¶å表å±ç¤º --> <div class="attachment-list" v-if="attachments && attachments.length > 0"> <div class="list-title">å·²ä¸ä¼ éä»¶ ({{ attachments.length }})</div> <el-table :data="attachments" style="width: 100%" size="small"> <el-table-column label="æä»¶å" min-width="200"> <template slot-scope="scope"> <div class="file-info"> <i :class="getFileIcon(scope.row.fileName)" style="margin-right: 8px; color: #409EFF;"></i> <span>{{ scope.row.fileName }}</span> </div> <i class="el-icon-document" :style="{ color: getFileIconColor(scope.row.fileName) }" ></i> <span class="file-name">{{ scope.row.fileName }}</span> </template> </el-table-column> <el-table-column label="æä»¶ç±»å" width="100" align="center"> <el-table-column label="æä»¶ç±»å" width="100"> <template slot-scope="scope"> <el-tag size="small">{{ getFileType(scope.row.fileName) }}</el-tag> <el-tag :type="getFileTagType(scope.row.fileName)" size="small"> {{ getFileTypeText(scope.row.fileName) }} </el-tag> </template> </el-table-column> <el-table-column label="æä»¶å¤§å°" width="100" align="center"> <el-table-column label="ä¸ä¼ æ¶é´" width="200"> <template slot-scope="scope"> <span>{{ formatDateTime(scope.row.uploadTime) }}</span> </template> </el-table-column> <el-table-column label="æä»¶å¤§å°" width="180"> <template slot-scope="scope"> <span>{{ formatFileSize(scope.row.fileSize) }}</span> </template> </el-table-column> <el-table-column label="ä¸ä¼ æ¶é´" width="160" align="center"> <template slot-scope="scope"> <span>{{ parseTime(scope.row.uploadTime) }}</span> </template> </el-table-column> <el-table-column label="æä½" width="150" align="center"> <el-table-column label="æä½" width="260" fixed="right"> <template slot-scope="scope"> <el-button size="mini" type="text" icon="el-icon-view" @click="handlePreviewAttachment(scope.row)" >é¢è§</el-button> type="primary" @click="handlePreview(scope.row)" :disabled="!isPreviewable(scope.row.fileName)" > é¢è§ </el-button> <el-button size="mini" type="text" icon="el-icon-download" type="success" @click="handleDownloadAttachment(scope.row)" >ä¸è½½</el-button> > ä¸è½½ </el-button> <el-button size="mini" type="text" icon="el-icon-delete" style="color: #F56C6C;" @click="handleRemoveAttachment(scope.row)" >å é¤</el-button> type="danger" @click="handleRemoveAttachment(scope.$index)" > å é¤ </el-button> </template> </el-table-column> </el-table> @@ -693,12 +609,15 @@ <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="å¨å®åç§°"> <el-input v-model="currentRecord.organName" readonly /> <el-input v-model="currentRecord.organname" readonly /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="ç§»æ¤ç¶æ"> <el-select v-model="currentRecord.transplantStatus" style="width: 100%"> <el-select v-model="currentRecord.transplantstate" style="width: 100%" > <el-option v-for="dict in transplantStatusList" :key="dict.value" @@ -709,13 +628,39 @@ </el-form-item> </el-col> </el-row> <el-form-item label="å¼ç¨è¯´æ" v-if="currentRecord.transplantStatus === '0'"> <el-form-item label="æªç§»æ¤åå " v-if="currentRecord.transplantstate === '0'" > <el-input type="textarea" :rows="3" v-model="currentRecord.abandonReason" placeholder="请è¾å ¥å¼ç¨çåå 说æ" v-model="currentRecord.abandonreason" placeholder="请è¾å ¥æªç§»æ¤åå " /> </el-form-item> <el-form-item label="ç§»æ¤å»é¢" v-if="currentRecord.transplantstate === '1'" > <el-select v-model="currentRecord.hospitalno" placeholder="è¯·éæ©ç§»æ¤å»é¢" style="width: 100%" > <el-option v-for="hospital in hospitalList" :key="hospital.hospitalNo" :label="hospital.hospitalName" :value="hospital.hospitalNo" /> </el-select> </el-form-item> <el-form-item label="åè å§å" v-if="currentRecord.transplantstate === '1'" > <el-input v-model="currentRecord.name" placeholder="请è¾å ¥åè å§å" /> </el-form-item> </el-form> <div slot="footer"> @@ -724,139 +669,82 @@ </div> </el-dialog> <!-- é访记å½å¯¹è¯æ¡ --> <el-dialog :title="followupDialogTitle" :visible.sync="followupDialogVisible" width="700px" > <el-form :model="currentFollowup" label-width="120px"> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="å¨å®åç§°"> <el-select v-model="currentFollowup.organNo" style="width: 100%"> <el-option v-for="organ in utilizationData.records" :key="organ.organNo" :label="organ.organName" :value="organ.organNo" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="é访类å"> <el-select v-model="currentFollowup.followupType" style="width: 100%"> <el-option label="常è§é访" value="routine" /> <el-option label="ç´§æ¥é访" value="emergency" /> <el-option label="ç¹æ®é访" value="special" /> </el-select> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="é访æ¶é´"> <el-date-picker v-model="currentFollowup.followupTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="é访å»ç"> <el-input v-model="currentFollowup.followupDoctor" placeholder="请è¾å ¥é访å»ç" /> </el-form-item> </el-col> </el-row> <el-form-item label="åè æ åµ"> <el-input type="textarea" :rows="3" v-model="currentFollowup.recipientCondition" placeholder="请è¾å ¥åè å½åæ åµ" /> </el-form-item> <el-form-item label="ç¨è¯æ åµ"> <el-input type="textarea" :rows="2" v-model="currentFollowup.medicationSituation" placeholder="请è¾å ¥ç¨è¯æ åµ" /> </el-form-item> <el-form-item label="æ£æ¥ç»æ"> <el-input type="textarea" :rows="2" v-model="currentFollowup.testResults" placeholder="请è¾å ¥æ£æ¥ç»æ" /> </el-form-item> <el-form-item label="䏿¬¡é访æ¶é´"> <el-date-picker v-model="currentFollowup.nextFollowupTime" type="date" value-format="yyyy-MM-dd" style="width: 100%" /> </el-form-item> </el-form> <div slot="footer"> <el-button @click="followupDialogVisible = false">åæ¶</el-button> <el-button type="primary" @click="handleSaveFollowup">ä¿å</el-button> </div> </el-dialog> <!-- æä»¶é¢è§å¯¹è¯æ¡ --> <FilePreviewDialog :visible="filePreviewVisible" :file="currentPreviewFile" @close="filePreviewVisible = false" @download="handleDownloadAttachment" /> </div> </template> <script> import { getOrganUtilizationDetail, updateOrganUtilization, addOrganUtilization, saveUtilizationRecords, saveFollowupRecord, getHospitalList, getLeaderList, getCoordinatorList } from "./organUtilization"; completionList, completionadd, completionedit } from "@/api/businessApi"; import UploadAttachment from "@/components/UploadAttachment"; // æ°å¢å¯¼å ¥ import FilePreviewDialog from "@/components/FilePreviewDialog"; // æ°å¢å¯¼å ¥ import CaseBasicInfo from "@/components/CaseBasicInfo"; import dayjs from "dayjs"; // æ°å¢å¯¼å ¥ï¼ç¨äºæ¶é´å¤ç export default { name: "OrganUtilizationDetail", dicts: ["sys_user_sex", "sys_Organ", "sys_0_1"], components: { UploadAttachment, FilePreviewDialog, CaseBasicInfo }, dicts: ["sys_BloodType", "sys_Organ", "sys_0_1"], data() { return { // è¡¨åæ°æ® caseId: null, // è¡¨åæ°æ® - æ ¹æ®æ¥å£åæ°è°æ´ form: { id: undefined, hospitalNo: "", infoid: undefined, inpatientno: "", recordstate: "pending", caseNo: "", donorName: "", gender: "", donorno: "", treatmenthospitalname: "", treatmenthospitalno: "", sex: "", name: "", age: "", birthDate: "", diagnosis: "", utilizationStatus: "pending", allocationTime: "", registrant: "", registrationTime: "", isBodyDonation: "0", receivingUnit: "", responsibleUserId: "", coordinatedUserId1: "", coordinatedUserId2: "", completionTime: "" bloodtype: "", idcardno: "", diagnosisname: "", completetime: "", responsibleuserid: "", responsibleusername: "", coordinateduserido: "", coordinatedusernameo: "", coordinateduseridt: "", coordinatedusernamet: "", assessannex: "", donateorgan: "", isbodydonation: "0", receivingunit: "", createBy: "", createTime: "", updateBy: "", updateTime: "", attachments: [] }, // 表åéªè¯è§å rules: { donorName: [ name: [ { required: true, message: "æç®è å§åä¸è½ä¸ºç©º", trigger: "blur" } ], diagnosis: [ diagnosisname: [ { required: true, message: "ç¾ç è¯æä¸è½ä¸ºç©º", trigger: "blur" } ], donorno: [ { required: true, message: "æç®è ç¼å·ä¸è½ä¸ºç©º", trigger: "blur" } ] }, // å©ç¨è®°å½éªè¯è§å @@ -870,10 +758,6 @@ selectedOrgans: [], // å»é¢å表 hospitalList: [], // è´è´£äººå表 leaderList: [], // åè°åå表 coordinatorList: [], // ç§»æ¤ç¶æå表 transplantStatusList: [ { value: "1", label: "已移æ¤" }, @@ -882,7 +766,7 @@ ], // å©ç¨è®°å½æ°æ® utilizationData: { records: [] serviceDonatecomporganList: [] }, // éè®¿è®°å½æ°æ® followupData: { @@ -890,15 +774,21 @@ }, // éä»¶æ°æ® attachments: [], // å½åæ¿æ´»çåè æ ç¾ activeRecipientTab: "", // å±å¼çè¡keys expandedRows: [], // ç¼è¾å¯¹è¯æ¡ editDialogVisible: false, currentRecord: {}, currentEditIndex: -1, // éè®¿å¯¹è¯æ¡ followupDialogVisible: false, followupDialogTitle: "æ°å¢é访记å½", // éä»¶ç¸å ³é ç½® - æ°å¢ attachmentFileList: [], attachmentLimit: 10, attachmentAccept: ".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt", // æä»¶é¢è§ç¸å ³ - æ°å¢ filePreviewVisible: false, currentPreviewFile: null, currentFollowup: {}, isEditingFollowup: false }; @@ -908,140 +798,179 @@ currentUser() { return JSON.parse(sessionStorage.getItem("user") || "{}"); }, // ä¸å®æ´çè®°å½æ°é incompleteRecords() { return this.utilizationData.records.filter( record => !record.caseNo || !record.hospitalNo || !record.recipientName || !record.transplantTime // å·²ç§»æ¤æ°é transplantedCount() { if (!this.utilizationData.serviceDonatecomporganList) return 0; return this.utilizationData.serviceDonatecomporganList.filter( record => record.transplantstate === "1" ).length; }, // å¯ä¸å»é¢æ°é uniqueHospitals() { const hospitals = this.utilizationData.records .map(record => record.hospitalNo) if (!this.utilizationData.serviceDonatecomporganList) return 0; const hospitals = this.utilizationData.serviceDonatecomporganList .map(record => record.hospitalno) .filter(Boolean); return new Set(hospitals).size; }, // è·åå¨å®åå ¸ organDict() { return this.dict.type.sys_Organ || []; } }, created() { const id = this.$route.query.id; if (id) { this.getDetail(id); } else { this.generateCaseNo(); this.form.registrant = this.currentUser.username || "å½åç¨æ·"; this.form.registrationTime = new Date() this.initData(); }, watch: { // çå¬éä»¶æ°æ®åå - æ°å¢ attachments: { handler(newAttachments) { this.attachmentFileList = newAttachments.map(item => ({ uid: item.id || Math.random(), name: item.fileName, fileSize: item.fileSize, url: item.path || item.fileUrl, uploadTime: item.uploadTime, status: "success" })); }, deep: true } }, methods: { // åå§åæ°æ® initData() { this.caseId = this.$route.query.infoid; if (!this.caseId) { this.$message.error("缺å°å¿ è¦çè·¯ç±åæ° infoid"); this.$router.back(); return; } this.form.infoid = this.caseId; this.form.createBy = this.currentUser.username || this.currentUser.name || "å½åç¨æ·"; this.form.createTime = new Date() .toISOString() .replace("T", " ") .substring(0, 19); } this.getHospitalData(); this.getLeaderData(); this.getCoordinatorData(); }, methods: { // çæä½é¢å· generateCaseNo() { this.generateDonorNo(); this.getDetail(); this.getHospitalData(); }, // çææç®è ç¼å· generateDonorNo() { const timestamp = Date.now().toString(); this.form.hospitalNo = "D" + timestamp.slice(-6); this.form.caseNo = "C" + timestamp.slice(-6); this.form.donorno = "D" + timestamp.slice(-8); this.form.caseNo = "CASE" + timestamp.slice(-6); this.form.inpatientno = "IP" + timestamp.slice(-6); }, // è·å详æ getDetail(id) { async getDetail() { this.loading = true; getOrganUtilizationDetail(id) .then(response => { if (response.code === 200) { this.form = response.data; if (response.data.utilizationRecords) { this.utilizationData.records = response.data.utilizationRecords; this.selectedOrgans = response.data.utilizationRecords.map( item => item.organNo ); if (this.utilizationData.records.length > 0) { this.activeRecipientTab = this.utilizationData.records[0].organNo; } } if (response.data.followupRecords) { this.followupData.records = response.data.followupRecords; } try { const response = await completionList({ infoid: this.caseId }); if ( response.code === 200 && response.data && response.data.length > 0 ) { const data = response.data[0]; // å¡«å è¡¨åæ°æ® Object.assign(this.form, data); // å¤çæç®å¨å®å段 if (data.donateorgan) { const organArray = Array.isArray(data.donateorgan) ? data.donateorgan : (data.donateorgan || "").split(",").filter(item => item); this.selectedOrgans = organArray; } this.loading = false; }) .catch(error => { console.error("è·åå¨å®å©ç¨è¯¦æ 失败:", error); this.loading = false; this.$message.error("è·å详æ 失败"); }); // å¤çå¨å®å©ç¨è®°å½ if (data.serviceDonatecomporganList) { this.utilizationData.serviceDonatecomporganList = Array.isArray( data.serviceDonatecomporganList ) ? data.serviceDonatecomporganList.map(record => ({ ...record, transplantstate: record.transplantstate ? record.transplantstate.toString() : "1" })) : []; } // åå§åéä»¶ if (this.form.assessannex) { this.form.attachments = JSON.parse(this.form.assessannex); this.attachments = Array.isArray(this.form.attachments) ? [...this.form.attachments] : []; } this.$message.success("æ°æ®å è½½æå"); } else { this.$message.warning("æªæ¾å°å¯¹åºçå¨å®å©ç¨æ°æ®"); } } catch (error) { console.error("è·åå¨å®å©ç¨è¯¦æ 失败:", error); this.$message.error("è·å详æ 失败"); } finally { this.loading = false; } }, // è·åå»é¢æ°æ® getHospitalData() { getHospitalList().then(response => { if (response.code === 200) { this.hospitalList = response.data; } }); async getHospitalData() { try { // TODO: æ¿æ¢ä¸ºå®é çå»é¢å表æ¥å£ // ææ¶ä½¿ç¨æ¨¡ææ°æ® this.hospitalList = [ { hospitalNo: "H001", hospitalName: "å京ååå»é¢" }, { hospitalNo: "H002", hospitalName: "䏿µ·åå±±å»é¢" }, { hospitalNo: "H003", hospitalName: "䏿µ·çéå»é¢" }, { hospitalNo: "H004", hospitalName: "广å·ä¸å±±å»é¢" }, { hospitalNo: "H005", hospitalName: "æ¦æ±åæµå»é¢" }, { hospitalNo: "H006", hospitalName: "æé½å西å»é¢" } ]; } catch (error) { console.error("è·åå»é¢æ°æ®å¤±è´¥:", error); this.$message.error("è·åå»é¢æ°æ®å¤±è´¥"); } }, // è·åè´è´£äººæ°æ® getLeaderData() { getLeaderList().then(response => { if (response.code === 200) { this.leaderList = response.data; } }); }, // è·ååè°åæ°æ® getCoordinatorData() { getCoordinatorList().then(response => { if (response.code === 200) { this.coordinatorList = response.data; } }); }, // å¨å®éæ©ç¶æåå handleOrganSelectionChange(selectedValues) { const currentOrganNos = this.utilizationData.records.map( item => item.organNo if (!this.utilizationData.serviceDonatecomporganList) { this.utilizationData.serviceDonatecomporganList = []; } const currentOrganValues = this.utilizationData.serviceDonatecomporganList.map( item => item.organno ); // å¤çäºæ¥é»è¾ this.handleExclusiveSelections(selectedValues); // æ´æ°æç®å¨å®å段 this.form.donateorgan = selectedValues.join(","); // æ°å¢éæ©çå¨å® selectedValues.forEach(organValue => { if (!currentOrganNos.includes(organValue)) { const organInfo = this.dict.type.sys_Organ.find( item => item.value === organValue ); if (organInfo) { this.utilizationData.records.push({ organName: organInfo.label, organNo: organValue, id: null, utilizationId: this.form.id, caseNo: "", hospitalNo: "", hospitalName: "", recipientName: "", transplantDoctor: "", transplantTime: "", transplantStatus: "1", abandonReason: "", recipientBirthDate: "", recipientGender: "", transplantCenter: "", location: "", originalDisease: "", testIndicators: "" }); } if (!currentOrganValues.includes(organValue)) { this.createOrganRecord(organValue); } }); // ç§»é¤åæ¶éæ©çå¨å® this.utilizationData.records = this.utilizationData.records.filter( this.utilizationData.serviceDonatecomporganList = this.utilizationData.serviceDonatecomporganList.filter( record => { if (selectedValues.includes(record.organNo)) { if (selectedValues.includes(record.organno)) { return true; } else { if (record.id) { @@ -1055,13 +984,13 @@ } ) .then(() => { this.utilizationData.records = this.utilizationData.records.filter( r => r.organNo !== record.organNo this.utilizationData.serviceDonatecomporganList = this.utilizationData.serviceDonatecomporganList.filter( r => r.organno !== record.organno ); this.$message.success("å 餿å"); }) .catch(() => { this.selectedOrgans.push(record.organNo); this.selectedOrgans.push(record.organno); }); return true; } else { @@ -1071,19 +1000,115 @@ } ); }, // å¤çäºæ¥éæ© handleExclusiveSelections(selectedValues) { // 妿鿩äº"åè¾"(å设åå ¸å¼ä¸ºC64)ï¼èªå¨åæ¶åç¬ç"å·¦è¾"(C64L)å"å³è¾"(C64R)éæ© if (selectedValues.includes("C64")) { this.selectedOrgans = selectedValues.filter( item => item !== "C64L" && item !== "C64R" ); } // 妿鿩äº"å·¦è¾"æ"å³è¾"ï¼åæ¶"åè¾"éæ© else if ( selectedValues.includes("C64L") || selectedValues.includes("C64R") ) { this.selectedOrgans = selectedValues.filter(item => item !== "C64"); } // 妿鿩äº"å ¨èº"(å设åå ¸å¼ä¸ºC34)ï¼èªå¨åæ¶åç¬ç"å·¦èº"(C34L)å"å³èº"(C34R)éæ© if (selectedValues.includes("C34")) { this.selectedOrgans = selectedValues.filter( item => item !== "C34L" && item !== "C34R" ); } // 妿鿩äº"å·¦èº"æ"å³èº"ï¼åæ¶"å ¨èº"éæ© else if ( selectedValues.includes("C34L") || selectedValues.includes("C34R") ) { this.selectedOrgans = selectedValues.filter(item => item !== "C34"); } }, // å建å¨å®è®°å½ createOrganRecord(organValue) { const organName = this.getOrganLabel(organValue); this.utilizationData.serviceDonatecomporganList.push({ organname: organName, organno: organValue, caseNo: "", hospitalno: "", hospitalname: "", name: "", transplantdoct: "", transplanttime: "", transplantstate: "1", abandonreason: "", sex: "", age: "", birthday: "", phone: "", residenceaddress: "", residenceprovince: "", residenceprovincename: "", residencecity: "", residencecityname: "", residencetown: "", residencetownname: "", residencecommunity: "", residencecommunityname: "", residencecountycode: "", residencecountyname: "", idcardtype: "", idcardno: "", ageunit: "" }); }, // æ ¹æ®åå ¸valueè·ålabel getOrganLabel(organValue) { const dictItem = this.organDict.find(item => item.value === organValue); return dictItem ? dictItem.label : organValue; }, // å»é¢éæ©åå handleHospitalChange(row, hospitalNo) { const hospital = this.hospitalList.find( item => item.hospitalNo === hospitalNo ); if (hospital) { row.hospitalName = hospital.hospitalName; row.hospitalname = hospital.hospitalName; } }, // ç§»æ¤ç¶æååå¤ç handleTransplantStatusChange(row, status) { if (status === "0") { // å¦æç¶æä¸ºæªç§»æ¤ï¼æ¸ é¤ç¸å ³å段 // row.transplanttime = ""; // row.transplantdoct = ""; // row.hospitalno = ""; // row.hospitalname = ""; } else if (status === "1") { // å¦æç¶æä¸ºå·²ç§»æ¤ï¼èªå¨è®¾ç½®ç§»æ¤æ¶é´ä¸ºå½åæ¶é´ if (!row.transplanttime) { row.transplanttime = new Date().toISOString().split("T")[0]; } } }, // è¡å±å¼äºä»¶ handleExpandChange(row, expandedRows) { this.expandedRows = expandedRows.map(item => item.organno); }, // ç¼è¾å©ç¨è®°å½ handleEditUtilization(row) { const index = this.utilizationData.records.findIndex( item => item.organNo === row.organNo const index = this.utilizationData.serviceDonatecomporganList.findIndex( item => item.organno === row.organno ); if (index !== -1) { this.currentRecord = { ...row }; @@ -1091,46 +1116,77 @@ this.editDialogVisible = true; } }, // 确认ç¼è¾ handleEditConfirm() { if (this.currentEditIndex !== -1) { this.utilizationData.records[this.currentEditIndex] = { this.utilizationData.serviceDonatecomporganList[ this.currentEditIndex ] = { ...this.currentRecord }; this.$message.success("å©ç¨è®°å½æ´æ°æå"); this.editDialogVisible = false; } }, // å é¤å¨å®è®°å½ handleRemoveOrgan(index) { this.$confirm("确认å é¤è¿æ¡å¨å®è®°å½åï¼", "æç¤º", { confirmButtonText: "ç¡®å®", cancelButtonText: "åæ¶", type: "warning" }) .then(() => { const organno = this.utilizationData.serviceDonatecomporganList[index] .organno; this.utilizationData.serviceDonatecomporganList.splice(index, 1); // ä»éä¸çå¨å®ä¸ç§»é¤ const idx = this.selectedOrgans.indexOf(organno); if (idx > -1) { this.selectedOrgans.splice(idx, 1); } this.$message.success("å¨å®è®°å½å 餿å"); }) .catch(() => {}); }, // å¨å®è¡æ ·å¼ getOrganRowClassName({ row }) { if ( !row.caseNo || !row.hospitalNo || !row.recipientName || !row.transplantTime row.transplantstate === "1" && (!row.caseNo || !row.hospitalno || !row.name || !row.transplanttime) ) { return "warning-row"; } if (row.transplantstate === "0" && !row.abandonreason) { return "warning-row"; } return ""; }, // è·åç¶ææ ç¾ç±»å getStatusTagType(status) { const typeMap = { completed: "success", in_progress: "warning", processing: "warning", pending: "info" }; return typeMap[status] || "info"; }, // è·åç¶æææ¬ getStatusText(status) { const textMap = { completed: "已宿", in_progress: "è¿è¡ä¸", processing: "è¿è¡ä¸", pending: "å¾ å¤ç" }; return textMap[status] || "æªç¥"; }, // è·åéè®¿ç±»åæ ç¾ getFollowupTypeTag(type) { const typeMap = { @@ -1140,6 +1196,7 @@ }; return typeMap[type] || "info"; }, // è·åéè®¿ç±»åææ¬ getFollowupTypeText(type) { const textMap = { @@ -1149,62 +1206,102 @@ }; return textMap[type] || "æªç¥"; }, // ä¿ååºæ¬ä¿¡æ¯ handleSave() { this.$refs.form.validate(valid => { async handleSave() { this.$refs.form.validate(async valid => { if (valid) { this.saveLoading = true; const apiMethod = this.form.id ? updateOrganUtilization : addOrganUtilization; try { const saveData = { ...this.form, assessannex: JSON.stringify(this.attachments), donateorgan: this.selectedOrgans.join(","), serviceDonatecomporganList: this.utilizationData.serviceDonatecomporganList || [] }; apiMethod(this.form) .then(response => { if (response.code === 200) { this.$message.success("ä¿åæå"); if (!this.form.id) { this.form.id = response.data.id; this.$router.replace({ query: { ...this.$route.query, id: this.form.id } }); } const apiMethod = this.form.id ? completionedit : completionadd; const response = await apiMethod(saveData); if (response.code === 200) { this.$message.success("ä¿åæå"); if (!this.form.id && response.data && response.data.id) { this.form.id = response.data.id; this.$router.replace({ query: { ...this.$route.query, id: this.form.id } }); } }) .catch(error => { console.error("ä¿å失败:", error); this.$message.error("ä¿å失败"); }) .finally(() => { this.saveLoading = false; }); } else { this.$message.error("ä¿å失败ï¼" + (response.msg || "æªç¥é误")); } } catch (error) { console.error("ä¿å失败:", error); this.$message.error("ä¿å失败"); } finally { this.saveLoading = false; } } }); }, // ä¿åå©ç¨è®°å½ handleSaveUtilization() { if (!this.form.id) { this.$message.warning("请å ä¿ååºæ¬ä¿¡æ¯"); async handleSaveUtilization() { if ( !this.utilizationData.serviceDonatecomporganList || this.utilizationData.serviceDonatecomporganList.length === 0 ) { this.$message.warning("è¯·å æ·»å å©ç¨è®°å½"); return; } this.saveLoading = true; saveUtilizationRecords(this.form.id, this.utilizationData.records) .then(response => { if (response.code === 200) { this.$message.success("å©ç¨è®°å½ä¿åæå"); } }) .catch(error => { console.error("ä¿åå©ç¨è®°å½å¤±è´¥:", error); this.$message.error("ä¿åå©ç¨è®°å½å¤±è´¥"); }) .finally(() => { this.saveLoading = false; }); try { const saveData = { ...this.form, attachments: this.attachments, donateorgan: this.selectedOrgans.join(","), serviceDonatecomporganList: this.utilizationData.serviceDonatecomporganList || [] }; const response = await completionedit(saveData); if (response.code === 200) { this.$message.success("å©ç¨è®°å½ä¿åæå"); } else { this.$message.error( "ä¿åå©ç¨è®°å½å¤±è´¥ï¼" + (response.msg || "æªç¥é误") ); } } catch (error) { console.error("ä¿åå©ç¨è®°å½å¤±è´¥:", error); this.$message.error("ä¿åå©ç¨è®°å½å¤±è´¥"); } finally { this.saveLoading = false; } }, // ç¡®è®¤å®æå©ç¨ handleConfirmUtilization() { if (this.incompleteRecords > 0) { async handleConfirmUtilization() { // æ£æ¥å©ç¨è®°å½æ¯å¦å®æ´ const incompleteRecords = this.utilizationData.serviceDonatecomporganList.filter( record => { if (record.transplantstate === "1") { return ( !record.caseNo || !record.hospitalno || !record.name || !record.transplanttime ); } else if (record.transplantstate === "0") { return !record.abandonreason; } return false; } ); if (incompleteRecords.length > 0) { this.$message.warning("请å å®åææå©ç¨è®°å½çä¿¡æ¯"); return; } @@ -1214,81 +1311,53 @@ cancelButtonText: "åæ¶", type: "warning" }) .then(() => { .then(async () => { this.confirmLoading = true; this.form.utilizationStatus = "completed"; this.form.completionTime = new Date() .toISOString() .replace("T", " ") .substring(0, 19); this.form.recordstate = "completed"; this.form.completetime = this.form.completetime || new Date() .toISOString() .replace("T", " ") .substring(0, 19); updateOrganUtilization(this.form) .then(response => { if (response.code === 200) { this.$message.success("å¨å®å©ç¨å·²å®æ"); } }) .catch(error => { console.error("确认å©ç¨å¤±è´¥:", error); this.$message.error("确认å©ç¨å¤±è´¥"); }) .finally(() => { this.confirmLoading = false; }); }) .catch(() => {}); }, // 宿å©ç¨ handleComplete() { this.handleConfirmUtilization(); }, // æ°å¢éè®¿è®°å½ handleAddFollowup() { this.followupDialogTitle = "æ°å¢é访记å½"; this.isEditingFollowup = false; this.currentFollowup = { organNo: this.utilizationData.records.length > 0 ? this.utilizationData.records[0].organNo : "", followupTime: new Date().toISOString().replace("T", " ").substring(0, 19), followupType: "routine", recipientCondition: "", medicationSituation: "", testResults: "", nextFollowupTime: "", followupDoctor: "" }; this.followupDialogVisible = true; }, // æ¥çéè®¿è®°å½ handleViewFollowup(record) { this.currentFollowup = { ...record }; this.followupDialogTitle = "æ¥çé访记å½"; this.followupDialogVisible = true; }, // ç¼è¾éè®¿è®°å½ handleEditFollowup(record) { this.followupDialogTitle = "ç¼è¾é访记å½"; this.isEditingFollowup = true; this.currentFollowup = { ...record }; this.followupDialogVisible = true; }, // å é¤éè®¿è®°å½ handleDeleteFollowup(record) { this.$confirm("ç¡®å®è¦å é¤è¿æ¡é访记å½åï¼", "æç¤º", { confirmButtonText: "ç¡®å®", cancelButtonText: "åæ¶", type: "warning" }) .then(() => { const index = this.followupData.records.findIndex( item => item.id === record.id ); if (index !== -1) { this.followupData.records.splice(index, 1); this.$message.success("é访记å½å 餿å"); try { const saveData = { ...this.form, attachments: this.attachments, donateorgan: this.selectedOrgans.join(","), serviceDonatecomporganList: this.utilizationData.serviceDonatecomporganList || [] }; const response = await completionedit(saveData); if (response.code === 200) { this.$message.success("å¨å®å©ç¨å·²å®æ"); } else { this.$message.error( "确认å©ç¨å¤±è´¥ï¼" + (response.msg || "æªç¥é误") ); this.form.recordstate = "pending"; this.form.completetime = ""; } } catch (error) { console.error("确认å©ç¨å¤±è´¥:", error); this.$message.error("确认å©ç¨å¤±è´¥"); this.form.recordstate = "pending"; this.form.completetime = ""; } finally { this.confirmLoading = false; } }) .catch(() => {}); }, // 宿å©ç¨ handleComplete() { this.handleConfirmUtilization(); }, // ä¿åéè®¿è®°å½ handleSaveFollowup() { if (!this.currentFollowup.organNo) { @@ -1304,10 +1373,10 @@ this.saveLoading = true; // è·åå¨å®åç§° const organRecord = this.utilizationData.records.find( item => item.organNo === this.currentFollowup.organNo const organRecord = this.utilizationData.serviceDonatecomporganList.find( item => item.organno === this.currentFollowup.organNo ); const organName = organRecord ? organRecord.organName : ""; const organName = organRecord ? organRecord.organname : ""; const followupData = { ...this.currentFollowup, @@ -1315,165 +1384,198 @@ utilizationId: this.form.id }; saveFollowupRecord(followupData) .then(response => { if (response.code === 200) { if (this.isEditingFollowup) { // æ´æ°ç°æè®°å½ const index = this.followupData.records.findIndex( item => item.id === this.currentFollowup.id ); if (index !== -1) { this.followupData.records[index] = response.data; } } else { // æ·»å æ°è®°å½ this.followupData.records.push(response.data); } this.$message.success("é访记å½ä¿åæå"); this.followupDialogVisible = false; // TODO: æ¿æ¢ä¸ºå®é çé访记å½ä¿åæ¥å£ setTimeout(() => { if (this.isEditingFollowup) { // æ´æ°ç°æè®°å½ const index = this.followupData.records.findIndex( item => item.id === this.currentFollowup.id ); if (index !== -1) { this.followupData.records[index] = { ...followupData, id: this.currentFollowup.id }; } }) .catch(error => { console.error("ä¿åé访记å½å¤±è´¥:", error); this.$message.error("ä¿åé访记å½å¤±è´¥"); }) .finally(() => { this.saveLoading = false; }); } else { // æ·»å æ°è®°å½ this.followupData.records.push({ ...followupData, id: Date.now() }); } this.$message.success("é访记å½ä¿åæå"); this.followupDialogVisible = false; this.saveLoading = false; }, 1000); }, // ä¸ä¼ éä»¶ handleUploadAttachment() { this.$message.info("éä»¶ä¸ä¼ åè½"); /** éä»¶ååå¤ç */ handleAttachmentChange(fileList) { this.attachmentFileList = fileList; }, // é¢è§éä»¶ handlePreviewAttachment(attachment) { this.$message.info("éä»¶é¢è§åè½"); }, // ä¸è½½éä»¶ handleDownloadAttachment(attachment) { this.$message.info("éä»¶ä¸è½½åè½"); }, // å é¤éä»¶ handleRemoveAttachment(attachment) { this.$confirm("ç¡®å®è¦å é¤è¿ä¸ªéä»¶åï¼", "æç¤º", { confirmButtonText: "ç¡®å®", cancelButtonText: "åæ¶", type: "warning" }) .then(() => { /** éä»¶ç§»é¤å¤ç */ handleAttachmentRemove(file) { if (file.url) { const index = this.attachments.findIndex( item => item.path === file.url || item.fileUrl === file.url ); if (index > -1) { this.attachments.splice(index, 1); this.$message.success("éä»¶å 餿å"); }) .catch(() => {}); } } }, // è·åæä»¶å¾æ getFileIcon(fileName) { const ext = fileName .split(".") .pop() .toLowerCase(); const iconMap = { pdf: "el-icon-document", doc: "el-icon-document", docx: "el-icon-document", xls: "el-icon-document", xlsx: "el-icon-document", jpg: "el-icon-picture", jpeg: "el-icon-picture", png: "el-icon-picture" /** ä¸ä¼ æåå¤ç */ handleUploadSuccess({ file, fileList, response }) { if (response.code === 200) { const attachmentObj = { fileName: file.name, path: response.fileUrl || file.url, fileUrl: response.fileUrl || file.url, fileType: this.getFileExtension(file.name), fileSize: file.size, uploadTime: dayjs().format("YYYY-MM-DD HH:mm:ss") }; if (!Array.isArray(this.attachments)) { this.attachments = []; } this.attachments.push(attachmentObj); this.attachmentFileList = fileList; this.$message.success("æä»¶ä¸ä¼ æå"); } }, /** ä¸ä¼ é误å¤ç */ handleUploadError({ file, fileList, error }) { console.error("éä»¶ä¸ä¼ 失败:", error); this.$message.error("æä»¶ä¸ä¼ 失败ï¼è¯·éè¯"); }, /** æå¨å é¤éä»¶ */ handleRemoveAttachment(index) { this.attachments.splice(index, 1); this.attachmentFileList.splice(index, 1); this.$message.success("éä»¶å 餿å"); }, /** æä»¶é¢è§ */ handlePreview(file) { this.currentPreviewFile = { fileName: file.fileName, fileUrl: file.path || file.fileUrl, fileType: this.getFileType(file.fileName) }; return iconMap[ext] || "el-icon-document"; this.filePreviewVisible = true; }, // è·åæä»¶ç±»å /** æä»¶ä¸è½½ */ handleDownloadAttachment(file) { const fileUrl = file.path || file.fileUrl; const fileName = file.fileName; if (fileUrl) { const link = document.createElement("a"); link.href = fileUrl; link.download = fileName; link.style.display = "none"; document.body.appendChild(link); link.click(); document.body.removeChild(link); this.$message.success("å¼å§ä¸è½½æä»¶"); } else { this.$message.warning("æä»¶è·¯å¾ä¸åå¨ï¼æ æ³ä¸è½½"); } }, /** è·åæä»¶ç±»å */ getFileType(fileName) { const ext = fileName if (!fileName) return "other"; const extension = fileName .split(".") .pop() .toLowerCase(); const typeMap = { pdf: "PDF", doc: "DOC", docx: "DOCX", xls: "XLS", xlsx: "XLSX", jpg: "JPG", jpeg: "JPEG", png: "PNG" }; return typeMap[ext] || ext.toUpperCase(); const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"]; const pdfTypes = ["pdf"]; const officeTypes = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"]; if (imageTypes.includes(extension)) return "image"; if (pdfTypes.includes(extension)) return "pdf"; if (officeTypes.includes(extension)) return "office"; return "other"; }, // æä»¶å¤§å°æ ¼å¼å formatFileSize(size) { if (size === 0) return "0 B"; /** è·åæä»¶å¾æ é¢è² */ getFileIconColor(fileName) { const type = this.getFileType(fileName); const colorMap = { image: "#67C23A", pdf: "#F56C6C", office: "#409EFF", other: "#909399" }; return colorMap[type] || "#909399"; }, /** è·åæä»¶æ ç¾ç±»å */ getFileTagType(fileName) { const type = this.getFileType(fileName); const typeMap = { image: "success", pdf: "danger", office: "primary", other: "info" }; return typeMap[type] || "info"; }, /** è·åæä»¶ç±»åææ¬ */ getFileTypeText(fileName) { const type = this.getFileType(fileName); const textMap = { image: "å¾ç", pdf: "PDF", office: "ææ¡£", other: "å ¶ä»" }; return textMap[type] || "æªç¥"; }, /** æ£æ¥æ¯å¦å¯é¢è§ */ isPreviewable(fileName) { const type = this.getFileType(fileName); return ["image", "pdf"].includes(type); }, /** è·åæä»¶æ©å±å */ getFileExtension(filename) { return filename .split(".") .pop() .toLowerCase(); }, /** æ ¼å¼åæä»¶å¤§å° */ formatFileSize(bytes) { if (!bytes || bytes === 0) return "0 B"; const k = 1024; const sizes = ["B", "KB", "MB", "GB"]; const i = Math.floor(Math.log(size) / Math.log(k)); return parseFloat((size / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]; }, // æ¶é´æ ¼å¼å parseTime(time) { if (!time) return ""; const date = new Date(time); return `${date.getFullYear()}-${(date.getMonth() + 1) .toString() .padStart(2, "0")}-${date .getDate() .toString() .padStart(2, "0")} ${date .getHours() .toString() .padStart(2, "0")}:${date .getMinutes() .toString() .padStart(2, "0")}`; }, // æäº¤å½æ¡£ handleSubmitArchive() { this.$confirm("确认æäº¤å½æ¡£åï¼å½æ¡£åå°æ æ³ä¿®æ¹æ°æ®ã", "æç¤º", { confirmButtonText: "ç¡®å®", cancelButtonText: "åæ¶", type: "warning" }) .then(() => { this.$message.success("æäº¤å½æ¡£æå"); }) .catch(() => {}); }, // æ¤é彿¡£ handleRevokeArchive() { this.$confirm("确认æ¤é彿¡£åï¼", "æç¤º", { confirmButtonText: "ç¡®å®", cancelButtonText: "åæ¶", type: "warning" }) .then(() => { this.$message.success("æ¤é彿¡£æå"); }) .catch(() => {}); }, // ç»æ¢æ¡ä¾ handleTerminateCase() { this.$confirm("ç¡®è®¤ç»æ¢æ¡ä¾åï¼", "æç¤º", { confirmButtonText: "ç¡®å®", cancelButtonText: "åæ¶", type: "warning" }) .then(() => { this.$message.success("æ¡ä¾å·²ç»æ¢"); }) .catch(() => {}); }, // æ¢å¤æ¡ä¾ handleRestoreCase() { this.$confirm("确认æ¢å¤æ¡ä¾åï¼", "æç¤º", { confirmButtonText: "ç¡®å®", cancelButtonText: "åæ¶", type: "warning" }) .then(() => { this.$message.success("æ¡ä¾å·²æ¢å¤"); }) .catch(() => {}); /** æ¥ææ¶é´æ ¼å¼å */ formatDateTime(dateTime) { if (!dateTime) return ""; try { const date = new Date(dateTime); if (isNaN(date.getTime())) return dateTime; const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, "0"); const day = String(date.getDate()).padStart(2, "0"); const hours = String(date.getHours()).padStart(2, "0"); const minutes = String(date.getMinutes()).padStart(2, "0"); return `${year}-${month}-${day} ${hours}:${minutes}`; } catch (error) { return dateTime; } } } }; @@ -1486,29 +1588,81 @@ min-height: 100vh; } .detail-card, .utilization-card, .recipient-card, .followup-card, .attachment-card { .detail-card, .utilization-card, .followup-card, .attachment-card { margin-bottom: 20px; border-radius: 8px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); border: 1px solid #e4e7ed; } /* æ°å¢é件头鍿 ·å¼ */ .attachment-header { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; padding-bottom: 8px; border-bottom: 1px solid #ebeef5; } .attachment-title { font-weight: 600; color: #303133; font-size: 16px; } .attachment-tip { font-size: 12px; color: #909399; margin-left: auto; } .attachment-list { margin-top: 20px; } .list-title { font-weight: bold; margin-bottom: 12px; color: #303133; font-size: 14px; } .file-name { font-size: 13px; margin-left: 8px; color: #606266; } /* æä»¶å¾æ æ ·å¼ */ .el-icon-document { font-size: 16px; vertical-align: middle; } /* ä¿æåææ ·å¼ */ .detail-title { font-size: 18px; font-weight: 600; color: #303133; line-height: 1.4; } /* è¡¨æ ¼æ´ä½æ ·å¼ */ :deep(.el-table) { border-radius: 8px; overflow: hidden; } :deep(.el-table th) { background-color: #f5f7fa; color: #606266; font-weight: 600; } :deep(.el-table .cell) { padding: 12px 8px; line-height: 1.5; @@ -1518,6 +1672,7 @@ :deep(.el-table__row.warning-row) { background-color: #fdf6ec; } :deep(.el-table__row.default-row) { background-color: #f0f9ff; } @@ -1535,6 +1690,7 @@ border-radius: 8px; color: white; } .stat-item { display: flex; flex-direction: column; @@ -1542,84 +1698,238 @@ padding: 10px; text-align: center; } .stat-label { font-size: 18px; font-size: 12px; opacity: 0.9; margin-bottom: 5px; color: rgba(255, 255, 255, 0.9); } .stat-value { font-size: 20px; font-size: 18px; font-weight: bold; color: white; } /* å±å¼è¡æ ·å¼ */ .recipient-detail-expand { padding: 20px; background: #fafafa; border-radius: 8px; margin: 10px 0; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } .recipient-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 2px solid #e4e7ed; } .recipient-title { font-size: 16px; font-weight: 600; color: #303133; } /* 表åé¨åæ ·å¼ */ .recipient-form { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); } /* 表åé¨åæ é¢ */ .form-section { margin-bottom: 25px; padding-bottom: 20px; border-bottom: 1px solid #f0f0f0; &:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; } } .section-title { font-size: 15px; font-weight: 600; color: #409eff; margin: 0 0 15px 0; padding-left: 10px; border-left: 4px solid #409eff; line-height: 1.2; } /* 表åè¡é´è· */ :deep(.el-form-item) { margin-bottom: 20px; .el-form-item__label { font-weight: 500; color: #606266; padding-right: 10px; } .el-form-item__content { line-height: 1.5; } } /* 表åè¾å ¥æ¡æ ·å¼ */ :deep(.el-input__inner) { height: 36px; line-height: 36px; border-radius: 4px; transition: all 0.3s ease; &:focus { border-color: #409eff; box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2); } &:disabled { background-color: #f5f7fa; border-color: #e4e7ed; color: #c0c4cc; cursor: not-allowed; } } /* ææ¬åæ ·å¼ */ :deep(.el-textarea__inner) { min-height: 80px; border-radius: 4px; transition: all 0.3s ease; &:focus { border-color: #409eff; box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2); } &:disabled { background-color: #f5f7fa; border-color: #e4e7ed; color: #c0c4cc; cursor: not-allowed; } } /* éæ©æ¡æ ·å¼ */ :deep(.el-select) { width: 100%; .el-input__inner { border-radius: 4px; } &.is-disabled { .el-input__inner { background-color: #f5f7fa; border-color: #e4e7ed; color: #c0c4cc; } } } /* æ¥æéæ©å¨æ ·å¼ */ :deep(.el-date-editor) { width: 100%; &.el-input__inner { border-radius: 4px; } &.is-disabled { .el-input__inner { background-color: #f5f7fa; border-color: #e4e7ed; color: #c0c4cc; } } } /* ååºå¼è°æ´ */ @media (max-width: 768px) { .recipient-detail-expand { padding: 15px; } .recipient-form { padding: 15px; } .attachment-header { flex-wrap: wrap; } .attachment-tip { width: 100%; margin-top: 8px; margin-left: 0; } .form-section { margin-bottom: 20px; padding-bottom: 15px; } :deep(.el-form-item) { margin-bottom: 15px; } .section-title { font-size: 14px; margin-bottom: 12px; } } :deep(.el-divider) { margin: 20px 0; background-color: #e4e7ed; } /* è¡¨åæ ç¾åè¾å ¥æ¡æ ·å¼ */ :deep(.el-form-item__label) { font-weight: 500; color: #606266; } :deep(.el-input__inner) { border-radius: 4px; transition: border-color 0.3s ease; } :deep(.el-input__inner:focus) { border-color: #409EFF; border-color: #409eff; box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2); } /* æé®æ ·å¼ä¼å */ :deep(.el-button--primary) { background: linear-gradient(135deg, #409EFF 0%, #3375e0 100%); background: linear-gradient(135deg, #409eff 0%, #3375e0 100%); border: none; border-radius: 4px; transition: all 0.3s ease; } :deep(.el-button--primary:hover) { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4); } /* æ ç¾é¡µæ ·å¼ */ :deep(.el-tabs__item) { font-weight: 500; } :deep(.el-tabs__active-bar) { background: linear-gradient(135deg, #409EFF 0%, #3375e0 100%); } /* å¹³æ¿è®¾å¤éé */ @media (max-width: 1024px) { .organ-utilization-detail { padding: 15px; } :deep(.el-col) { margin-bottom: 10px; } /* åºé¨æä½æé® */ .dialog-footer { margin-top: 20px; text-align: center; padding-top: 20px; border-top: 1px solid #e4e7ed; } /* ææºè®¾å¤éé */ @media (max-width: 768px) { .organ-utilization-detail { padding: 10px; } .detail-title { font-size: 16px; } :deep(.el-table .cell) { padding: 8px 4px; font-size: 12px; } :deep(.el-form-item__label) { font-size: 12px; } .dialog-footer .el-button { margin: 0 10px; min-width: 120px; } /* è¶ å°å±å¹è®¾å¤ */ @media (max-width: 480px) { .organ-utilization-detail { padding: 5px; } :deep(.el-card__header) { padding: 10px 15px; } } /* ç©ºç¶ææ ·å¼ */ .empty-utilization { text-align: center; @@ -1630,27 +1940,39 @@ margin: 20px 0; } /* å è½½ç¶æ */ :deep(.el-loading-mask) { border-radius: 4px; } /* æä»¶ä¿¡æ¯æ ·å¼ */ .file-info { display: flex; align-items: center; padding: 5px 0; } .file-info i { font-size: 18px; margin-right: 10px; } /* å¨ç»ææ */ .fade-enter-active, .fade-leave-active { transition: opacity 0.3s ease; /* å¹³æ¿è®¾å¤éé */ @media (max-width: 1024px) { .organ-utilization-detail { padding: 15px; } :deep(.el-col) { margin-bottom: 10px; } } .fade-enter, .fade-leave-to { opacity: 0; /* ææºè®¾å¤éé */ /* è¶ å°å±å¹è®¾å¤ */ @media (max-width: 480px) { .organ-utilization-detail { padding: 5px; } :deep(.el-card__header) { padding: 10px 15px; } } </style> src/views/business/allocation/allocationInfo.vue
@@ -12,7 +12,7 @@ <el-button type="success" @click="handleConfirmAllocation" :disabled="form.allocationStatus === '1'" :disabled="form.allocationStatus == '1'" :loading="confirmLoading" > 确认åé @@ -44,7 +44,7 @@ type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" :disabled="form.allocationStatus === '1'" :disabled="form.allocationStatus == '1'" /> </el-form-item> </el-col> @@ -77,17 +77,17 @@ <div style="float: right;"> <el-tag :type=" form.allocationStatus === '1' form.allocationStatus == '1' ? 'success' : form.allocationStatus === '2' : form.allocationStatus == '2' ? 'danger' : 'warning' " > {{ form.allocationStatus === "1" form.allocationStatus == "1" ? "å·²åé " : form.allocationStatus === "2" : form.allocationStatus == "2" ? "ä½åº" : "æªåé " }} @@ -112,7 +112,7 @@ v-for="dict in dict.type.sys_Organ || []" :key="dict.value" :label="dict.value" :disabled="form.allocationStatus === '1'" :disabled="form.allocationStatus == '1'" > {{ dict.label }} </el-checkbox> @@ -162,7 +162,7 @@ <el-input v-model="scope.row.caseno" placeholder="åé ç³»ç»ç¼å·" :disabled="form.allocationStatus === '1'" :disabled="form.allocationStatus == '1'" /> </template> </el-table-column> @@ -182,7 +182,7 @@ type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="éæ©åé æ¥æ¶æ¶é´" :disabled="form.allocationStatus === '1'" :disabled="form.allocationStatus == '1'" /> </template> </el-table-column> @@ -197,7 +197,7 @@ <el-input v-model="scope.row.name" placeholder="åä½å§æ°" :disabled="form.allocationStatus === '1'" :disabled="form.allocationStatus == '1'" /> </template> </el-table-column> @@ -233,7 +233,7 @@ clearable v-model="scope.row.reallocationreason" placeholder="请è¾å ¥è¯´æ" :disabled="form.allocationStatus === '1'" :disabled="form.allocationStatus == '1'" /> </template> </el-table-column> @@ -297,17 +297,17 @@ <span class="stat-value"> <el-tag :type=" form.allocationStatus === '1' form.allocationStatus == '1' ? 'success' : form.allocationStatus === '2' : form.allocationStatus == '2' ? 'danger' : 'warning' " > {{ form.allocationStatus === "1" form.allocationStatus == "1" ? "å·²åé " : form.allocationStatus === "2" : form.allocationStatus == "2" ? "ä½åº" : "æªåé " }} @@ -332,7 +332,7 @@ :loading="saveLoading" :disabled=" !allocationData.serviceDonateorganList || allocationData.serviceDonateorganList.length === 0 allocationData.serviceDonateorganList.length == 0 " > ä¿ååé è®°å½ @@ -645,7 +645,7 @@ methods: { // æ ¹æ®åå ¸valueè·ålabel getOrganLabel(organValue) { const dictItem = this.organDict.find(item => item.value === organValue); const dictItem = this.organDict.find(item => item.value == organValue); return dictItem ? dictItem.label : organValue; }, @@ -702,17 +702,14 @@ donateorganBaseinfoInfo(id); try { const response = await allocationList({ infoid }); if ( response.code === 200 && response.data && response.data.length > 0 ) { if (response.code == 200 && response.data && response.data.length > 0) { const data = response.data[0]; data.allocationStatus = JSON.stringify(data.allocationStatus); // å¡«å è¡¨åæ°æ® Object.assign(this.form, data); // 转æ¢é件为éå this.parseFilePatch(this.form.fileName); this.parseFilePatch(this.form.fileName); // åå§åéä»¶ if (this.form.attachments) { @@ -741,7 +738,7 @@ if (item.organname) { const dictItem = this.organDict.find( org => org.label === item.organname || org.label == item.organname || (item.organname && item.organname.includes(org.label)) ); return dictItem ? dictItem.value : null; @@ -881,7 +878,7 @@ let organName = this.getOrganLabel(organValue); // 妿æ¯"å ¶ä»"å¨å®ä¸æè¾å ¥å¼ if (organValue === "C01" && this.otherOrganInput) { if (organValue == "C01" && this.otherOrganInput) { organName = `å ¶ä»(${this.otherOrganInput})`; } @@ -902,7 +899,7 @@ // å»é¢éæ©åå handleHospitalChange(row, hospitalNo) { const hospital = this.hospitalList.find( item => item.hospitalNo === hospitalNo item => item.hospitalNo == hospitalNo ); if (hospital) { row.transplantHospitalName = hospital.hospitalName; @@ -942,7 +939,7 @@ }, // æå»º filePatch åæ®µ buildFilePatch() { if (!this.attachments || this.attachments.length === 0) { if (!this.attachments || this.attachments.length == 0) { return ""; } return JSON.stringify(this.attachments); @@ -962,23 +959,22 @@ serviceDonateorganList: this.allocationData.serviceDonateorganList || [] }; saveData.fileName=this.buildFilePatch(); saveData.fileName = this.buildFilePatch(); saveData.serviceDonateorganList.forEach(item => { item.baseid = this.form.id; item.infoid = this.form.infoid; }); console.log(this.form.recordstate); this.form.recordstate = 1; const apiMethod = this.form.id ? allocationedit : allocationadd; const response = await apiMethod(saveData); if (response.code === 200) { if (response.code == 200) { this.$message.success("ä¿åæå"); if (!this.form.id && response.data && response.data.id) { this.form.id = response.data.id; this.$router.replace({ query: { ...this.$route.query, id: this.form.id } }); if (!this.form.id && response.data) { this.form.id = response.data; // this.$router.replace({ // query: { ...this.$route.query, id: this.form.id } // }); } } else { this.$message.error("ä¿å失败ï¼" + (response.msg || "æªç¥é误")); @@ -1009,7 +1005,7 @@ const response = await allocationedit(saveData); if (response.code === 200) { if (response.code == 200) { this.$message.success("åé è®°å½ä¿åæå"); } else { this.$message.error( @@ -1053,7 +1049,7 @@ const response = await allocationedit(saveData); if (response.code === 200) { if (response.code == 200) { this.$message.success("å¨å®åé 已宿"); } else { this.$message.error( @@ -1084,7 +1080,7 @@ handleAttachmentRemove(file) { if (file.url) { const index = this.attachments.findIndex( item => item.path === file.url || item.fileUrl === file.url item => item.path == file.url || item.fileUrl == file.url ); if (index > -1) { this.attachments.splice(index, 1); @@ -1095,7 +1091,7 @@ /** ä¸ä¼ æåå¤ç */ handleUploadSuccess({ file, fileList, response }) { if (response.code === 200) { if (response.code == 200) { const attachmentObj = { fileName: file.name, path: response.fileUrl || file.url, @@ -1224,7 +1220,7 @@ /** æ ¼å¼åæä»¶å¤§å° */ formatFileSize(bytes) { if (!bytes || bytes === 0) return "0 B"; if (!bytes || bytes == 0) return "0 B"; const k = 1024; const sizes = ["B", "KB", "MB", "GB"]; const i = Math.floor(Math.log(bytes) / Math.log(k)); src/views/business/followupVisit/index.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,1349 @@ <template> <div class="followup-list"> <!-- æ¥è¯¢æ¡ä»¶ --> <el-card class="search-card"> <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="100px" > <el-form-item label="å¨å®åä½è å§å" prop="recipientname"> <el-input v-model="queryParams.recipientname" placeholder="请è¾å ¥å¨å®åä½è å§å" clearable style="width: 200px" @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item label="ç§»æ¤å»é¢" prop="hospitalname"> <el-input v-model="queryParams.hospitalname" placeholder="请è¾å ¥ç§»æ¤å»é¢åç§°" clearable style="width: 200px" @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item label="é访è " prop="followupno"> <el-input v-model="queryParams.followupno" placeholder="请è¾å ¥é访è " clearable style="width: 180px" @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item label="æç®ç»æ" prop="donateresult"> <el-select v-model="queryParams.donateresult" placeholder="è¯·éæ©æç®ç»æ" clearable style="width: 180px" > <el-option label="æå" value="1" /> <el-option label="失败" value="0" /> <el-option label="è¿è¡ä¸" value="2" /> </el-select> </el-form-item> <el-form-item label="é访æ¶é´" prop="followupTimeRange"> <el-date-picker v-model="queryParams.followupTimeRange" type="daterange" range-separator="è³" start-placeholder="å¼å§æ¥æ" end-placeholder="ç»ææ¥æ" value-format="yyyy-MM-dd" style="width: 240px" /> </el-form-item> <el-form-item label="å建æ¶é´" prop="createTimeRange"> <el-date-picker v-model="queryParams.createTimeRange" type="daterange" range-separator="è³" start-placeholder="å¼å§æ¥æ" end-placeholder="ç»ææ¥æ" value-format="yyyy-MM-dd" style="width: 240px" /> </el-form-item> <el-form-item> <el-button type="primary" icon="el-icon-search" @click="handleQuery" >æç´¢</el-button > <el-button icon="el-icon-refresh" @click="resetQuery">éç½®</el-button> </el-form-item> </el-form> </el-card> <!-- æä½æé® --> <el-card class="tool-card"> <el-row :gutter="10"> <el-col :span="16"> <el-button type="primary" icon="el-icon-plus" @click="handleCreate" v-hasPermi="['system:followup:add']" >æ°å¢é访</el-button > <el-button type="success" icon="el-icon-edit" :disabled="single" @click="handleUpdate" v-hasPermi="['system:followup:edit']" >ä¿®æ¹</el-button > <el-button type="danger" icon="el-icon-delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:followup:remove']" >å é¤</el-button > <el-button type="warning" icon="el-icon-download" @click="handleExport" v-hasPermi="['system:followup:export']" >导åº</el-button > </el-col> <el-col :span="8" style="text-align: right"> <el-tooltip content="å·æ°" placement="top"> <el-button icon="el-icon-refresh" circle @click="getList" /> </el-tooltip> </el-col> </el-row> </el-card> <!-- æ°æ®è¡¨æ ¼ --> <el-card> <el-table v-loading="loading" :data="followupList" @selection-change="handleSelectionChange" border :default-sort="{ prop: 'followuptime', order: 'descending' }" > <el-table-column type="selection" width="55" align="center" /> <el-table-column label="é访åºå·" align="center" prop="seqno" width="100" > <template slot-scope="scope"> <span>第{{ scope.row.seqno || 1 }}次</span> </template> </el-table-column> <el-table-column label="é访æ¶é´" align="center" prop="followuptime" width="120" > <template slot-scope="scope"> <span>{{ parseTime(scope.row.followuptime, "{y}-{m}-{d}") }}</span> </template> </el-table-column> <el-table-column label="å¨å®åä½è å§å" align="center" prop="recipientname" width="120" /> <el-table-column label="ç§»æ¤å»é¢" align="center" prop="hospitalname" width="150" show-overflow-tooltip /> <el-table-column label="ç§»æ¤ç§å®¤" align="center" prop="hospitaldept" width="120" /> <el-table-column label="é访å»ç" align="center" prop="doctorname" width="120" /> <el-table-column label="å»ççµè¯" align="center" prop="doctorphone" width="120" /> <el-table-column label="æç®ç»æ" align="center" prop="donateresult" width="100" > <template slot-scope="scope"> <el-tag :type="resultTypeFilter(scope.row.donateresult)"> {{ resultTextFilter(scope.row.donateresult) }} </el-tag> </template> </el-table-column> <el-table-column label="é访è " align="center" prop="followupno" width="100" /> <el-table-column label="é访æè¿°" align="center" prop="followupdescribe" min-width="200" show-overflow-tooltip /> <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="120" > <template slot-scope="scope"> <span>{{ parseTime(scope.row.createTime, "{y}-{m}-{d}") }}</span> </template> </el-table-column> <el-table-column label="æä½" align="center" width="150" fixed="right" class-name="small-padding fixed-width" > <template slot-scope="scope"> <el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)" v-hasPermi="['system:followup:query']" >详æ </el-button > <!-- <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:followup:edit']" >ä¿®æ¹</el-button > --> <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['system:followup:remove']" >å é¤</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="éæ©æç®æ¡ä¾" :visible.sync="selectCaseOpen" width="1200px" append-to-body :close-on-click-modal="false" > <!-- æç´¢è¡¨å --> <el-form :model="caseQueryParams" ref="caseQueryForm" :inline="true" label-width="88px" > <el-form-item label="æç®è å§å" prop="name"> <el-input v-model="caseQueryParams.name" placeholder="请è¾å ¥å§å" clearable size="small" @keyup.enter.native="searchCaseList" /> </el-form-item> <el-form-item label="æ²»çå»é¢" prop="treatmenthospitalname"> <el-input v-model="caseQueryParams.treatmenthospitalname" placeholder="请è¾å ¥æ²»çå»é¢" clearable size="small" style="width: 150px" /> </el-form-item> <el-form-item label="䏿¥æ¶é´"> <el-date-picker style="width: 100%" v-model="caseSelectTime" type="monthrange" range-separator="è³" start-placeholder="å¼å§æä»½" end-placeholder="ç»ææä»½" value-format="yyyy-MM-dd" @change="handleCaseTimeSelect" size="small" /> </el-form-item> <el-row> <el-col :span="4"> <el-form-item> <el-button type="primary" icon="el-icon-search" size="mini" @click="searchCaseList" > æç´¢ </el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetCaseSearch" > éç½® </el-button> </el-form-item> </el-col> </el-row> </el-form> <!-- æ¡ä¾è¡¨æ ¼ --> <el-table v-loading="caseLoading" :data="availableCaseList" @row-click="handleCaseRowClick" highlight-current-row style="width: 100%; margin-top: 20px;" > <el-table-column label="æ¡ä¾æ¶é´" align="center" prop="donatetime" width="100" > <template slot-scope="scope"> <span>{{ parseTime(scope.row.donatetime, "{y}-{m}-{d}") }}</span> </template> </el-table-column> <el-table-column label="æ¡ä¾ç¼å·" align="center" prop="caseNo" width="200" /> <el-table-column label="æç®è å§å" align="center" prop="name" width="100" /> <el-table-column label="æ§å«" align="center" prop="sex" width="100"> <template slot-scope="scope"> <dict-tag :options="dict.type.sys_user_sex" :value="parseInt(scope.row.sex)" /> </template> </el-table-column> <el-table-column label="å¹´é¾" align="center" prop="age" width="100"> <template slot-scope="scope"> {{ `${ scope.row.age && scope.row.age !== 0 ? `${scope.row.age}${scope.row.ageunit || ""}` : "" } ${ scope.row.age2 && scope.row.age2 !== 0 ? `${scope.row.age2}${scope.row.ageunit2}` : "" }`.trim() }} </template> </el-table-column> <el-table-column label="æ²»çå»é¢" align="center" prop="treatmenthospitalname" show-overflow-tooltip /> <el-table-column label="GCSè¯å" align="center" prop="gcsScore" width="100" /> <el-table-column label="è¡å" align="center" prop="bloodtype" width="100" > <template slot-scope="scope"> <dict-tag :options="dict.type.sys_BloodType" :value="scope.row.bloodtype" /> </template> </el-table-column> <el-table-column label="æç®ç±»å«" align="center" prop="donationcategory" > <template slot-scope="scope"> <dict-tag :options="dict.type.sys_DonationCategory" :value="scope.row.donationcategory" /> </template> </el-table-column> <el-table-column label="æ¥å人" align="center" prop="reportername" /> <el-table-column label="æç®è¿åº¦" align="center" prop="workflow" > <template slot-scope="scope"> <div v-if="!scope.row.terminationCase"> <dict-tag :options="dict.type.sys_donornode" :value="scope.row.workflow" /> </div> <div v-else> <el-button type="danger" plain>ä»»å¡ç»æ¢</el-button> </div> </template> </el-table-column> <el-table-column label="æ¯å¦å·²æé访" width="100" align="center"> <template slot-scope="scope"> <el-tag :type="hasFollowup(scope.row) ? 'danger' : 'success'" size="small" > {{ hasFollowup(scope.row) ? "å·²æé访" : "å¯éæ©" }} </el-tag> </template> </el-table-column> <el-table-column label="æä½" align="center"> <template slot-scope="scope"> <el-button type="text" size="mini" @click.stop="selectCase(scope.row)" :disabled="hasFollowup(scope.row) || scope.row.terminationCase" > éæ© </el-button> </template> </el-table-column> </el-table> <!-- å页 --> <pagination v-show="caseTotal > 0" :total="caseTotal" :page.sync="caseQueryParams.pageNum" :limit.sync="caseQueryParams.pageSize" @pagination="searchCaseList" style="padding: 10px 0; background: #fff; border-top: 1px solid #ebeef5;" /> <div slot="footer" class="dialog-footer"> <el-button @click="selectCaseOpen = false">åæ¶</el-button> <el-button type="primary" @click="confirmCaseSelection" v-if="selectedCaseRow" > ç¡®è®¤éæ© </el-button> </div> </el-dialog> <!-- æ°å¢/ä¿®æ¹å¯¹è¯æ¡ --> <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body :close-on-click-modal="false" > <el-form ref="form" :model="form" :rules="rules" label-width="120px"> <el-form-item label="å ³èæ¡ä¾" prop="infoid"> <el-input v-model="form.infoid" placeholder="è¯·éæ©æ¡ä¾" :disabled="true" style="width: 300px" > <el-button slot="append" icon="el-icon-search" @click="openCaseDialog" v-if="!form.id" >éæ©æ¡ä¾</el-button > </el-input> <div v-if="selectedCase" style="margin-top: 8px; color: #666;"> <span>æ¡ä¾ç¼å·: {{ selectedCase.caseNo }}</span> <span style="margin-left: 20px;" >æç®è : {{ selectedCase.name }}</span > <span style="margin-left: 20px; display: block; margin-top: 5px;"> æ²»çå»é¢: {{ selectedCase.treatmenthospitalname }} </span> <span style="margin-left: 20px; display: block; margin-top: 5px;"> è¯æ: {{ selectedCase.diagnosisname }} </span> <span style="margin-left: 20px; display: block; margin-top: 5px;"> è¡å: <dict-tag :options="dict.type.sys_BloodType" :value="selectedCase.bloodtype" /> </span> </div> </el-form-item> <el-row> <el-col :span="12"> <el-form-item label="å¨å®åä½è å§å" prop="recipientname"> <el-input v-model="form.recipientname" placeholder="请è¾å ¥å¨å®åä½è å§å" maxlength="50" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="åä½çµè¯" prop="recipientphone"> <el-input v-model="form.recipientphone" placeholder="请è¾å ¥å¨å®åä½è çµè¯" maxlength="20" /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="ç§»æ¤å»é¢åç§°" prop="hospitalname"> <el-input v-model="form.hospitalname" placeholder="请è¾å ¥ç§»æ¤å»é¢åç§°" maxlength="100" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="ç§»æ¤ç§å®¤" prop="hospitaldept"> <el-input v-model="form.hospitaldept" placeholder="请è¾å ¥ç§»æ¤å»é¢ç§å®¤" maxlength="50" /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="é访å»çå§å" prop="doctorname"> <el-input v-model="form.doctorname" placeholder="请è¾å ¥æ¥åé访å»çå§å" maxlength="50" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="å»ççµè¯" prop="doctorphone"> <el-input v-model="form.doctorphone" placeholder="请è¾å ¥æ¥åé访å»ççµè¯" maxlength="20" /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="æç®ç»æ" prop="donateresult"> <el-select v-model="form.donateresult" placeholder="è¯·éæ©æç®ç»æ" style="width: 100%" > <el-option label="æå" value="1" /> <el-option label="失败" value="0" /> <el-option label="è¿è¡ä¸" value="2" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="é访æ¶é´" prop="followuptime"> <el-date-picker v-model="form.followuptime" type="datetime" placeholder="éæ©é访æ¶é´" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" /> </el-form-item> </el-col> </el-row> <el-form-item label="é访åºå·" prop="seqno"> <el-input-number v-model="form.seqno" :min="1" :max="20" placeholder="请è¾å ¥é访åºå·" style="width: 200px" /> <span style="margin-left: 10px; color: #999;" >(第{{ form.seqno || 1 }}次é访)</span > </el-form-item> <el-form-item label="é访è " prop="followupno"> <el-input v-model="form.followupno" placeholder="请è¾å ¥é访è " maxlength="50" style="width: 300px" /> </el-form-item> <el-form-item label="å»çæè¿°" prop="doctordescribe"> <el-input v-model="form.doctordescribe" type="textarea" placeholder="请è¾å ¥å»çæè¿°" maxlength="500" :rows="3" show-word-limit /> </el-form-item> <el-form-item label="é访æè¿°" prop="followupdescribe"> <el-input v-model="form.followupdescribe" type="textarea" placeholder="请è¾å ¥é访æè¿°" maxlength="1000" :rows="4" show-word-limit /> </el-form-item> <el-form-item label="åä½è æè¿°" prop="recipientdescribe"> <el-input v-model="form.recipientdescribe" type="textarea" placeholder="请è¾å ¥å¨å®åä½è æè¿°" maxlength="500" :rows="3" show-word-limit /> </el-form-item> <el-form-item label="夿³¨" prop="remark"> <el-input v-model="form.remark" type="textarea" placeholder="请è¾å ¥å¤æ³¨" maxlength="500" :rows="3" show-word-limit /> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button type="primary" @click="submitForm">ç¡® å®</el-button> <el-button @click="cancel">å æ¶</el-button> </div> </el-dialog> </div> </template> <script> import { listFollowup, getFollowup, addFollowup, updateFollowup, delFollowup, exportFollowup } from "@/api/businessApi/followup"; import { listDonatebaseinfo } from "@/api/project/donatebaseinfo"; import Pagination from "@/components/Pagination"; export default { name: "Followup", components: { Pagination }, dicts: [ "sys_user_sex", "sys_BloodType", "sys_DonationCategory", "sys_donornode" ], data() { return { // é®ç½©å± loading: true, caseLoading: false, exportLoading: false, // é䏿°ç» ids: [], // éå个ç¦ç¨ single: true, // éå¤ä¸ªç¦ç¨ multiple: true, // æ»æ¡æ° total: 0, caseTotal: 0, // éè®¿è¡¨æ ¼æ°æ® followupList: [], // å¼¹åºå±æ é¢ title: "", // æ¯å¦æ¾ç¤ºå¼¹åºå± open: false, // æ¯å¦æ¾ç¤ºéæ©æ¡ä¾å¼¹åºå± selectCaseOpen: false, // æ¶é´éæ© caseSelectTime: [], // æ¥è¯¢åæ° queryParams: { pageNum: 1, pageSize: 10, recipientname: undefined, hospitalname: undefined, followupno: undefined, donateresult: undefined, followupTimeRange: [], createTimeRange: [] }, // æ¡ä¾æ¥è¯¢åæ° caseQueryParams: { pageNum: 1, pageSize: 10, name: undefined, treatmenthospitalname: undefined, starttime: undefined, endtime: undefined }, // å¯éæ©çæ¡ä¾å表 availableCaseList: [], // å½åéä¸çæ¡ä¾ selectedCase: null, selectedCaseRow: null, // å·²æéè®¿çæ¡ä¾IDç¼å existingFollowupCases: new Set(), // 表ååæ° form: { id: undefined, infoid: undefined, organid: undefined, recipientname: "", recipientphone: "", recipientdescribe: "", hospitalname: "", hospitaldept: "", hospitalno: "", doctorname: "", doctorphone: "", doctordescribe: "", donateresult: "", followuptime: undefined, followupno: "", followupdescribe: "", seqno: 1, remark: "" }, // è¡¨åæ ¡éª rules: { infoid: [ { required: true, message: "è¯·éæ©å ³èæ¡ä¾", trigger: "blur" } ], recipientname: [ { required: true, message: "å¨å®åä½è å§åä¸è½ä¸ºç©º", trigger: "blur" }, { max: 50, message: "é¿åº¦ä¸è½è¶ è¿50个å符", trigger: "blur" } ], hospitalname: [ { required: true, message: "ç§»æ¤å»é¢åç§°ä¸è½ä¸ºç©º", trigger: "blur" }, { max: 100, message: "é¿åº¦ä¸è½è¶ è¿100个å符", trigger: "blur" } ], followuptime: [ { required: true, message: "é访æ¶é´ä¸è½ä¸ºç©º", trigger: "change" } ], followupno: [ { required: true, message: "é访è ä¸è½ä¸ºç©º", trigger: "blur" }, { max: 50, message: "é¿åº¦ä¸è½è¶ è¿50个å符", trigger: "blur" } ], donateresult: [ { required: true, message: "æç®ç»æä¸è½ä¸ºç©º", trigger: "change" } ], seqno: [ { required: true, message: "é访åºå·ä¸è½ä¸ºç©º", trigger: "blur" }, { type: "number", min: 1, max: 20, message: "é访åºå·èå´ä¸º1-20", trigger: "blur" } ] } }; }, created() { this.getList(); }, methods: { // ç»æç±»åè¿æ»¤å¨ resultTypeFilter(result) { const resultMap = { "1": "success", // æå "0": "danger", // 失败 "2": "primary" // è¿è¡ä¸ }; return resultMap[result] || "info"; }, resultTextFilter(result) { const resultMap = { "1": "æå", "0": "失败", "2": "è¿è¡ä¸" }; return resultMap[result] || "æªç¥"; }, // æ¥è¯¢é访å表 async getList() { this.loading = true; try { const requestParams = this.buildRequestParams(); const response = await listFollowup(requestParams); if (response.code === 200) { this.handleResponseData(response); // å è½½éè®¿æ°æ®åï¼æåå·²æçæ¡ä¾ID this.extractExistingCaseIds(); } else { this.$message.error("è·åæ°æ®å¤±è´¥ï¼" + (response.msg || "æªç¥é误")); this.followupList = []; this.total = 0; } } catch (error) { console.error("è·åé访å表失败:", error); this.$message.error("è·åæ°æ®å¤±è´¥"); this.followupList = []; this.total = 0; } finally { this.loading = false; } }, // æå»ºè¯·æ±åæ° buildRequestParams() { const params = { pageNum: this.queryParams.pageNum, pageSize: this.queryParams.pageSize }; if (this.queryParams.recipientname) { params.recipientname = this.queryParams.recipientname; } if (this.queryParams.hospitalname) { params.hospitalname = this.queryParams.hospitalname; } if (this.queryParams.followupno) { params.followupno = this.queryParams.followupno; } if ( this.queryParams.donateresult !== undefined && this.queryParams.donateresult !== "" ) { params.donateresult = this.queryParams.donateresult; } if ( this.queryParams.followupTimeRange && this.queryParams.followupTimeRange.length === 2 ) { params.startFollowupTime = this.queryParams.followupTimeRange[0]; params.endFollowupTime = this.queryParams.followupTimeRange[1]; } if ( this.queryParams.createTimeRange && this.queryParams.createTimeRange.length === 2 ) { params.startCreateTime = this.queryParams.createTimeRange[0]; params.endCreateTime = this.queryParams.createTimeRange[1]; } return params; }, // å¤çæ¥å£ååºæ°æ® handleResponseData(response) { if (response.data) { if (Array.isArray(response.data)) { this.followupList = response.data; this.total = response.data.length; } else if (response.data.rows) { this.followupList = response.data.rows; this.total = response.data.total; } else if (Array.isArray(response.data.list)) { this.followupList = response.data.list; this.total = response.data.total || response.data.list.length; } else { this.followupList = response.data; this.total = response.total || response.data.length; } } else { if (Array.isArray(response.rows)) { this.followupList = response.rows; this.total = response.total; } else if (Array.isArray(response.list)) { this.followupList = response.list; this.total = response.total; } else { this.followupList = []; this.total = 0; } } if (!Array.isArray(this.followupList)) { this.followupList = []; } }, // æåå·²æéè®¿çæ¡ä¾ID extractExistingCaseIds() { this.existingFollowupCases.clear(); this.followupList.forEach(followup => { if (followup.infoid) { this.existingFollowupCases.add(followup.infoid); } }); }, // æç´¢æé®æä½ handleQuery() { this.queryParams.pageNum = 1; this.getList(); }, // éç½®æé®æä½ resetQuery() { this.$refs.queryForm.resetFields(); this.queryParams.pageNum = 1; this.getList(); }, // å¤éæ¡é䏿°æ® handleSelectionChange(selection) { this.ids = selection.map(item => item.id); this.single = selection.length !== 1; this.multiple = !selection.length; }, // æ¥ç详æ async handleView(row) { this.$router.push({ path: "/follow/followupVisitinfo", query: { id: row.id, infoid: row.infoid } }); }, // æ°å¢æé®æä½ handleCreate() { this.reset(); this.open = true; this.title = "æ°å¢åè é访"; }, // ä¿®æ¹æé®æä½ async handleUpdate(row) { const id = row.id || this.ids[0]; if (!id) { this.$message.warning("请å éæ©è¦æä½çæ°æ®"); return; } try { this.loading = true; const response = await getFollowup(id); if (response.code === 200) { this.form = response.data; this.open = true; this.title = "ä¿®æ¹åè é访"; // 妿æ¯ä¿®æ¹ï¼å°è¯å è½½æ¡ä¾ä¿¡æ¯ if (this.form.infoid) { this.loadSelectedCaseInfo(this.form.infoid); } } else { this.$message.error("è·åæ°æ®å¤±è´¥ï¼" + response.msg); } } catch (error) { console.error("è·åé访详æ 失败:", error); this.$message.error("è·åæ°æ®å¤±è´¥"); } finally { this.loading = false; } }, // å è½½éä¸çæ¡ä¾ä¿¡æ¯ async loadSelectedCaseInfo(infoid) { try { const response = await listDonatebaseinfo({ pageNum: 1, pageSize: 1, id: infoid }); if ( response.code === 200 && response.data && response.data.length > 0 ) { this.selectedCase = response.data[0]; } } catch (error) { console.error("å è½½æ¡ä¾ä¿¡æ¯å¤±è´¥:", error); } }, // å é¤æé®æä½ async handleDelete(row) { const ids = row.id ? [row.id] : this.ids; if (ids.length === 0) { this.$message.warning("请å éæ©è¦å é¤çæ°æ®"); return; } try { await this.$confirm("æ¯å¦ç¡®è®¤å é¤éä¸çæ°æ®é¡¹ï¼", "è¦å", { confirmButtonText: "ç¡®å®", cancelButtonText: "åæ¶", type: "warning" }); const response = await delFollowup(ids); if (response.code === 200) { this.$message.success("å 餿å"); this.getList(); } else { this.$message.error("å é¤å¤±è´¥ï¼" + response.msg); } } catch (error) { if (error !== "cancel") { console.error("å é¤å¤±è´¥:", error); } } }, // å¯¼åºæé®æä½ async handleExport() { try { await this.$confirm("æ¯å¦ç¡®è®¤å¯¼åºææéè®¿æ°æ®ï¼", "è¦å", { confirmButtonText: "ç¡®å®", cancelButtonText: "åæ¶", type: "warning" }); this.exportLoading = true; const exportParams = this.buildRequestParams(); const response = await exportFollowup(exportParams); if (response.code === 200) { this.download(response.msg || "éè®¿æ°æ®.xlsx"); } else { this.$message.error("导åºå¤±è´¥ï¼" + response.msg); } } catch (error) { if (error !== "cancel") { console.error("导åºå¤±è´¥:", error); this.$message.error("导åºå¤±è´¥"); } } finally { this.exportLoading = false; } }, // æä»¶ä¸è½½å¤ç download(fileName) { // è¿éå®ç°æä»¶ä¸è½½é»è¾ console.log("ä¸è½½æä»¶:", fileName); // æ ¹æ®æ¨ç项ç®å®é æä»¶ä¸è½½æ¹å¼å®ç° }, // 表åéç½® reset() { this.form = { id: undefined, infoid: undefined, organid: undefined, recipientname: "", recipientphone: "", recipientdescribe: "", hospitalname: "", hospitaldept: "", hospitalno: "", doctorname: "", doctorphone: "", doctordescribe: "", donateresult: "", followuptime: undefined, followupno: "", followupdescribe: "", seqno: 1, remark: "" }; this.selectedCase = null; this.selectedCaseRow = null; this.resetForm("form"); }, // åæ¶æé® cancel() { this.open = false; this.reset(); }, // æäº¤è¡¨å submitForm() { this.$refs["form"].validate(async valid => { if (valid) { let response; if (this.form.id) { // ä¿®æ¹ response = await updateFollowup(this.form); } else { // æ°å¢ response = await addFollowup(this.form); } if (response.code === 200) { this.$message.success("æä½æå"); this.open = false; this.getList(); } else { this.$message.error(response.msg || "æä½å¤±è´¥"); } } }); }, // æå¼éæ©æ¡ä¾å¯¹è¯æ¡ openCaseDialog() { this.selectCaseOpen = true; this.caseQueryParams.pageNum = 1; this.resetCaseSearch(); this.searchCaseList(); }, // æç´¢æ¡ä¾å表 async searchCaseList() { this.caseLoading = true; try { const params = { pageNum: this.caseQueryParams.pageNum, pageSize: this.caseQueryParams.pageSize }; if (this.caseQueryParams.name) { params.name = this.caseQueryParams.name; } if (this.caseQueryParams.treatmenthospitalname) { params.treatmenthospitalname = this.caseQueryParams.treatmenthospitalname; } if (this.caseQueryParams.starttime) { params.starttime = this.caseQueryParams.starttime; } if (this.caseQueryParams.endtime) { params.endtime = this.caseQueryParams.endtime; } const response = await listDonatebaseinfo(params); if (response.code === 200) { this.availableCaseList = response.data || []; this.caseTotal = response.total || this.availableCaseList.length; } else { this.$message.error("è·åæ¡ä¾å表失败"); this.availableCaseList = []; this.caseTotal = 0; } } catch (error) { console.error("æç´¢æ¡ä¾å¤±è´¥:", error); this.$message.error("è·åæ¡ä¾å表失败"); this.availableCaseList = []; this.caseTotal = 0; } finally { this.caseLoading = false; } }, // éç½®æ¡ä¾æç´¢ resetCaseSearch() { this.caseQueryParams = { pageNum: 1, pageSize: 10, name: undefined, treatmenthospitalname: undefined, starttime: undefined, endtime: undefined }; this.caseSelectTime = []; this.handleCaseTimeSelect(); }, // å¤çæ¡ä¾æ¶é´éæ© handleCaseTimeSelect(timeRange) { if (!timeRange) { this.caseQueryParams.starttime = undefined; this.caseQueryParams.endtime = undefined; return; } const [start, end] = timeRange; this.caseQueryParams.starttime = `${start} 00:00:00`; const monthNum = Number(end.slice(5, 7)); const nextMonth = monthNum < 9 ? `0${monthNum + 1}` : monthNum + 1; this.caseQueryParams.endtime = `${end.slice( 0, 5 )}${nextMonth}-01 00:00:00`; }, // æ£æ¥æ¡ä¾æ¯å¦å·²æéè®¿è®°å½ hasFollowup(row) { return this.existingFollowupCases.has(row.id); }, // æ¡ä¾è¡ç¹å»äºä»¶ handleCaseRowClick(row) { this.selectedCaseRow = row; }, // éæ©æ¡ä¾ selectCase(row) { this.selectedCaseRow = row; }, // ç¡®è®¤éæ©æ¡ä¾ confirmCaseSelection() { if (this.selectedCaseRow) { this.selectedCase = this.selectedCaseRow; this.form.infoid = this.selectedCaseRow.id; this.form.organid = this.selectedCaseRow.organid; this.selectCaseOpen = false; // 妿鿩æ¡ä¾æåï¼èªå¨å¡«å ä¸äºé»è®¤å¼ this.form.seqno = this.calculateNextSeqNo(); this.form.followupno = this.$store.state.user.name || ""; } else { this.$message.warning("请å éæ©ä¸ä¸ªæ¡ä¾"); } }, // 计ç®ä¸ä¸ä¸ªé访åºå· calculateNextSeqNo() { if (this.selectedCase) { const caseFollowups = this.followupList.filter( followup => followup.infoid === this.selectedCase.id ); if (caseFollowups.length === 0) { return 1; } const maxSeqNo = Math.max( ...caseFollowups.map(item => Number(item.seqno) || 1) ); return maxSeqNo + 1; } return 1; }, // æ¶é´æ ¼å¼å parseTime(time, pattern) { if (!time) return ""; const date = new Date(time); if (pattern) { if (pattern === "{y}-{m}-{d}") { return `${date.getFullYear()}-${(date.getMonth() + 1) .toString() .padStart(2, "0")}-${date .getDate() .toString() .padStart(2, "0")}`; } } return `${date.getFullYear()}-${(date.getMonth() + 1) .toString() .padStart(2, "0")}-${date .getDate() .toString() .padStart(2, "0")} ${date .getHours() .toString() .padStart(2, "0")}:${date .getMinutes() .toString() .padStart(2, "0")}:${date .getSeconds() .toString() .padStart(2, "0")}`; } } }; </script> <style scoped> .followup-list { padding: 20px; } .search-card { margin-bottom: 20px; } .tool-card { margin-bottom: 20px; } .fixed-width .el-button { margin: 0 5px; } .case-select-container { max-height: 600px; overflow-y: auto; } .dialog-footer { text-align: right; } /* é¼ æ æ¬åè¡æ ·å¼ */ .el-table__row:hover { cursor: pointer; background-color: #f5f7fa; } </style> src/views/business/followupVisit/info.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,743 @@ <template> <div class="followup-detail"> <!-- æ¡ä¾åºæ¬ä¿¡æ¯ç»ä»¶ --> <case-basic-info :case-id="caseId" :show-attachment="true" /> <!-- é访记å½ç®¡ç --> <el-card> <div slot="header" class="clearfix"> <span>é访记å½ç®¡ç</span> <el-button style="float: right; padding: 3px 0" type="text" @click="goBack">è¿åå表</el-button> </div> <!-- æä½æé®åºå --> <div class="operation-bar"> <el-button type="primary" icon="el-icon-plus" @click="handleAddFollowup" v-hasPermi="['system:followup:add']" > æ°å¢é访 </el-button> <el-button type="danger" icon="el-icon-delete" :disabled="!selectedFollowup" @click="handleDeleteFollowup" v-hasPermi="['system:followup:remove']" > å é¤éä¸ </el-button> <el-button type="warning" icon="el-icon-refresh" @click="getFollowupList" > å·æ°å表 </el-button> </div> <!-- é访记å½å表 --> <el-table v-loading="loading" :data="followupList" highlight-current-row @row-click="handleRowClick" style="width: 100%; margin-top: 20px;" :default-sort="{prop: 'followuptime', order: 'descending'}" > <el-table-column label="é访åºå·" align="center" prop="seqno" width="120" > <template slot-scope="scope"> <span>第{{ scope.row.seqno || 1 }}次</span> </template> </el-table-column> <el-table-column label="é访æ¶é´" align="center" prop="followuptime" sortable > <template slot-scope="scope"> <span>{{ parseTime(scope.row.followuptime, "{y}-{m}-{d}") }}</span> </template> </el-table-column> <el-table-column label="å¨å®åä½è " align="center" prop="recipientname" /> <el-table-column label="ç§»æ¤å»é¢" align="center" prop="hospitalname" show-overflow-tooltip /> <el-table-column label="é访å»ç" align="center" prop="doctorname" /> <el-table-column label="æç®ç»æ" align="center" prop="donateresult" > <template slot-scope="scope"> <el-tag :type="resultTypeFilter(scope.row.donateresult)" size="small"> {{ resultTextFilter(scope.row.donateresult) }} </el-tag> </template> </el-table-column> <el-table-column label="é访è " align="center" prop="followupno" /> <el-table-column label="å建æ¶é´" align="center" prop="createTime" > <template slot-scope="scope"> <span>{{ parseTime(scope.row.createTime, "{y}-{m}-{d}") }}</span> </template> </el-table-column> <el-table-column label="æä½" align="center" fixed="right" > <template slot-scope="scope"> <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDeleteSingle(scope.row)" v-hasPermi="['system:followup:remove']" > å é¤ </el-button> </template> </el-table-column> </el-table> <!-- å页ç»ä»¶ --> <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getFollowupList" /> </el-card> <!-- ç¼è¾/æ°å¢åºå - å§ç»æ¾ç¤º --> <el-card class="edit-area-card"> <div slot="header" class="clearfix"> <span>{{ editForm.id ? 'ç¼è¾é访记å½' : 'æ°å¢é访记å½' }}</span> <div style="float: right;"> <el-button type="text" @click="handleReset" v-if="editForm.id" > éç½® </el-button> </div> </div> <el-form ref="editFormRef" :model="editForm" :rules="editRules" label-width="120px" > <el-row> <el-col :span="12"> <el-form-item label="é访åºå·" prop="seqno"> <el-input-number v-model="editForm.seqno" :min="1" :max="20" placeholder="请è¾å ¥é访åºå·" style="width: 200px" /> <span style="margin-left: 10px; color: #999;">(第{{ editForm.seqno || 1 }}次é访)</span> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="é访æ¶é´" prop="followuptime"> <el-date-picker v-model="editForm.followuptime" type="datetime" placeholder="éæ©é访æ¶é´" value-format="yyyy-MM-dd HH:mm:ss" style="width: 200px" /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="å¨å®åä½è å§å" prop="recipientname"> <el-input v-model="editForm.recipientname" placeholder="请è¾å ¥å¨å®åä½è å§å" maxlength="50" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="åä½çµè¯" prop="recipientphone"> <el-input v-model="editForm.recipientphone" placeholder="请è¾å ¥å¨å®åä½è çµè¯" maxlength="20" /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="ç§»æ¤å»é¢åç§°" prop="hospitalname"> <el-input v-model="editForm.hospitalname" placeholder="请è¾å ¥ç§»æ¤å»é¢åç§°" maxlength="100" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="ç§»æ¤ç§å®¤" prop="hospitaldept"> <el-input v-model="editForm.hospitaldept" placeholder="请è¾å ¥ç§»æ¤å»é¢ç§å®¤" maxlength="50" /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="é访å»çå§å" prop="doctorname"> <el-input v-model="editForm.doctorname" placeholder="请è¾å ¥æ¥åé访å»çå§å" maxlength="50" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="å»ççµè¯" prop="doctorphone"> <el-input v-model="editForm.doctorphone" placeholder="请è¾å ¥æ¥åé访å»ççµè¯" maxlength="20" /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="æç®ç»æ" prop="donateresult"> <el-select v-model="editForm.donateresult" placeholder="è¯·éæ©æç®ç»æ" style="width: 200px" > <el-option label="æå" value="1" /> <el-option label="失败" value="0" /> <el-option label="è¿è¡ä¸" value="2" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="é访è " prop="followupno"> <el-input v-model="editForm.followupno" placeholder="请è¾å ¥é访è " maxlength="50" /> </el-form-item> </el-col> </el-row> <el-form-item label="é访æè¿°" prop="followupdescribe"> <el-input v-model="editForm.followupdescribe" type="textarea" placeholder="请è¾å ¥é访æè¿°" maxlength="1000" :rows="3" show-word-limit /> </el-form-item> <el-form-item label="å»çæè¿°" prop="doctordescribe"> <el-input v-model="editForm.doctordescribe" type="textarea" placeholder="请è¾å ¥å»çæè¿°" maxlength="500" :rows="3" show-word-limit /> </el-form-item> <el-form-item label="åä½è æè¿°" prop="recipientdescribe"> <el-input v-model="editForm.recipientdescribe" type="textarea" placeholder="请è¾å ¥å¨å®åä½è æè¿°" maxlength="500" :rows="3" show-word-limit /> </el-form-item> <el-form-item label="夿³¨" prop="remark"> <el-input v-model="editForm.remark" type="textarea" placeholder="请è¾å ¥å¤æ³¨" maxlength="500" :rows="3" show-word-limit /> </el-form-item> <el-form-item> <el-button type="primary" @click="submitEditForm"> {{ editForm.id ? 'ä¿åä¿®æ¹' : 'å建é访' }} </el-button> <el-button @click="resetEditForm">éç½®</el-button> </el-form-item> </el-form> </el-card> </div> </template> <script> import { listFollowup, getFollowup, addFollowup, updateFollowup, delFollowup } from "@/api/businessApi/followup"; import CaseBasicInfo from "@/components/CaseBasicInfo"; import Pagination from "@/components/Pagination"; export default { name: "FollowupDetail", components: { CaseBasicInfo, Pagination }, data() { return { // æ¡ä¾ID caseId: null, // å è½½ç¶æ loading: false, // é访记å½å表 followupList: [], // æ»æ¡æ° total: 0, // æ¥è¯¢åæ° queryParams: { pageNum: 1, pageSize: 10 }, // å½åéä¸çéè®¿è®°å½ selectedFollowup: null, // ç¼è¾è¡¨å editForm: { id: undefined, infoid: null, organid: undefined, recipientname: "", recipientphone: "", recipientdescribe: "", hospitalname: "", hospitaldept: "", hospitalno: "", doctorname: "", doctorphone: "", doctordescribe: "", donateresult: "", followuptime: undefined, followupno: "", followupdescribe: "", seqno: 1, remark: "" }, // ç¼è¾è¡¨åæ ¡éªè§å editRules: { seqno: [ { required: true, message: "é访åºå·ä¸è½ä¸ºç©º", trigger: "blur" }, { type: "number", min: 1, max: 20, message: "é访åºå·èå´ä¸º1-20", trigger: "blur" } ], followuptime: [ { required: true, message: "é访æ¶é´ä¸è½ä¸ºç©º", trigger: "change" } ], recipientname: [ { required: true, message: "å¨å®åä½è å§åä¸è½ä¸ºç©º", trigger: "blur" }, { max: 50, message: "é¿åº¦ä¸è½è¶ è¿50个å符", trigger: "blur" } ], hospitalname: [ { required: true, message: "ç§»æ¤å»é¢åç§°ä¸è½ä¸ºç©º", trigger: "blur" }, { max: 100, message: "é¿åº¦ä¸è½è¶ è¿100个å符", trigger: "blur" } ], followupno: [ { required: true, message: "é访è ä¸è½ä¸ºç©º", trigger: "blur" }, { max: 50, message: "é¿åº¦ä¸è½è¶ è¿50个å符", trigger: "blur" } ], donateresult: [ { required: true, message: "æç®ç»æä¸è½ä¸ºç©º", trigger: "change" } ] } }; }, created() { this.caseId = this.$route.query.infoid; if (this.caseId) { this.getFollowupList(); } else { this.$message.error("åæ°é误"); this.goBack(); } }, methods: { // è·åå½åæ¡ä¾ä¸çé访记å½å表 async getFollowupList() { this.loading = true; try { const params = { ...this.queryParams, infoid: this.caseId }; const response = await listFollowup(params); if (response.code === 200) { this.handleResponseData(response); // å¦æææ°æ®ï¼é»è®¤éä¸ç¬¬ä¸æ¡ if (this.followupList.length > 0) { this.selectFirstRecord(); } else { // æ²¡ææ°æ®æ¶ï¼è®¾ç½®æ°å¢ç¶æ this.resetEditForm(); } } else { this.$message.error("è·åé访记å½å¤±è´¥ï¼" + (response.msg || "æªç¥é误")); this.followupList = []; this.total = 0; this.resetEditForm(); } } catch (error) { console.error("è·åé访记å½å¤±è´¥:", error); this.$message.error("è·åæ°æ®å¤±è´¥"); this.followupList = []; this.total = 0; this.resetEditForm(); } finally { this.loading = false; } }, // å¤çæ¥å£ååºæ°æ® handleResponseData(response) { if (response.data) { if (Array.isArray(response.data)) { this.followupList = response.data; this.total = response.data.length; } else if (response.data.rows) { this.followupList = response.data.rows; this.total = response.data.total; } else if (Array.isArray(response.data.list)) { this.followupList = response.data.list; this.total = response.data.total || response.data.list.length; } else { this.followupList = response.data; this.total = response.total || response.data.length; } } else { if (Array.isArray(response.rows)) { this.followupList = response.rows; this.total = response.total; } else if (Array.isArray(response.list)) { this.followupList = response.list; this.total = response.total; } else { this.followupList = []; this.total = 0; } } }, // éæ©ç¬¬ä¸æ¡è®°å½ selectFirstRecord() { if (this.followupList.length > 0) { const firstRecord = this.followupList[0]; this.selectedFollowup = firstRecord; this.loadFollowupData(firstRecord); } }, // å è½½éè®¿æ°æ®å°ç¼è¾è¡¨å loadFollowupData(record) { this.editForm = { ...record }; // ç¡®ä¿æ°æ®ç±»åæ£ç¡® if (this.editForm.seqno) { this.editForm.seqno = Number(this.editForm.seqno); } // æ¸ ç©ºè¡¨åéªè¯ if (this.$refs.editFormRef) { this.$nextTick(() => { this.$refs.editFormRef.clearValidate(); }); } }, // ç»æç±»åè¿æ»¤å¨ resultTypeFilter(result) { const resultMap = { "1": "success", // æå "0": "danger", // 失败 "2": "primary" // è¿è¡ä¸ }; return resultMap[result] || "info"; }, resultTextFilter(result) { const resultMap = { "1": "æå", "0": "失败", "2": "è¿è¡ä¸" }; return resultMap[result] || "æªç¥"; }, // è¡ç¹å»äºä»¶ handleRowClick(row) { this.selectedFollowup = row; this.loadFollowupData(row); }, // æ°å¢é访 handleAddFollowup() { this.resetEditForm(); this.selectedFollowup = null; }, // 计ç®ä¸ä¸ä¸ªé访åºå· calculateNextSeqNo() { if (this.followupList.length === 0) { return 1; } const maxSeqNo = Math.max(...this.followupList.map(item => Number(item.seqno) || 1)); return maxSeqNo + 1; }, // æäº¤ç¼è¾è¡¨å submitEditForm() { this.$refs.editFormRef.validate(async (valid) => { if (valid) { try { // ç¡®ä¿infoidæ£ç¡® this.editForm.infoid = this.caseId; let response; if (this.editForm.id) { // ä¿®æ¹ response = await updateFollowup(this.editForm); } else { // æ°å¢ response = await addFollowup(this.editForm); } if (response.code === 200) { this.$message.success(this.editForm.id ? "ä¿®æ¹æå" : "æ°å¢æå"); this.getFollowupList(); // æ°å¢æååï¼æ¸ 空表å if (!this.editForm.id) { this.resetEditForm(); } } else { this.$message.error(response.msg || "æä½å¤±è´¥"); } } catch (error) { console.error("æä½å¤±è´¥:", error); this.$message.error("æä½å¤±è´¥"); } } }); }, // éç½®ç¼è¾è¡¨å resetEditForm() { this.editForm = { id: undefined, infoid: this.caseId, organid: undefined, recipientname: "", recipientphone: "", recipientdescribe: "", hospitalname: "", hospitaldept: "", hospitalno: "", doctorname: "", doctorphone: "", doctordescribe: "", donateresult: "", followuptime: undefined, followupno: "", followupdescribe: "", seqno: this.calculateNextSeqNo(), remark: "" }; if (this.$refs.editFormRef) { this.$refs.editFormRef.clearValidate(); } }, // éç½® handleReset() { if (this.selectedFollowup) { this.loadFollowupData(this.selectedFollowup); } else { this.resetEditForm(); } }, // å é¤éä¸é访 async handleDeleteFollowup() { if (!this.selectedFollowup) { this.$message.warning("请å éæ©è¦å é¤çé访记å½"); return; } await this.deleteFollowupRecord(this.selectedFollowup.id); }, // å é¤åæ¡é访 async handleDeleteSingle(row, event) { event.stopPropagation(); // 黿¢äºä»¶å泡 await this.deleteFollowupRecord(row.id); }, // å é¤éè®¿è®°å½ async deleteFollowupRecord(id) { try { await this.$confirm('确认å é¤è¯¥é访记å½åï¼', "è¦å", { confirmButtonText: "ç¡®å®", cancelButtonText: "åæ¶", type: "warning" }); const response = await delFollowup([id]); if (response.code === 200) { this.$message.success("å 餿å"); // 妿å é¤çæ¯å½åéä¸çè®°å½ if (this.selectedFollowup && this.selectedFollowup.id === id) { this.selectedFollowup = null; this.resetEditForm(); } this.getFollowupList(); } else { this.$message.error("å é¤å¤±è´¥ï¼" + response.msg); } } catch (error) { if (error !== "cancel") { console.error("å é¤å¤±è´¥:", error); } } }, // è¿åå表页 goBack() { this.$router.go(-1); }, // æ¶é´æ ¼å¼å parseTime(time, pattern) { if (!time) return ""; const date = new Date(time); if (pattern) { if (pattern === "{y}-{m}-{d}") { return `${date.getFullYear()}-${(date.getMonth() + 1) .toString() .padStart(2, "0")}-${date .getDate() .toString() .padStart(2, "0")}`; } } return `${date.getFullYear()}-${(date.getMonth() + 1) .toString() .padStart(2, "0")}-${date .getDate() .toString() .padStart(2, "0")} ${date .getHours() .toString() .padStart(2, "0")}:${date .getMinutes() .toString() .padStart(2, "0")}:${date .getSeconds() .toString() .padStart(2, "0")}`; } } }; </script> <style scoped> .followup-detail { padding: 20px; } .operation-bar { margin-bottom: 20px; display: flex; gap: 10px; align-items: center; } .edit-area-card { margin-top: 20px; animation: fadeIn 0.5s; } @keyframes fadeIn { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } /* è¡¨æ ¼éä¸è¡æ ·å¼ */ .el-table__row.current-row { background-color: #f0f9ff !important; } /* é¼ æ æ¬åè¡æ ·å¼ */ .el-table__row:hover { cursor: pointer; background-color: #f5f7fa; } </style> src/views/project/components/orgselect/index.vue
@@ -154,7 +154,6 @@ }; this.dataList.unshift(all); } console.log(this.dataList,'this.dataList'); this.tempList = this.dataList.map(item => item); this.focusEvents.loaded = true;