| | |
| | | import request from '@/utils/request' |
| | | import request from "@/utils/request"; |
| | | |
| | | // æ¡ä¾å表å详æ
|
| | | export function reviewinitiateBaseInfoList(data) { |
| | | return request({ |
| | | url: '/project/ethicalreviewinitiate/reviewinitiateBaseInfoList', |
| | | method: 'post', |
| | | url: "/project/ethicalreviewinitiate/reviewinitiateBaseInfoList", |
| | | method: "post", |
| | | data: data |
| | | }) |
| | | }); |
| | | } |
| | | // 伦ç审æ¥ä¿¡æ¯ä¿®æ¹ |
| | | export function ethicalreviewadd(data) { |
| | | return request({ |
| | | url: '/project/ethicalreviewinitiate/add', |
| | | method: 'post', |
| | | url: "/project/ethicalreviewinitiate/add", |
| | | method: "post", |
| | | data: data |
| | | }) |
| | | }); |
| | | } |
| | | // 伦ç审æ¥ä¿¡æ¯ä¿®æ¹ |
| | | export function ethicalreviewedit(data) { |
| | | return request({ |
| | | url: '/project/ethicalreviewinitiate/edit', |
| | | method: 'post', |
| | | url: "/project/ethicalreviewinitiate/edit", |
| | | method: "post", |
| | | data: data |
| | | }) |
| | | }); |
| | | } |
| | | // 审æ¥ä¸å®¶ç»è®¡ |
| | | export function ethicalreExpertTotal(query) { |
| | | return request({ |
| | | url: '/project/ethicalreviewopinions/expertTotal', |
| | | method: 'get', |
| | | url: "/project/ethicalreviewopinions/expertTotal", |
| | | method: "get", |
| | | params: query |
| | | }) |
| | | }); |
| | | } |
| | | // 伦ç审æ¥ä¿¡æ¯è¯¦æ
|
| | | export function ethicalreviewInfo(id) { |
| | | return request({ |
| | | url: '/project/ethicalreviewinitiate/getInfo/' + id, |
| | | method: 'get' |
| | | }) |
| | | url: "/project/ethicalreviewinitiate/getInfo/" + id, |
| | | method: "get" |
| | | }); |
| | | } |
| | | // 伦ç审æ¥ä¿¡æ¯infoidæ¥è¯¢è¯¦æ
|
| | | export function ethicalreviewgetInfoID(query) { |
| | | return request({ |
| | | url: "/project/ethicalreviewinitiate/getInfoID", |
| | | method: "get", |
| | | params: query |
| | | }); |
| | | } |
| | | // 审æ¥åç¶æåæ´ |
| | | export function ethicalreviewreceiveStatus(id) { |
| | | return request({ |
| | | url: '/project/ethicalreviewopinions/receiveStatus', |
| | | method: 'get' |
| | | }) |
| | | url: "/project/ethicalreviewopinions/receiveStatus", |
| | | method: "get" |
| | | }); |
| | | } |
| | | // ä¸å®¶æ¶æ¯æ¨é |
| | | export function sendNotification(data) { |
| | | return request({ |
| | | url: '/system/dingtalk/sendNotification', |
| | | method: 'post', |
| | | url: "/system/dingtalk/sendNotification", |
| | | method: "post", |
| | | data: data |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | // çä¿¡ |
| | | export function sendcall(data) { |
| | | return request({ |
| | | url: "/sms/send", |
| | | method: "post", |
| | | data: data |
| | | }); |
| | | } |
| | |
| | | import request from '@/utils/request' |
| | | import request from "@/utils/request"; |
| | | |
| | | // æ¥è¯¢æç®åºç¡å表 |
| | | export function listDonatebaseinfo(data) { |
| | | return request({ |
| | | url: '/project/donatebaseinfo/list', |
| | | method: 'post', |
| | | url: "/project/donatebaseinfo/list", |
| | | method: "post", |
| | | data: data |
| | | }) |
| | | }); |
| | | } |
| | | export function listDonationProcess(query) { |
| | | return request({ |
| | | url: '/VDonationworkflow/donationworkflow/list', |
| | | method: 'get', |
| | | url: "/VDonationworkflow/donationworkflow/list", |
| | | method: "get", |
| | | params: query |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢æç®åºç¡è¯¦ç» |
| | | export function getDonatebaseinfo(id) { |
| | | return request({ |
| | | url: '/project/donatebaseinfo/' + id, |
| | | method: 'get' |
| | | }) |
| | | url: "/project/donatebaseinfo/" + id, |
| | | method: "get" |
| | | }); |
| | | } |
| | | |
| | | // è·åæç®ç¼å· |
| | | export function getfileList(data) { |
| | | return request({ |
| | | url: "/project/donatebaseinfo/fileList", |
| | | method: "get", |
| | | params: data |
| | | }); |
| | | } |
| | | // è·åæç®ç¼å· |
| | | export function getDonationNumber(data) { |
| | | return request({ |
| | | url: '/project/donatebaseinfo/donatenumber', |
| | | method: 'post', |
| | | url: "/project/donatebaseinfo/donatenumber", |
| | | method: "post", |
| | | data: data |
| | | }) |
| | | }); |
| | | } |
| | | // æ¥è¯¢æç®å·¥ä½æµ |
| | | export function getDonatebaseinfoflow(id) { |
| | | return request({ |
| | | url: '/project/donatebaseinfo/getWorkFlow/' + id, |
| | | method: 'get' |
| | | }) |
| | | url: "/project/donatebaseinfo/getWorkFlow/" + id, |
| | | method: "get" |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢æç®åºç¡ |
| | | export function addDonatebaseinfo(data) { |
| | | return request({ |
| | | url: '/project/donatebaseinfo/add', |
| | | method: 'post', |
| | | url: "/project/donatebaseinfo/add", |
| | | method: "post", |
| | | data: data |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹æç®åºç¡ |
| | | export function updateDonatebaseinfo(data) { |
| | | return request({ |
| | | url: '/project/donatebaseinfo/edit', |
| | | method: 'post', |
| | | url: "/project/donatebaseinfo/edit", |
| | | method: "post", |
| | | data: data |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | // å 餿ç®åºç¡ |
| | | export function delDonatebaseinfo(id) { |
| | | return request({ |
| | | url: '/project/donatebaseinfo/remove/' + id, |
| | | method: 'get', |
| | | }) |
| | | url: "/project/donatebaseinfo/remove/" + id, |
| | | method: "get" |
| | | }); |
| | | } |
| | | |
| | | // å¯¼åºæç®åºç¡ |
| | | export function exportDonatebaseinfo(query) { |
| | | return request({ |
| | | url: '/project/donatebaseinfo/export', |
| | | method: 'get', |
| | | url: "/project/donatebaseinfo/export", |
| | | method: "get", |
| | | params: query |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | // è·åæç®ç¼å· |
| | | export function getdonatorno(data) { |
| | | // console.log("è·åæç®ç¼å·ï¼å
¥åï¼" + JSON.stringify(data)); |
| | | return request({ |
| | | url: '/project/donatebaseinfo/donatenumber', |
| | | method: 'get', |
| | | url: "/project/donatebaseinfo/donatenumber", |
| | | method: "get", |
| | | params: data |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | // ä¸è½½äººä½å¨å®æ½å¨æç®è
ç»è®°è¡¨ |
| | | export function downloadbaseinfo(id) { |
| | | return request({ |
| | | url: '/project/donatebaseinfo/download/' + id, |
| | | method: 'get' |
| | | }) |
| | | url: "/project/donatebaseinfo/download/" + id, |
| | | method: "get" |
| | | }); |
| | | } |
| | | // ä¸è½½äººä½å¨å®æ½å¨æç®è
ç»è®°è¡¨ |
| | | export function fileCase(data) { |
| | | return request({ |
| | | url: '/project/pdfmerge/merge', |
| | | method: 'get', |
| | | url: "/project/pdfmerge/merge", |
| | | method: "get", |
| | | params: data |
| | | }) |
| | | }); |
| | | } |
| | |
| | | <el-card class="basic-info-card" v-loading="loading"> |
| | | <div slot="header" class="clearfix"> |
| | | <span>æ¡ä¾åºæ¬ä¿¡æ¯</span> |
| | | |
| | | <el-button |
| | | v-if="showAttachment" |
| | | type="text" |
| | | style="float: right; margin-left: 12px" |
| | | @click="openStageAttachments" |
| | | > |
| | | <i class="el-icon-folder"></i> æ¥çåé¶æ®µéä»¶ |
| | | </el-button> |
| | | |
| | | <el-button |
| | | v-if="showAttachment && hasAttachments" |
| | | style="float: right; padding: 3px 0" |
| | |
| | | <div v-else class="empty-state"> |
| | | <el-empty description="ææ æ¡ä¾ä¿¡æ¯" :image-size="100"></el-empty> |
| | | </div> |
| | | <!-- åé¶æ®µéä»¶å¼¹æ¡ --> |
| | | <case-stage-attachments-dialog |
| | | ref="stageDialog" |
| | | :case-id="caseId" |
| | | :selected-ids="selectedAttachmentIds" |
| | | @confirm="onAttachmentsConfirm" |
| | | /> |
| | | </el-card> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getDonatebaseinfo } from "@/api/project/donatebaseinfo"; |
| | | import { getDonatebaseinfo, getfileList } from "@/api/project/donatebaseinfo"; |
| | | import CaseStageAttachmentsDialog from "@/components/CaseStageAttachmentsDialog"; |
| | | |
| | | export default { |
| | | name: "CaseBasicInfoSimple", |
| | | components: { CaseStageAttachmentsDialog }, |
| | | |
| | | props: { |
| | | // æ¡ä¾ID |
| | | caseId: { |
| | |
| | | basicData: null, |
| | | // åå
¸é项 |
| | | sexOptions: [], |
| | | bloodTypeOptions: [] |
| | | bloodTypeOptions: [], |
| | | selectedAttachmentIds: ["123", "456"], |
| | | finalAttachments: [] |
| | | }; |
| | | }, |
| | | computed: { |
| | |
| | | console.warn("å è½½åå
¸å¤±è´¥:", error); |
| | | } |
| | | }, |
| | | // æå¼åé¶æ®µéä»¶å¼¹æ¡ |
| | | openStageAttachments() { |
| | | this.$refs.stageDialog.open(); |
| | | }, |
| | | |
| | | onAttachmentsConfirm(list) { |
| | | this.finalAttachments = list; |
| | | console.log("éä¸çé¶æ®µéä»¶ï¼", list); |
| | | // å¯ç´æ¥æäº¤ç»æ¥å£ |
| | | }, |
| | | // å è½½åºæ¬ä¿¡æ¯ |
| | | async loadBasicInfo() { |
| | | if (!this.caseId) return; |
| | |
| | | |
| | | if (response.code === 200) { |
| | | this.basicData = this.mapApiData(response.data); |
| | | console.log(this.basicData ); |
| | | console.log(this.basicData); |
| | | |
| | | this.loading = false; |
| | | } else { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog |
| | | title="æ¡ä¾åé¶æ®µéä»¶" |
| | | :visible.sync="visible" |
| | | width="1200px" |
| | | top="4vh" |
| | | append-to-body |
| | | :close-on-click-modal="false" |
| | | @closed="handleClosed" |
| | | > |
| | | <!-- é¶æ®µ Tabs --> |
| | | <el-tabs v-model="activeStage" type="card" @tab-click="handleStageChange"> |
| | | <el-tab-pane |
| | | v-for="stage in stageTypes" |
| | | :key="stage.value" |
| | | :label="stage.label" |
| | | :name="stage.value" |
| | | > |
| | | <!-- é¶æ®µå
çéä»¶ç±»å Tabs --> |
| | | <div class="stage-content"> |
| | | <el-tabs v-model="activeType" type="border-card"> |
| | | <el-tab-pane |
| | | v-for="type in getTypesByStage(stage.value)" |
| | | :key="type.value" |
| | | :label="type.label" |
| | | :name="type.value" |
| | | > |
| | | <!-- éä»¶å表 --> |
| | | <div class="attachment-list"> |
| | | <el-table |
| | | :data="getAttachmentsByStageAndType(stage.value, type.value)" |
| | | size="small" |
| | | v-loading="loading" |
| | | style="width: 100%;" |
| | | @row-click="handleRowClick" |
| | | :row-class-name="tableRowClassName" |
| | | > |
| | | <el-table-column label="æä»¶å" min-width="220"> |
| | | <template slot-scope="scope"> |
| | | <i |
| | | class="el-icon-document" |
| | | style="color: #409EFF; margin-right: 8px;" |
| | | ></i> |
| | | <span class="file-name">{{ scope.row.fileName }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column label="æä»¶ç±»å" width="100" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-tag size="small">{{ |
| | | getFileType(scope.row.fileName) |
| | | }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column label="æä»¶å¤§å°" width="100" align="center"> |
| | | <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>{{ formatDateTime(scope.row.uploadTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column label="ä¸ä¼ 人" width="120" align="center"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ scope.row.uploader || "-" }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column label="æä½" width="180" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="primary" |
| | | @click="handlePreview(scope.row)" |
| | | > |
| | | é¢è§ |
| | | </el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="danger" |
| | | @click="handleDownload(scope.row)" |
| | | > |
| | | ä¸è½½ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- ç©ºç¶æ --> |
| | | <div |
| | | v-if=" |
| | | getAttachmentsByStageAndType(stage.value, type.value) |
| | | .length === 0 |
| | | " |
| | | class="empty-attachment" |
| | | > |
| | | <el-empty |
| | | :description="`ææ ${type.label}éä»¶`" |
| | | :image-size="80" |
| | | ></el-empty> |
| | | </div> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | |
| | | <span slot="footer" class="dialog-footer"> |
| | | <el-button @click="visible = false">å
³é</el-button> |
| | | <!-- <el-button type="primary" @click="handleConfirm"> |
| | | ç¡®è®¤éæ© ({{ selectedCount }}) |
| | | </el-button> --> |
| | | </span> |
| | | |
| | | <!-- æä»¶é¢è§å¼¹çª --> |
| | | <FilePreviewDialog |
| | | :visible="previewVisible" |
| | | :file="currentPreviewFile" |
| | | @close="previewVisible = false" |
| | | @download="handleDownload" |
| | | /> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getfileList } from "@/api/project/donatebaseinfo"; |
| | | import FilePreviewDialog from "@/components/FilePreviewDialog"; |
| | | import { parseTime } from "@/utils/ruoyi"; |
| | | |
| | | export default { |
| | | name: "StageAttachmentsDialog", |
| | | components: { |
| | | FilePreviewDialog |
| | | }, |
| | | props: { |
| | | caseId: { |
| | | type: [String, Number], |
| | | required: true |
| | | }, |
| | | // å·²éä¸çéä»¶IDéåï¼ç¨äºåæ¾ï¼ |
| | | selectedIds: { |
| | | type: Array, |
| | | default: () => [] |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | visible: false, |
| | | loading: false, |
| | | |
| | | // é¶æ®µå®ä¹ |
| | | stageTypes: [ |
| | | { value: "death", label: "æ»äº¡å¤å®" }, |
| | | { value: "confirm", label: "æç®ç¡®è®¤" }, |
| | | { value: "maintain", label: "ä¾è
ç»´æ¤" }, |
| | | { value: "witness", label: "å¨å®è·åè§è¯" }, |
| | | { value: "ethics", label: "伦ç审æ¥" } |
| | | ], |
| | | |
| | | // åé¶æ®µéä»¶ç±»åå®ä¹ |
| | | typeDefinitions: { |
| | | death: [ |
| | | { value: "brain", label: "èæ»äº¡å¤å®" }, |
| | | { value: "heart", label: "å¿æ»äº¡å¤å®" } |
| | | ], |
| | | confirm: [ |
| | | { value: "1", label: "人ä½å¨å®æ½å¨æç®è
ç»è®°è¡¨" }, |
| | | { value: "2", label: "人ä½å¨å®æç®äº²å±ç¡®è®¤ç»è®°è¡¨" }, |
| | | { value: "3", label: "æç®è
åç´ç³»äº²å±èº«ä»½è¯ãæ·å£ç°¿ç¸å
³è¯æ" }, |
| | | { value: "4", label: "å
¬æ°èº«æ
å人ä½å¨å®ï¼è§èï¼é使ç®åç¥ä¹¦" }, |
| | | { value: "5", label: "èæ»äº¡å¤å®ç¥æ
åæä¹¦" }, |
| | | { value: "6", label: "å¿æ»äº¡å¤å®ç¥æ
åæä¹¦" } |
| | | ], |
| | | maintain: [ |
| | | { value: "urine", label: "尿常è§" }, |
| | | { value: "blood", label: "è¡å¸¸è§" }, |
| | | { value: "liver", label: "èè¾åè½" }, |
| | | { value: "culture", label: "å¹å
ȍȾ" }, |
| | | { value: "nurse", label: "æ¤çè®°å½" } |
| | | ], |
| | | witness: [{ value: "deathCert", label: "æ»äº¡è¯æ" }], |
| | | ethics: [{ value: "review", label: "伦çå®¡æ¥ææ" }] |
| | | }, |
| | | |
| | | // å½åæ¿æ´»çTab |
| | | activeStage: "death", |
| | | activeType: "", |
| | | |
| | | // åå§æ¥å£æ°æ® |
| | | rawData: null, |
| | | |
| | | // å¤çåçéä»¶æ°æ® stage -> type -> list |
| | | attachmentData: {}, |
| | | |
| | | // éä¸çéä»¶éå |
| | | selectedAttachments: new Map(), |
| | | |
| | | // é¢è§ç¸å
³ |
| | | previewVisible: false, |
| | | currentPreviewFile: null |
| | | }; |
| | | }, |
| | | computed: { |
| | | // å½åé¶æ®µä¸çéä»¶ç±»å |
| | | currentStageTypes() { |
| | | return this.typeDefinitions[this.activeStage] || []; |
| | | }, |
| | | |
| | | // 已鿰é |
| | | selectedCount() { |
| | | return this.selectedAttachments.size; |
| | | }, |
| | | selectedCount() { |
| | | return this.selectedAttachments?.size || 0; |
| | | } |
| | | }, |
| | | watch: { |
| | | selectedIds: { |
| | | handler(newVal) { |
| | | this.initSelectedState(newVal); |
| | | }, |
| | | immediate: true |
| | | } |
| | | }, |
| | | methods: { |
| | | open() { |
| | | this.visible = true; |
| | | this.loadData(); |
| | | }, |
| | | |
| | | // åå§åéä¸ç¶æ |
| | | initSelectedState(ids) { |
| | | this.selectedAttachments.clear(); |
| | | ids.forEach(id => { |
| | | this.selectedAttachments.set(id, true); |
| | | }); |
| | | }, |
| | | |
| | | // å è½½æ°æ® |
| | | async loadData() { |
| | | this.loading = true; |
| | | try { |
| | | const res = await getfileList({ infoid: this.caseId }); |
| | | if (res.code === 200) { |
| | | this.rawData = res.data || {}; |
| | | this.processData(); |
| | | } |
| | | } catch (e) { |
| | | console.error(e); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | |
| | | // å¤çæ¥å£æ°æ® |
| | | processData() { |
| | | const d = this.rawData; |
| | | const result = {}; |
| | | |
| | | // åå§åç»æ |
| | | this.stageTypes.forEach(stage => { |
| | | result[stage.value] = {}; |
| | | (this.typeDefinitions[stage.value] || []).forEach(type => { |
| | | result[stage.value][type.value] = []; |
| | | }); |
| | | }); |
| | | |
| | | // ===== 1. æ»äº¡å¤å® ===== |
| | | (d.deathinfo || []).forEach(item => { |
| | | this.pushAttachment( |
| | | result.death, |
| | | "brain", |
| | | this.parseAttachments(item.deathjudgeannex) |
| | | ); |
| | | this.pushAttachment( |
| | | result.death, |
| | | "heart", |
| | | this.parseAttachments(item.heartdeathjudgeannex) |
| | | ); |
| | | }); |
| | | |
| | | // ===== 2. æç®ç¡®è®¤ ===== |
| | | (d.relativesconfirmation || []).forEach(item => { |
| | | this.pushAttachment( |
| | | result.confirm, |
| | | "1", |
| | | this.parseAttachments(item.assessannex) |
| | | ); |
| | | }); |
| | | |
| | | // ===== 3. ä¾è
ç»´æ¤ ===== |
| | | (d.donatemaintenance || []).forEach(item => { |
| | | try { |
| | | const itemDesc = JSON.parse(item.itemDesc || "{}"); |
| | | this.pushAttachment( |
| | | result.maintain, |
| | | "urine", |
| | | itemDesc.urineRoutine?.attachments || [] |
| | | ); |
| | | this.pushAttachment( |
| | | result.maintain, |
| | | "blood", |
| | | itemDesc.bloodRoutine?.attachments || [] |
| | | ); |
| | | this.pushAttachment( |
| | | result.maintain, |
| | | "liver", |
| | | itemDesc.liverKidney?.attachments || [] |
| | | ); |
| | | this.pushAttachment( |
| | | result.maintain, |
| | | "culture", |
| | | itemDesc.cultureResults?.flatMap(c => c.attachments || []) || [] |
| | | ); |
| | | this.pushAttachment( |
| | | result.maintain, |
| | | "nurse", |
| | | itemDesc.nursingRecords?.flatMap(n => n.attachments || []) || [] |
| | | ); |
| | | } catch {} |
| | | }); |
| | | |
| | | // ===== 4. å¨å®è·åè§è¯ ===== |
| | | (d.donationwitness || []).forEach(item => { |
| | | this.pushAttachment( |
| | | result.witness, |
| | | "deathCert", |
| | | this.parseAttachments(item.deathjudgeannex) |
| | | ); |
| | | }); |
| | | |
| | | // ===== 5. 伦çå®¡æ¥ ===== |
| | | (d.donateflowcharts || []).forEach(item => { |
| | | this.pushAttachment( |
| | | result.ethics, |
| | | "review", |
| | | this.parseAttachments(item.filePatch) |
| | | ); |
| | | }); |
| | | |
| | | this.attachmentData = result; |
| | | |
| | | this.$nextTick(() => { |
| | | if (this.currentStageTypes.length > 0) { |
| | | this.activeType = this.currentStageTypes[0].value; |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // è¾
å©ï¼è§£æéä»¶åæ®µ |
| | | parseAttachments(val) { |
| | | if (!val) return []; |
| | | if (Array.isArray(val)) return val; |
| | | try { |
| | | const arr = JSON.parse(val); |
| | | return Array.isArray(arr) ? arr : []; |
| | | } catch { |
| | | return val |
| | | .split(";") |
| | | .filter(Boolean) |
| | | .map(p => ({ fileName: p.split("/").pop(), fileUrl: p })); |
| | | } |
| | | }, |
| | | |
| | | // è¾
å©ï¼æ¨ééä»¶å¹¶è¡¥å
åæ®µ |
| | | pushAttachment(result, type, files) { |
| | | files.forEach(file => { |
| | | const attachment = { |
| | | id: file.id || `${Date.now()}_${Math.random()}`, |
| | | fileName: file.fileName, |
| | | fileUrl: file.path || file.fileUrl, |
| | | fileSize: file.fileSize, |
| | | uploadTime: file.uploadTime, |
| | | uploader: file.uploader, |
| | | type: type, |
| | | stage: this.activeStage |
| | | }; |
| | | result[type].push(attachment); |
| | | |
| | | // // åæ¾éä¸ç¶æ |
| | | // if (this.selectedAttachments.has(attachment.id)) { |
| | | // attachment._selected = true; |
| | | // } |
| | | }); |
| | | }, |
| | | |
| | | // è·åæé¶æ®µä¸çéä»¶ç±»å |
| | | getTypesByStage(stage) { |
| | | return this.typeDefinitions[stage] || []; |
| | | }, |
| | | |
| | | // è·åéä»¶å表 |
| | | getAttachmentsByStageAndType(stage, type) { |
| | | return this.attachmentData[stage]?.[type] || []; |
| | | }, |
| | | |
| | | // é¶æ®µåæ¢ |
| | | handleStageChange() { |
| | | this.$nextTick(() => { |
| | | if (this.currentStageTypes.length > 0) { |
| | | this.activeType = this.currentStageTypes[0].value; |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // ç¹å»è¡éæ©/åæ¶ |
| | | handleRowClick(row) { |
| | | if (this.selectedAttachments.has(row.id)) { |
| | | this.selectedAttachments.delete(row.id); |
| | | } else { |
| | | this.selectedAttachments.set(row.id, row); |
| | | } |
| | | }, |
| | | tableRowClassName({ row }) { |
| | | return this.selectedAttachments.has(row.id) |
| | | ? "selected-row" |
| | | : ""; |
| | | }, |
| | | // é¢è§ |
| | | handlePreview(row) { |
| | | this.currentPreviewFile = { |
| | | fileName: row.fileName, |
| | | fileUrl: row.fileUrl, |
| | | fileType: this.getFileType(row.fileName) |
| | | }; |
| | | this.previewVisible = true; |
| | | }, |
| | | |
| | | // ä¸è½½ |
| | | handleDownload(file) { |
| | | const link = document.createElement("a"); |
| | | link.href = file.fileUrl || file.path; |
| | | link.download = file.fileName; |
| | | link.click(); |
| | | }, |
| | | |
| | | // è·åæä»¶ç±»å |
| | | getFileType(fileName) { |
| | | const ext = fileName |
| | | .split(".") |
| | | .pop() |
| | | .toLowerCase(); |
| | | if (["jpg", "jpeg", "png"].includes(ext)) return "image"; |
| | | if (ext === "pdf") return "pdf"; |
| | | if (["doc", "docx"].includes(ext)) return "office"; |
| | | return "other"; |
| | | }, |
| | | |
| | | // æä»¶å¤§å°æ ¼å¼å |
| | | formatFileSize(size) { |
| | | if (!size) 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]; |
| | | }, |
| | | |
| | | // æ¥ææ¶é´æ ¼å¼å |
| | | formatDateTime(dateTime) { |
| | | return dateTime ? parseTime(dateTime) : "-"; |
| | | }, |
| | | |
| | | // ç¡®è®¤éæ© |
| | | handleConfirm() { |
| | | const result = []; |
| | | this.selectedAttachments.forEach(attachment => { |
| | | result.push({ |
| | | id: attachment.id, |
| | | fileName: attachment.fileName, |
| | | fileUrl: attachment.fileUrl, |
| | | fileSize: attachment.fileSize, |
| | | uploadTime: attachment.uploadTime, |
| | | uploader: attachment.uploader, |
| | | stage: attachment.stage, |
| | | stageName: |
| | | this.stageTypes.find(s => s.value === attachment.stage)?.label || |
| | | "", |
| | | type: attachment.type, |
| | | typeName: |
| | | this.typeDefinitions[attachment.stage]?.find( |
| | | t => t.value === attachment.type |
| | | )?.label || "" |
| | | }); |
| | | }); |
| | | |
| | | this.$emit("confirm", result); |
| | | this.visible = false; |
| | | }, |
| | | |
| | | // å¼¹æ¡å
³é |
| | | handleClosed() { |
| | | this.attachmentData = {}; |
| | | this.selectedAttachments.clear(); |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .stage-content { |
| | | padding: 15px 0; |
| | | } |
| | | |
| | | .attachment-list { |
| | | margin-top: 15px; |
| | | } |
| | | |
| | | .empty-attachment { |
| | | text-align: center; |
| | | padding: 40px 0; |
| | | color: #909399; |
| | | border: 1px dashed #dcdfe6; |
| | | border-radius: 4px; |
| | | margin-top: 15px; |
| | | } |
| | | |
| | | .file-name { |
| | | font-size: 13px; |
| | | color: #606266; |
| | | } |
| | | |
| | | /* éä¸è¡é«äº® */ |
| | | ::v-deep .el-table__row:hover { |
| | | cursor: pointer; |
| | | } |
| | | ::v-deep .el-table__row.selected-row { |
| | | background-color: #ecf5ff !important; |
| | | } |
| | | </style> |
| | |
| | | border |
| | | style="width: 100%" |
| | | class="medical-table" |
| | | v-fit-columns |
| | | :key="tableKey" |
| | | @header-dragend="handleHeaderDragEnd" |
| | | v-loading="tableLoading" |
| | |
| | | style="width: 100%" |
| | | class="medical-table" |
| | | :key="tableKey" |
| | | v-fit-columns |
| | | |
| | | @header-dragend="handleHeaderDragEnd" |
| | | > |
| | | <el-table-column |
| | |
| | | border |
| | | style="width: 100%" |
| | | class="medical-table" |
| | | v-fit-columns |
| | | |
| | | :key="tableKey" |
| | | @header-dragend="handleHeaderDragEnd" |
| | | v-loading="tableLoading" |
| | |
| | | const s_url = sessionObj.url; // 请æ±å°å |
| | | const s_data = sessionObj.data; // è¯·æ±æ°æ® |
| | | const s_time = sessionObj.time; // è¯·æ±æ¶é´ |
| | | const interval = 500; // é´éæ¶é´(ms)ï¼å°äºæ¤æ¶é´è§ä¸ºéå¤æäº¤ |
| | | const interval = 50; // é´éæ¶é´(ms)ï¼å°äºæ¤æ¶é´è§ä¸ºéå¤æäº¤ |
| | | if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { |
| | | const message = 'æ°æ®æ£å¨å¤çï¼è¯·å¿éå¤æäº¤'; |
| | | console.warn(`[${s_url}]: ` + message) |
| | |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <!-- <el-col :span="8"> |
| | | <el-form-item label="åè°åç¾å" prop="coordinatorSign"> |
| | | <el-input v-model="form.coordinatorSign" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-col> --> |
| | | <el-col :span="8"> |
| | | <el-form-item label="ç¾åæ¶é´" prop="coordinatorSignTime"> |
| | | <el-form-item label="è·åæ¶é´" prop="coordinatorSignTime"> |
| | | <el-date-picker |
| | | v-model="form.coordinatorSignTime" |
| | | type="datetime" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="æ¯å¦é»åç¼
æ" prop="isspendremember"> |
| | | <el-select |
| | | v-model="form.isspendremember" |
| | | style="width: 100%" |
| | | > |
| | | <el-option label="æ¯" :value="1" /> |
| | | <el-option label="å¦" :value="0" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="æ¢å¤éä½ä»ªå®¹" prop="isrestoreremains"> |
| | | <el-select |
| | | v-model="form.isrestoreremains" |
| | | style="width: 100%" |
| | | > |
| | | <el-option label="æ¯" :value="1" /> |
| | | <el-option label="å¦" :value="0" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="èç»äººä¸" prop="coordinatedusernameo"> |
| | | <el-form-item label="åè°åä¸" prop="coordinatedusernameo"> |
| | | <el-input v-model="form.coordinatedusernameo" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="èç»äººäº" prop="coordinatedusernamet"> |
| | | <el-form-item label="åè°åäº" prop="coordinatedusernamet"> |
| | | <el-input v-model="form.coordinatedusernamet" /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | </div> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="6"> |
| | | <el-form-item align="left" label="é使ç®" prop="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 || []" |
| | |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="18" v-if="form.isbodydonation == 1"> |
| | | <el-form-item |
| | | align="left" |
| | | label="æ¥æ¶åä½" |
| | | prop="receivingunitname" |
| | | > |
| | | <el-input |
| | | v-model="form.receivingunitname" |
| | | placeholder="请è¾å
¥æ¥æ¶åä½" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8" v-else> |
| | | |
| | | <el-col :span="8"> |
| | | <el-form-item align="left" label="æ¥æ¶å®¶å±" prop="relationname"> |
| | | <el-input |
| | | v-model="form.relationname" |
| | | placeholder="请è¾å
¥æ¥æ¶å®¶å±" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="䏿ç®è
å
³ç³»" prop="signfamilyrelations"> |
| | | <el-select |
| | | v-model="form.signfamilyrelations" |
| | | placeholder="è¯·éæ©ä¸æç®è
å
³ç³»" |
| | | > |
| | | <el-option |
| | | v-for="dict in dict.type.sys_FamilyRelation || []" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | FilePreviewDialog, |
| | | CaseBasicInfo |
| | | }, |
| | | dicts: ["sys_BloodType", "sys_Organ", "sys_0_1", "utilize_statue"], |
| | | dicts: [ |
| | | "sys_BloodType", |
| | | "sys_Organ", |
| | | "sys_FamilyRelation", |
| | | "sys_0_1", |
| | | "utilize_statue" |
| | | ], |
| | | data() { |
| | | return { |
| | | caseId: null, |
| | |
| | | coordinatedusernamet: "", |
| | | assessannex: "", |
| | | donateorgan: "", |
| | | isbodydonation: "0", |
| | | isbodydonation: "1", |
| | | receivingunitname: "", |
| | | createBy: "", |
| | | createTime: "", |
| | |
| | | .replace("T", " ") |
| | | .substring(0, 19); |
| | | |
| | | this.generateDonorNo(); |
| | | this.getDetail(); |
| | | 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); |
| | | }, |
| | | |
| | | // è·å详æ
|
| | |
| | | if (!data.completeState || data.completeState == 1) { |
| | | data.completeState = "2"; |
| | | } |
| | | this.form = data; |
| | | // å¡«å
è¡¨åæ°æ® |
| | | Object.assign(this.form, data); |
| | | |
| | | // Object.assign(this.form, data); |
| | | this.form.signfamilyrelations = this.form.signfamilyrelations || ""; |
| | | // å¤çæç®å¨å®å段 |
| | | if (data.donateorgan) { |
| | | const organArray = Array.isArray(data.donateorgan) |
| | |
| | | return false; |
| | | } |
| | | ); |
| | | |
| | | |
| | | if (incompleteRecords.length > 0) { |
| | | this.$message.warning("请å
å®åææå©ç¨è®°å½çä¿¡æ¯"); |
| | |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="è®°å½ç¶æ" prop="recordstate"> |
| | | <el-form-item label="å©ç¨ç¶æ" prop="completeState"> |
| | | <el-select |
| | | v-model="queryParams.recordstate" |
| | | placeholder="è¯·éæ©è®°å½ç¶æ" |
| | | v-model="queryParams.completeState" |
| | | placeholder="è¯·éæ©å©ç¨ç¶æ" |
| | | clearable |
| | | style="width: 200px" |
| | | > |
| | | <el-option label="已宿" value="completed" /> |
| | | <el-option label="è¿è¡ä¸" value="processing" /> |
| | | <el-option label="å¾
å¤ç" value="pending" /> |
| | | <el-option label="å·²å
³é" value="closed" /> |
| | | <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-form-item> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å¹´é¾" align="center" prop="age" width="80" /> |
| | | <el-table-column label="è¡å" align="center" prop="bloodtype" width="80"> |
| | | <el-table-column |
| | | label="è¡å" |
| | | align="center" |
| | | prop="bloodtype" |
| | | width="80" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <dict-tag |
| | | v-if="scope.row.bloodtype" |
| | |
| | | :value="scope.row.bloodtype" |
| | | /> |
| | | <span v-else>-</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="å©ç¨ç¶æ" |
| | | align="center" |
| | | prop="recordstate" |
| | | width="100" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <dict-tag |
| | | :options="dict.type.utilize_statue" |
| | | :value="scope.row.completeState" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | |
| | | <span>{{ scope.row.responsibleusername || "-" }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="è®°å½ç¶æ" |
| | | align="center" |
| | | prop="recordstate" |
| | | width="100" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <dict-tag |
| | | :options="dict.type.utilize_statue" |
| | | :value="scope.row.completeState" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | label="æä½" |
| | | fixed="right" |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { completionList, completionadd, completionedit } from "@/api/businessApi"; |
| | | import { |
| | | completionList, |
| | | completionadd, |
| | | completionedit |
| | | } from "@/api/businessApi"; |
| | | import Pagination from "@/components/Pagination"; |
| | | |
| | | export default { |
| | | name: "OrganUtilizationList", |
| | | components: { Pagination }, |
| | | dicts: ["sys_user_sex", "sys_BloodType",'utilize_statue'], |
| | | dicts: ["sys_user_sex", "sys_BloodType", "utilize_statue"], |
| | | data() { |
| | | return { |
| | | // é®ç½©å± |
| | |
| | | let data = response.data; |
| | | if (Array.isArray(data)) { |
| | | this.organUtilizationList = data; |
| | | this.total = data.length; |
| | | this.total = response.total; |
| | | } else if (data && data.rows) { |
| | | this.organUtilizationList = data.rows; |
| | | this.total = data.total || data.rows.length; |
| | | this.total = response.total; |
| | | } else if (data && data.list) { |
| | | this.organUtilizationList = data.list; |
| | | this.total = data.total || data.list.length; |
| | | this.total = response.total; |
| | | } else { |
| | | this.organUtilizationList = []; |
| | | this.total = 0; |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row style="margin-bottom: 10px;"> |
| | | <el-button |
| | | type="primary" |
| | | size="mini" |
| | | icon="el-icon-plus" |
| | | @click="openOtherFamilyDialog()" |
| | | > |
| | | æ·»å å
¶ä»å®¶å± |
| | | </el-button> |
| | | </el-row> |
| | | <el-table :data="otherFamilyList" size="small" border> |
| | | <el-table-column label="å§å" prop="name" /> |
| | | <el-table-column label="ä¸æèµ è
å
³ç³»" prop="relation"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag |
| | | :options="dict.type.sys_FamilyRelation" |
| | | :value="scope.row.relation" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="èç³»çµè¯" prop="phone" /> |
| | | |
| | | <el-table-column label="æä½" width="120" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | @click="editOtherFamily(scope.$index)" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | style="color:red" |
| | | @click="deleteOtherFamily(scope.$index)" |
| | | > |
| | | å é¤ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <el-row> |
| | | <el-form-item label-width="100px" label="æç®å³å®"> |
| | | <el-checkbox-group v-model="organdecision"> |
| | |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </el-card> |
| | | <!-- å
¶ä»å®¶å±å¼¹çª --> |
| | | <el-dialog |
| | | :title="isEditOtherFamily ? 'ç¼è¾å
¶ä»å®¶å±' : 'æ·»å å
¶ä»å®¶å±'" |
| | | :visible.sync="otherFamilyDialogVisible" |
| | | width="400px" |
| | | > |
| | | <el-form :model="currentOtherFamily" label-width="100px"> |
| | | <el-form-item label="å§å" prop="name"> |
| | | <el-input v-model="currentOtherFamily.name" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="å
³ç³»" prop="relation"> |
| | | <el-select v-model="currentOtherFamily.relation" style="width:100%"> |
| | | <el-option |
| | | v-for="dict in dict.type.sys_FamilyRelation" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="çµè¯" prop="phone"> |
| | | <el-input v-model="currentOtherFamily.phone" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <span slot="footer"> |
| | | <el-button @click="otherFamilyDialogVisible = false">åæ¶</el-button> |
| | | <el-button type="primary" @click="saveOtherFamily">ç¡®å®</el-button> |
| | | </span> |
| | | </el-dialog> |
| | | <!-- ä¸ä¼ å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | :title="`ä¸ä¼ ${getCurrentTypeLabel}éä»¶`" |
| | |
| | | ref="uploadRef" |
| | | class="upload-demo" |
| | | drag |
| | | action="#" |
| | | :action="uploadAction" |
| | | :headers="headers" |
| | | multiple |
| | | :file-list="tempFileList" |
| | | :before-upload="beforeUpload" |
| | | :on-change="handleFileChange" |
| | | :on-remove="handleTempRemove" |
| | | :on-success="handleUploadSuccess" |
| | | :auto-upload="false" |
| | | :http-request="handleHttpRequest" |
| | | > |
| | | <i class="el-icon-upload"></i> |
| | | <div class="el-upload__text">å°æä»¶æå°æ¤å¤ï¼æ<em>ç¹å»ä¸ä¼ </em></div> |
| | |
| | | import { relativesList, relativesEdit, relativesAdd } from "@/api/businessApi"; |
| | | import FilePreviewDialog from "@/components/FilePreviewDialog"; |
| | | import CaseBasicInfo from "@/components/CaseBasicInfo"; |
| | | import { getToken } from "@/utils/auth"; |
| | | |
| | | export default { |
| | | name: "ConfirmationDetail", |
| | | components: { |
| | |
| | | relativeidcardno: "", |
| | | relativephone: "", |
| | | relativeRemark: "", |
| | | assessannex: "" // JSONå符串å卿æéä»¶ |
| | | assessannex: "", // JSONå符串å卿æéä»¶ |
| | | otherFamilyMembers: "" // â
æ°å¢ |
| | | }, |
| | | uploadAction: process.env.VUE_APP_BASE_API + "/common/upload", |
| | | headers: { |
| | | Authorization: "Bearer " + getToken() |
| | | }, |
| | | // å
¶ä»å®¶å±è¡¨æ ¼æ°æ® |
| | | otherFamilyList: [], |
| | | |
| | | // å½åç¼è¾çå
¶ä»å®¶å±ï¼å¼¹çªç¨ï¼ |
| | | currentOtherFamily: { |
| | | name: "", |
| | | relation: "", |
| | | phone: "" |
| | | }, |
| | | |
| | | // æ¯å¦ç¼è¾æ¨¡å¼ï¼å
¶ä»å®¶å±ï¼ |
| | | isEditOtherFamily: false, |
| | | editOtherFamilyIndex: -1, |
| | | |
| | | // å
¶ä»å®¶å±å¼¹çª |
| | | otherFamilyDialogVisible: false, |
| | | organdecision: [], |
| | | organdecisionOther: "", |
| | | organselection: [ |
| | | "èè", |
| | | "åè¾", |
| | | "å·¦è¾", |
| | | "å³è¾", |
| | | "è¾è", |
| | | "å¿è", |
| | | "èºè", |
| | | "è°è
º", |
| | | "å°è ", |
| | | "åç¼ç»ç»", |
| | | "éä½", |
| | | "ç¼è§è", |
| | | "å
¶ä»" |
| | | ], |
| | | // å è½½ç¶æ |
| | |
| | | } else { |
| | | detailData = response; |
| | | } |
| | | |
| | | // å¤çå
¶ä»å®¶å±æ°æ® |
| | | if (detailData.otherFamilyMembers) { |
| | | try { |
| | | this.otherFamilyList = |
| | | typeof detailData.otherFamilyMembers === "string" |
| | | ? JSON.parse(detailData.otherFamilyMembers) |
| | | : detailData.otherFamilyMembers || []; |
| | | } catch (e) { |
| | | this.otherFamilyList = []; |
| | | } |
| | | } |
| | | // æ å°å段å°è¡¨å |
| | | this.form = { |
| | | ...this.form, |
| | |
| | | this.tempFileList = fileList; |
| | | }, |
| | | |
| | | // èªå®ä¹ä¸ä¼ è¯·æ± |
| | | handleHttpRequest(options) { |
| | | return new Promise((resolve, reject) => { |
| | | this.uploadLoading = true; |
| | | handleUploadSuccess(response, file) { |
| | | if (response.code !== 200) { |
| | | this.$message.error(response.msg || "ä¸ä¼ 失败"); |
| | | return; |
| | | } |
| | | |
| | | // 模æä¸ä¼ è¿ç¨ |
| | | setTimeout(() => { |
| | | const newAttachment = { |
| | | id: Date.now(), |
| | | fileName: options.file.name, |
| | | fileUrl: URL.createObjectURL(options.file), |
| | | fileSize: options.file.size, |
| | | fileType: this.getFileExtension(options.file.name), |
| | | type: this.currentUploadType, // è®°å½éä»¶ç±»å |
| | | uploadTime: new Date().toISOString(), |
| | | uploader: "å½åç¨æ·" |
| | | }; |
| | | const newAttachment = { |
| | | id: Date.now(), |
| | | fileName: file.name, |
| | | fileUrl: response.url, |
| | | fileSize: file.size, |
| | | fileType: this.getFileExtension(file.name), |
| | | type: this.currentUploadType, |
| | | uploadTime: this.getCurrentTime(), |
| | | uploader: "å½åç¨æ·" |
| | | }; |
| | | |
| | | // æ·»å å°å¯¹åºç±»åçéä»¶å表 |
| | | if (this.attachmentData[this.currentUploadType]) { |
| | | this.attachmentData[this.currentUploadType].push(newAttachment); |
| | | } |
| | | this.attachmentData[this.currentUploadType].push(newAttachment); |
| | | this.updateAssessannexField(); |
| | | |
| | | this.uploadLoading = false; |
| | | this.updateAssessannexField(); // æ´æ°åå¨å段 |
| | | resolve({ code: 200, data: newAttachment }); |
| | | }, 1500); |
| | | }); |
| | | this.$message.success("ä¸ä¼ æå"); |
| | | this.uploadLoading = false; |
| | | this.uploadDialogVisible = false; |
| | | this.tempFileList = []; |
| | | }, |
| | | |
| | | // æäº¤ä¸ä¼ |
| | | async submitUpload() { |
| | | submitUpload() { |
| | | if (this.tempFileList.length === 0) { |
| | | this.$message.warning("请å
éæ©è¦ä¸ä¼ çæä»¶"); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | for (const file of this.tempFileList) { |
| | | await this.$refs.uploadRef.submit(); |
| | | } |
| | | |
| | | this.$message.success("æä»¶ä¸ä¼ æå"); |
| | | this.uploadDialogVisible = false; |
| | | this.tempFileList = []; |
| | | } catch (error) { |
| | | this.$message.error("æä»¶ä¸ä¼ 失败"); |
| | | console.error("ä¸ä¼ 失败:", error); |
| | | } |
| | | this.uploadLoading = true; |
| | | this.$refs.uploadRef.submit(); // â
åªè°ç¨ä¸æ¬¡ |
| | | }, |
| | | |
| | | // å é¤éä»¶ |
| | |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | openOtherFamilyDialog(index) { |
| | | this.isEditOtherFamily = typeof index === "number"; |
| | | this.editOtherFamilyIndex = index || -1; |
| | | |
| | | this.currentOtherFamily = this.isEditOtherFamily |
| | | ? { ...this.otherFamilyList[index] } |
| | | : { name: "", relation: "", phone: "" }; |
| | | |
| | | this.otherFamilyDialogVisible = true; |
| | | }, |
| | | editOtherFamily(index) { |
| | | this.openOtherFamilyDialog(index); |
| | | }, |
| | | deleteOtherFamily(index) { |
| | | this.$confirm("确认å é¤è¯¥å®¶å±ï¼", "æç¤º", { type: "warning" }).then( |
| | | () => { |
| | | this.otherFamilyList.splice(index, 1); |
| | | this.updateOtherFamilyField(); |
| | | } |
| | | ); |
| | | }, |
| | | saveOtherFamily() { |
| | | if ( |
| | | !this.currentOtherFamily.name || |
| | | !this.currentOtherFamily.relation || |
| | | !this.currentOtherFamily.phone |
| | | ) { |
| | | this.$message.warning("请填å宿´ä¿¡æ¯"); |
| | | return; |
| | | } |
| | | |
| | | if (this.isEditOtherFamily) { |
| | | this.otherFamilyList.splice(this.editOtherFamilyIndex, 1, { |
| | | ...this.currentOtherFamily |
| | | }); |
| | | } else { |
| | | this.otherFamilyList.push({ ...this.currentOtherFamily }); |
| | | } |
| | | |
| | | this.updateOtherFamilyField(); |
| | | this.otherFamilyDialogVisible = false; |
| | | }, |
| | | updateOtherFamilyField() { |
| | | this.form.otherFamilyMembers = JSON.stringify(this.otherFamilyList); |
| | | }, |
| | | // æ´æ°assessannexåå¨å段 |
| | | updateAssessannexField() { |
| | | // å°ææç±»åçéä»¶å并为ä¸ä¸ªæ°ç» |
| | |
| | | await this.$refs.form.validate(); |
| | | this.saveLoading = true; |
| | | |
| | | // ç¡®ä¿éä»¶æ°æ®æ¯ææ°ç |
| | | this.updateOtherFamilyField(); |
| | | this.updateAssessannexField(); |
| | | |
| | | const saveData = { |
| | | ...this.form, |
| | | infoid: this.infoid, |
| | |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»è®°äºº" prop="registrationName"> |
| | | <el-form-item label="è´è´£äºº" prop="registrationName"> |
| | | <el-input v-model="form.registrationName" /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | v-model="otherOrganInput" |
| | | placeholder="请è¾å
¥å
¶ä»å¨å®åç§°" |
| | | style="margin-top: 10px; width: 300px;" |
| | | :disabled="form.allocationStatus == '1'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | style="width: 100%" |
| | | :row-class-name="getOrganRowClassName" |
| | | > |
| | | <el-table-column |
| | | label="åºå·" |
| | | type="index" |
| | | width="60" |
| | | align="center" |
| | | fixed |
| | | ></el-table-column> |
| | | |
| | | <el-table-column |
| | | label="åé
ç¶æ" |
| | | align="center" |
| | | width="100" |
| | | prop="allocationstatus" |
| | | fixed |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-tag |
| | | :type=" |
| | | getAllocationStatusTagType(scope.row.allocationstatus) |
| | | " |
| | | size="small" |
| | | > |
| | | {{ getAllocationStatusText(scope.row.allocationstatus) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | label="å¨å®åç§°" |
| | | align="center" |
| | |
| | | <el-input |
| | | v-model="scope.row.caseno" |
| | | placeholder="åé
ç³»ç»ç¼å·" |
| | | :disabled="form.allocationStatus == '1'" |
| | | :disabled=" |
| | | form.allocationStatus == '1' || |
| | | scope.row.allocationstatus == '3' |
| | | " |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | label="åé
æ¥æ¶æ¶é´" |
| | | label="åé
å¼å§æ¶é´" |
| | | align="center" |
| | | width="180" |
| | | prop="applicanttime" |
| | |
| | | v-model="scope.row.applicanttime" |
| | | type="datetime" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | placeholder="éæ©å¼å§æ¥æ¶æ¶é´" |
| | | :disabled=" |
| | | form.allocationStatus == '1' || |
| | | scope.row.allocationstatus == '3' |
| | | " |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="åé
æ¥æ¶æ¶é´" |
| | | align="center" |
| | | width="180" |
| | | prop="organgettime" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-date-picker |
| | | clearable |
| | | size="small" |
| | | style="width: 100%" |
| | | v-model="scope.row.organgettime" |
| | | type="datetime" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | placeholder="éæ©åé
æ¥æ¶æ¶é´" |
| | | :disabled="form.allocationStatus == '1'" |
| | | :disabled=" |
| | | form.allocationStatus == '1' || |
| | | scope.row.allocationstatus == '3' |
| | | " |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | <el-input |
| | | v-model="scope.row.name" |
| | | placeholder="åä½å§æ°" |
| | | :disabled="form.allocationStatus == '1'" |
| | | :disabled=" |
| | | form.allocationStatus == '1' || |
| | | scope.row.allocationstatus == '3' |
| | | " |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | :dataList="dataList" |
| | | v-model="scope.row.transplanthospitalno" |
| | | style="width: 100%" |
| | | :disabled=" |
| | | form.allocationStatus == '1' || |
| | | scope.row.allocationstatus == '3' |
| | | " |
| | | /> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <!-- ä¿®æ¹templateä¸ç说æå --> |
| | | <el-table-column |
| | | label="说æ" |
| | | align="center" |
| | |
| | | min-width="200" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-input |
| | | type="textarea" |
| | | clearable |
| | | v-model="scope.row.reallocationreason" |
| | | placeholder="请è¾å
¥è¯´æ" |
| | | :disabled="form.allocationStatus == '1'" |
| | | /> |
| | | <div v-if="scope.row.allocationstatus != '3'"> |
| | | <el-input |
| | | type="textarea" |
| | | clearable |
| | | v-model="scope.row.reallocationreason" |
| | | placeholder="请è¾å
¥è¯´æ" |
| | | :disabled=" |
| | | form.allocationStatus == '1' || |
| | | scope.row.allocationstatus == '3' |
| | | " |
| | | /> |
| | | </div> |
| | | <div v-else> |
| | | <!-- éåé
è®°å½ï¼æ¾ç¤ºè¯¦ç»æ¥çæé® --> |
| | | <el-button |
| | | v-if="scope.row.reallocationreason" |
| | | type="text" |
| | | size="small" |
| | | @click="handleViewRedistributionDetail(scope.row)" |
| | | style="color: #e6a23c;" |
| | | > |
| | | <i class="el-icon-document"></i> |
| | | æ¥çéåé
详æ
|
| | | </el-button> |
| | | <span v-else class="no-data">-</span> |
| | | |
| | | <!-- ä¿çåæçå·¥å
·æç¤ºï¼å¯ç§»é¤æä¿çï¼ --> |
| | | <el-tooltip |
| | | v-if="scope.row.redistributionInfo" |
| | | :content=" |
| | | formatRedistributionTooltip( |
| | | scope.row.redistributionInfo |
| | | ) |
| | | " |
| | | placement="top" |
| | | > |
| | | <el-button |
| | | type="text" |
| | | size="small" |
| | | style="margin-left: 5px;" |
| | | > |
| | | <i class="el-icon-info"></i> |
| | | </el-button> |
| | | </el-tooltip> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | |
| | | width="120" |
| | | class-name="small-padding fixed-width" |
| | | v-if="form.allocationStatus !== '1'" |
| | | fixed="right" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | |
| | | type="text" |
| | | icon="el-icon-copy-document" |
| | | @click="handleRedistribution(scope.row)" |
| | | :disabled="!scope.row.caseno" |
| | | :disabled=" |
| | | scope.row.allocationstatus == '3' || !scope.row.caseno |
| | | " |
| | | style="color: #e6a23c;" |
| | | > |
| | | éåé
|
| | | {{ |
| | | scope.row.allocationstatus == "3" |
| | | ? "å·²éåé
" |
| | | : "éåé
" |
| | | }} |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="stat-item"> |
| | | <span class="stat-label">å¾
å®åä¿¡æ¯:</span> |
| | | <span class="stat-value">{{ incompleteRecords }} 个</span> |
| | | <span class="stat-label">å¾
å®¡æ ¸:</span> |
| | | <span class="stat-value">{{ pendingReviewCount }} 个</span> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="stat-item"> |
| | | <span class="stat-label">åé
ç¶æ:</span> |
| | | <span class="stat-value"> |
| | | <el-tag |
| | | :type=" |
| | | form.allocationStatus == '1' |
| | | ? 'success' |
| | | : form.allocationStatus == '2' |
| | | ? 'danger' |
| | | : 'warning' |
| | | " |
| | | > |
| | | {{ |
| | | form.allocationStatus == "1" |
| | | ? "å·²åé
" |
| | | : form.allocationStatus == "2" |
| | | ? "ä½åº" |
| | | : "æªåé
" |
| | | }} |
| | | </el-tag> |
| | | </span> |
| | | <span class="stat-label">éåé
:</span> |
| | | <span class="stat-value">{{ redistributedCount }} 个</span> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | </el-empty> |
| | | </div> |
| | | </el-form> |
| | | |
| | | <!-- <div class="dialog-footer" v-if="form.allocationStatus !== '1'"> |
| | | <el-button |
| | | type="primary" |
| | | @click="handleSaveAllocation" |
| | | :loading="saveLoading" |
| | | :disabled=" |
| | | !allocationData.serviceDonateorganList || |
| | | allocationData.serviceDonateorganList.length == 0 |
| | | " |
| | | > |
| | | ä¿ååé
è®°å½ |
| | | </el-button> |
| | | <el-button |
| | | type="success" |
| | | @click="handleConfirmAllocation" |
| | | :loading="confirmLoading" |
| | | :disabled="incompleteRecords > 0" |
| | | > |
| | | ç¡®è®¤å®æåé
|
| | | </el-button> |
| | | </div> --> |
| | | </el-card> |
| | | |
| | | <!-- é件管çé¨åä¼å --> |
| | |
| | | title="å¨å®éåé
" |
| | | :visible.sync="redistributionDialogVisible" |
| | | width="500px" |
| | | @close="handleRedistributionDialogClose" |
| | | > |
| | | <el-form :model="redistributionForm" label-width="100px"> |
| | | <el-form |
| | | :model="redistributionForm" |
| | | :rules="redistributionRules" |
| | | ref="redistributionFormRef" |
| | | label-width="100px" |
| | | > |
| | | <el-form-item label="åå¨å®ä¿¡æ¯"> |
| | | <el-input v-model="redistributionForm.organname" readonly /> |
| | | </el-form-item> |
| | | <el-form-item label="éåé
åå " prop="reason"> |
| | | <el-form-item label="éåé
åå " prop="reason" required> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="4" |
| | |
| | | placeholder="请è¾å
¥éåé
åå " |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="éåé
æ¶é´" prop="redistributionTime" required> |
| | | <el-date-picker |
| | | v-model="redistributionForm.redistributionTime" |
| | | type="datetime" |
| | | placeholder="è¯·éæ©éåé
æ¶é´" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="éåé
éä»¶"> |
| | | <UploadAttachment |
| | | ref="redistributionAttachmentUpload" |
| | | :file-list="redistributionAttachmentList" |
| | | :limit="5" |
| | | :accept="attachmentAccept" |
| | | :multiple="true" |
| | | @change="handleRedistributionChange" |
| | | @upload-success="handleRedistributionUploadSuccess" |
| | | @upload-error="handleRedistributionUploadError" |
| | | @remove="handleRedistributionAttachmentRemove" |
| | | /> |
| | | <div style="margin-top: 5px; font-size: 12px; color: #999;"> |
| | | æ¯æä¸ä¼ éåé
ç¸å
³æä»¶ (æå¤5个) |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div slot="footer"> |
| | | <el-button @click="redistributionDialogVisible = false">åæ¶</el-button> |
| | | <el-button type="primary" @click="handleRedistributionConfirm" |
| | | >确认éåé
</el-button |
| | | <el-button |
| | | type="primary" |
| | | @click="handleRedistributionConfirm" |
| | | :loading="redistributionLoading" |
| | | > |
| | | 确认éåé
|
| | | </el-button> |
| | | </div> |
| | | </el-dialog> |
| | | <!-- å¨template䏿·»å éåé
详æ
å¼¹çª --> |
| | | <el-dialog |
| | | title="éåé
详æ
" |
| | | :visible.sync="redistributionDetailDialogVisible" |
| | | width="600px" |
| | | > |
| | | <div v-loading="redistributionDetailLoading"> |
| | | <div v-if="currentRedistributionDetail" style="padding: 20px;"> |
| | | <!-- åºæ¬ä¿¡æ¯ --> |
| | | <el-descriptions title="éåé
ä¿¡æ¯" :column="2" border> |
| | | <el-descriptions-item label="å¨å®åç§°"> |
| | | {{ currentRedistributionDetail.organname || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="æä½äºº"> |
| | | {{ currentRedistributionDetail.operator || "-" }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="æä½æ¶é´"> |
| | | {{ |
| | | currentRedistributionDetail.operatorTime |
| | | ? formatDateTime(currentRedistributionDetail.operatorTime) |
| | | : "-" |
| | | }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="éåé
æ¶é´"> |
| | | {{ |
| | | currentRedistributionDetail.redistributionTime |
| | | ? formatDateTime( |
| | | currentRedistributionDetail.redistributionTime |
| | | ) |
| | | : "-" |
| | | }} |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | |
| | | <!-- éåé
åå --> |
| | | <div style="margin-top: 20px;"> |
| | | <div class="section-title">éåé
åå </div> |
| | | <div |
| | | class="section-content" |
| | | style="padding: 10px; background: #f5f7fa; border-radius: 4px;" |
| | | > |
| | | {{ currentRedistributionDetail.reason || "æ " }} |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- éåé
éä»¶ --> |
| | | <div |
| | | style="margin-top: 20px;" |
| | | v-if=" |
| | | currentRedistributionDetail.attachments && |
| | | currentRedistributionDetail.attachments.length > 0 |
| | | " |
| | | > |
| | | <div class="section-title"> |
| | | éåé
éä»¶ ({{ currentRedistributionDetail.attachments.length }}) |
| | | </div> |
| | | <div class="redistribution-attachments"> |
| | | <el-table |
| | | :data="currentRedistributionDetail.attachments" |
| | | size="small" |
| | | style="width: 100%" |
| | | > |
| | | <el-table-column label="æä»¶å" min-width="200"> |
| | | <template slot-scope="scope"> |
| | | <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"> |
| | | <template slot-scope="scope"> |
| | | <el-tag |
| | | :type="getFileTagType(scope.row.fileName)" |
| | | size="small" |
| | | > |
| | | {{ getFileTypeText(scope.row.fileName) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ä¸ä¼ æ¶é´" width="150"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ |
| | | scope.row.uploadTime |
| | | ? formatDateTime(scope.row.uploadTime) |
| | | : "-" |
| | | }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="150" fixed="right"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="primary" |
| | | @click="handleRedistributionAttachmentPreview(scope.row)" |
| | | :disabled="!isPreviewable(scope.row.fileName)" |
| | | > |
| | | é¢è§ |
| | | </el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="success" |
| | | @click="handleRedistributionAttachmentDownload(scope.row)" |
| | | > |
| | | ä¸è½½ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | |
| | | <div |
| | | v-else |
| | | style="margin-top: 20px; text-align: center; color: #909399;" |
| | | > |
| | | æ éåé
éä»¶ |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div slot="footer"> |
| | | <el-button @click="redistributionDetailDialogVisible = false" |
| | | >å
³é</el-button |
| | | > |
| | | </div> |
| | | </el-dialog> |
| | | |
| | | <!-- éä»¶é¢è§å¯¹è¯æ¡ --> |
| | | <FilePreviewDialog |
| | | :visible="filePreviewVisible" |
| | |
| | | data() { |
| | | return { |
| | | caseId: null, |
| | | |
| | | // éåé
详æ
ç¸å
³ |
| | | redistributionDetailDialogVisible: false, |
| | | redistributionDetailLoading: false, |
| | | currentRedistributionDetail: null, |
| | | // è¡¨åæ°æ® |
| | | form: { |
| | | id: undefined, |
| | |
| | | }, |
| | | // åé
è®°å½éªè¯è§å |
| | | allocationRules: {}, |
| | | // éåé
éªè¯è§å |
| | | redistributionRules: { |
| | | reason: [ |
| | | { required: true, message: "éåé
åå ä¸è½ä¸ºç©º", trigger: "blur" } |
| | | ], |
| | | redistributionTime: [ |
| | | { required: true, message: "éåé
æ¶é´ä¸è½ä¸ºç©º", trigger: "blur" } |
| | | ] |
| | | }, |
| | | // ä¿åå è½½ç¶æ |
| | | saveLoading: false, |
| | | confirmLoading: false, |
| | | redistributionLoading: false, |
| | | // å è½½ç¶æ |
| | | loading: false, |
| | | // éä¸çå¨å®ï¼åå¨åå
¸valueï¼ |
| | |
| | | redistributionDialogVisible: false, |
| | | redistributionForm: { |
| | | organname: "", |
| | | reason: "" |
| | | reason: "", |
| | | redistributionTime: "" |
| | | }, |
| | | redistributionAttachmentList: [], |
| | | redistributionFormRef: null, |
| | | currentRedistributeRecord: null, |
| | | // æä»¶é¢è§ç¸å
³ |
| | | filePreviewVisible: false, |
| | |
| | | record => |
| | | !record.caseno || |
| | | !record.applicanttime || |
| | | !record.organgettime || |
| | | !record.name || |
| | | !record.transplanthospitalno |
| | | ).length; |
| | | }, |
| | | // å¾
å®¡æ ¸è®°å½æ°é |
| | | pendingReviewCount() { |
| | | if (!this.allocationData.serviceDonateorganList) return 0; |
| | | return this.allocationData.serviceDonateorganList.filter( |
| | | record => record.allocationstatus == "0" |
| | | ).length; |
| | | }, |
| | | // éåé
è®°å½æ°é |
| | | redistributedCount() { |
| | | if (!this.allocationData.serviceDonateorganList) return 0; |
| | | return this.allocationData.serviceDonateorganList.filter( |
| | | record => record.allocationstatus == "3" |
| | | ).length; |
| | | }, |
| | | // å¯ä¸å»é¢æ°é |
| | |
| | | // 夿æ¯å¦éè¦æ¾ç¤ºå
¶ä»è¾å
¥æ¡ |
| | | showOtherInput() { |
| | | return this.selectedOrgans.includes("C01"); // å设"å
¶ä»"çåå
¸å¼æ¯C01 |
| | | }, |
| | | // åé
ç¶æåå
¸æ å° |
| | | allocationStatusDict() { |
| | | return { |
| | | "0": { label: "æäº¤åé
", type: "info" }, |
| | | "1": { label: "å®¡æ ¸éè¿", type: "success" }, |
| | | "2": { label: "å®¡æ ¸æç»", type: "danger" }, |
| | | "3": { label: "éåé
", type: "warning" } |
| | | }; |
| | | } |
| | | }, |
| | | watch: { |
| | |
| | | this.initData(); |
| | | }, |
| | | methods: { |
| | | // è·ååé
ç¶ææ ç¾ç±»å |
| | | getAllocationStatusTagType(status) { |
| | | const statusMap = this.allocationStatusDict; |
| | | return statusMap[status] ? statusMap[status].type : "info"; |
| | | }, |
| | | |
| | | // è·ååé
ç¶æææ¬ |
| | | getAllocationStatusText(status) { |
| | | const statusMap = this.allocationStatusDict; |
| | | return statusMap[status] ? statusMap[status].label : "æªç¥ç¶æ"; |
| | | }, |
| | | |
| | | // æ¥çéåé
详æ
|
| | | handleViewRedistributionDetail(row) { |
| | | this.redistributionDetailLoading = true; |
| | | this.redistributionDetailDialogVisible = true; |
| | | |
| | | try { |
| | | if (row.redistributionInfo) { |
| | | // è§£æéåé
ä¿¡æ¯ |
| | | const redistributionInfo = JSON.parse(row.redistributionInfo); |
| | | this.currentRedistributionDetail = { |
| | | organname: row.organname || "-", |
| | | ...redistributionInfo |
| | | }; |
| | | } else { |
| | | this.currentRedistributionDetail = { |
| | | organname: row.organname || "-", |
| | | reason: "æ éåé
åå ", |
| | | attachments: [] |
| | | }; |
| | | } |
| | | } catch (error) { |
| | | console.error("è§£æéåé
ä¿¡æ¯å¤±è´¥:", error); |
| | | this.$message.error("éåé
ä¿¡æ¯è§£æå¤±è´¥"); |
| | | this.currentRedistributionDetail = { |
| | | organname: row.organname || "-", |
| | | reason: "éåé
ä¿¡æ¯æ ¼å¼é误", |
| | | attachments: [] |
| | | }; |
| | | } finally { |
| | | this.redistributionDetailLoading = false; |
| | | } |
| | | }, |
| | | |
| | | // é¢è§éåé
éä»¶ |
| | | handleRedistributionAttachmentPreview(file) { |
| | | this.currentPreviewFile = { |
| | | fileName: file.fileName, |
| | | fileUrl: file.path || file.fileUrl, |
| | | fileType: this.getFileType(file.fileName) |
| | | }; |
| | | this.filePreviewVisible = true; |
| | | }, |
| | | |
| | | // ä¸è½½éåé
éä»¶ |
| | | handleRedistributionAttachmentDownload(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("æä»¶è·¯å¾ä¸åå¨ï¼æ æ³ä¸è½½"); |
| | | } |
| | | }, |
| | | |
| | | // å¢å¼ºæ ¼å¼åå·¥å
·æç¤ºæ¹æ³ |
| | | formatRedistributionTooltip(redistributionInfo) { |
| | | if (!redistributionInfo) return ""; |
| | | try { |
| | | const info = JSON.parse(redistributionInfo); |
| | | let tooltip = `éåé
åå : ${info.reason}\néåé
æ¶é´: ${info.redistributionTime}`; |
| | | |
| | | // æ·»å éä»¶ä¿¡æ¯ |
| | | if (info.attachments && info.attachments.length > 0) { |
| | | tooltip += `\n\néä»¶(${info.attachments.length}个):`; |
| | | info.attachments.forEach((att, index) => { |
| | | tooltip += `\n${index + 1}. ${att.fileName}`; |
| | | }); |
| | | } |
| | | |
| | | return tooltip; |
| | | } catch (error) { |
| | | return redistributionInfo; |
| | | } |
| | | }, |
| | | // æ ¹æ®åå
¸valueè·ålabel |
| | | getOrganLabel(organValue) { |
| | | const dictItem = this.organDict.find(item => item.value == organValue); |
| | |
| | | |
| | | this.getHospitalData(); |
| | | }, |
| | | |
| | | // çææç®è
ç¼å· |
| | | generateDonorNo() { |
| | | const timestamp = Date.now().toString(); |
| | |
| | | this.form.attachments = []; |
| | | } |
| | | }, |
| | | |
| | | // è·å详æ
|
| | | async getDetail(infoid, id) { |
| | | this.loading = true; |
| | | donateorganBaseinfoInfo(id); |
| | | try { |
| | | const response = await allocationList({ infoid }); |
| | | if (response.code == 200 && response.data && response.data.length > 0) { |
| | |
| | | this.allocationData.serviceDonateorganList = Array.isArray( |
| | | data.serviceDonateorganList |
| | | ) |
| | | ? data.serviceDonateorganList |
| | | ? data.serviceDonateorganList.map(item => { |
| | | // ç¡®ä¿æ¯æ¡è®°å½é½æåé
ç¶æåæ®µï¼é»è®¤å¼ä¸º0 |
| | | const allocationstatus = item.allocationstatus || "0"; |
| | | let redistributionInfo = null; |
| | | |
| | | // è§£æéåé
ä¿¡æ¯ |
| | | if (allocationstatus == "3" && item.reallocationreason) { |
| | | try { |
| | | redistributionInfo = JSON.parse(item.reallocationreason); |
| | | console.log(redistributionInfo); |
| | | } catch (error) { |
| | | console.warn("è§£æéåé
ä¿¡æ¯å¤±è´¥:", error); |
| | | redistributionInfo = item.reallocationreason; |
| | | } |
| | | } |
| | | |
| | | return { |
| | | ...item, |
| | | allocationstatus, |
| | | redistributionInfo: redistributionInfo |
| | | ? JSON.stringify(redistributionInfo) |
| | | : null |
| | | }; |
| | | }) |
| | | : []; |
| | | |
| | | // æ´æ°éä¸çå¨å® |
| | |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | |
| | | // è·åå»é¢æ°æ® |
| | | async getHospitalData() { |
| | | try { |
| | |
| | | this.$message.error("è·åå»é¢æ°æ®å¤±è´¥"); |
| | | } |
| | | }, |
| | | |
| | | // å¨å®éæ©ç¶æåå |
| | | handleOrganSelectionChange(selectedValues) { |
| | | if (!this.allocationData.serviceDonateorganList) { |
| | |
| | | organno: organValue, |
| | | caseno: "", |
| | | applicanttime: "", |
| | | organgettime: "", |
| | | name: "", |
| | | transplanthospitalno: "", |
| | | transplantHospitalName: "", |
| | | reallocationreason: "", |
| | | allocationstatus: "0", // é»è®¤æäº¤åé
ç¶æ |
| | | redistributionInfo: null, |
| | | organState: 1 |
| | | }); |
| | | }, |
| | |
| | | row.transplantHospitalName = hospital.hospitalName; |
| | | } |
| | | }, |
| | | |
| | | // éåé
æä½ |
| | | handleRedistribution(row) { |
| | | this.currentRedistributeRecord = row; |
| | | this.redistributionForm.organname = row.organname; |
| | | this.redistributionForm.reason = row.reallocationreason || ""; |
| | | this.redistributionForm.reason = ""; |
| | | this.redistributionForm.redistributionTime = new Date() |
| | | .toISOString() |
| | | .replace("T", " ") |
| | | .substring(0, 19); |
| | | this.redistributionAttachmentList = []; |
| | | this.redistributionDialogVisible = true; |
| | | }, |
| | | // 确认éåé
|
| | | handleRedistributionConfirm() { |
| | | if (!this.redistributionForm.reason) { |
| | | this.$message.warning("请è¾å
¥éåé
åå "); |
| | | return; |
| | | } |
| | | |
| | | if (this.currentRedistributeRecord) { |
| | | this.currentRedistributeRecord.reallocationreason = this.redistributionForm.reason; |
| | | this.$message.success("éåé
åå å·²æ´æ°"); |
| | | this.redistributionDialogVisible = false; |
| | | // éåé
å¯¹è¯æ¡å
³é |
| | | handleRedistributionDialogClose() { |
| | | this.redistributionForm = { |
| | | organname: "", |
| | | reason: "", |
| | | redistributionTime: "" |
| | | }; |
| | | this.redistributionAttachmentList = []; |
| | | this.currentRedistributeRecord = null; |
| | | }, |
| | | |
| | | // éåé
éä»¶ä¸ä¼ æå |
| | | handleRedistributionUploadSuccess({ 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") |
| | | }; |
| | | console.log(11); |
| | | |
| | | this.redistributionAttachmentList = fileList; |
| | | this.$message.success("éåé
éä»¶ä¸ä¼ æå"); |
| | | } |
| | | }, |
| | | |
| | | // éåé
éä»¶ä¸ä¼ é误 |
| | | handleRedistributionUploadError({ file, fileList, error }) { |
| | | console.error("éåé
éä»¶ä¸ä¼ 失败:", error); |
| | | this.$message.error("éåé
éä»¶ä¸ä¼ 失败ï¼è¯·éè¯"); |
| | | }, |
| | | |
| | | // éåé
éä»¶ç§»é¤ |
| | | handleRedistributionAttachmentRemove(file) { |
| | | if (file.url) { |
| | | const index = this.redistributionAttachmentList.findIndex( |
| | | item => item.path == file.url || item.fileUrl == file.url |
| | | ); |
| | | if (index > -1) { |
| | | this.redistributionAttachmentList.splice(index, 1); |
| | | } |
| | | } |
| | | }, |
| | | |
| | | // 确认éåé
|
| | | async handleRedistributionConfirm() { |
| | | this.$refs.redistributionFormRef.validate(async valid => { |
| | | if (!valid) { |
| | | this.$message.warning("请å®åéåé
ä¿¡æ¯"); |
| | | return; |
| | | } |
| | | console.log(1, this.redistributionAttachmentList); |
| | | |
| | | this.redistributionLoading = true; |
| | | |
| | | try { |
| | | // æå»ºéåé
ä¿¡æ¯å¯¹è±¡ |
| | | const redistributionInfo = { |
| | | reason: this.redistributionForm.reason, |
| | | redistributionTime: this.redistributionForm.redistributionTime, |
| | | attachments: this.redistributionAttachmentList.map(att => ({ |
| | | // fileName: att.fileName, |
| | | // path: att.path || att.fileUrl, |
| | | // fileUrl: att.path || att.fileUrl, |
| | | // fileType: this.getFileExtension(att.name), |
| | | // fileSize: att.fileSize, |
| | | // uploadTime: att.uploadTime |
| | | fileName: att.name, |
| | | path: att.url, |
| | | fileUrl: att.url, |
| | | fileType: this.getFileExtension(att.name), |
| | | fileSize: att.size, |
| | | uploadTime: dayjs().format("YYYY-MM-DD HH:mm:ss") |
| | | })), |
| | | |
| | | operator: this.currentUser.username || this.currentUser.nickName, |
| | | operatorTime: new Date() |
| | | .toISOString() |
| | | .replace("T", " ") |
| | | .substring(0, 19) |
| | | }; |
| | | console.log(2, this.redistributionAttachmentList); |
| | | |
| | | // æ¾å°å½åè®°å½çç´¢å¼ |
| | | const currentIndex = this.allocationData.serviceDonateorganList.findIndex( |
| | | item => item == this.currentRedistributeRecord |
| | | ); |
| | | |
| | | if (currentIndex !== -1) { |
| | | // 1. æ´æ°åè®°å½çç¶æä¸º3ï¼éåé
ï¼å¹¶ä¿åéåé
ä¿¡æ¯ |
| | | const originalRecord = { ...this.currentRedistributeRecord }; |
| | | originalRecord.allocationstatus = "3"; |
| | | originalRecord.reallocationreason = JSON.stringify( |
| | | redistributionInfo |
| | | ); |
| | | originalRecord.redistributionInfo = JSON.stringify( |
| | | redistributionInfo |
| | | ); |
| | | |
| | | // 2. å建æ°çè®°å½ |
| | | const newRecord = { |
| | | ...this.currentRedistributeRecord, |
| | | id: null, // æ°è®°å½ID为空 |
| | | allocationstatus: "0", // æ°è®°å½ç¶æä¸ºæäº¤åé
|
| | | reallocationreason: "", // æ¸
空éåé
åå |
| | | redistributionInfo: null, |
| | | // éç½®ç¸å
³å段ï¼ä½ä¿çå¨å®ä¿¡æ¯ |
| | | caseno: "", |
| | | applicanttime: "", |
| | | organgettime: "", |
| | | name: "", |
| | | transplanthospitalno: "", |
| | | transplantHospitalName: "" |
| | | }; |
| | | |
| | | // 3. 卿°ç»ä¸æå
¥æ°è®°å½ï¼å¨æ§è®°å½ä¹åï¼ |
| | | this.allocationData.serviceDonateorganList.splice( |
| | | currentIndex + 1, |
| | | 0, |
| | | newRecord |
| | | ); |
| | | // 4. æ´æ°åè®°å½ |
| | | this.allocationData.serviceDonateorganList[ |
| | | currentIndex |
| | | ] = originalRecord; |
| | | |
| | | // 5. æ´æ°éä¸çå¨å®å表 |
| | | this.selectedOrgans.push(this.currentRedistributeRecord.organno); |
| | | |
| | | this.$message.success("éåé
æä½æå宿"); |
| | | this.redistributionDialogVisible = false; |
| | | } else { |
| | | this.$message.error("æªæ¾å°å¯¹åºçè®°å½"); |
| | | } |
| | | } catch (error) { |
| | | console.error("éåé
æä½å¤±è´¥:", error); |
| | | this.$message.error("éåé
æä½å¤±è´¥"); |
| | | } finally { |
| | | this.redistributionLoading = false; |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // å¨å®è¡æ ·å¼ |
| | | getOrganRowClassName({ row }) { |
| | | if ( |
| | | if (row.allocationstatus == "3") { |
| | | return "redistributed-row"; // éåé
è®°å½æ ·å¼ |
| | | } else if ( |
| | | !row.caseno || |
| | | !row.applicanttime || |
| | | !row.organgettime || |
| | | !row.name || |
| | | !row.transplanthospitalno |
| | | ) { |
| | | return "warning-row"; |
| | | return "warning-row"; // ä¿¡æ¯ä¸å®æ´æ ·å¼ |
| | | } else if (row.allocationstatus == "0") { |
| | | return "pending-row"; // å¾
å®¡æ ¸æ ·å¼ |
| | | } |
| | | return ""; |
| | | }, |
| | | |
| | | // æå»º filePatch åæ®µ |
| | | buildFilePatch() { |
| | | if (!this.attachments || this.attachments.length == 0) { |
| | |
| | | } |
| | | return JSON.stringify(this.attachments); |
| | | }, |
| | | |
| | | // ä¿ååºæ¬ä¿¡æ¯ |
| | | async handleSave() { |
| | | this.$refs.form.validate(async valid => { |
| | |
| | | serviceDonateorganList: |
| | | this.allocationData.serviceDonateorganList || [] |
| | | }; |
| | | if ( |
| | | submitData.allocationStatus == 1 || |
| | | !submitData.allocationStatus |
| | | ) { |
| | | submitData.allocationStatus = 2; |
| | | } |
| | | saveData.fileName = this.buildFilePatch(); |
| | | |
| | | // ç¡®ä¿æ¯æ¡è®°å½é½æåé
ç¶æ |
| | | saveData.serviceDonateorganList.forEach(item => { |
| | | item.baseid = this.form.id; |
| | | item.infoid = this.form.infoid; |
| | | // ç¡®ä¿æåé
ç¶æåæ®µ |
| | | if (!item.allocationstatus) { |
| | | item.allocationstatus = "0"; |
| | | } |
| | | // 妿æ¯éåé
è®°å½ï¼ç¡®ä¿æéåé
ä¿¡æ¯ |
| | | if (item.allocationstatus == "3" && !item.reallocationreason) { |
| | | item.reallocationreason = item.redistributionInfo || ""; |
| | | } |
| | | }); |
| | | |
| | | if (saveData.allocationStatus == 1 || !saveData.allocationStatus) { |
| | | saveData.allocationStatus = 2; |
| | | } |
| | | saveData.fileName = this.buildFilePatch(); |
| | | |
| | | const apiMethod = this.form.id ? allocationedit : allocationadd; |
| | | const response = await apiMethod(saveData); |
| | | |
| | |
| | | this.$message.success("ä¿åæå"); |
| | | 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 || "æªç¥é误")); |
| | |
| | | } |
| | | }); |
| | | }, |
| | | // ä¿ååé
è®°å½ |
| | | async handleSaveAllocation() { |
| | | if (!this.form.id) { |
| | | this.$message.warning("请å
ä¿ååºæ¬ä¿¡æ¯"); |
| | | return; |
| | | } |
| | | |
| | | this.saveLoading = true; |
| | | try { |
| | | const saveData = { |
| | | ...this.form, |
| | | attachments: this.attachments, |
| | | serviceDonateorganList: |
| | | this.allocationData.serviceDonateorganList || [] |
| | | }; |
| | | |
| | | const response = await allocationedit(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; |
| | | } |
| | | }, |
| | | // ç¡®è®¤å®æåé
|
| | | async handleConfirmAllocation() { |
| | | if (this.incompleteRecords > 0) { |
| | |
| | | /** éä»¶ååå¤ç */ |
| | | handleAttachmentChange(fileList) { |
| | | this.attachmentFileList = fileList; |
| | | }, |
| | | handleRedistributionChange(fileList) { |
| | | this.redistributionAttachmentList = fileList; |
| | | }, |
| | | |
| | | /** éä»¶ç§»é¤å¤ç */ |
| | |
| | | fileUrl: file.path || file.fileUrl, |
| | | fileType: this.getFileType(file.fileName) |
| | | }; |
| | | // this.filePreviewTitle = file.fileName; |
| | | this.filePreviewVisible = true; |
| | | }, |
| | | |
| | | handleDownloadAttachment(file) { |
| | | const fileUrl = file.path || file.fileUrl; |
| | | const fileName = file.fileName; |
| | |
| | | |
| | | /** è·åæä»¶æ©å±å */ |
| | | getFileExtension(filename) { |
| | | console.log(filename, "filename"); |
| | | |
| | | return filename |
| | | .split(".") |
| | | .pop() |
| | |
| | | font-size: 20px; |
| | | font-weight: bold; |
| | | } |
| | | /* å¨styleé¨åæ·»å */ |
| | | .section-title { |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 8px; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .section-content { |
| | | background: #f5f7fa; |
| | | padding: 12px; |
| | | border-radius: 4px; |
| | | border-left: 3px solid #e6a23c; |
| | | line-height: 1.6; |
| | | } |
| | | |
| | | .redistribution-attachments { |
| | | margin-top: 10px; |
| | | border: 1px solid #ebeef5; |
| | | border-radius: 4px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | /* éåé
详æ
è¡¨æ ¼æ ·å¼ */ |
| | | :deep(.redistribution-attachments .el-table) { |
| | | border: none; |
| | | } |
| | | |
| | | :deep(.redistribution-attachments .el-table th) { |
| | | background-color: #f5f7fa; |
| | | color: #606266; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | /* ååºå¼è°æ´ */ |
| | | @media (max-width: 768px) { |
| | | .redistribution-attachments { |
| | | overflow-x: auto; |
| | | } |
| | | } |
| | | /* ç©ºç¶ææ ·å¼ */ |
| | | .empty-allocation { |
| | | text-align: center; |
| | |
| | | color: #909399; |
| | | } |
| | | |
| | | /* å¯¹è¯æ¡åºé¨æé® */ |
| | | .dialog-footer { |
| | | margin-top: 20px; |
| | | text-align: center; |
| | | padding-top: 20px; |
| | | border-top: 1px solid #e4e7ed; |
| | | /* æ æ°æ®æ ·å¼ */ |
| | | .no-data { |
| | | color: #909399; |
| | | font-style: italic; |
| | | } |
| | | |
| | | /* è¡¨æ ¼è¡æ ·å¼ */ |
| | | :deep(.redistributed-row) { |
| | | background-color: #fdf6ec; |
| | | opacity: 0.8; |
| | | } |
| | | |
| | | :deep(.redistributed-row:hover) { |
| | | background-color: #faecd8; |
| | | opacity: 0.9; |
| | | } |
| | | |
| | | :deep(.warning-row) { |
| | | background-color: #fff7e6; |
| | | } |
| | |
| | | background-color: #ffecc2; |
| | | } |
| | | |
| | | :deep(.pending-row) { |
| | | background-color: #f0f9ff; |
| | | } |
| | | |
| | | :deep(.pending-row:hover) { |
| | | background-color: #e0f2ff; |
| | | } |
| | | |
| | | /* ç¦ç¨ç¶æçè¾å
¥æ¡æ ·å¼ */ |
| | | :deep(.el-input.is-disabled .el-input__inner) { |
| | | background-color: #f5f7fa; |
| | | border-color: #e4e7ed; |
| | | color: #c0c4cc; |
| | | cursor: not-allowed; |
| | | } |
| | | |
| | | :deep(.el-textarea.is-disabled .el-textarea__inner) { |
| | | background-color: #f5f7fa; |
| | | border-color: #e4e7ed; |
| | | color: #c0c4cc; |
| | | cursor: not-allowed; |
| | | } |
| | | |
| | | /* éåé
æé®æ ·å¼ */ |
| | | :deep(.el-button--text.is-disabled) { |
| | | color: #c0c4cc !important; |
| | | cursor: not-allowed; |
| | | } |
| | | |
| | | /* éåé
ä¿¡æ¯æç¤ºæ¡æ ·å¼ */ |
| | | :deep(.el-tooltip__popper) { |
| | | max-width: 300px; |
| | | white-space: pre-line; |
| | | line-height: 1.6; |
| | | } |
| | | |
| | | /* ååºå¼è®¾è®¡ */ |
| | | @media (max-width: 768px) { |
| | | .organ-allocation-detail { |
| | |
| | | <span class="section-title">å»é¢ä¿¡æ¯</span> |
| | | </div> |
| | | <el-descriptions :column="2" border> |
| | | <el-descriptions-item label="æ²»çå»é¢åç§°">{{ |
| | | <el-descriptions-item label="ICUè¯ä¼°å»ç">{{ |
| | | caseData.icuDoctor || "-" |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="ICUå»ççµè¯">{{ |
| | | caseData.icuDoctorPhone || "-" |
| | | }}</el-descriptions-item |
| | | ><el-descriptions-item label="æ²»çå»é¢åç§°">{{ |
| | | caseData.treatmenthospitalname || "-" |
| | | }}</el-descriptions-item> |
| | | <!-- <el-descriptions-item label="æ²»çç§å®¤åç§°">{{ |
| | |
| | | ></i> |
| | | <span>å»é¢ä¿¡æ¯</span> |
| | | </div> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ICUè¯ä¼°å»ç" prop="icuDoctor"> |
| | | <el-input |
| | | v-model="editForm.icuDoctor" |
| | | placeholder="请è¾å
¥ICUè¯ä¼°å»ç" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ICUå»ççµè¯" prop="icuDoctorPhone"> |
| | | <el-input |
| | | v-model="editForm.icuDoctorPhone" |
| | | placeholder="请è¾å
¥ICUå»çææºå·" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ²»çå»é¢" prop="treatmenthospitalname"> |
| | |
| | | FilePreviewDialog |
| | | }, |
| | | dicts: ["sys_user_sex", "sys_BloodType", "sys_Infectious", "sys_IDType"], |
| | | |
| | | data() { |
| | | const validateConfirmResult = (rule, value, callback) => { |
| | | if (this.approveForm.approveResult === "4" && !value) { |
| | | callback(new Error("驳忶å¿
须填å驳åæè§")); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }; |
| | | return { |
| | | // é®ç½©å± |
| | | loading: false, |
| | |
| | | approveResult: [ |
| | | { required: true, message: "è¯·éæ©ç¡®è®¤ç»æ", trigger: "change" } |
| | | ], |
| | | confirmResult: [ |
| | | { required: true, message: "请è¾å
¥ç¡®è®¤æè§", trigger: "blur" } |
| | | ], |
| | | confirmResult: [{ validator: validateConfirmResult, trigger: "blur" }], |
| | | rejectType: { |
| | | required: false, |
| | | validator: (rule, value, callback) => { |
| | |
| | | } |
| | | return "æè½¬è¿å"; |
| | | } |
| | | return "é转è¿"; |
| | | return "æªç¥"; |
| | | }, |
| | | |
| | | /** 跳转å°å建转è¿åé¡µé¢ */ |
| | |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </el-card> |
| | | <el-card class="detail-card common-info-card"> |
| | | <!-- <el-card class="detail-card common-info-card"> |
| | | <div slot="header" class="clearfix"> |
| | | <span class="detail-title">å
Œ
±ä¿¡æ¯</span> |
| | | </div> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </el-card> |
| | | </el-card> --> |
| | | <!-- èæ»äº¡å¤å®æ¨¡å --> |
| | | <el-card v-if="activeJudgmentType === 'brain'" class="detail-card"> |
| | | <div slot="header" class="clearfix"> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="ä¸æèµ è
å
³ç³»" prop="signfamilyrelations"> |
| | | <el-form-item label="䏿ç®è
å
³ç³»" prop="signfamilyrelations"> |
| | | <el-select |
| | | v-model="form.signfamilyrelations" |
| | | placeholder="è¯·éæ©ä¸æèµ è
å
³ç³»" |
| | | placeholder="è¯·éæ©ä¸æç®è
å
³ç³»" |
| | | > |
| | | <el-option |
| | | v-for="dict in dict.type.sys_FamilyRelation || []" |
| | |
| | | <script> |
| | | import { getToken } from "@/utils/auth"; |
| | | import { |
| | | reviewinitiateBaseInfoList, |
| | | ethicalreviewgetInfoID, |
| | | ethicalreviewedit, |
| | | ethicalreviewadd, |
| | | ethicalreviewInfo, |
| | |
| | | if (id) { |
| | | response = await ethicalreviewInfo(id); |
| | | } else if (infoid) { |
| | | response = await reviewinitiateBaseInfoList({ infoid: infoid }); |
| | | response = await ethicalreviewgetInfoID({ InfoId: infoid }); |
| | | } |
| | | |
| | | if (response.code === 200) { |
| | |
| | | this.$set(this.form, "ethicalreviewopinionsList", []); |
| | | } |
| | | } else if (response.data && infoid) { |
| | | this.form = response.data[0]; |
| | | this.form = response.data; |
| | | // è§£æ filePatch åæ®µ |
| | | this.parseFilePatch(this.form.filePatch); |
| | | this.initAttachmentFileList(); |
| | |
| | | // è·å详æ
|
| | | async getDetail(infoid, id) { |
| | | this.loading = true; |
| | | donateorganBaseinfoInfo(id); |
| | | |
| | | try { |
| | | const response = await allocationList({ infoid }); |
| | | if (response.code == 200 && response.data && response.data.length > 0) { |
| | |
| | | border |
| | | style="width: 100%" |
| | | class="medical-table" |
| | | v-fit-columns |
| | | |
| | | :key="tableKey" |
| | | @header-dragend="handleHeaderDragEnd" |
| | | v-loading="tableLoading" |
| | |
| | | style="width: 100%" |
| | | class="medical-table" |
| | | :key="tableKey" |
| | | v-fit-columns |
| | | |
| | | @header-dragend="handleHeaderDragEnd" |
| | | > |
| | | <el-table-column |
| | |
| | | border |
| | | style="width: 100%" |
| | | class="medical-table" |
| | | v-fit-columns |
| | | |
| | | :key="tableKey" |
| | | @header-dragend="handleHeaderDragEnd" |
| | | v-loading="tableLoading" |
| | |
| | | <div class="donation-process-detail"> |
| | | <el-card class="process-card"> |
| | | <div class="process-container"> |
| | | <!-- 左侧æ¶é´çº¿ - ç¬ç«åºå®ï¼å
é¨å¯æ»å¨ --> |
| | | <!-- 左侧æ¶é´çº¿ --> |
| | | <div class="timeline-section"> |
| | | <div class="section-header"> |
| | | <h3>æç®è¿ç¨æ¶é´çº¿</h3> |
| | | <el-tag :type="getOverallStatusTag(caseInfo.status)"> |
| | | {{ getStatusText(caseInfo.status) }} |
| | | </el-tag> |
| | | </div> |
| | | |
| | | <div class="timeline-scroll-container"> |
| | |
| | | :key="stage.key" |
| | | class="timeline-item" |
| | | :class="{ |
| | | active: activeStage === stage.key, |
| | | completed: stage.status === 'completed', |
| | | 'in-progress': stage.status === 'in_progress', |
| | | pending: stage.status === 'pending' |
| | | active: stage.status == 'active', |
| | | completed: stage.status == 'completed', |
| | | progress: stage.status == 'progress', |
| | | pending: stage.status == 'pending' |
| | | }" |
| | | @click="handleStageClick(stage)" |
| | | > |
| | | <div class="timeline-marker"> |
| | | <i |
| | | v-if="stage.status === 'completed'" |
| | | v-if="stage.status == 'completed'" |
| | | class="el-icon-check" |
| | | ></i> |
| | | <i |
| | | v-else-if="stage.status === 'in_progress'" |
| | | v-else-if="stage.status == 'progress'" |
| | | class="el-icon-loading" |
| | | ></i> |
| | | <i v-else class="el-icon-time"></i> |
| | |
| | | <div class="timeline-content"> |
| | | <div class="stage-header"> |
| | | <span class="stage-name">{{ stage.name }}</span> |
| | | <el-tag |
| | | size="small" |
| | | :type="getStageStatusTag(stage.status)" |
| | | > |
| | | {{ getStageStatusText(stage.status) }} |
| | | </el-tag> |
| | | <dict-tag |
| | | :options="dict.type[stage.dict]" |
| | | :value="stage.state" |
| | | /> |
| | | </div> |
| | | |
| | | <div class="stage-info"> |
| | | <div v-if="stage.completeTime" class="time-info"> |
| | | <span |
| | | >宿æ¶é´: {{ formatTime(stage.completeTime) }}</span |
| | | > |
| | | <div v-if="stage.createtime" class="time-info"> |
| | | å建æ¶é´: {{ formatTime(stage.createtime) }} |
| | | </div> |
| | | <div v-if="stage.updateTime" class="time-info"> |
| | | <span>æè¿æ´æ°: {{ formatTime(stage.updateTime) }}</span> |
| | | æè¿æ´æ°: {{ formatTime(stage.updateTime) }} |
| | | </div> |
| | | <div v-if="stage.operator" class="operator-info"> |
| | | <span>è´è´£äºº: {{ stage.operator }}</span> |
| | | è´è´£äºº: {{ stage.operator }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- å³ä¾§å
容åºå - ç¬ç«æ»å¨ --> |
| | | <!-- å³ä¾§å
容 --> |
| | | <div class="content-section"> |
| | | <!-- æ¡ä¾åºæ¬ä¿¡æ¯ - åºå®é«åº¦ï¼å¯æ»å¨ --> |
| | | <case-basic-info :case-id="caseId" :show-attachment="true" /> |
| | | |
| | | <!-- é¶æ®µè¯¦æ
å
容 - èªéåºé«åº¦ï¼å¯æ»å¨ --> |
| | | <div class="stage-detail-section"> |
| | | <div class="section-header"> |
| | | <h3>{{ activeStageName }} - é¶æ®µè¯¦æ
</h3> |
| | | <div class="stage-actions"></div> |
| | | </div> |
| | | |
| | | <!-- 卿鶿®µå
容 --> |
| | | <div class="stage-content-wrapper"> |
| | | <component |
| | | :is="getStageComponent()" |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | // ===================== åå
¸ Label â UI ä¸»é¢ ===================== |
| | | function mapDictLabelToTheme(label) { |
| | | if (!label) return "pending"; |
| | | |
| | | const l = label.trim(); |
| | | |
| | | // å¾
XX |
| | | if (/^å¾
/.test(l)) { |
| | | return "progress"; |
| | | } |
| | | |
| | | // XXä¸ |
| | | if (/ä¸$/.test(l)) { |
| | | return "active"; |
| | | } |
| | | |
| | | // 宿 / 宿XX |
| | | if (/宿/.test(l)) { |
| | | return "completed"; |
| | | } |
| | | |
| | | // å¼ç¨ / æ¾å¼ |
| | | if (/å¼ç¨|æ¾å¼/.test(l)) { |
| | | return "danger"; |
| | | } |
| | | |
| | | return "pending"; |
| | | } |
| | | import { getDonatebaseinfoflow } from "@/api/project/donatebaseinfo"; |
| | | import { getDonationProcessDetail } from "./donationProcess"; |
| | | import CaseBasicInfo from "@/components/CaseBasicInfo"; |
| | | |
| | | import DonorMaintenanceStage from "./components/DonorMaintenanceStage"; |
| | | import MedicalAssessmentStage from "./components/MedicalAssessmentStage"; |
| | | import DeathJudgmentStage from "./components/DeathJudgmentStage"; |
| | | import MedicalAssessmentStage from "./components/MedicalAssessmentStage"; |
| | | import DonationConfirmStage from "./components/DonationConfirmStage"; |
| | | import EthicalReviewStage from "./components/EthicalReviewStage"; |
| | | import OrganAllocationStage from "./components/OrganAllocationStage"; |
| | | import OrganProcurementStage from "./components/OrganProcurementStage"; |
| | | import OrganUtilizationStage from "./components/OrganUtilizationStage"; |
| | | import CaseBasicInfo from "@/components/CaseBasicInfo"; |
| | | |
| | | import dayjs from "dayjs"; |
| | | |
| | | // ============== åå
¸æ å°ï¼ä½ åé¢èªå·±æ¹ï¼ ============== |
| | | const STAGE_DICT_MAP = { |
| | | donatemaintenance: "maintain_type", |
| | | deathinfo: "decide_type", |
| | | medicalevaluation: "state_Evaluation", |
| | | relativesconfirmation: "affirm_type", |
| | | donateflowcharts: "sys_ethical", |
| | | donateorgansService: "allocation_Status", |
| | | donationwitness: "Obtain_status", |
| | | donatecompletioninfo: "utilize_statue" |
| | | }; |
| | | |
| | | // state -> æµç¨ç¶æ |
| | | const STATE_MAP = { |
| | | 0: "pending", |
| | | 1: "progress", |
| | | 2: "completed", |
| | | 3: "terminated" |
| | | }; |
| | | |
| | | // é¶æ®µé
ç½® |
| | | const STAGE_CONFIG = [ |
| | | { key: "donor_maintenance", name: "ä¾è
ç»´æ¤", apiKey: "donatemaintenance" }, |
| | | { key: "death_judgment", name: "æ»äº¡å¤å®", apiKey: "deathinfo" }, |
| | | { key: "medical_assessment", name: "å»å¦è¯ä¼°", apiKey: "medicalevaluation" }, |
| | | { |
| | | key: "donation_confirm", |
| | | name: "æç®ç¡®è®¤", |
| | | apiKey: "relativesconfirmation" |
| | | }, |
| | | { key: "ethical_review", name: "伦ç审æ¥", apiKey: "donateflowcharts" }, |
| | | { key: "organ_allocation", name: "å¨å®åé
", apiKey: "donateorgansService" }, |
| | | { key: "organ_procurement", name: "å¨å®è·å", apiKey: "donationwitness" }, |
| | | { key: "organ_utilization", name: "å¨å®å©ç¨", apiKey: "donatecompletioninfo" } |
| | | ]; |
| | | |
| | | export default { |
| | | name: "DonationProcessDetail", |
| | | components: { |
| | | CaseBasicInfo, |
| | | DonorMaintenanceStage, |
| | | MedicalAssessmentStage, |
| | | DeathJudgmentStage, |
| | | MedicalAssessmentStage, |
| | | DonationConfirmStage, |
| | | EthicalReviewStage, |
| | | OrganAllocationStage, |
| | | OrganProcurementStage, |
| | | OrganUtilizationStage, |
| | | CaseBasicInfo |
| | | OrganUtilizationStage |
| | | }, |
| | | dicts: ["sys_user_sex", "sys_BloodType", "sys_0_1"], |
| | | dicts: [ |
| | | "decide_type", |
| | | "maintain_type", |
| | | "state_Evaluation", |
| | | "affirm_type", |
| | | "sys_ethical", |
| | | "allocation_Status", |
| | | "Obtain_status", |
| | | "utilize_statue" |
| | | ], // è¿éåªå£°æä¸ä¸ªå³å¯ï¼å
¶ä½éè¿ dict.type[xxx] ä½¿ç¨ |
| | | data() { |
| | | return { |
| | | caseId: null, |
| | | infoid: null, |
| | | caseInfo: { |
| | | id: "", |
| | | caseNo: "", |
| | | hospitalNo: "", |
| | | donorName: "", |
| | | gender: "", |
| | | age: "", |
| | | bloodType: "", |
| | | diagnosis: "", |
| | | status: "in_progress", |
| | | createTime: "", |
| | | registrant: "", |
| | | currentStage: "donor_maintenance" |
| | | }, |
| | | processStages: [ |
| | | { |
| | | key: "donor_maintenance", |
| | | name: "ä¾è
ç»´æ¤", |
| | | status: "completed", |
| | | completeTime: "2025-12-01 10:00:00", |
| | | updateTime: "2025-12-01 10:00:00", |
| | | operator: "å¼ å»ç" |
| | | }, |
| | | { |
| | | key: "death_judgment", |
| | | name: "æ»äº¡å¤å®", |
| | | status: "completed", |
| | | completeTime: "2025-12-02 14:30:00", |
| | | updateTime: "2025-12-02 14:30:00", |
| | | operator: "çå»ç" |
| | | }, |
| | | { |
| | | key: "medical_assessment", |
| | | name: "å»å¦è¯ä¼°", |
| | | status: "completed", |
| | | |
| | | completeTime: "2025-12-03 09:15:00", |
| | | updateTime: "2025-12-03 09:15:00", |
| | | operator: "æä¸»ä»»" |
| | | }, |
| | | { |
| | | key: "donation_confirm", |
| | | name: "æç®ç¡®è®¤", |
| | | status: "completed", |
| | | completeTime: "2025-12-03 11:00:00", |
| | | updateTime: "2025-12-03 11:00:00", |
| | | operator: "èµµåè°å" |
| | | }, |
| | | { |
| | | key: "ethical_review", |
| | | name: "伦ç审æ¥", |
| | | status: "completed", |
| | | completeTime: "2025-12-03 15:20:00", |
| | | updateTime: "2025-12-03 15:20:00", |
| | | operator: "伦çå§åä¼" |
| | | }, |
| | | { |
| | | key: "organ_allocation", |
| | | name: "å¨å®åé
", |
| | | status: "in_progress", |
| | | updateTime: "2025-12-04 10:00:00", |
| | | operator: "åé
ç³»ç»" |
| | | }, |
| | | { |
| | | key: "organ_procurement", |
| | | name: "å¨å®è·å", |
| | | status: "in_progress", |
| | | operator: "å¾
åé
" |
| | | }, |
| | | { |
| | | key: "organ_utilization", |
| | | name: "å¨å®å©ç¨", |
| | | status: "in_progress", |
| | | operator: "å¾
åé
" |
| | | } |
| | | ], |
| | | activeStage: "organ_allocation", |
| | | activeStageName: "å¨å®åé
", |
| | | activeStageData: {}, |
| | | loading: false |
| | | caseInfo: {}, |
| | | processStages: [], |
| | | activeStage: "", |
| | | activeStageName: "", |
| | | activeStageData: {} |
| | | }; |
| | | }, |
| | | computed: {}, |
| | | created() { |
| | | this.caseId = this.$route.query.id; |
| | | this.infoid = this.$route.query.id; |
| | | |
| | | if (this.caseId) { |
| | | this.getDetail(); |
| | | } else { |
| | | this.generateMockData(); |
| | | } |
| | | this.setActiveStage(this.activeStage); |
| | | }, |
| | | methods: { |
| | | async getDetail() { |
| | | try { |
| | | const res = await getDonatebaseinfoflow(this.caseId); |
| | | |
| | | const data = res; |
| | | |
| | | this.caseInfo = data.donatebaseinfo || {}; |
| | | |
| | | this.processStages = STAGE_CONFIG.map(stage => { |
| | | const obj = data[stage.apiKey] || {}; |
| | | console.log(stage.apiKey, "stage.apiKey"); |
| | | console.log(this.dict?.type?.[STAGE_DICT_MAP[stage.apiKey]]); |
| | | |
| | | const dictLabel = |
| | | this.dict?.type?.[STAGE_DICT_MAP[stage.apiKey]]?.find( |
| | | d => d.value == obj.state |
| | | )?.label || ""; |
| | | |
| | | const theme = mapDictLabelToTheme(dictLabel); |
| | | |
| | | return { |
| | | key: stage.key, |
| | | name: stage.name, |
| | | dict: STAGE_DICT_MAP[stage.apiKey], |
| | | state: obj.state, |
| | | dictLabel, |
| | | status: theme, // â
æ ¸å¿ï¼UI 主é¢ç± dictLabel å³å® |
| | | createtime: obj.createtime, |
| | | updateTime: obj.updatetime, |
| | | operator: obj.updateperson || obj.createperson |
| | | }; |
| | | }); |
| | | |
| | | const active = |
| | | this.processStages.find(s => s.status == "progress") || |
| | | [...this.processStages].reverse().find(s => s.status == "completed"); |
| | | |
| | | this.setActiveStage(active?.key || STAGE_CONFIG[0].key); |
| | | } catch (e) { |
| | | console.error(e); |
| | | this.$message.error("è·åæµç¨è¯¦æ
失败"); |
| | | } |
| | | }, |
| | | |
| | | setActiveStage(key) { |
| | | const stage = this.processStages.find(s => s.key == key); |
| | | if (!stage) return; |
| | | this.activeStage = key; |
| | | this.activeStageName = stage.name; |
| | | this.activeStageData = stage; |
| | | }, |
| | | |
| | | getStageComponent() { |
| | | const componentMap = { |
| | | const map = { |
| | | donor_maintenance: "DonorMaintenanceStage", |
| | | death_judgment: "DeathJudgmentStage", |
| | | medical_assessment: "MedicalAssessmentStage", |
| | |
| | | organ_procurement: "OrganProcurementStage", |
| | | organ_utilization: "OrganUtilizationStage" |
| | | }; |
| | | return componentMap[this.activeStage]; |
| | | return map[this.activeStage]; |
| | | }, |
| | | // è·å详æ
æ°æ® |
| | | async getDetail() { |
| | | this.loading = true; |
| | | try { |
| | | const response = await getDonatebaseinfoflow(this.caseId); |
| | | if (response.code === 200) { |
| | | this.caseInfo = response.data.caseInfo; |
| | | this.processStages = response.data.processStages; |
| | | this.setActiveStage(response.data.currentStage); |
| | | } |
| | | } catch (error) { |
| | | console.error("è·åæç®è¿ç¨è¯¦æ
失败:", error); |
| | | this.$message.error("è·å详æ
失败"); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | // çææ¨¡ææ°æ® |
| | | generateMockData() { |
| | | this.caseInfo = { |
| | | id: "202512001", |
| | | caseNo: "C202512001", |
| | | hospitalNo: "D202512001", |
| | | donorName: "å¼ ä¸", |
| | | gender: "0", |
| | | age: 45, |
| | | bloodType: "A", |
| | | diagnosis: "èå¤ä¼¤", |
| | | status: "in_progress", |
| | | createTime: "2025-12-01 08:00:00", |
| | | registrant: "æåè°å", |
| | | currentStage: "organ_allocation" |
| | | }; |
| | | }, |
| | | // 设置å½åæ¿æ´»é¶æ®µ |
| | | setActiveStage(stageKey) { |
| | | this.activeStage = stageKey; |
| | | const stage = this.processStages.find(s => s.key === stageKey); |
| | | if (stage) { |
| | | this.activeStageName = stage.name; |
| | | this.activeStageData = stage; |
| | | console.log(this.activeStageData, "this.activeStageData"); |
| | | } |
| | | }, |
| | | // å¤çé¶æ®µç¹å» |
| | | |
| | | handleStageClick(stage) { |
| | | if (stage.status !== "pending") { |
| | | this.setActiveStage(stage.key); |
| | | } else { |
| | | this.$message.warning("è¯¥é¶æ®µå°æªå¼å§ï¼æ æ³æ¥ç详æ
"); |
| | | if (stage.status == "pending") { |
| | | this.$message.warning("è¯¥é¶æ®µå°æªå¼å§"); |
| | | return; |
| | | } |
| | | this.setActiveStage(stage.key); |
| | | }, |
| | | // è·åé¶æ®µç¶ææ ç¾ç±»å |
| | | getStageStatusTag(status) { |
| | | const map = { |
| | | completed: "success", |
| | | in_progress: "warning", |
| | | pending: "info" |
| | | }; |
| | | return map[status] || "info"; |
| | | }, |
| | | // è·åé¶æ®µç¶æææ¬ |
| | | getStageStatusText(status) { |
| | | const map = { |
| | | completed: "已宿", |
| | | in_progress: "è¿è¡ä¸", |
| | | pending: "æªå¼å§" |
| | | }; |
| | | return map[status] || "æªç¥"; |
| | | }, |
| | | // è·åæ´ä½ç¶ææ ç¾ç±»å |
| | | getOverallStatusTag(status) { |
| | | const map = { |
| | | completed: "success", |
| | | in_progress: "warning", |
| | | pending: "info", |
| | | terminated: "danger" |
| | | }; |
| | | return map[status] || "info"; |
| | | }, |
| | | // è·åæ´ä½ç¶æææ¬ |
| | | getStatusText(status) { |
| | | const map = { |
| | | completed: "已宿", |
| | | in_progress: "è¿è¡ä¸", |
| | | pending: "æªå¼å§", |
| | | terminated: "å·²ç»æ¢" |
| | | }; |
| | | return map[status] || "æªç¥"; |
| | | }, |
| | | // æ¶é´æ ¼å¼å |
| | | |
| | | formatTime(time) { |
| | | if (!time) return "-"; |
| | | return dayjs(time).format("YYYY-MM-DD HH:mm"); |
| | | }, |
| | | |
| | | // è·åå½åé¶æ®µåç§° |
| | | getCurrentStageName() { |
| | | const currentStage = this.processStages.find( |
| | | stage => stage.status === "in_progress" |
| | | ); |
| | | return currentStage ? currentStage.name : "已宿"; |
| | | }, |
| | | // ç¼è¾åºæ¬ä¿¡æ¯ |
| | | handleEditBasicInfo() { |
| | | this.$message.info("ç¼è¾åºæ¬ä¿¡æ¯åè½"); |
| | | }, |
| | | // 宿鶿®µ |
| | | handleCompleteStage() { |
| | | this.$confirm(`ç¡®å®è¦å®æã${this.activeStageName}ãé¶æ®µåï¼`, "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }).then(() => { |
| | | // æ´æ°å½åé¶æ®µç¶æ |
| | | const currentIndex = this.processStages.findIndex( |
| | | stage => stage.key === this.activeStage |
| | | ); |
| | | |
| | | if (currentIndex !== -1) { |
| | | this.processStages[currentIndex].status = "completed"; |
| | | this.processStages[ |
| | | currentIndex |
| | | ].completeTime = new Date().toISOString(); |
| | | |
| | | // æ¿æ´»ä¸ä¸ä¸ªé¶æ®µ |
| | | if (currentIndex < this.processStages.length - 1) { |
| | | this.processStages[currentIndex + 1].status = "in_progress"; |
| | | this.setActiveStage(this.processStages[currentIndex + 1].key); |
| | | } else { |
| | | this.caseInfo.status = "completed"; |
| | | } |
| | | |
| | | this.$message.success("é¶æ®µå·²å®æ"); |
| | | } |
| | | }); |
| | | }, |
| | | // æ¥ç详æ
|
| | | handleViewDetail() { |
| | | const routeMap = { |
| | | donor_maintenance: "/case/donorMaintenance/detail", |
| | | death_judgment: "/case/deathJudgment/detail", |
| | | medical_assessment: "/case/medicalAssessment/detail", |
| | | donation_confirm: "/case/donationConfirm/detail", |
| | | ethical_review: "/case/ethicalReview/detail", |
| | | organ_allocation: "/case/organAllocation/detail", |
| | | organ_procurement: "/case/organProcurement/detail", |
| | | organ_utilization: "/case/organUtilization/detail" |
| | | }; |
| | | |
| | | const route = routeMap[this.activeStage]; |
| | | if (route) { |
| | | this.$router.push({ |
| | | path: route, |
| | | query: { id: this.caseId } |
| | | }); |
| | | } |
| | | }, |
| | | // ä¿®æ¹é¶æ®µä¿¡æ¯ |
| | | handleModifyStage() { |
| | | this.$message.info(`ä¿®æ¹${this.activeStageName}ä¿¡æ¯åè½`); |
| | | return time ? dayjs(time).format("YYYY-MM-DD HH:mm") : "-"; |
| | | } |
| | | } |
| | | }; |
| | |
| | | |
| | | .process-container { |
| | | display: flex; |
| | | min-height: 600px; /* 设置ä¸ä¸ªæå°é«åº¦ */ |
| | | min-height: 600px; |
| | | /* 设置ä¸ä¸ªæå°é«åº¦ */ |
| | | gap: 20px; |
| | | align-items: flex-start; /* é¡¶é¨å¯¹é½ */ |
| | | align-items: flex-start; |
| | | /* é¡¶é¨å¯¹é½ */ |
| | | } |
| | | |
| | | /* 左侧æ¶é´çº¿æ ·å¼ - åºå®é«åº¦ï¼å
鍿»å¨ */ |
| | | .timeline-section { |
| | | flex: 0 0 320px; /* åºå®å®½åº¦ */ |
| | | flex: 0 0 320px; |
| | | /* åºå®å®½åº¦ */ |
| | | display: flex; |
| | | flex-direction: column; |
| | | background: white; |
| | | border-radius: 6px; |
| | | padding: 20px; |
| | | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1); |
| | | height: calc(120vh - 120px); /* æ ¹æ®è§å£é«åº¦èªéåº */ |
| | | max-height: 1200px; /* 设置æå¤§é«åº¦ */ |
| | | position: sticky; /* ä½¿ç¨ sticky å®ä½ */ |
| | | top: 20px; /* è·ç¦»é¡¶é¨ 20px */ |
| | | height: calc(120vh - 120px); |
| | | /* æ ¹æ®è§å£é«åº¦èªéåº */ |
| | | max-height: 1200px; |
| | | /* 设置æå¤§é«åº¦ */ |
| | | position: sticky; |
| | | /* ä½¿ç¨ sticky å®ä½ */ |
| | | top: 20px; |
| | | /* è·ç¦»é¡¶é¨ 20px */ |
| | | } |
| | | |
| | | .timeline-scroll-container { |
| | | flex: 1; |
| | | overflow-y: auto; /* å
é¨å¯æ»å¨ */ |
| | | overflow-y: auto; |
| | | /* å
é¨å¯æ»å¨ */ |
| | | margin-top: 20px; |
| | | padding-right: 8px; /* 为æ»å¨æ¡çåºç©ºé´ */ |
| | | padding-right: 8px; |
| | | /* 为æ»å¨æ¡çåºç©ºé´ */ |
| | | } |
| | | |
| | | .timeline-scroll-container::-webkit-scrollbar { |
| | |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20px; |
| | | min-height: 0; /* éè¦ï¼å
许flexå项å缩 */ |
| | | min-height: 0; |
| | | /* éè¦ï¼å
许flexå项å缩 */ |
| | | } |
| | | |
| | | .basic-info-section { |
| | |
| | | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1); |
| | | display: flex; |
| | | flex-direction: column; |
| | | min-height: 0; /* éè¦ */ |
| | | min-height: 0; |
| | | /* éè¦ */ |
| | | } |
| | | |
| | | .basic-info-content { |
| | | flex: 1; |
| | | max-height: 300px; /* åºæ¬ä¿¡æ¯åºåæå¤§é«åº¦ */ |
| | | overflow-y: auto; /* åºæ¬ä¿¡æ¯å
é¨å¯æ»å¨ */ |
| | | max-height: 300px; |
| | | /* åºæ¬ä¿¡æ¯åºåæå¤§é«åº¦ */ |
| | | overflow-y: auto; |
| | | /* åºæ¬ä¿¡æ¯å
é¨å¯æ»å¨ */ |
| | | margin-top: 20px; |
| | | padding-right: 8px; |
| | | } |
| | |
| | | } |
| | | |
| | | .stage-detail-section { |
| | | flex: 1; /* å æ®å©ä½ç©ºé´ */ |
| | | flex: 1; |
| | | /* å æ®å©ä½ç©ºé´ */ |
| | | background: white; |
| | | border-radius: 6px; |
| | | padding: 20px; |
| | | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1); |
| | | display: flex; |
| | | flex-direction: column; |
| | | min-height: 400px; /* æå°é«åº¦ */ |
| | | max-height: 800px; /* æå¤§é«åº¦ï¼å¯æ ¹æ®éè¦è°æ´ */ |
| | | overflow: hidden; /* éèå¤å±æº¢åº */ |
| | | min-height: 400px; |
| | | /* æå°é«åº¦ */ |
| | | max-height: 800px; |
| | | /* æå¤§é«åº¦ï¼å¯æ ¹æ®éè¦è°æ´ */ |
| | | overflow: hidden; |
| | | /* éèå¤å±æº¢åº */ |
| | | } |
| | | |
| | | .stage-content-wrapper { |
| | | flex: 1; |
| | | overflow-y: auto; /* é¶æ®µè¯¦æ
å
é¨å¯æ»å¨ */ |
| | | overflow-y: auto; |
| | | /* é¶æ®µè¯¦æ
å
é¨å¯æ»å¨ */ |
| | | margin-top: 20px; |
| | | padding-right: 8px; |
| | | min-height: 0; /* éè¦ */ |
| | | min-height: 0; |
| | | /* éè¦ */ |
| | | } |
| | | |
| | | .stage-content-wrapper::-webkit-scrollbar { |
| | |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | flex-shrink: 0; /* 鲿¢è¢«å缩 */ |
| | | flex-shrink: 0; |
| | | /* 鲿¢è¢«å缩 */ |
| | | } |
| | | |
| | | .section-header h3 { |
| | |
| | | cursor: pointer; |
| | | transition: all 0.3s ease; |
| | | border: 1px solid #e4e7ed; |
| | | flex-shrink: 0; /* 鲿¢è¢«å缩 */ |
| | | flex-shrink: 0; |
| | | /* 鲿¢è¢«å缩 */ |
| | | } |
| | | |
| | | .timeline-item:hover { |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | transform: translateY(-1px); |
| | | } |
| | | .timeline-item.danger { |
| | | border-color: #f56c6c; |
| | | background-color: #fef0f0; |
| | | } |
| | | |
| | | .timeline-item.danger .timeline-marker { |
| | | background-color: #f56c6c; |
| | | } |
| | | .timeline-item.active { |
| | | border-color: #409eff; |
| | | background-color: #f0f9ff; |
| | |
| | | background-color: #f0f9e8; |
| | | } |
| | | |
| | | .timeline-item.in-progress { |
| | | .timeline-item.progress { |
| | | border-color: #e6a23c; |
| | | background-color: #fdf6ec; |
| | | } |
| | |
| | | .timeline-item.completed .timeline-marker { |
| | | background-color: #67c23a; |
| | | } |
| | | .timeline-item.active .timeline-marker { |
| | | background-color: #409eff; |
| | | } |
| | | |
| | | .timeline-item.in-progress .timeline-marker { |
| | | .timeline-item.progress .timeline-marker { |
| | | background-color: #e6a23c; |
| | | } |
| | | |
| | |
| | | width: 100%; |
| | | height: auto; |
| | | max-height: 300px; |
| | | position: static; /* å°å±å¹åæ¶ sticky */ |
| | | position: static; |
| | | /* å°å±å¹åæ¶ sticky */ |
| | | } |
| | | |
| | | .timeline-scroll-container { |
| | |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </el-card> |
| | | <el-card class="detail-card common-info-card"> |
| | | <!-- <el-card class="detail-card common-info-card"> |
| | | <div slot="header" class="clearfix"> |
| | | <span class="detail-title">å
Œ
±ä¿¡æ¯</span> |
| | | </div> |
| | |
| | | <el-input v-model="form.gainhospitalname" :readonly="!isEdit" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="æ¯å¦é»åç¼
æ" prop="isspendremember"> |
| | | <el-select |
| | | v-model="form.isspendremember" |
| | | :disabled="!isEdit" |
| | | style="width: 100%" |
| | | > |
| | | <el-option label="æ¯" :value="1" /> |
| | | <el-option label="å¦" :value="0" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="æ¢å¤éä½ä»ªå®¹" prop="isrestoreremains"> |
| | | <el-select |
| | | v-model="form.isrestoreremains" |
| | | :disabled="!isEdit" |
| | | style="width: 100%" |
| | | > |
| | | <el-option label="æ¯" :value="1" /> |
| | | <el-option label="å¦" :value="0" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | |
| | | </el-row> |
| | | </el-form> |
| | | </el-card> |
| | | </el-card> --> |
| | | <!-- èæ»äº¡å¤å®æ¨¡å --> |
| | | <el-card v-if="activeJudgmentType === 'brain'" class="detail-card"> |
| | | <div slot="header" class="clearfix"> |
| | |
| | | <template slot-scope="scope"> |
| | | <el-tag |
| | | v-if="scope.row.deathreason" |
| | | :type="getDeathReasonTagType(scope.row.deathreason)" |
| | | type="danger" |
| | | > |
| | | {{ getDeathReasonText(scope.row.deathreason) }} |
| | | {{ scope.row.deathreason }} |
| | | </el-tag> |
| | | <span v-else>-</span> |
| | | </template> |
| | |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-tag v-if="scope.row.heartdeathreason" type="danger"> |
| | | {{ getHeartDeathReasonText(scope.row.heartdeathreason) }} |
| | | {{ scope.row.heartdeathreason }} |
| | | </el-tag> |
| | | <span v-else>-</span> |
| | | </template> |
| | |
| | | <el-input v-model="form.initiatePerson" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <!-- <el-col :span="8"> |
| | | <el-form-item label="审æ¥ç¶æ" prop="status"> |
| | | <el-select v-model="form.status" style="width: 100%"> |
| | | <el-option |
| | |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-col> --> |
| | | </el-row> |
| | | |
| | | <!-- ä¸å®¶ç¸å
³ä¿¡æ¯ --> |
| | |
| | | <div slot="header" class="clearfix"> |
| | | <span class="detail-title">ä¸å®¶å®¡æ¥æ
åµ</span> |
| | | <div style="float: right;"> |
| | | <el-button |
| | | type="warning" |
| | | size="mini" |
| | | @click="handleRefresh" |
| | | icon="el-icon-refresh" |
| | | > |
| | | å·æ° |
| | | </el-button> |
| | | <el-button size="mini" type="primary" @click="handleAddExpert"> |
| | | æ·»å ä¸å®¶ |
| | | </el-button> |
| | |
| | | <span v-else class="no-data">-</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <!-- å¨"å®¡æ¥æ¶é´"åå颿·»å "æç¾éä»¶"å --> |
| | | <el-table-column label="æç¾éä»¶" width="120" align="center"> |
| | | <template slot-scope="scope"> |
| | | <template v-if="scope.row.sigin"> |
| | | <!-- æç¾åï¼æ¾ç¤ºå¯ç¹å»é¢è§çå¾ç --> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handlePreviewSignature(scope.row.sigin)" |
| | | class="signature-preview-btn" |
| | | > |
| | | <i class="el-icon-picture" style="margin-right: 4px;"></i> |
| | | æ¥çç¾å |
| | | </el-button> |
| | | </template> |
| | | <template v-else> |
| | | <!-- æ ç¾åï¼æ¾ç¤ºææ --> |
| | | <span class="no-signature">/</span> |
| | | </template> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å®¡æ¥æè§" min-width="200" show-overflow-tooltip> |
| | | <template slot-scope="scope"> |
| | | <span :class="{ 'expert-opinion': scope.row.expertopinion }"> |
| | |
| | | <el-dialog |
| | | title="æ·»å ä¸å®¶" |
| | | :visible.sync="expertDialogVisible" |
| | | width="800px" |
| | | width="900px" |
| | | @close="handleExpertDialogClose" |
| | | > |
| | | <div style="margin-bottom: 20px;"> |
| | |
| | | :data="filteredExpertList" |
| | | v-loading="expertListLoading" |
| | | style="width: 100%" |
| | | max-height="400" |
| | | max-height="600" |
| | | @selection-change="handleExpertSelectionChange" |
| | | > |
| | | <el-table-column type="selection" width="55"></el-table-column> |
| | |
| | | ></el-table-column> |
| | | <el-table-column |
| | | label="èç³»çµè¯" |
| | | prop="telephone" |
| | | prop="donorno" |
| | | width="120" |
| | | ></el-table-column> |
| | | </el-table> |
| | |
| | | placeholder="è¯·éæ©æªæ¢æ¶é´" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | style="width: 100%" |
| | | :disabled="sendForm.expertType === 'chief'" |
| | | :disabled="sendForm.expertType == 'chief'" |
| | | /> |
| | | <div v-if="sendForm.expertType !== 'chief'" style="margin-top: 5px;"> |
| | | <el-button-group> |
| | |
| | | </el-button-group> |
| | | </div> |
| | | <div |
| | | v-if="sendForm.expertType === 'chief'" |
| | | v-if="sendForm.expertType == 'chief'" |
| | | style="font-size: 12px; color: #999; margin-top: 5px;" |
| | | > |
| | | 主å§ä¸å®¶æ éè®¾ç½®æªæ¢æ¶é´ |
| | |
| | | </el-form> |
| | | <div slot="footer"> |
| | | <el-button @click="sendDialogVisible = false">åæ¶</el-button> |
| | | <el-button type="primary" @click="handleSendConfirm" :loading="sending" |
| | | >确认åé</el-button |
| | | <el-button |
| | | type="primary" |
| | | @click="handleSendConfirm" |
| | | :loading="sendingAll" |
| | | :disabled="sendingAll" |
| | | > |
| | | {{ |
| | | sendingAll |
| | | ? `åéä¸ (${sendingProgress}/${sendingTotal})` |
| | | : "确认åé" |
| | | }} |
| | | </el-button> |
| | | </div> |
| | | </el-dialog> |
| | | |
| | | <!-- æè
å¨é¡µé¢ä¸æ·»å è¿åº¦æ¡ --> |
| | | <div v-if="sendingAll" class="send-progress-container"> |
| | | <el-progress |
| | | :percentage="Math.round((sendingProgress / sendingTotal) * 100)" |
| | | :text-inside="true" |
| | | :stroke-width="20" |
| | | status="success" |
| | | > |
| | | <span>å·²åé {{ sendingProgress }} / {{ sendingTotal }}</span> |
| | | </el-progress> |
| | | <div class="send-stats"> |
| | | <span class="stat-item success">æå: {{ sendingSuccessCount }}</span> |
| | | <span class="stat-item fail">失败: {{ sendingFailCount }}</span> |
| | | </div> |
| | | </div> |
| | | <!-- ä¸å®¶åå²å®¡æ¹æ
åµå¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | title="ä¸å®¶åå²å®¡æ¹æ
åµ" |
| | |
| | | ethicalreviewadd, |
| | | ethicalreviewInfo, |
| | | ethicalreExpertTotal, |
| | | sendNotification |
| | | sendNotification, |
| | | sendcall |
| | | } from "@/api/businessApi"; |
| | | import { listExternalperson } from "@/api/project/externalperson"; |
| | | import CaseBasicInfo from "@/components/CaseBasicInfo"; |
| | |
| | | { max: 500, message: "é¿åº¦ä¸è½è¶
è¿ 500 个å符", trigger: "blur" } |
| | | ] |
| | | }, |
| | | |
| | | sending: false, // å个åéç¶æ |
| | | sendingAll: false, // å
¨å±åéç¶æ |
| | | sendingProgress: 0, // åéè¿åº¦ |
| | | sendingTotal: 0, // æ»åéæ° |
| | | sendingSuccessCount: 0, // æåæ° |
| | | sendingFailCount: 0, // å¤±è´¥æ° |
| | | sendingResults: [], // åéç»æå表 |
| | | originalFormData: null, // åå§è¡¨åæ°æ® |
| | | originalExpertList: null, // åå§ä¸å®¶å表 |
| | | originalAttachments: null, // åå§éä»¶å表 |
| | | isDataLoaded: false, // æ°æ®æ¯å¦å·²å è½½ |
| | | // ä¿åå è½½ç¶æ |
| | | saveLoading: false, |
| | | completeLoading: false, |
| | |
| | | // 计ç®å±æ§ï¼æ®éä¸å®¶æ°é |
| | | normalExpertsCount() { |
| | | return this.ethicalreviewopinionsList.filter( |
| | | expert => expert.expertType === "0" |
| | | expert => expert.expertType == "0" |
| | | ).length; |
| | | }, |
| | | |
| | | // 计ç®å±æ§ï¼ä¸»å§ä¸å®¶æ°é |
| | | chiefExpertsCount() { |
| | | return this.ethicalreviewopinionsList.filter( |
| | | expert => expert.expertType === "1" |
| | | expert => expert.expertType == "1" |
| | | ).length; |
| | | }, |
| | | |
| | |
| | | // 计ç®å±æ§ï¼å·²åæä¸å®¶æ°é |
| | | approvedExpertsCount() { |
| | | return this.ethicalreviewopinionsList.filter( |
| | | expert => expert.expertconclusion === "1" |
| | | expert => expert.expertconclusion == "1" |
| | | ).length; |
| | | }, |
| | | |
| | |
| | | const total = this.totalExpertsCount; |
| | | const approved = this.approvedExpertsCount; |
| | | |
| | | if (total === 0) return "æªå®¡æ¥"; |
| | | if (total == 0) return "æªå®¡æ¥"; |
| | | if (approved >= Math.ceil(total * 0.7)) { |
| | | // è¶
è¿70%åæ |
| | | return "éè¿"; |
| | |
| | | const total = this.totalExpertsCount; |
| | | const approved = this.approvedExpertsCount; |
| | | |
| | | if (total === 0) return "info"; |
| | | if (total == 0) return "info"; |
| | | if (approved >= Math.ceil(total * 0.7)) { |
| | | return "success"; |
| | | } else if (approved >= Math.ceil(total * 0.5)) { |
| | |
| | | availableNormalExperts() { |
| | | return this.ethicalreviewopinionsList.filter( |
| | | expert => |
| | | expert.expertType === "0" && |
| | | expert.expertType == "0" && |
| | | (!expert.receiveStatus || |
| | | expert.receiveStatus === "0" || |
| | | expert.receiveStatus === "1") |
| | | expert.receiveStatus == "0" || |
| | | expert.receiveStatus == "1") |
| | | ); |
| | | }, |
| | | |
| | |
| | | availableChiefExperts() { |
| | | return this.ethicalreviewopinionsList.filter( |
| | | expert => |
| | | expert.expertType === "1" && |
| | | expert.expertType == "1" && |
| | | (!expert.receiveStatus || |
| | | expert.receiveStatus === "0" || |
| | | expert.receiveStatus === "1") |
| | | expert.receiveStatus == "0" || |
| | | expert.receiveStatus == "1") |
| | | ); |
| | | }, |
| | | |
| | |
| | | // æ¯å¦å¯ä»¥åéç»ä¸»å§ä¸å®¶ï¼éè¦è³å°12个æ®éä¸å®¶åæï¼ |
| | | canSendToChiefExpert() { |
| | | const normalApprovedCount = this.ethicalreviewopinionsList.filter( |
| | | expert => expert.expertType === "0" && expert.expertconclusion === "1" |
| | | expert => expert.expertType == "0" && expert.expertconclusion == "1" |
| | | ).length; |
| | | return this.availableChiefExperts.length > 0 && normalApprovedCount >= 12; |
| | | }, |
| | |
| | | |
| | | // åéå¯¹è¯æ¡æ é¢ |
| | | sendDialogTitle() { |
| | | if (this.sendForm.expertType === "chief") { |
| | | if (this.sendForm.expertType == "chief") { |
| | | return "åé主å§ä¸å®¶å®¡æ¥"; |
| | | } else if (this.sendForm.expertType === "normal") { |
| | | } else if (this.sendForm.expertType == "normal") { |
| | | return "åéæ®éä¸å®¶å®¡æ¥"; |
| | | } else { |
| | | return "åéä¸å®¶å®¡æ¥"; |
| | |
| | | this.id = this.$route.query.id; |
| | | this.caseId = this.$route.query.infoid; |
| | | this.getDetail(this.infoid, this.id); |
| | | // çå¬è·¯ç±ååï¼é²æ¢ç¨æ·ç¦»å¼é¡µé¢ |
| | | window.addEventListener("beforeunload", this.beforeUnloadHandler); |
| | | }, |
| | | beforeDestroy() { |
| | | // ç§»é¤äºä»¶çå¬å¨ |
| | | window.removeEventListener("beforeunload", this.beforeUnloadHandler); |
| | | }, |
| | | methods: { |
| | | // åå§åæ°å¢æ°æ® |
| | |
| | | response = await reviewinitiateBaseInfoList({ infoid: infoid }); |
| | | } |
| | | |
| | | if (response.code === 200) { |
| | | if (response.code == 200) { |
| | | let detailData = {}; |
| | | |
| | | if (response.data && id) { |
| | |
| | | this.parseFilePatch(this.form.filePatch); |
| | | this.initAttachmentFileList(); |
| | | |
| | | // 妿ä¸å®¶å®¡æ¥æè§å表ä¸åå¨ï¼åå§å为空æ°ç» |
| | | if (!this.form.ethicalreviewopinionsList) { |
| | | this.$set(this.form, "ethicalreviewopinionsList", []); |
| | | } |
| | | } else if (response.data && infoid) { |
| | | this.form = response.data[0]; |
| | | // è§£æ filePatch åæ®µ |
| | | this.parseFilePatch(this.form.filePatch); |
| | | this.initAttachmentFileList(); |
| | | |
| | | // 妿ä¸å®¶å®¡æ¥æè§å表ä¸åå¨ï¼åå§å为空æ°ç» |
| | | if (!this.form.ethicalreviewopinionsList) { |
| | | this.$set(this.form, "ethicalreviewopinionsList", []); |
| | | } |
| | | } |
| | | |
| | | // 设置 expertReviews ç¨äºè¡¨æ ¼æ¾ç¤º |
| | | // ä¿ååå§æ°æ®ç¨äºæ¯è¾ |
| | | this.saveOriginalData(); |
| | | |
| | | this.expertReviews = this.form.ethicalreviewopinionsList; |
| | | this.isDataLoaded = true; |
| | | |
| | | this.$message.success("æ°æ®å è½½æå"); |
| | | } else { |
| | |
| | | } finally { |
| | | this.expertLoading = false; |
| | | } |
| | | }, |
| | | |
| | | // ä¿ååå§æ°æ® |
| | | saveOriginalData() { |
| | | // æ·±æ·è´è¡¨åæ°æ® |
| | | this.originalFormData = JSON.parse(JSON.stringify(this.form)); |
| | | |
| | | // æ·±æ·è´ä¸å®¶å表 |
| | | this.originalExpertList = this.form.ethicalreviewopinionsList |
| | | ? JSON.parse(JSON.stringify(this.form.ethicalreviewopinionsList)) |
| | | : []; |
| | | |
| | | // æ·±æ·è´éä»¶å表 |
| | | this.originalAttachments = this.form.annexfilesList |
| | | ? JSON.parse(JSON.stringify(this.form.annexfilesList)) |
| | | : []; |
| | | }, |
| | | |
| | | // è§£æ filePatch åæ®µ |
| | |
| | | |
| | | // æå»º filePatch åæ®µ |
| | | buildFilePatch() { |
| | | if (!this.form.annexfilesList || this.form.annexfilesList.length === 0) { |
| | | if (!this.form.annexfilesList || this.form.annexfilesList.length == 0) { |
| | | return ""; |
| | | } |
| | | return JSON.stringify(this.form.annexfilesList); |
| | |
| | | handleAttachmentRemove(file) { |
| | | if (file.url) { |
| | | const index = this.form.annexfilesList.findIndex( |
| | | item => item.path === file.url || item.fileUrl === file.url |
| | | item => item.path == file.url || item.fileUrl == file.url |
| | | ); |
| | | if (index > -1) { |
| | | this.form.annexfilesList.splice(index, 1); |
| | |
| | | |
| | | // ä¸ä¼ æåå¤ç |
| | | handleUploadSuccess({ file, fileList, response }) { |
| | | if (response.code === 200) { |
| | | if (response.code == 200) { |
| | | const attachmentObj = { |
| | | fileName: file.name, |
| | | path: response.data || file.url, |
| | |
| | | |
| | | // æä»¶é¢è§ |
| | | handlePreview(file) { |
| | | console.log(file, "file"); |
| | | |
| | | this.currentPreviewFile = { |
| | | fileName: file.fileName, |
| | | fileUrl: file.path || file.fileUrl, |
| | | fileType: this.getFileType(file.fileName) |
| | | }; |
| | | this.previewVisible = true; |
| | | }, |
| | | // æä»¶é¢è§ |
| | | handlePreviewSignature(file) { |
| | | console.log(file, "file"); |
| | | |
| | | this.currentPreviewFile = { |
| | | fileName: file, |
| | | fileUrl: file, |
| | | fileType: "png" |
| | | }; |
| | | this.previewVisible = true; |
| | | }, |
| | |
| | | // èç§°å
å«"主任å§å"æè
expertType为"1" |
| | | return ( |
| | | (expert.title && expert.title.includes("主任å§å")) || |
| | | expert.expertType === "1" |
| | | expert.expertType == "1" |
| | | ); |
| | | }, |
| | | |
| | | // ä¸å®¶ç±»åææ¬è½¬æ¢ |
| | | getExpertTypeText(type) { |
| | | return type === "1" ? "主å§ä¸å®¶" : "æ®éä¸å®¶"; |
| | | return type == "1" ? "主å§ä¸å®¶" : "æ®éä¸å®¶"; |
| | | }, |
| | | |
| | | // 审æ¥ç¶æè¿æ»¤å¨ |
| | |
| | | |
| | | // ä¸å®¶è¡æ ·å¼ |
| | | getExpertRowClassName({ row }) { |
| | | return row.expertType === "1" ? "chief-expert-row" : "normal-expert-row"; |
| | | return row.expertType == "1" ? "chief-expert-row" : "normal-expert-row"; |
| | | }, |
| | | |
| | | // è·åä¸å®¶å¯ä¸æ è¯ |
| | |
| | | |
| | | // ä¸å®¶ç±»ååæ´å¤ç |
| | | handleExpertTypeChange() { |
| | | if (this.sendForm.expertType === "chief") { |
| | | if (this.sendForm.expertType == "chief") { |
| | | // 主å§ä¸å®¶æ éè®¾ç½®æªæ¢æ¶é´ |
| | | this.sendForm.endTime = ""; |
| | | } else { |
| | |
| | | if (valid) { |
| | | this.saveLoading = true; |
| | | // ä¿åæ¸
空id便äºå端æ´ä½å 餿°å¢ |
| | | this.form.ethicalreviewopinionsList.forEach(item=>{ |
| | | item.id=null |
| | | }) |
| | | this.form.ethicalreviewopinionsList.forEach(item => { |
| | | item.id = null; |
| | | }); |
| | | try { |
| | | const submitData = { |
| | | ...this.form, |
| | |
| | | response = await ethicalreviewadd(submitData); |
| | | } |
| | | |
| | | if (response.code === 200) { |
| | | if (response.code == 200) { |
| | | this.$message.success("ä¿åæå"); |
| | | // ä¿åæååæ´æ°åå§æ°æ® |
| | | this.saveOriginalData(); |
| | | this.isEdit = false; |
| | | if (!this.form.id && response.data && response.data.id) { |
| | | this.form.id = response.data.id; |
| | |
| | | |
| | | const response = await ethicalreviewedit(updateData); |
| | | |
| | | if (response.code === 200) { |
| | | if (response.code == 200) { |
| | | this.$message.success("审æ¥ç¶æå·²æ´æ°ä¸ºå®æ"); |
| | | this.form.status = "3"; |
| | | this.form.endTime = updateData.endTime; |
| | |
| | | |
| | | const response = await ethicalreviewedit(updateData); |
| | | |
| | | if (response.code === 200) { |
| | | if (response.code == 200) { |
| | | this.$message.success("审æ¥å·²ä¸æ¢ï¼ææä¸å®¶ç¶æå·²æ´æ°"); |
| | | this.form.status = "2"; |
| | | } else { |
| | |
| | | try { |
| | | const updateData = { |
| | | ...this.form, |
| | | status: "2", // 审æ¥ä¸æ¢ |
| | | status: "4", // 审æ¥ä¸æ¢ |
| | | endTime: new Date() |
| | | .toISOString() |
| | | .replace("T", " ") |
| | |
| | | |
| | | const response = await ethicalreviewedit(updateData); |
| | | |
| | | if (response.code === 200) { |
| | | if (response.code == 200) { |
| | | this.$message.success("审æ¥å·²ç»æ"); |
| | | this.form.status = "2"; |
| | | this.form.status = "4"; |
| | | this.form.endTime = updateData.endTime; |
| | | } else { |
| | | this.$message.error("æä½å¤±è´¥ï¼" + (response.msg || "æªç¥é误")); |
| | |
| | | this.expertDialogVisible = true; |
| | | this.loadExperts(); |
| | | }, |
| | | /** |
| | | * å·æ°é¡µé¢æ°æ® |
| | | */ |
| | | async refreshPageData() { |
| | | try { |
| | | // éç½®æ°æ®ç¶æ |
| | | this.isDataLoaded = false; |
| | | |
| | | // æ¸
空å½åæ°æ® |
| | | this.form = { |
| | | id: undefined, |
| | | infoid: undefined, |
| | | caseNo: "", |
| | | initiateTheme: "", |
| | | initiatePerson: "", |
| | | status: "0", |
| | | startTime: "", |
| | | cutOffTime: "", |
| | | endTime: "", |
| | | expertName: "", |
| | | expertNo: "", |
| | | expertType: "0", |
| | | expertConclusion: "", |
| | | expertOpinion: "", |
| | | expertTime: "", |
| | | orderNo: 1, |
| | | remark: "", |
| | | annexfilesList: [], |
| | | filePatch: "", |
| | | ethicalreviewopinionsList: [], |
| | | createBy: "", |
| | | createTime: "", |
| | | updateBy: "", |
| | | updateTime: "", |
| | | delFlag: "0" |
| | | }; |
| | | |
| | | this.attachmentFileList = []; |
| | | this.originalFormData = null; |
| | | this.originalExpertList = null; |
| | | this.originalAttachments = null; |
| | | |
| | | // éæ°è·åæ°æ® |
| | | if (this.id) { |
| | | await this.getDetail(this.infoid, this.id); |
| | | } else if (this.infoid) { |
| | | await this.getDetail(this.infoid, null); |
| | | } else { |
| | | this.$message.warning("æ æ³å·æ°ï¼ç¼ºå°å¿
è¦çåæ°"); |
| | | } |
| | | |
| | | this.$message.success("æ°æ®å·æ°æå"); |
| | | } catch (error) { |
| | | console.error("å·æ°æ°æ®å¤±è´¥:", error); |
| | | this.$message.error("å·æ°æ°æ®å¤±è´¥ï¼è¯·éè¯"); |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * å¤ç页é¢å·æ° |
| | | * æ£æ¥æ¯å¦ææªä¿åæ°æ®ï¼ç¡®è®¤åå·æ°é¡µé¢ |
| | | */ |
| | | handleRefresh() { |
| | | // æ£æ¥æ¯å¦ææªä¿åçç¼è¾ |
| | | if (this.hasUnsavedChanges()) { |
| | | this.$confirm( |
| | | "å½åææªä¿åçæ°æ®ï¼å·æ°é¡µé¢å°ä¸¢å¤±è¿äºæ´æ¹ãæ¯å¦ç»§ç»å·æ°ï¼", |
| | | "è¦å", |
| | | { |
| | | confirmButtonText: "ç»§ç»å·æ°", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | distinguishCancelAndClose: true, |
| | | beforeClose: (action, instance, done) => { |
| | | if (action === "confirm") { |
| | | instance.confirmButtonLoading = true; |
| | | instance.confirmButtonText = "å·æ°ä¸..."; |
| | | |
| | | // å»¶è¿æ§è¡ä»¥ç¡®ä¿UIæ´æ° |
| | | setTimeout(() => { |
| | | done(); |
| | | instance.confirmButtonLoading = false; |
| | | |
| | | // ç¨æ·ç¡®è®¤å·æ° |
| | | this.refreshPageData(); |
| | | }, 300); |
| | | } else { |
| | | this.$message({ |
| | | type: "info", |
| | | message: "已忶巿°" |
| | | }); |
| | | done(); |
| | | } |
| | | } |
| | | } |
| | | ).catch(action => { |
| | | if (action === "cancel") { |
| | | this.$message({ |
| | | type: "info", |
| | | message: "已忶巿°" |
| | | }); |
| | | } |
| | | }); |
| | | } else { |
| | | // æ²¡ææªä¿åçç¼è¾ï¼ç´æ¥å·æ° |
| | | this.refreshPageData(); |
| | | } |
| | | }, |
| | | // æ£æ¥æ¯å¦ææªä¿åçæ°æ®åå |
| | | hasUnsavedChanges() { |
| | | if (!this.isDataLoaded) { |
| | | return false; // æ°æ®æªå è½½ï¼æ éæ£æµ |
| | | } |
| | | |
| | | // 1. æ£æ¥è¡¨ååæ®µåå |
| | | const formFieldsChanged = this.checkFormFieldsChanged(); |
| | | |
| | | // 2. æ£æ¥ä¸å®¶å表åå |
| | | const expertListChanged = this.checkExpertListChanged(); |
| | | |
| | | // 3. æ£æ¥éä»¶å表åå |
| | | const attachmentsChanged = this.checkAttachmentsChanged(); |
| | | |
| | | return formFieldsChanged || expertListChanged || attachmentsChanged; |
| | | }, |
| | | |
| | | // æ£æ¥è¡¨ååæ®µæ¯å¦æåå |
| | | checkFormFieldsChanged() { |
| | | if (!this.originalFormData) return false; |
| | | |
| | | const formKeys = [ |
| | | "initiateTheme", |
| | | "initiatePerson", |
| | | "status", |
| | | "expertConclusion", |
| | | "expertOpinion", |
| | | "expertTime", |
| | | "remark" |
| | | ]; |
| | | |
| | | for (const key of formKeys) { |
| | | if (this.form[key] !== this.originalFormData[key]) { |
| | | console.log( |
| | | `表ååæ®µåå: ${key}`, |
| | | this.form[key], |
| | | this.originalFormData[key] |
| | | ); |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | }, |
| | | |
| | | // æ£æ¥ä¸å®¶å表åå |
| | | checkExpertListChanged() { |
| | | if (!this.originalExpertList || !this.form.ethicalreviewopinionsList) { |
| | | return false; |
| | | } |
| | | |
| | | const original = this.originalExpertList; |
| | | const current = this.form.ethicalreviewopinionsList; |
| | | |
| | | // 1. æ£æ¥æ°éåå |
| | | if (original.length !== current.length) { |
| | | console.log("ä¸å®¶æ°éåå:", original.length, "->", current.length); |
| | | return true; |
| | | } |
| | | |
| | | // 2. æ£æ¥æ¯ä¸ªä¸å®¶çåå |
| | | for (let i = 0; i < original.length; i++) { |
| | | const origExpert = original[i]; |
| | | const currExpert = current[i]; |
| | | |
| | | // æ£æ¥å
³é®å段åå |
| | | const fieldsToCheck = [ |
| | | "expertconclusion", |
| | | "expertopinion", |
| | | "receiveStatus", |
| | | "conclusiontime", |
| | | "startTime", |
| | | "endTime", |
| | | "sendType" |
| | | ]; |
| | | |
| | | for (const field of fieldsToCheck) { |
| | | if (origExpert[field] !== currExpert[field]) { |
| | | console.log( |
| | | `ä¸å®¶${i}ç${field}åæ®µåå:`, |
| | | origExpert[field], |
| | | "->", |
| | | currExpert[field] |
| | | ); |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | }, |
| | | |
| | | // æ£æ¥éä»¶å表åå |
| | | checkAttachmentsChanged() { |
| | | if (!this.originalAttachments || !this.form.annexfilesList) { |
| | | return false; |
| | | } |
| | | |
| | | const original = this.originalAttachments; |
| | | const current = this.form.annexfilesList; |
| | | |
| | | // æ£æ¥æ°éåå |
| | | if (original.length !== current.length) { |
| | | console.log("éä»¶æ°éåå:", original.length, "->", current.length); |
| | | return true; |
| | | } |
| | | |
| | | // æ£æ¥æä»¶åååï¼é常éä»¶ä¸ä¼ä¿®æ¹ï¼åªå¢å ï¼ |
| | | const originalFileNames = original.map(f => f.fileName || f.name).sort(); |
| | | const currentFileNames = current.map(f => f.fileName || f.name).sort(); |
| | | |
| | | for (let i = 0; i < originalFileNames.length; i++) { |
| | | if (originalFileNames[i] !== currentFileNames[i]) { |
| | | console.log( |
| | | "éä»¶æä»¶ååå:", |
| | | originalFileNames[i], |
| | | "->", |
| | | currentFileNames[i] |
| | | ); |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | }, |
| | | |
| | | // æµè§å¨ç¦»å¼é¡µé¢æ£æµ |
| | | beforeUnloadHandler(event) { |
| | | if (this.hasUnsavedChanges()) { |
| | | const message = "æ¨ææªä¿åçæ´æ¹ï¼ç¡®å®è¦ç¦»å¼åï¼"; |
| | | event.returnValue = message; // æ åæ¹å¼ |
| | | return message; // æäºæµè§å¨éè¦è¿åå符串 |
| | | } |
| | | }, |
| | | // å è½½ä¸å®¶å表 |
| | | async loadExperts() { |
| | | try { |
| | | this.expertListLoading = true; |
| | | const params = { |
| | | usertype: "伦çä¸å®¶", // 伦çä¸å®¶ |
| | | usertype: "ethical", // 伦çä¸å®¶ |
| | | pageNum: this.expertPage.pageNum, |
| | | pageSize: this.expertPage.pageSize |
| | | }; |
| | |
| | | } |
| | | |
| | | const response = await listExternalperson(params); |
| | | if (response.code === 200) { |
| | | if (response.code == 200) { |
| | | this.expertList = response.rows || []; |
| | | this.expertTotal = response.total || 0; |
| | | } else { |
| | |
| | | |
| | | // 确认添å ä¸å®¶ |
| | | handleConfirmAddExpert() { |
| | | if (this.selectedExperts.length === 0) { |
| | | if (this.selectedExperts.length == 0) { |
| | | this.$message.warning("è¯·éæ©è¦æ·»å çä¸å®¶"); |
| | | return; |
| | | } |
| | |
| | | expertType: isChief ? "1" : "0", // 主任å§å设置为主å§ä¸å®¶ |
| | | deptName: expert.unitname || "", |
| | | title: expert.title || "", |
| | | deptname: expert.telephone || "", |
| | | donorno: expert.telephone || "", |
| | | receiveStatus: "0", // å¾
æ¥æ¶ |
| | | expertconclusion: "", |
| | | expertopinion: "", |
| | |
| | | // åéç»å个ä¸å®¶ |
| | | handleSendToExpert(expert) { |
| | | this.currentSendExperts = [expert]; |
| | | this.sendForm.expertType = expert.expertType === "1" ? "chief" : "normal"; |
| | | this.sendForm.endTime = expert.expertType === "1" ? "" : ""; // 主å§ä¸å®¶æ éæªæ¢æ¶é´ |
| | | this.sendForm.expertType = expert.expertType == "1" ? "chief" : "normal"; |
| | | this.sendForm.endTime = expert.expertType == "1" ? "" : ""; // 主å§ä¸å®¶æ éæªæ¢æ¶é´ |
| | | this.sendDialogVisible = true; |
| | | }, |
| | | |
| | |
| | | return; |
| | | } |
| | | |
| | | if (this.currentSendExperts.length === 0) { |
| | | if (this.currentSendExperts.length == 0) { |
| | | this.$message.warning("æ²¡ææ¾å°å¯åéçä¸å®¶"); |
| | | return; |
| | | } |
| | | |
| | | this.sending = true; |
| | | // åå§ååéç¶æ |
| | | this.sendingAll = true; |
| | | this.sendingProgress = 0; |
| | | this.sendingTotal = this.currentSendExperts.length; |
| | | this.sendingSuccessCount = 0; |
| | | this.sendingFailCount = 0; |
| | | this.sendingResults = []; |
| | | |
| | | // å建ä¸ä¸ªè¿åº¦å¯¹è¯æ¡ |
| | | const progressDialog = this.$message({ |
| | | type: "info", |
| | | message: `æ£å¨åééç¥ï¼è¯·ç¨å... (0/${this.sendingTotal})`, |
| | | duration: 0, // ä¸ä¼èªå¨å
³é |
| | | showClose: true |
| | | }); |
| | | |
| | | try { |
| | | // åéç»æ¯ä¸ªä¸å®¶ |
| | | const sendPromises = this.currentSendExperts.map(async expert => { |
| | | // 使ç¨Promiseæ°ç»æ¥é¡ºåºæ§è¡åé |
| | | for (let i = 0; i < this.currentSendExperts.length; i++) { |
| | | const expert = this.currentSendExperts[i]; |
| | | |
| | | // æ´æ°è¿åº¦ |
| | | this.sendingProgress = i; |
| | | progressDialog.message = `æ£å¨åééç¥ï¼è¯·ç¨å... (${i}/${this.sendingTotal})`; |
| | | |
| | | try { |
| | | // æå»ºåéæ°æ® |
| | | const sendData = { |
| | | number: expert.deptname || "", // ç¨æ·ææºå· |
| | | title: this.sendForm.title, |
| | | url: this.sendForm.url || "", |
| | | // åéå个ä¸å®¶éç¥ |
| | | const result = await this.sendSingleExpert(expert, i); |
| | | this.sendingResults.push(result); |
| | | |
| | | createTime: new Date() |
| | | .toISOString() |
| | | .replace("T", " ") |
| | | .substring(0, 19) |
| | | }; |
| | | if (result.success) { |
| | | this.sendingSuccessCount++; |
| | | |
| | | // è°ç¨åééç¥æ¥å£ |
| | | const response = await sendNotification(sendData); |
| | | |
| | | if (response.code === 200) { |
| | | // æ´æ°ä¸å®¶ç¶æ |
| | | const index = this.form.ethicalreviewopinionsList.findIndex( |
| | | e => |
| | | e.expertNo === expert.expertNo || |
| | | e.expertname === expert.expertname |
| | | e.expertNo == expert.expertNo || |
| | | e.expertname == expert.expertname |
| | | ); |
| | | |
| | | if (index !== -1) { |
| | | if (index != -1) { |
| | | this.form.ethicalreviewopinionsList[index].receiveStatus = "1"; // å·²æ¥æ¶ |
| | | this.form.ethicalreviewopinionsList[ |
| | | index |
| | |
| | | this.form.ethicalreviewopinionsList[index] |
| | | ); |
| | | } |
| | | |
| | | return { success: true, expert: expert.expertname }; |
| | | } else { |
| | | return { |
| | | success: false, |
| | | expert: expert.expertname, |
| | | error: response.msg |
| | | }; |
| | | this.sendingFailCount++; |
| | | } |
| | | } catch (error) { |
| | | console.error(`åéç»ä¸å®¶ ${expert.expertname} 失败:`, error); |
| | | return { |
| | | this.sendingResults.push({ |
| | | success: false, |
| | | expert: expert.expertname, |
| | | error: error.message |
| | | }; |
| | | }); |
| | | this.sendingFailCount++; |
| | | } |
| | | }); |
| | | |
| | | // çå¾
ææåé宿 |
| | | const results = await Promise.all(sendPromises); |
| | | |
| | | // ç»è®¡åéç»æ |
| | | const successCount = results.filter(r => r.success).length; |
| | | const failCount = results.filter(r => !r.success).length; |
| | | |
| | | if (failCount === 0) { |
| | | this.$message.success(`æååéç» ${successCount} ä½ä¸å®¶`); |
| | | } else if (successCount > 0) { |
| | | this.$message.warning( |
| | | `æååéç» ${successCount} ä½ä¸å®¶ï¼å¤±è´¥ ${failCount} ä½` |
| | | ); |
| | | } else { |
| | | this.$message.error("åé失败ï¼è¯·ç¨åéè¯"); |
| | | // 妿䏿¯æåä¸ä¸ªï¼çå¾
100msååéä¸ä¸ä¸ª |
| | | if (i < this.currentSendExperts.length - 1) { |
| | | await this.sleep(100); |
| | | } |
| | | } |
| | | |
| | | // 宿è¿åº¦ |
| | | this.sendingProgress = this.sendingTotal; |
| | | progressDialog.message = `åéå®æï¼æå ${this.sendingSuccessCount} 个ï¼å¤±è´¥ ${this.sendingFailCount} 个`; |
| | | |
| | | // å»¶è¿1ç§åå
³éè¿åº¦å¯¹è¯æ¡ |
| | | await this.sleep(1000); |
| | | progressDialog.close(); |
| | | |
| | | // æ¾ç¤ºæç»ç»æ |
| | | if (this.sendingFailCount == 0) { |
| | | this.$message.success( |
| | | `æååéç» ${this.sendingSuccessCount} ä½ä¸å®¶` |
| | | ); |
| | | } else if (this.sendingSuccessCount > 0) { |
| | | this.$message.warning( |
| | | `æååéç» ${this.sendingSuccessCount} ä½ä¸å®¶ï¼å¤±è´¥ ${this.sendingFailCount} ä½` |
| | | ); |
| | | // 妿æå¤±è´¥ï¼å¯ä»¥æ¾ç¤ºè¯¦ç»å¤±è´¥ä¿¡æ¯ |
| | | this.showFailedDetails(); |
| | | } else { |
| | | this.$message.error("å
¨é¨åé失败ï¼è¯·ç¨åéè¯"); |
| | | } |
| | | |
| | | // å
³éåéå¯¹è¯æ¡ |
| | | this.sendDialogVisible = false; |
| | | this.sendForm = { |
| | | expertType: "normal", |
| | |
| | | url: "" |
| | | }; |
| | | this.currentSendExperts = []; |
| | | // ä¿åæ´ä¸ªåæ® |
| | | this.handleSave(); |
| | | } catch (error) { |
| | | console.error("åé失败:", error); |
| | | this.$message.error("åé失败ï¼è¯·éè¯"); |
| | | console.error("åéè¿ç¨ä¸åçé误:", error); |
| | | progressDialog.close(); |
| | | this.$message.error("åéè¿ç¨ä¸åçé误ï¼è¯·éè¯"); |
| | | } finally { |
| | | this.sending = false; |
| | | this.sendingAll = false; |
| | | } |
| | | }, |
| | | // åéå个ä¸å®¶çæ¹æ³ |
| | | async sendSingleExpert(expert, index) { |
| | | try { |
| | | // æå»ºåéæ°æ® |
| | | const sendData = { |
| | | number: expert.deptname || "", // ç¨æ·ææºå· |
| | | title: this.sendForm.title, |
| | | url: this.sendForm.url || "", |
| | | createTime: new Date() |
| | | .toISOString() |
| | | .replace("T", " ") |
| | | .substring(0, 19) |
| | | }; |
| | | |
| | | console.log(`æ£å¨åé第 ${index + 1} 个ä¸å®¶: ${expert.expertname}`); |
| | | |
| | | // è°ç¨åééç¥æ¥å£ |
| | | // const response = await sendNotification(sendData); |
| | | const response = await sendcall({ |
| | | tel: expert.donorno ? expert.donorno : 13634195431, // è¿éåºè¯¥æ¯ expert.deptname æ expert.phone |
| | | messageContent: |
| | | "éå²å¤§å¦éå±å»é¢ä¸æ¥æ½å¨æç®æ¡ä¾ï¼è¯·ç»å½OPOç³»ç»æ¥ç详ç»ä¿¡æ¯ï¼åæ¶è¿è¡å¯¹æ¥ãç»å½é¾æ¥:https://brdeddd.qduhosos.cn/dklejdj/deljf/index" |
| | | }); |
| | | |
| | | if (response.code == 200) { |
| | | return { |
| | | success: true, |
| | | expert: expert.expertname, |
| | | index: index |
| | | }; |
| | | } else { |
| | | return { |
| | | success: false, |
| | | expert: expert.expertname, |
| | | index: index, |
| | | error: response.msg |
| | | }; |
| | | } |
| | | } catch (error) { |
| | | console.error(`åéç»ä¸å®¶ ${expert.expertname} 失败:`, error); |
| | | return { |
| | | success: false, |
| | | expert: expert.expertname, |
| | | index: index, |
| | | error: error.message |
| | | }; |
| | | } |
| | | }, |
| | | |
| | | // æ¾ç¤ºå¤±è´¥è¯¦æ
çæ¹æ³ |
| | | showFailedDetails() { |
| | | const failedExperts = this.sendingResults.filter(r => !r.success); |
| | | if (failedExperts.length > 0) { |
| | | this.$confirm( |
| | | `æ ${failedExperts.length} ä½ä¸å®¶åéå¤±è´¥ï¼æ¯å¦æ¥ç失败详æ
ï¼`, |
| | | "åéç»æ", |
| | | { |
| | | confirmButtonText: "æ¥ç详æ
", |
| | | cancelButtonText: "å
³é", |
| | | type: "warning" |
| | | } |
| | | ) |
| | | .then(() => { |
| | | let detailMessage = "åé失败çä¸å®¶ï¼\n\n"; |
| | | failedExperts.forEach((expert, index) => { |
| | | detailMessage += `${index + 1}. ${expert.expert}: ${ |
| | | expert.error |
| | | }\n`; |
| | | }); |
| | | |
| | | this.$alert(detailMessage, "åé失败详æ
", { |
| | | confirmButtonText: "ç¡®å®", |
| | | customClass: "failed-details-dialog" |
| | | }); |
| | | }) |
| | | .catch(() => {}); |
| | | } |
| | | }, |
| | | |
| | | // ç¡ç 彿°ï¼ç¨äºé´é |
| | | sleep(ms) { |
| | | return new Promise(resolve => setTimeout(resolve, ms)); |
| | | }, |
| | | // å é¤ä¸å®¶å®¡æ¥ |
| | | handleDeleteExpertReview(expert, index) { |
| | | this.$confirm("ç¡®å®è¦å é¤è¯¥ä¸å®¶ç审æ¥è®°å½åï¼", "æç¤º", { |
| | |
| | | |
| | | const response = await ethicalreExpertTotal(params); |
| | | |
| | | if (response && response.code === 200) { |
| | | if (response && response.code == 200) { |
| | | this.expertHistoryData = response.data || response[0] || null; |
| | | } else { |
| | | this.$message.error( |
| | |
| | | .selected-case-info { |
| | | margin-bottom: 20px; |
| | | } |
| | | /* åéè¿åº¦æ ·å¼ */ |
| | | .send-progress-container { |
| | | margin: 20px 0; |
| | | padding: 20px; |
| | | background: #f5f7fa; |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | .send-stats { |
| | | display: flex; |
| | | justify-content: center; |
| | | gap: 30px; |
| | | margin-top: 10px; |
| | | } |
| | | |
| | | .stat-item { |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | padding: 4px 12px; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .stat-item.success { |
| | | color: #67c23a; |
| | | background: #f0f9eb; |
| | | } |
| | | |
| | | .stat-item.fail { |
| | | color: #f56c6c; |
| | | background: #fef0f0; |
| | | } |
| | | |
| | | /* 失败详æ
å¯¹è¯æ¡ */ |
| | | .failed-details-dialog { |
| | | min-width: 400px; |
| | | max-width: 600px; |
| | | } |
| | | |
| | | .failed-details-dialog .el-message-box__content { |
| | | max-height: 400px; |
| | | overflow-y: auto; |
| | | white-space: pre-wrap; |
| | | word-break: break-word; |
| | | } |
| | | .case-info-card { |
| | | border-left: 4px solid #67c23a; |
| | | } |
| | | /* å¨CSS䏿·»å */ |
| | | :deep(.el-message-box) { |
| | | max-width: 500px; |
| | | } |
| | | |
| | | /* æ·»å æªä¿åç¶ææ ·å¼ */ |
| | | .unsaved-hint { |
| | | position: absolute; |
| | | top: 10px; |
| | | right: 10px; |
| | | background: #e6a23c; |
| | | color: white; |
| | | padding: 4px 8px; |
| | | border-radius: 4px; |
| | | font-size: 12px; |
| | | animation: pulse 2s infinite; |
| | | } |
| | | |
| | | @keyframes pulse { |
| | | 0% { |
| | | opacity: 0.8; |
| | | } |
| | | 50% { |
| | | opacity: 1; |
| | | } |
| | | 100% { |
| | | opacity: 0.8; |
| | | } |
| | | } |
| | | /* ååºå¼è®¾è®¡ */ |
| | | @media (max-width: 768px) { |
| | | .ethics-review-detail { |
| | |
| | | <el-tag |
| | | :type="scope.row.result === 'é´æ§' ? 'success' : 'danger'" |
| | | effect="plain" |
| | | @click="handleResultClick(scope.row)" |
| | | style="cursor: pointer;" |
| | | > |
| | | {{ scope.row.result }} |
| | | <i |
| | | v-if=" |
| | | scope.row.result === '鳿§' && scope.row.positiveDetails |
| | | " |
| | | class="el-icon-info" |
| | | style="margin-left: 4px;" |
| | | ></i> |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | v-model="cultureForm.result" |
| | | placeholder="è¯·éæ©å¹å
ȍȾ" |
| | | style="width: 100%" |
| | | @change="handleResultChange" |
| | | > |
| | | <el-option label="é´æ§" value="é´æ§" /> |
| | | <el-option label="鳿§" value="鳿§" /> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-form-item |
| | | v-if="cultureForm.result === '鳿§'" |
| | | label="鳿§è¯¦æ
" |
| | | prop="positiveDetails" |
| | | > |
| | | <el-input |
| | | type="textarea" |
| | | :rows="2" |
| | | v-model="cultureForm.positiveDetails" |
| | | placeholder="请è¾å
¥é³æ§ç»æç详ç»ä¿¡æ¯" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="éä»¶"> |
| | | <UploadAttachment |
| | | ref="cultureUploadAttachment" |
| | |
| | | cultureType: "", |
| | | sampleTime: "", |
| | | result: "é´æ§", |
| | | positiveDetails: "", // æ°å¢ï¼é³æ§è¯¦æ
|
| | | attachments: [] |
| | | }, |
| | | cultureFileList: [], |
| | |
| | | ], |
| | | result: [ |
| | | { required: true, message: "è¯·éæ©å¹å
ȍȾ", trigger: "change" } |
| | | ] |
| | | ], |
| | | positiveDetails: [] // 卿éªè¯è§å |
| | | }, |
| | | cultureTypeOptions: [ |
| | | { value: "1", label: "è¡å¹å
»" }, |
| | |
| | | this.recordLoading = false; |
| | | } |
| | | }, |
| | | // å¤çå¹å
»ç»æéæ©åå |
| | | handleResultChange(value) { |
| | | this.$nextTick(() => { |
| | | if (value === "鳿§") { |
| | | this.cultureRules.positiveDetails = [ |
| | | { required: true, message: "请è¾å
¥é³æ§è¯¦æ
", trigger: "blur" } |
| | | ]; |
| | | } else { |
| | | this.cultureRules.positiveDetails = []; |
| | | this.cultureForm.positiveDetails = ""; |
| | | } |
| | | // æ¸
é¤éªè¯ |
| | | if (this.$refs.cultureForm) { |
| | | this.$refs.cultureForm.clearValidate("positiveDetails"); |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // å¤çç¹å»å¹å
»ç»ææ ç¾ |
| | | handleResultClick(row) { |
| | | if (row.result === "鳿§" && row.positiveDetails) { |
| | | this.$alert( |
| | | `<div style="padding: 10px;"> |
| | | <h4 style="margin-bottom: 10px; color: #f56c6c;">鳿§è¯¦æ
ï¼</h4> |
| | | <div style="background: #fef0f0; padding: 15px; border-radius: 4px; border-left: 4px solid #f56c6c;"> |
| | | <p style="margin: 0; white-space: pre-wrap; line-height: 1.5;">${row.positiveDetails}</p> |
| | | </div> |
| | | </div>`, |
| | | "鳿§ç»æè¯¦æ
", |
| | | { |
| | | dangerouslyUseHTMLString: true, |
| | | confirmButtonText: "å
³é", |
| | | customClass: "result-details-dialog", |
| | | showClose: false |
| | | } |
| | | ); |
| | | } else if (row.result === "鳿§") { |
| | | this.$message.warning("è¯¥é³æ§è®°å½ææ 详æ
ä¿¡æ¯"); |
| | | } |
| | | }, |
| | | // ä¿åæææ°æ® |
| | | async handleSave() { |
| | | try { |
| | |
| | | }); |
| | | }, |
| | | |
| | | // 5. ä¿®æ¹ç¼è¾å¹å
»è®°å½æ¹æ³ |
| | | handleEditCulture(row) { |
| | | this.cultureDialogTitle = "ç¼è¾å¹å
»è®°å½"; |
| | | this.cultureForm = { ...row }; |
| | | this.cultureForm = { |
| | | ...row, |
| | | positiveDetails: row.positiveDetails || "" // ç¡®ä¿æpositiveDetailsåæ®µ |
| | | }; |
| | | this.cultureFileList = row.attachments |
| | | ? row.attachments.map(item => ({ |
| | | uid: item.id || Math.random(), |
| | |
| | | this.cultureDialogVisible = true; |
| | | this.$nextTick(() => { |
| | | this.$refs.cultureForm && this.$refs.cultureForm.clearValidate(); |
| | | // 妿ç¼è¾æ¶æ¯é³æ§ç»æï¼è®¾ç½®éªè¯è§å |
| | | if (row.result === "鳿§") { |
| | | this.cultureRules.positiveDetails = [ |
| | | { required: true, message: "请è¾å
¥é³æ§è¯¦æ
", trigger: "blur" } |
| | | ]; |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // 6. ä¿®æ¹ä¿åå¹å
»è®°å½æ¹æ³ |
| | | handleSaveCulture() { |
| | | this.$refs.cultureForm.validate(valid => { |
| | | if (valid) { |
| | | this.cultureSaveLoading = true; |
| | | |
| | | if (this.cultureForm.id) { |
| | | // æå»ºä¿åæ°æ® |
| | | const saveData = { |
| | | ...this.cultureForm, |
| | | // 妿æ¯é´æ§ï¼æ¸
ç©ºé³æ§è¯¦æ
|
| | | positiveDetails: |
| | | this.cultureForm.result === "鳿§" |
| | | ? this.cultureForm.positiveDetails || "" |
| | | : "" |
| | | }; |
| | | |
| | | if (saveData.id) { |
| | | const index = this.cultureList.findIndex( |
| | | item => item.id === this.cultureForm.id |
| | | item => item.id === saveData.id |
| | | ); |
| | | if (index !== -1) { |
| | | this.cultureList.splice(index, 1, { ...this.cultureForm }); |
| | | this.cultureList.splice(index, 1, { ...saveData }); |
| | | } |
| | | } else { |
| | | this.cultureForm.id = Date.now(); |
| | | this.cultureList.push({ ...this.cultureForm }); |
| | | saveData.id = Date.now(); |
| | | this.cultureList.push({ ...saveData }); |
| | | } |
| | | |
| | | this.$message.success(this.cultureForm.id ? "ä¿®æ¹æå" : "æ°å¢æå"); |
| | | this.$message.success(saveData.id ? "ä¿®æ¹æå" : "æ°å¢æå"); |
| | | this.cultureDialogVisible = false; |
| | | this.cultureSaveLoading = false; |
| | | } |
| | |
| | | font-size: 13px; |
| | | margin-left: 8px; |
| | | } |
| | | /* 7. æ·»å ä¸äºæ ·å¼ */ |
| | | .result-details-dialog { |
| | | width: 500px; |
| | | } |
| | | |
| | | .result-details-dialog .el-message-box__content { |
| | | padding: 0; |
| | | } |
| | | |
| | | .result-details-dialog .el-message-box__header { |
| | | background: #fef0f0; |
| | | border-bottom: 1px solid #fde2e2; |
| | | } |
| | | |
| | | .result-details-dialog .el-message-box__title { |
| | | color: #f56c6c; |
| | | font-weight: bold; |
| | | } |
| | | </style> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ICUè¯ä¼°å»ç" prop="icuDoctor"> |
| | | <el-input |
| | | v-model="formData.icuDoctor" |
| | | placeholder="请è¾å
¥ICUè¯ä¼°å»ç" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ICUå»ççµè¯" prop="icuDoctorPhone"> |
| | | <el-input |
| | | v-model="formData.icuDoctorPhone" |
| | | placeholder="请è¾å
¥ICUå»çææºå·" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-card> |
| | | |
| | | <!-- 转è¿ä¿¡æ¯ --> |
| | |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¥è¯ç§å»ç" prop="doctor"> |
| | | <el-form-item label="转è¿å»ç" prop="doctor"> |
| | | <el-input |
| | | v-model="formData.doctor" |
| | | placeholder="请è¾å
¥æ¥è¯ç§å»ç" |
| | | placeholder="请è¾å
¥è½¬è¿å»ç" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¤å£«" prop="nurse"> |
| | | <el-form-item label="è½¬è¿æ¤å£«" prop="nurse"> |
| | | <el-input v-model="formData.nurse" placeholder="请è¾å
¥æ¤å£«å§å" /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="驾驶å" prop="driver"> |
| | | <el-form-item label="转è¿é©¾é©¶å" prop="driver"> |
| | | <el-input |
| | | v-model="formData.driver" |
| | | placeholder="请è¾å
¥é©¾é©¶åå§å" |
| | |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ICUè¯ä¼°å»ç" prop="icuDoctor"> |
| | | <el-input |
| | | v-model="formData.icuDoctor" |
| | | placeholder="请è¾å
¥ICUè¯ä¼°å»ç" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ICUå»ççµè¯" prop="icuDoctorPhone"> |
| | | <el-input |
| | | v-model="formData.icuDoctorPhone" |
| | | placeholder="请è¾å
¥ICUå»çææºå·" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | </el-card> |
| | | |
| | | <!-- éä»¶ä¿¡æ¯ --> |
| | |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-view" |
| | | size="small" |
| | | type="primary" |
| | | @click="handleDetail(scope.row)" |
| | | >详æ
</el-button |
| | | > |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-edit" |
| | | size="small" |
| | | type="primary" |
| | | style="margin-bottom: 10px;" |
| | | plain |
| | | @click="handleUpdate(scope.row)" |
| | | >ç¼è¾</el-button |
| | | > |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-video-play" |
| | | size="small" |
| | | type="primary" |
| | | plain |
| | | @click="handleStartTransport(scope.row)" |
| | | v-if="scope.row.transitStatus === 1" |
| | | >å¼å§è½¬è¿</el-button |
| | | > |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-check" |
| | | size="small" |
| | | type="success" |
| | | plain |
| | | @click="handleCompleteTransport(scope.row)" |
| | | v-if="scope.row.transitStatus === 2" |
| | | >å®æè½¬è¿</el-button |
| | | ><el-button |
| | | size="small" |
| | | type="danger" |
| | | plain |
| | | @click="cancelTransport(scope.row)" |
| | | v-if="scope.row.transitStatus === 2" |
| | | >åæ¶è½¬è¿</el-button |
| | | > |
| | | <el-button |
| | | size="small" |
| | | type="warning" |
| | | plain |
| | | @click="recoverTransport(scope.row)" |
| | | v-if="scope.row.transitStatus === 4" |
| | | >æ¢å¤è½¬è¿</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | |
| | | // å
¶ä»å段å¯ä»¥æ ¹æ®éè¦ä»æ¡ä¾ä¸è·å |
| | | transportStartPlace: caseData.treatmenthospitalname || "", |
| | | contactPerson: caseData.coordinatorName || "", |
| | | icuDoctor: caseData.icuDoctor, |
| | | icuDoctorPhone: caseData.icuDoctorPhone, |
| | | transitStatus: 1, // é»è®¤å¾
è½¬è¿ |
| | | // æ¸
空å
¶ä»å段 |
| | | id: undefined, |
| | |
| | | this.actionTitle = "å®æè½¬è¿"; |
| | | this.actionText = "宿"; |
| | | this.actionOpen = true; |
| | | } /** å®æè½¬è¿æä½ */, |
| | | async cancelTransport(row) { |
| | | this.currentTransport = row; |
| | | this.actionTitle = "åæ¶è½¬è¿"; |
| | | this.actionText = "åæ¶"; |
| | | this.actionOpen = true; |
| | | } /** å®æè½¬è¿æä½ */, |
| | | async recoverTransport(row) { |
| | | this.currentTransport = row; |
| | | this.actionTitle = "æ¢å¤è½¬è¿"; |
| | | this.actionText = "æ¢å¤"; |
| | | this.actionOpen = true; |
| | | }, |
| | | |
| | | /** 确认æä½ */ |
| | |
| | | requestData.transitStatus = 2; // 设置为转è¿ä¸ |
| | | } else if (this.actionText === "宿") { |
| | | requestData.transitStatus = 3; // 设置为转è¿å®æ |
| | | } else if (this.actionText === "åæ¶") { |
| | | requestData.transitStatus = 4; // 设置为转è¿åæ¶ |
| | | } else if (this.actionText === "æ¢å¤") { |
| | | requestData.transitStatus = 2; // 设置为转è¿ä¸ |
| | | } |
| | | |
| | | requestData.annexfilesList.forEach(item => { |
| | | item.id = null; |
| | | }); |
| | | const response = await transportEdit(requestData); |
| | | |
| | | if (response.code == 200) { |
| | | this.$modal.msgSuccess(`${this.actionText}è½¬è¿æå`); |
| | | if (requestData.transitStatus==3) { |
| | | if (requestData.transitStatus == 3) { |
| | | const resappear = await donateInfo(requestData.reportId); |
| | | if (resappear.code) { |
| | | let obj = resappear.data; |
| | |
| | | this.getCode(); |
| | | this.getCookie(); |
| | | this.getAuthCode(); |
| | | this.loginForm.password=this.generatePassword(); |
| | | this.loginForm.password=''; |
| | | // this.loginForm.password=this.generatePassword(); |
| | | // this.avoidLogin(); |
| | | }, |
| | | methods: { |
| | |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="ä¼ æç
" |
| | | align="center" |
| | | prop="infectious" |
| | | width="180" |
| | | /> |
| | | <el-table-column label="ä¼ æç
" align="center" prop="infectious"> |
| | | <template slot-scope="scope"> |
| | | <span v-for="item in scope.row.infectious.split(',')" |
| | | ><dict-tag :options="dict.type.sys_Infectious" :value="item" /> |
| | | </span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | label="é¦è¯å»é¢" |
| | |
| | | "sys_donornode", |
| | | "sys_BloodType", |
| | | "sys_EthicalReview", |
| | | 'sys_Infectious', |
| | | "sys_BaseAssessConclusion" |
| | | ], |
| | | data() { |
| | |
| | | <dict-tag :options="dict.type.sys_user_sex" :value="scope.row.sex"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ä¸æèµ è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" align="center" prop="familyrelations"> |
| | | <el-table-column label="䏿ç®è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" align="center" prop="familyrelations"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_FamilyRelation" :value="scope.row.familyrelations"/> |
| | | </template> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ä¸æèµ è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" prop="familyrelations"> |
| | | <el-input v-model="form.familyrelations" placeholder="请è¾å
¥ä¸æèµ è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" /> |
| | | <el-form-item label="䏿ç®è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" prop="familyrelations"> |
| | | <el-input v-model="form.familyrelations" placeholder="请è¾å
¥ä¸æç®è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" /> |
| | | </el-form-item> |
| | | <el-form-item label="èç³»çµè¯" prop="phone"> |
| | | <el-input v-model="form.phone" placeholder="请è¾å
¥èç³»çµè¯" /> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container archive-container"> |
| | | <div class="archive-header"> |
| | | <span class="archive-title">æç®æ¡ä¾å½æ¡£ç®¡ç</span> |
| | | <span class="archive-tag">ä»
å±ç¤ºå·²å½æ¡£æ¡ä¾ï¼ä¸å¯ç¼è¾ï¼</span> |
| | | </div> |
| | | <!-- æç´¢ --> |
| | | <el-card class="search-card"> |
| | | <el-form |
| | | :model="queryParams" |
| | | ref="queryForm" |
| | | :inline="true" |
| | | v-show="showSearch" |
| | | label-width="70px" |
| | | > |
| | | <el-row :gutter="8"> |
| | | <el-col :span="5"> |
| | | <el-form-item label="å§å" prop="name"> |
| | | <el-input |
| | | v-model="queryParams.name" |
| | | placeholder="请è¾å
¥å§å" |
| | | clearable |
| | | size="small" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | |
| | | <el-col :span="5"> |
| | | <el-form-item label="æ¥åå»é¢" prop="treatmenthospitalno"> |
| | | <org-selecter |
| | | ref="orgSelecter" |
| | | :org-type="'3'" |
| | | v-model="queryParams.treatmenthospitalno" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | |
| | | <el-col :span="9"> |
| | | <el-form-item label="彿¡£æ¶é´"> |
| | | <el-date-picker |
| | | v-model="selecttime" |
| | | type="daterange" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | value-format="yyyy-MM-dd" |
| | | @change="getTimeList" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row> |
| | | <el-col :span="4"> |
| | | <el-form-item> |
| | | <el-button |
| | | type="primary" |
| | | icon="el-icon-search" |
| | | size="mini" |
| | | @click="handleQuery" |
| | | > |
| | | æç´¢ |
| | | </el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"> |
| | | éç½® |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </el-card> |
| | | |
| | | <!-- æä½ --> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="el-icon-download" |
| | | size="mini" |
| | | :loading="exportLoading" |
| | | @click="handleExport" |
| | | > |
| | | å¯¼åº |
| | | </el-button> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-card class="table-card"> |
| | | |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="tableList" |
| | | class="archive-table" |
| | | border |
| | | > |
| | | <el-table-column label="å§å" align="center" prop="name" /> |
| | | <el-table-column label="ä½é¢å·" align="center" prop="inpatientno" /> |
| | | <el-table-column label="æ§å«" align="center" prop="sex"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag |
| | | :options="dict.type.sys_user_sex" |
| | | :value="scope.row.sex" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å¹´é¾" align="center" prop="age" /> |
| | | <el-table-column label="è¡å" align="center" prop="bloodtype"> |
| | | <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="filingtime" /> |
| | | |
| | | <el-table-column |
| | | label="æä½" |
| | | width="120" |
| | | align="center" |
| | | fixed="right" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | style="color:#67C23A;" |
| | | @click="handleCancelArchive(scope.row)" |
| | | > |
| | | 忶彿¡£ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | <!-- è¡¨æ ¼ --> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | :page.sync="queryParams.pageNum" |
| | | :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | </div> |
| | | </template> |
| | | <script> |
| | | import { |
| | | listDonatebaseinfo, |
| | | updateDonatebaseinfo, |
| | | exportDonatebaseinfo |
| | | } from "@/api/project/donatebaseinfo"; |
| | | import OrgSelecter from "@/views/project/components/orgselect"; |
| | | |
| | | export default { |
| | | name: "DonateArchive", |
| | | components: { OrgSelecter }, |
| | | dicts: ["sys_user_sex", "sys_BloodType"], |
| | | |
| | | data() { |
| | | return { |
| | | loading: true, |
| | | exportLoading: false, |
| | | tableList: [], |
| | | total: 0, |
| | | selecttime: [], |
| | | |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: null, |
| | | treatmenthospitalno: null, |
| | | starttime: null, |
| | | endtime: null, |
| | | recordstate: "4" // â
åªæ¥å½æ¡£æ¡ä¾ |
| | | } |
| | | }; |
| | | }, |
| | | |
| | | created() { |
| | | this.getList(); |
| | | }, |
| | | |
| | | methods: { |
| | | getTimeList() { |
| | | if (!this.selecttime) return; |
| | | const [start, end] = this.selecttime; |
| | | this.queryParams.starttime = start; |
| | | this.queryParams.endtime = end; |
| | | }, |
| | | |
| | | getList() { |
| | | this.loading = true; |
| | | listDonatebaseinfo(this.queryParams).then(res => { |
| | | this.tableList = res.data; |
| | | this.total = res.total; |
| | | this.loading = false; |
| | | }); |
| | | }, |
| | | |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1; |
| | | this.getList(); |
| | | }, |
| | | |
| | | resetQuery() { |
| | | this.queryParams = { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: null, |
| | | treatmenthospitalno: null, |
| | | starttime: null, |
| | | endtime: null, |
| | | recordstate: "4" |
| | | }; |
| | | this.selecttime = []; |
| | | this.resetForm("queryForm"); |
| | | this.getList(); |
| | | }, |
| | | |
| | | /** 忶彿¡£ */ |
| | | handleCancelArchive(row) { |
| | | this.$confirm("ç¡®è®¤åæ¶å½æ¡£ï¼åæ¶åæ¡ä¾å°æ¢å¤ä¸ºæ£å¸¸ç¶æã", "æç¤º", { |
| | | type: "warning" |
| | | }).then(async () => { |
| | | const res = await updateDonatebaseinfo({ |
| | | id: row.id, |
| | | recordstate: "2" |
| | | }); |
| | | |
| | | if (res.code === 200) { |
| | | this.$modal.msgSuccess("已忶彿¡£"); |
| | | this.getList(); |
| | | } else { |
| | | this.$modal.msgError(res.msg || "æä½å¤±è´¥"); |
| | | } |
| | | }).catch(() => {}); |
| | | }, |
| | | |
| | | /** å¯¼åº */ |
| | | async handleExport() { |
| | | this.$modal.confirm("æ¯å¦å¯¼åºå½æ¡£æ¡ä¾æ°æ®ï¼").then(async () => { |
| | | this.exportLoading = true; |
| | | const res = await exportDonatebaseinfo(this.queryParams); |
| | | this.$download.name(res.msg); |
| | | this.exportLoading = false; |
| | | }).catch(() => {}); |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | <style scoped> |
| | | /* ===== 彿¡£é¡µé¢æ´ä½é£æ ¼ ===== */ |
| | | .archive-container { |
| | | background: #f5f7fa; |
| | | min-height: calc(100vh - 84px); |
| | | padding: 20px; |
| | | } |
| | | |
| | | /* ===== 页颿 é¢åº ===== */ |
| | | .archive-header { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .archive-title { |
| | | font-size: 18px; |
| | | font-weight: bold; |
| | | color: #606266; |
| | | } |
| | | |
| | | .archive-tag { |
| | | margin-left: 12px; |
| | | background: #fdf6ec; |
| | | color: #e6a23c; |
| | | border: 1px solid #faecd8; |
| | | padding: 4px 10px; |
| | | border-radius: 4px; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | /* ===== æç´¢åºå ===== */ |
| | | .search-card { |
| | | background: #ffffff; |
| | | padding: 18px 20px 0; |
| | | border-radius: 6px; |
| | | margin-bottom: 16px; |
| | | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04); |
| | | } |
| | | |
| | | /* ===== è¡¨æ ¼åºå ===== */ |
| | | .table-card { |
| | | background: #ffffff; |
| | | padding: 16px; |
| | | border-radius: 6px; |
| | | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04); |
| | | } |
| | | |
| | | /* ===== 彿¡£è¡¨æ ¼è¡æ ·å¼ï¼éç¹ï¼ ===== */ |
| | | ::v-deep .archive-table .el-table__row { |
| | | background: #fdfbf5; |
| | | } |
| | | |
| | | ::v-deep .archive-table .el-table__row:hover > td { |
| | | background: #f9f3e3 !important; |
| | | } |
| | | |
| | | /* ===== æä½æé® ===== */ |
| | | .archive-action-btn { |
| | | color: #67c23a; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | /* ===== ç©ºç¶æ ===== */ |
| | | .empty-archive { |
| | | text-align: center; |
| | | padding: 60px 0; |
| | | color: #909399; |
| | | } |
| | | </style> |
| | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="å
¥é¢æ¶é´" prop="Reporttothehospital"> |
| | | <el-input |
| | | v-model="formData.Reporttothehospital" |
| | | placeholder="请è¾å
¥å
¥é¢æ¶é´" |
| | | /> |
| | | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="å
¥é¢ç§å®¤" prop="treatmentdeptname"> |
| | | <el-input |
| | | v-model="formData.treatmentdeptname" |
| | | placeholder="请è¾å
¥ç§å®¤" |
| | | <el-date-picker |
| | | v-model="formData.entryTime" |
| | | type="datetime" |
| | | placeholder="éæ©å
¥é¢æ¶é´" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="åè°åç¼å·" prop="coordinatorNo"> |
| | | <el-input |
| | | v-model="formData.coordinatorNo" |
| | | placeholder="请è¾å
¥åè°åç¼å·" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | |
| | | <el-col :span="8"> |
| | | <el-form-item label="åè°åå§å" prop="coordinatorName"> |
| | | <el-input |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="ä¸æèµ è
å
³ç³»" prop="familyrelations"> |
| | | <el-form-item label="䏿ç®è
å
³ç³»" prop="familyrelations"> |
| | | <el-select |
| | | v-model="formData.familyrelations" |
| | | placeholder="è¯·éæ©ä¸æèµ è
å
³ç³»" |
| | | placeholder="è¯·éæ©ä¸æç®è
å
³ç³»" |
| | | > |
| | | <el-option |
| | | v-for="dict in dict.type.sys_FamilyRelation || []" |
| | |
| | | // 设置å°åä¿¡æ¯ |
| | | if (data.residenceprovince) { |
| | | this.residenceAddress = { |
| | | sheng: data.residenceprovincename, |
| | | shi: data.residencecityname, |
| | | qu: data.residencetownname |
| | | sheng: data.residenceprovince, |
| | | shi: data.residencecity, |
| | | qu: data.residencetown |
| | | }; |
| | | } |
| | | |
| | | if (data.registerprovince) { |
| | | this.registerAddress = { |
| | | sheng: data.registerprovincename, |
| | | shi: data.registercityname, |
| | | qu: data.registertownname |
| | | sheng: data.registerprovince, |
| | | shi: data.registercity, |
| | | qu: data.registertown |
| | | }; |
| | | } |
| | | console.log(this.registerAddress,'registerAddress12'); |
| | | |
| | | |
| | | this.calculateAge(data.birthday); |
| | | } catch (error) { |
| | |
| | | }, |
| | | |
| | | handleRegisterAddressChange(address) { |
| | | console.log(this.registerAddress,'registerAddress11'); |
| | | |
| | | this.formData.registerprovince = address.sheng; |
| | | this.formData.registercity = address.shi; |
| | | this.formData.registertown = address.qu; |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="ä½é¢å·" |
| | | align="center" |
| | | prop="inpatientno" |
| | | width="200" |
| | | /> |
| | | <el-table-column |
| | | label="æç®è¿åº¦" |
| | | align="center" |
| | | prop="workflow" |
| | |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æ¡ä¾ç¼å·" |
| | | align="center" |
| | | prop="caseNo" |
| | | width="200" |
| | | /> |
| | | |
| | | <el-table-column label="æ§å«" align="center" prop="sex" width="100"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag |
| | |
| | | }} |
| | | </template> |
| | | </el-table-column> |
| | | <<<<<<< HEAD |
| | | <el-table-column label="GCSè¯å" align="center" prop="gcsScore" width="100"/> |
| | | ======= |
| | | <el-table-column |
| | | label="䏿¥å»é¢" |
| | | label="GCSè¯å" |
| | | align="center" |
| | | prop="treatmenthospitalname" |
| | | prop="gcsScore" |
| | | width="100" |
| | | /> |
| | | <el-table-column label="GCSè¯å" align="center" prop="gcsScore" /> |
| | | >>>>>>> 059398ad3ad81ea49dfb75ac09f268bc0b0f6145 |
| | | <el-table-column label="è¡å" align="center" prop="bloodtype" width="100"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag |
| | |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column label="ä¼ æç
" align="center" prop="infectious"> |
| | | <template slot-scope="scope"> |
| | | <span v-for="item in scope.row.infectious.split(',')" |
| | | ><dict-tag :options="dict.type.sys_Infectious" :value="item" /> |
| | | </span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¾ç
è¯æ" align="center" prop="diagnosisname" /> |
| | | <el-table-column |
| | | label="æ¥åå»é¢" |
| | | label="åè°å" |
| | | align="center" |
| | | prop="treatmenthospitalname" |
| | | /> |
| | | <el-table-column |
| | | label="æ¥å人" |
| | | align="center" |
| | | prop="reportername" |
| | | prop="coordinatorName" |
| | | width="100" |
| | | /> |
| | | <el-table-column |
| | | label="æä½" |
| | | width="190" |
| | | width="220" |
| | | align="center" |
| | | class-name="small-padding fixed-width" |
| | | fixed="right" |
| | |
| | | > |
| | | 详æ
|
| | | </el-button> |
| | | |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-edit" |
| | | @click="handleOpenEdit(scope.row)" |
| | | v-hasPermi="['project:donatebaseinfo:edit']" |
| | | >ç¼è¾</el-button |
| | | v-if="scope.row.recordstate !== '4'" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | |
| | | <!-- â
æ°å¢ï¼å½æ¡£æé® --> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | style="color:#E6A23C;" |
| | | @click="handleArchive(scope.row)" |
| | | v-if="scope.row.recordstate !== '4'" |
| | | > |
| | | 彿¡£ |
| | | </el-button> |
| | | |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | |
| | | > |
| | | ç»æ¢ |
| | | </el-button> |
| | | |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | |
| | | import { |
| | | listDonatebaseinfo, |
| | | addDonatebaseinfo, |
| | | exportDonatebaseinfo |
| | | exportDonatebaseinfo, |
| | | updateDonatebaseinfo |
| | | } from "@/api/project/donatebaseinfo"; |
| | | import Li_area_select from "@/components/Address"; |
| | | import OrgSelecter from "@/views/project/components/orgselect"; |
| | |
| | | dicts: [ |
| | | "sys_user_sex", |
| | | "sys_BloodType", |
| | | "sys_Infectious", |
| | | "sys_DonationCategory", |
| | | "sys_donornode" |
| | | ], |
| | |
| | | this.currentRecord = { ...row }; |
| | | this.modalVisible = { ...this.modalVisible, restore: true }; |
| | | }, |
| | | /** 彿¡£ */ |
| | | handleArchive(row) { |
| | | this.$confirm("确认å°è¯¥æ¡ä¾å½æ¡£ï¼å½æ¡£åå°ä¸å¯ç¼è¾ã", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }) |
| | | .then(async () => { |
| | | try { |
| | | const res = await updateDonatebaseinfo({ |
| | | id: row.id, |
| | | recordstate: "4", |
| | | filingtime: this.getCurrentTime() |
| | | }); |
| | | |
| | | if (res.code === 200) { |
| | | this.$modal.msgSuccess("彿¡£æå"); |
| | | this.getList(); |
| | | } else { |
| | | this.$modal.msgError(res.msg || "彿¡£å¤±è´¥"); |
| | | } |
| | | } catch (err) { |
| | | this.$modal.msgError("æä½å¤±è´¥"); |
| | | } |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | // è·åå½åæ¶é´ |
| | | getCurrentTime() { |
| | | const now = new Date(); |
| | | return `${now.getFullYear()}-${(now.getMonth() + 1) |
| | | .toString() |
| | | .padStart(2, "0")}-${now |
| | | .getDate() |
| | | .toString() |
| | | .padStart(2, "0")} ${now |
| | | .getHours() |
| | | .toString() |
| | | .padStart(2, "0")}:${now |
| | | .getMinutes() |
| | | .toString() |
| | | .padStart(2, "0")}:${now |
| | | .getSeconds() |
| | | .toString() |
| | | .padStart(2, "0")}`; |
| | | }, |
| | | getTimeList() { |
| | | if (!this.selecttime) { |
| | | // this.queryParams.starttime = "1998-01-01 00:00:00"; |
| | |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | /** æå¼ç¼è¾å¼¹çª */ |
| | | handleOpenEdit(row) { |
| | | // ç¡®ä¿å¨æå¼å¼¹æ¡åéç½®currentEditData |
| | | this.currentEditData = {}; |
| | | if (row.recordstate === "4") { |
| | | this.$modal.msgWarning("彿¡£æ¡ä¾ä¸å¯ç¼è¾"); |
| | | return; |
| | | } |
| | | |
| | | // 使ç¨$nextTickç¡®ä¿DOMæ´æ°å®æ |
| | | this.currentEditData = {}; |
| | | this.$nextTick(() => { |
| | | this.currentEditData = { ...row }; |
| | | this.editModalVisible = true; |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="ä¸æèµ è
å
³ç³»" prop="familyrelations"> |
| | | <el-form-item label="䏿ç®è
å
³ç³»" prop="familyrelations"> |
| | | <el-select |
| | | v-model="form.familyrelations" |
| | | placeholder="è¯·éæ©ä¸æèµ è
å
³ç³»" |
| | | placeholder="è¯·éæ©ä¸æç®è
å
³ç³»" |
| | | > |
| | | <el-option |
| | | v-for="dict in dict.type.sys_FamilyRelation" |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="ä¸æèµ è
å
³ç³»" prop="familyrelations"> |
| | | <el-form-item label="䏿ç®è
å
³ç³»" prop="familyrelations"> |
| | | <el-select |
| | | v-model="form.familyrelations" |
| | | placeholder="è¯·éæ©ä¸æèµ è
å
³ç³»" |
| | | placeholder="è¯·éæ©ä¸æç®è
å
³ç³»" |
| | | > |
| | | <el-option |
| | | v-for="dict in dict.type.sys_FamilyRelation || []" |
| | |
| | | > |
| | | <el-row> |
| | | <el-col :span="6"> |
| | | <el-form-item label="æèµ è
æ°æ" prop="nation"> |
| | | <el-form-item label="æç®è
æ°æ" prop="nation"> |
| | | <el-select |
| | | filterable |
| | | v-model="affirmform.nation" |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="æèµ è
å¦å" prop="education"> |
| | | <el-form-item label="æç®è
å¦å" prop="education"> |
| | | <el-select |
| | | v-model="affirmform.education" |
| | | placeholder="è¯·éæ©å¦å" |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="æèµ è
èä¸" prop="occupation"> |
| | | <el-form-item label="æç®è
èä¸" prop="occupation"> |
| | | <el-select |
| | | filterable |
| | | v-model="affirmform.occupation" |
| | |
| | | <el-col :span="6"> |
| | | <el-form-item |
| | | align="left" |
| | | label="ä¸æèµ è
å
³ç³»" |
| | | label="䏿ç®è
å
³ç³»" |
| | | prop="familyrelations" |
| | | > |
| | | <el-select |
| | | v-model="affirmform.familyrelations" |
| | | placeholder="è¯·éæ©ä¸æèµ è
å
³ç³»" |
| | | placeholder="è¯·éæ©ä¸æç®è
å
³ç³»" |
| | | > |
| | | <el-option |
| | | v-for="dict in dict.type.sys_FamilyRelation || []" |
| | |
| | | } |
| | | } |
| | | ], |
| | | bankcardno: [ |
| | | { required: true, message: "请è¾å
¥é¶è¡è´¦å·", trigger: "blur" } |
| | | ], |
| | | depositbank: [ |
| | | { required: true, message: "请è¾å
¥å¼æ·é¶è¡", trigger: "blur" } |
| | | ] |
| | | |
| | | }, |
| | | //æ¯å¦æ¯ä¸å®¶è´¹çOPO审æ¹äººå |
| | | ismanager: false |
| | |
| | | <el-option label="è¯·éæ©åå
¸çæ" value="" /> |
| | | </el-select> |
| | | </el-form-item></el-col> |
| | | <el-col :span="5"><el-form-item label="ä¸æèµ è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" prop="familyrelations"> |
| | | <el-input v-model="form.familyrelations" placeholder="请è¾å
¥ä¸æèµ è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" /> |
| | | <el-col :span="5"><el-form-item label="䏿ç®è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" prop="familyrelations"> |
| | | <el-input v-model="form.familyrelations" placeholder="请è¾å
¥ä¸æç®è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" /> |
| | | </el-form-item></el-col> |
| | | <el-col :span="5"><el-form-item label="èç³»çµè¯" prop="phone"> |
| | | <el-input v-model="form.phone" placeholder="请è¾å
¥èç³»çµè¯" /> |
| | |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ä¸æèµ è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" prop="familyrelations"> |
| | | <el-form-item label="䏿ç®è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" prop="familyrelations"> |
| | | <el-input |
| | | v-model="queryParams.familyrelations" |
| | | placeholder="请è¾å
¥ä¸æèµ è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" |
| | | placeholder="请è¾å
¥ä¸æç®è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" |
| | | clearable |
| | | size="small" |
| | | @keyup.enter.native="handleQuery" |
| | |
| | | <el-table-column label="å¡å·" align="center" prop="bankcardno" /> |
| | | <el-table-column label="ç³è¯·éé¢" align="center" prop="amount" /> |
| | | <el-table-column label="èç³»çµè¯" align="center" prop="phone" /> |
| | | <el-table-column label="ä¸æèµ è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" align="center" prop="familyrelations" /> |
| | | <el-table-column label="䏿ç®è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" align="center" prop="familyrelations" /> |
| | | <el-table-column label="仿¬¾æ¥æ" align="center" prop="paiddate" width="180"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.paiddate, '{y}-{m}-{d}') }}</span> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | |
| | | <el-form-item label="èç³»çµè¯" prop="phone"> |
| | | <el-input v-model="form.phone" placeholder="请è¾å
¥èç³»çµè¯" /> |
| | | </el-form-item> |
| | | <el-form-item label="ä¸æèµ è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" prop="familyrelations"> |
| | | <el-input v-model="form.familyrelations" placeholder="请è¾å
¥ä¸æèµ è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" /> |
| | | <el-form-item label="䏿ç®è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" prop="familyrelations"> |
| | | <el-input v-model="form.familyrelations" placeholder="请è¾å
¥ä¸æç®è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" /> |
| | | </el-form-item> |
| | | <el-form-item label="仿¬¾æ¥æ" prop="paiddate"> |
| | | <el-date-picker clearable size="small" |
| | |
| | | <el-col :span="6"> |
| | | <el-form-item |
| | | align="left" |
| | | label="ä¸æèµ è
å
³ç³»" |
| | | label="䏿ç®è
å
³ç³»" |
| | | prop="familyrelations" |
| | | > |
| | | <el-select |
| | | v-model="form.familyrelations" |
| | | placeholder="è¯·éæ©ä¸æèµ è
å
³ç³»" |
| | | placeholder="è¯·éæ©ä¸æç®è
å
³ç³»" |
| | | > |
| | | <el-option |
| | | v-for="dict in dict.type.sys_FamilyRelation" |
| | |
| | | <!-- æ·»å æä¿®æ¹è´¹ç¨ç³è¯·æç»å¯¹è¯æ¡ --> |
| | | <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> |
| | | <el-form ref="form" :model="form" :rules="rules" label-width="80px"> |
| | | |
| | | |
| | | <el-form-item label="æ¶ç人" prop="beneficiaryname"> |
| | | <el-input |
| | | v-model="form.beneficiaryname" |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item |
| | | label="ä¸æèµ è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" |
| | | label="䏿ç®è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" |
| | | prop="familyrelations" |
| | | > |
| | | <el-input |
| | | v-model="form.familyrelations" |
| | | placeholder="请è¾å
¥ä¸æèµ è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" |
| | | placeholder="请è¾å
¥ä¸æç®è
å
³ç³» æ ¹æ®åå
¸sys_FamilyRelation" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="èç³»çµè¯" prop="phone"> |
| | |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | </script> |
| | |
| | | 'use strict' |
| | | const path = require('path') |
| | | "use strict"; |
| | | const path = require("path"); |
| | | |
| | | function resolve(dir) { |
| | | return path.join(__dirname, dir) |
| | | return path.join(__dirname, dir); |
| | | } |
| | | |
| | | const name = process.env.VUE_APP_TITLE || 'ééé¢OPO管çå¹³å°' // ç½é¡µæ é¢ |
| | | const name = process.env.VUE_APP_TITLE || "ééé¢OPO管çå¹³å°"; // ç½é¡µæ é¢ |
| | | |
| | | const port = process.env.port || process.env.npm_config_port || 80 // ç«¯å£ |
| | | const port = process.env.port || process.env.npm_config_port || 80; // ç«¯å£ |
| | | |
| | | // vue.config.js é
置说æ |
| | | //宿¹vue.config.js åèææ¡£ https://cli.vuejs.org/zh/config/#css-loaderoptions |
| | |
| | | // ä¾å¦ https://www.ruoyi.vip/ã妿åºç¨è¢«é¨ç½²å¨ä¸ä¸ªåè·¯å¾ä¸ï¼ä½ å°±éè¦ç¨è¿ä¸ªé项æå®è¿ä¸ªåè·¯å¾ãä¾å¦ï¼å¦æä½ çåºç¨è¢«é¨ç½²å¨ https://www.ruoyi.vip/admin/ï¼å设置 baseUrl 为 /admin/ã |
| | | publicPath: process.env.NODE_ENV === "production" ? "/" : "/", |
| | | // å¨npm run build æ yarn build æ¶ ï¼çææä»¶çç®å½åç§°ï¼è¦åbaseUrlçç产ç¯å¢è·¯å¾ä¸è´ï¼ï¼é»è®¤distï¼ |
| | | outputDir: 'dist', |
| | | outputDir: "dist", |
| | | // ç¨äºæ¾ç½®çæçéæèµæº (jsãcssãimgãfonts) çï¼ï¼é¡¹ç®æå
ä¹åï¼éæèµæºä¼æ¾å¨è¿ä¸ªæä»¶å¤¹ä¸ï¼ |
| | | assetsDir: 'static', |
| | | assetsDir: "static", |
| | | // æ¯å¦å¼å¯eslintä¿åæ£æµï¼ææå¼ï¼ture | false | 'error' |
| | | lintOnSave: process.env.NODE_ENV === 'development', |
| | | lintOnSave: process.env.NODE_ENV === "development", |
| | | // å¦æä½ ä¸éè¦ç产ç¯å¢ç source mapï¼å¯ä»¥å°å
¶è®¾ç½®ä¸º false 以å éç产ç¯å¢æå»ºã |
| | | productionSourceMap: false, |
| | | // webpack-dev-server ç¸å
³é
ç½® |
| | | devServer: { |
| | | host: '0.0.0.0', |
| | | host: "0.0.0.0", |
| | | port: port, |
| | | open: true, |
| | | proxy: { |
| | | // detail: https://cli.vuejs.org/config/#devserver-proxy |
| | | [process.env.VUE_APP_BASE_API]: { |
| | | target:`http://localhost:8080`, |
| | | target: `http://www.qdopo.com:9095`, |
| | | // target:`http://192.168.76.25:9095`,//æå
å°å |
| | | // target:`http://192.168.100.10:8080`, |
| | | // target:`http://192.168.100.137:8080`, |
| | | // target: `https://slb.hospitalstar.com:9093`, |
| | | changeOrigin: true, |
| | | pathRewrite: { |
| | | ['^' + process.env.VUE_APP_BASE_API]: '' |
| | | ["^" + process.env.VUE_APP_BASE_API]: "" |
| | | } |
| | | }, |
| | | //å½pdfåæ°æ®æ¥å£ä¸å¨åä¸ä¸ªè¯·æ±å°å䏿¶,为pdfé¢è§è¿½å ä¸ä¸ªä»£ç |
| | | '/pdf': { |
| | | target: 'http://192.168.1.4/pdf/data', |
| | | "/pdf": { |
| | | target: "http://192.168.1.4/pdf/data", |
| | | changOrigin: true, |
| | | pathRewrite: { |
| | | '^/pdf': '' |
| | | "^/pdf": "" |
| | | } |
| | | } |
| | | }, |
| | |
| | | name: name, |
| | | resolve: { |
| | | alias: { |
| | | '@': resolve('src') |
| | | |
| | | "@": resolve("src") |
| | | } |
| | | } |
| | | }, |
| | | chainWebpack(config) { |
| | | config.plugins.delete('preload') // TODO: need test |
| | | config.plugins.delete('prefetch') // TODO: need test |
| | | config.plugins.delete("preload"); // TODO: need test |
| | | config.plugins.delete("prefetch"); // TODO: need test |
| | | |
| | | // set svg-sprite-loader |
| | | config.module |
| | | .rule('svg') |
| | | .exclude.add(resolve('src/assets/icons')) |
| | | .end() |
| | | .rule("svg") |
| | | .exclude.add(resolve("src/assets/icons")) |
| | | .end(); |
| | | config.module |
| | | .rule('icons') |
| | | .rule("icons") |
| | | .test(/\.svg$/) |
| | | .include.add(resolve('src/assets/icons')) |
| | | .include.add(resolve("src/assets/icons")) |
| | | .end() |
| | | .use('svg-sprite-loader') |
| | | .loader('svg-sprite-loader') |
| | | .use("svg-sprite-loader") |
| | | .loader("svg-sprite-loader") |
| | | .options({ |
| | | symbolId: 'icon-[name]' |
| | | symbolId: "icon-[name]" |
| | | }) |
| | | .end() |
| | | .end(); |
| | | |
| | | config |
| | | .when(process.env.NODE_ENV !== 'development', |
| | | config => { |
| | | config |
| | | .plugin('ScriptExtHtmlWebpackPlugin') |
| | | .after('html') |
| | | .use('script-ext-html-webpack-plugin', [{ |
| | | // `runtime` must same as runtimeChunk name. default is `runtime` |
| | | inline: /runtime\..*\.js$/ |
| | | }]) |
| | | .end() |
| | | config |
| | | .optimization.splitChunks({ |
| | | chunks: 'all', |
| | | cacheGroups: { |
| | | libs: { |
| | | name: 'chunk-libs', |
| | | test: /[\\/]node_modules[\\/]/, |
| | | priority: 10, |
| | | chunks: 'initial' // only package third parties that are initially dependent |
| | | }, |
| | | elementUI: { |
| | | name: 'chunk-elementUI', // split elementUI into a single package |
| | | priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app |
| | | test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm |
| | | }, |
| | | commons: { |
| | | name: 'chunk-commons', |
| | | test: resolve('src/components'), // can customize your rules |
| | | minChunks: 3, // minimum common number |
| | | priority: 5, |
| | | reuseExistingChunk: true |
| | | } |
| | | } |
| | | }) |
| | | config.optimization.runtimeChunk('single'), |
| | | config.when(process.env.NODE_ENV !== "development", config => { |
| | | config |
| | | .plugin("ScriptExtHtmlWebpackPlugin") |
| | | .after("html") |
| | | .use("script-ext-html-webpack-plugin", [ |
| | | { |
| | | from: path.resolve(__dirname, './public/robots.txt'), //é²ç¬è«æä»¶ |
| | | to: './' //å°æ ¹ç®å½ä¸ |
| | | // `runtime` must same as runtimeChunk name. default is `runtime` |
| | | inline: /runtime\..*\.js$/ |
| | | } |
| | | ]) |
| | | .end(); |
| | | config.optimization.splitChunks({ |
| | | chunks: "all", |
| | | cacheGroups: { |
| | | libs: { |
| | | name: "chunk-libs", |
| | | test: /[\\/]node_modules[\\/]/, |
| | | priority: 10, |
| | | chunks: "initial" // only package third parties that are initially dependent |
| | | }, |
| | | elementUI: { |
| | | name: "chunk-elementUI", // split elementUI into a single package |
| | | priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app |
| | | test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm |
| | | }, |
| | | commons: { |
| | | name: "chunk-commons", |
| | | test: resolve("src/components"), // can customize your rules |
| | | minChunks: 3, // minimum common number |
| | | priority: 5, |
| | | reuseExistingChunk: true |
| | | } |
| | | } |
| | | ) |
| | | }); |
| | | config.optimization.runtimeChunk("single"), |
| | | { |
| | | from: path.resolve(__dirname, "./public/robots.txt"), //é²ç¬è«æä»¶ |
| | | to: "./" //å°æ ¹ç®å½ä¸ |
| | | }; |
| | | }); |
| | | } |
| | | } |
| | | }; |