From 3453ba7e5243022ad4388da1515dc75ad8d81f94 Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期日, 17 五月 2026 15:00:23 +0800
Subject: [PATCH] 近期调试
---
src/api/businessApi/ethicalReview.js | 15
src/views/business/course/components/MedicalAssessmentStage.vue | 662 +-
src/views/business/course/components/DonationConfirmStage.vue | 97
src/views/business/course/components/OrganAllocationStage.vue | 1686 ++++++-
src/views/business/decide/DecideInfo.vue | 33
src/views/business/allocation/index.vue | 49
src/views/business/course/components/OrganUtilizationStage.vue | 2499 ++++++++---
src/views/business/affirm/index.vue | 16
src/views/business/ethicalReview/ethicalReviewInfo.vue | 489 +-
src/views/business/course/components/DonorMaintenanceStage.vue | 394 -
src/views/business/decide/index.vue | 554 +
src/views/business/course/components/DeathJudgmentStage.vue | 1004 +++-
src/views/business/maintain/index.vue | 45
src/views/business/course/index.vue | 70
src/views/business/OrganUtilization/OrganUtilizationInfo.vue | 74
src/views/business/assess/index.vue | 43
src/views/business/course/components/EthicalReviewStage.vue | 2634 +++++++----
src/views/business/course/components/OrganProcurementStage.vue | 1967 +++++++--
src/views/business/affirm/affirmInfo.vue | 30
src/views/business/maintain/maintainInfo.vue | 168
src/views/business/allocation/allocationInfo.vue | 13
src/views/business/ethicalReview/index.vue | 41
src/views/business/assess/assessInfo.vue | 24
23 files changed, 8,345 insertions(+), 4,262 deletions(-)
diff --git a/src/api/businessApi/ethicalReview.js b/src/api/businessApi/ethicalReview.js
index 71139a8..cda4d19 100644
--- a/src/api/businessApi/ethicalReview.js
+++ b/src/api/businessApi/ethicalReview.js
@@ -46,11 +46,12 @@
method: 'get'
})
}
-// // 浼︾悊瀹℃煡淇℃伅璇︽儏
-// export function ethicalreviewInfo(id) {
-// return request({
-// url: '/project/ethicalreviewinitiate/getInfo/' + id,
-// method: 'get'
-// })
-// }
+// 涓撳娑堟伅鎺ㄩ��
+export function sendNotification(data) {
+ return request({
+ url: '/system/dingtalk/sendNotification',
+ method: 'post',
+ data: data
+ })
+}
diff --git a/src/views/business/OrganUtilization/OrganUtilizationInfo.vue b/src/views/business/OrganUtilization/OrganUtilizationInfo.vue
index 534c3a6..6106b5f 100644
--- a/src/views/business/OrganUtilization/OrganUtilizationInfo.vue
+++ b/src/views/business/OrganUtilization/OrganUtilizationInfo.vue
@@ -82,46 +82,41 @@
<el-card class="detail-card">
<div slot="header" class="clearfix">
<span class="detail-title">閬椾綋鎹愮尞淇℃伅</span>
-
</div>
- <el-row :gutter="20">
- <el-col :span="6">
- <el-form-item align="left" label="閬椾綋鎹愮尞" prop="isbodydonation">
- <el-radio-group v-model="form.isbodydonation">
- <el-radio
- v-for="dict in dict.type.sys_0_1 || []"
- :key="dict.value"
- :label="dict.value"
- >{{ dict.label }}</el-radio
- >
- </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-form-item
- align="left"
- label="鎺ユ敹瀹跺睘"
- prop="relationname"
- >
- <el-input
- v-model="form.relationname"
- placeholder="璇疯緭鍏ユ帴鏀跺灞�"
- />
- </el-form-item>
- </el-col>
- </el-row>
+ <el-row :gutter="20">
+ <el-col :span="6">
+ <el-form-item align="left" label="閬椾綋鎹愮尞" prop="isbodydonation">
+ <el-radio-group v-model="form.isbodydonation">
+ <el-radio
+ v-for="dict in dict.type.sys_0_1 || []"
+ :key="dict.value"
+ :label="dict.value"
+ >{{ dict.label }}</el-radio
+ >
+ </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-form-item align="left" label="鎺ユ敹瀹跺睘" prop="relationname">
+ <el-input
+ v-model="form.relationname"
+ placeholder="璇疯緭鍏ユ帴鏀跺灞�"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
</el-card>
</el-form>
<!-- 鍣ㄥ畼鍒╃敤璁板綍閮ㄥ垎 - 鏁村悎鍙楄�呰鎯� -->
@@ -1186,6 +1181,7 @@
}
);
+
if (incompleteRecords.length > 0) {
this.$message.warning("璇峰厛瀹屽杽鎵�鏈夊埄鐢ㄨ褰曠殑淇℃伅");
return;
diff --git a/src/views/business/affirm/affirmInfo.vue b/src/views/business/affirm/affirmInfo.vue
index bc14269..613f64e 100644
--- a/src/views/business/affirm/affirmInfo.vue
+++ b/src/views/business/affirm/affirmInfo.vue
@@ -7,12 +7,20 @@
<div slot="header" class="clearfix">
<span class="detail-title">鎹愮尞纭淇℃伅</span>
<el-button
- type="success"
- style="float: right;"
+ type="primary"
+ style="float: right;margin-left: 20px;"
@click="handleSave"
:loading="saveLoading"
>
淇濆瓨纭淇℃伅
+ </el-button>
+ <el-button
+ type="success"
+ style="float: right;margin-left: 20px;"
+ @click="accomplish"
+ :loading="saveLoading"
+ >
+ 纭瀹屾垚
</el-button>
</div>
@@ -359,7 +367,7 @@
// 鍔犺浇鐘舵��
loading: false,
saveLoading: false,
- infoid:null,
+ infoid: null,
// 闄勪欢鐩稿叧鏁版嵁
activeAttachmentType: "1",
attachmentLoading: false,
@@ -756,6 +764,19 @@
.toString()
.padStart(2, "0")}`;
},
+ accomplish() {
+ this.$confirm("鏄惁瀹屾垚璇ユ渚嬫崘鐚‘璁ゆ楠わ紵", "鎻愰啋", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(() => {
+ this.form.state = 3;
+ this.handleSave();
+ })
+
+ .catch(() => {});
+ },
// 淇濆瓨纭淇℃伅
async handleSave() {
@@ -773,6 +794,9 @@
organdecisionOther: this.organdecisionOther
// assessannex瀛楁宸插湪updateAssessannexField涓洿鏂�
};
+ if (saveData.state == 1 || !saveData.state) {
+ saveData.state = 2;
+ }
let response = null;
if (saveData.id) {
response = await relativesEdit(saveData);
diff --git a/src/views/business/affirm/index.vue b/src/views/business/affirm/index.vue
index a7ede48..6a1e061 100644
--- a/src/views/business/affirm/index.vue
+++ b/src/views/business/affirm/index.vue
@@ -165,7 +165,19 @@
}}</span>
</template>
</el-table-column>
-
+<el-table-column
+ label="纭鐘舵��"
+ align="center"
+ prop="state"
+ width="100"
+ >
+ <template slot-scope="scope">
+ <dict-tag
+ :options="dict.type.affirm_type"
+ :value="scope.row.state"
+ />
+ </template>
+ </el-table-column>
<el-table-column
label="瀹跺睘鎰忚"
align="center"
@@ -244,7 +256,7 @@
export default {
name: "ConfirmationList",
components: { Pagination },
- dicts: ["sys_user_sex"],
+ dicts: ["sys_user_sex",'affirm_type'],
data() {
return {
// 閬僵灞�
diff --git a/src/views/business/allocation/allocationInfo.vue b/src/views/business/allocation/allocationInfo.vue
index cfa9d2d..c2106f3 100644
--- a/src/views/business/allocation/allocationInfo.vue
+++ b/src/views/business/allocation/allocationInfo.vue
@@ -505,7 +505,6 @@
id: undefined,
infoid: undefined,
donationcategory: "",
- recordstate: "",
caseNo: "",
donorno: "",
treatmenthospitalname: "",
@@ -535,9 +534,6 @@
],
diagnosisname: [
{ required: true, message: "鐤剧梾璇婃柇涓嶈兘涓虹┖", trigger: "blur" }
- ],
- recordstate: [
- { required: true, message: "璁板綍鐘舵�佷笉鑳戒负绌�", trigger: "change" }
]
},
// 鍒嗛厤璁板綍楠岃瘉瑙勫垯
@@ -959,12 +955,17 @@
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;
});
- this.form.recordstate = 1;
const apiMethod = this.form.id ? allocationedit : allocationadd;
const response = await apiMethod(saveData);
@@ -1033,7 +1034,7 @@
})
.then(async () => {
this.confirmLoading = true;
- this.form.allocationStatus = "1";
+ this.form.allocationStatus = "3";
this.form.allocationTime = new Date()
.toISOString()
.replace("T", " ")
diff --git a/src/views/business/allocation/index.vue b/src/views/business/allocation/index.vue
index 8061001..32a9119 100644
--- a/src/views/business/allocation/index.vue
+++ b/src/views/business/allocation/index.vue
@@ -26,7 +26,7 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
-
+
<el-form-item label="妗堜緥缂栧彿" prop="caseNo">
<el-input
v-model="queryParams.caseNo"
@@ -36,7 +36,7 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
-
+
<el-form-item label="鍒嗛厤鐘舵��" prop="allocationStatus">
<el-select
v-model="queryParams.allocationStatus"
@@ -111,50 +111,7 @@
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
-<<<<<<< HEAD
- <!--
- <el-table-column
-=======
- <!-- <el-table-column
->>>>>>> 059398ad3ad81ea49dfb75ac09f268bc0b0f6145
- label="妗堜緥缂栧彿"
- align="center"
- prop="caseNo"
- width="120"
-<<<<<<< HEAD
- />
- <el-table-column
- label="鎹愮尞鑰呯紪鍙�"
- align="center"
- prop="donorno"
- width="120"
- />
- <el-table-column
- label="璇佷欢鍙风爜"
- align="center"
- prop="idcardno"
- width="180"
- />
- <el-table-column
- label="琛�鍨�"
- align="center"
- prop="bloodtype"
- width="80"
- />
-
- <el-table-column
- label="鍖荤枟鏈烘瀯"
- align="center"
- prop="treatmenthospitalname"
- min-width="150"
- show-overflow-tooltip
- />
- -->
-=======
- /> -->
- <el-table-column label="濮撳悕" align="center" prop="name" width="100" />
->>>>>>> 059398ad3ad81ea49dfb75ac09f268bc0b0f6145
<el-table-column
label="浣忛櫌鍙�"
align="center"
@@ -170,7 +127,7 @@
/>
</template>
</el-table-column>
- <el-table-column label="骞撮緞" align="center" prop="age" width="80" />
+ <el-table-column label="骞撮緞" align="center" prop="age" width="80" />
<el-table-column
label="鐤剧梾璇婃柇"
align="center"
diff --git a/src/views/business/assess/assessInfo.vue b/src/views/business/assess/assessInfo.vue
index a465c99..e75e559 100644
--- a/src/views/business/assess/assessInfo.vue
+++ b/src/views/business/assess/assessInfo.vue
@@ -6,7 +6,7 @@
<el-card class="organ-assessment-card">
<div slot="header" class="clearfix">
<span>鍣ㄥ畼璇勪及琛�</span>
- <el-button
+ <!-- <el-button
v-if="isCoordinator && allOrgansAssessed"
style="float: right; margin-left: 10px"
type="primary"
@@ -18,7 +18,7 @@
</el-button>
<span v-if="!isCoordinator" class="jstitle">
褰撳墠瑙掕壊锛歿{ currentDepartment }}璇勪及浜哄憳
- </span>
+ </span> -->
</div>
<!-- 鎹愮尞鍐冲畾琛ㄥ崟 -->
@@ -420,7 +420,9 @@
<el-button type="primary" @click="handleSaveAll" :loading="saveLoading"
>淇濆瓨璇勪及琛�</el-button
>
- <el-button @click="handleCancel">鍙栨秷</el-button>
+ <el-button type="success" @click="accomplish" :loading="saveLoading"
+ >璇勪及瀹屾垚</el-button
+ >
</div>
<!-- 鏂囦欢棰勮寮圭獥 -->
@@ -690,7 +692,19 @@
this.$forceUpdate();
}
},
+ accomplish() {
+ this.$confirm("鏄惁瀹屾垚璇ユ渚嬪櫒瀹樿瘎浼版楠わ紵", "鎻愰啋", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(() => {
+ this.form.assessState = 3;
+ this.handleSaveAll();
+ })
+ .catch(() => {});
+ },
// 鏁翠綋淇濆瓨鏂规硶
async handleSaveAll() {
this.saveLoading = true;
@@ -735,7 +749,9 @@
})
)
};
-
+ if (saveData.assessState == 1 || !saveData.assessState) {
+ saveData.assessState = 2;
+ }
const saveMethod = this.assessmentData.id ? assessedit : assessAdd;
const response = await saveMethod(saveData);
diff --git a/src/views/business/assess/index.vue b/src/views/business/assess/index.vue
index bbe6a36..1b7bc39 100644
--- a/src/views/business/assess/index.vue
+++ b/src/views/business/assess/index.vue
@@ -123,18 +123,13 @@
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
- <el-table-column
+ <el-table-column
label="浣忛櫌鍙�"
align="center"
prop="inpatientno"
width="120"
/>
- <el-table-column
- label="濮撳悕"
- align="center"
- prop="name"
- width="120"
- />
+ <el-table-column label="濮撳悕" align="center" prop="name" width="120" />
<el-table-column label="鎬у埆" align="center" prop="sex" width="80">
<template slot-scope="scope">
<dict-tag
@@ -170,7 +165,7 @@
</template>
</el-table-column>
-->
-
+
<el-table-column
label="璇勪及鐘舵��"
align="center"
@@ -178,9 +173,10 @@
width="100"
>
<template slot-scope="scope">
- <el-tag :type="statusFilter(scope.row.assessState)">
- {{ statusTextFilter(scope.row.assessState) }}
- </el-tag>
+ <dict-tag
+ :options="dict.type.state_Evaluation"
+ :value="scope.row.assessState"
+ />
</template>
</el-table-column>
<el-table-column
@@ -220,8 +216,7 @@
>
<el-button
v-if="
- scope.row.assessState != '3' ||
- scope.row.assessState != '4'
+ scope.row.assessState != '3' || scope.row.assessState != '4'
"
size="mini"
type="text"
@@ -260,7 +255,7 @@
export default {
name: "AssessmentList",
components: { Pagination },
- dicts: ["sys_user_sex"],
+ dicts: ["sys_user_sex", "state_Evaluation"],
data() {
return {
// 閬僵灞�
@@ -359,12 +354,18 @@
}
// 澶勭悊鏃堕棿鑼冨洿鏌ヨ
- if (this.queryParams.applyTimeRange && this.queryParams.applyTimeRange.length === 2) {
+ if (
+ this.queryParams.applyTimeRange &&
+ this.queryParams.applyTimeRange.length === 2
+ ) {
params.startApplyTime = this.queryParams.applyTimeRange[0];
params.endApplyTime = this.queryParams.applyTimeRange[1];
}
- if (this.queryParams.assessTimeRange && this.queryParams.assessTimeRange.length === 2) {
+ if (
+ this.queryParams.assessTimeRange &&
+ this.queryParams.assessTimeRange.length === 2
+ ) {
params.startAssessTime = this.queryParams.assessTimeRange[0];
params.endAssessTime = this.queryParams.assessTimeRange[1];
}
@@ -463,7 +464,7 @@
// 鍒锋柊鍒楄〃
this.getList();
} catch (error) {
- if (error !== 'cancel') {
+ if (error !== "cancel") {
console.error("纭澶辫触:", error);
}
}
@@ -496,7 +497,6 @@
// 杩欓噷闇�瑕佽皟鐢ㄥ垹闄ゆ帴鍙o紝鏆傛椂妯℃嫙鎴愬姛
this.$message.success("鍒犻櫎鎴愬姛");
this.getList();
-
} catch (error) {
if (error !== "cancel") {
console.error("鍒犻櫎澶辫触:", error);
@@ -529,7 +529,6 @@
} else {
this.$message.error("瀵煎嚭澶辫触锛�" + (response.msg || "鏈煡閿欒"));
}
-
} catch (error) {
if (error !== "cancel") {
console.error("瀵煎嚭澶辫触:", error);
@@ -548,11 +547,11 @@
// 妯℃嫙鏂囦欢涓嬭浇
const blob = new Blob([JSON.stringify(data, null, 2)], {
- type: 'application/vnd.ms-excel'
+ type: "application/vnd.ms-excel"
});
- const link = document.createElement('a');
+ const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
- link.download = '鍖诲璇勪及鏁版嵁.xlsx';
+ link.download = "鍖诲璇勪及鏁版嵁.xlsx";
link.click();
},
// 鏃堕棿鏍煎紡鍖�
diff --git a/src/views/business/course/components/DeathJudgmentStage.vue b/src/views/business/course/components/DeathJudgmentStage.vue
index ce25f7f..b64306c 100644
--- a/src/views/business/course/components/DeathJudgmentStage.vue
+++ b/src/views/business/course/components/DeathJudgmentStage.vue
@@ -1,80 +1,114 @@
<template>
<div class="death-judgment-detail">
- <el-card class="detail-card">
- <!-- 鍩虹淇℃伅 -->
+ <!-- 鍏叡淇℃伅妯″潡锛堢嫭绔嬫樉绀猴級 -->
+
+ <!-- 鍒ゅ畾绫诲瀷鏍囩椤� -->
+ <el-card class="type-card">
+ <el-tabs
+ v-model="activeJudgmentType"
+ type="card"
+ @tab-click="handleTabChange"
+ >
+ <el-tab-pane label="鑴戞浜″垽瀹�" name="brain">
+ <span slot="label">
+ <i class="el-icon-s-promotion" style="margin-right: 5px;"></i>
+ 鑴戞浜″垽瀹�
+ </span>
+ </el-tab-pane>
+ <el-tab-pane label="蹇冩浜″垽瀹�" name="heart">
+ <span slot="label">
+ <i class="el-icon-help" style="margin-right: 5px;"></i>
+ 蹇冩浜″垽瀹�
+ </span>
+ </el-tab-pane>
+ </el-tabs>
+ </el-card>
+ <el-card class="detail-card common-info-card">
<div slot="header" class="clearfix">
- <span class="detail-title">姝讳骸鍒ゅ畾鍩烘湰淇℃伅</span>
+ <span class="detail-title">鍏叡淇℃伅</span>
+ </div>
+
+ <el-form :model="form" label-width="120px">
+ <el-row>
+ <el-col :span="8">
+ <el-form-item label="璐熻矗浜�" prop="responsibleusername">
+ <el-input
+ v-model="form.responsibleusername"
+ :readonly="!isEdit"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="8">
+ <el-form-item label="鍣ㄥ畼鑾峰彇鏈烘瀯" prop="gainhospitalname">
+ <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 v-if="activeJudgmentType === 'brain'" class="detail-card">
+ <div slot="header" class="clearfix">
+ <span class="detail-title">鑴戞浜″垽瀹氫俊鎭�</span>
<el-button
v-if="isEdit"
+ style="float: right; margin-left: 10px;"
type="success"
- style="float: right"
@click="handleSave"
:loading="saveLoading"
>
淇濆瓨淇℃伅
</el-button>
<el-button
+ v-if="isEdit"
+ style="float: right; margin-left: 10px;"
+ type="success"
+ @click="accomplish"
+ :loading="saveLoading"
+ >
+ 瀹屾垚鍒ゅ畾
+ </el-button>
+ <el-button
v-else
+ style="float: right; margin-left: 10px;"
type="primary"
- style="float: right"
@click="handleEdit"
>
缂栬緫淇℃伅
</el-button>
</div>
- <el-form :model="form" ref="form" :rules="rules" label-width="120px">
+ <el-form :model="form" ref="brainForm" :rules="rules" label-width="120px">
<el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="鎹愮尞鑰呯紪鍙�" prop="donorno">
- <el-input
- v-model="form.donorno"
- :readonly="!isEdit"
- placeholder="鑷姩鐢熸垚鎹愮尞鑰呯紪鍙�"
- />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鎹愮尞鑰呭鍚�" prop="name">
- <el-input v-model="form.name" :readonly="!isEdit" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鎬у埆" prop="sex">
- <el-select
- v-model="form.sex"
- :disabled="!isEdit"
- style="width: 100%"
- >
- <el-option label="鐢�" value="1" />
- <el-option label="濂�" value="2" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="骞撮緞" prop="age">
- <el-input v-model="form.age" :readonly="!isEdit" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鐤剧梾璇婃柇" prop="diagnosisname">
- <el-input v-model="form.diagnosisname" :readonly="!isEdit" />
- </el-form-item>
- </el-col>
<el-col :span="8">
<el-form-item label="姝讳骸鍘熷洜" prop="deathreason">
- <el-select
- v-model="form.deathreason"
- :disabled="!isEdit"
- style="width: 100%"
- >
- <el-option label="鑴戞浜�" value="brain_death" />
- <el-option label="蹇冩浜�" value="heart_death" />
- <el-option label="鍏朵粬" value="other" />
- </el-select>
+ <el-input v-model="form.deathreason" :readonly="!isEdit" />
</el-form-item>
</el-col>
</el-row>
@@ -102,198 +136,310 @@
</el-form-item>
</el-col>
</el-row>
+ </el-form>
+ <!-- 鑴戞浜¤瘎浼拌〃闄勪欢 -->
+ <div class="attachment-section">
+ <div class="attachment-header">
+ <h3>鑴戞浜″垽瀹氳瘎浼拌〃闄勪欢</h3>
+ </div>
+
+ <!-- 闄勪欢绫诲瀷閫夐」鍗� -->
+ <el-tabs v-model="activeAttachmentType" type="card">
+ <el-tab-pane
+ v-for="type in brainDeathAttachmentTypes"
+ :key="type.value"
+ :label="type.label"
+ :name="type.value"
+ >
+ <div class="attachment-upload-section">
+ <div class="upload-header">
+ <span class="upload-title">{{ type.label }}</span>
+ <el-tooltip content="鐐瑰嚮涓婁紶璇ョ被鍨嬭瘎浼拌〃" placement="top">
+ <el-button
+ size="mini"
+ type="primary"
+ icon="el-icon-plus"
+ @click="openUploadDialog(type.value)"
+ :disabled="!isEdit"
+ >
+ 娣诲姞璇勪及琛�
+ </el-button>
+ </el-tooltip>
+ </div>
+
+ <!-- 闄勪欢鍒楄〃 -->
+ <el-table
+ :data="getAttachmentsByType(type.value)"
+ v-loading="attachmentLoading"
+ style="width: 100%; margin-top: 15px;"
+ >
+ <el-table-column label="鏂囦欢鍚嶇О" min-width="200">
+ <template slot-scope="scope">
+ <div class="file-info">
+ <i
+ class="el-icon-document"
+ style="margin-right: 8px; color: #409EFF;"
+ ></i>
+ <span>{{ scope.row.fileName }}</span>
+ </div>
+ </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>{{ parseTime(scope.row.uploadTime) }}</span>
+ </template>
+ </el-table-column>
+
+ <el-table-column label="涓婁紶浜�" width="100" 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="text"
+ icon="el-icon-view"
+ @click="handlePreview(scope.row)"
+ >棰勮</el-button
+ >
+ <el-button
+ size="mini"
+ type="text"
+ icon="el-icon-download"
+ @click="handleDownload(scope.row)"
+ >涓嬭浇</el-button
+ >
+ <el-button
+ v-if="isEdit"
+ size="mini"
+ type="text"
+ icon="el-icon-delete"
+ style="color: #F56C6C;"
+ @click="handleRemoveAttachment(scope.row)"
+ >鍒犻櫎</el-button
+ >
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <div
+ v-if="getAttachmentsByType(type.value).length === 0"
+ class="empty-attachment"
+ >
+ <el-empty
+ description="鏆傛棤璇勪及琛ㄩ檮浠�"
+ :image-size="80"
+ ></el-empty>
+ </div>
+ </div>
+ </el-tab-pane>
+ </el-tabs>
+ </div>
+ </el-card>
+
+ <!-- 蹇冩浜″垽瀹氭ā鍧� -->
+ <el-card v-else class="detail-card">
+ <div slot="header" class="clearfix">
+ <span class="detail-title">蹇冩浜″垽瀹氫俊鎭�</span>
+ <el-button
+ v-if="isEdit"
+ style="float: right; margin-left: 10px;"
+ type="success"
+ @click="handleSave"
+ :loading="saveLoading"
+ >
+ 淇濆瓨淇℃伅
+ </el-button>
+ <el-button
+ v-else
+ style="float: right; margin-left: 10px;"
+ type="primary"
+ @click="handleEdit"
+ >
+ 缂栬緫淇℃伅
+ </el-button>
+ </div>
+
+ <el-form :model="form" ref="heartForm" :rules="rules" label-width="120px">
<el-row :gutter="20">
<el-col :span="8">
- <el-form-item label="鍣ㄥ畼鑾峰彇鏈烘瀯" prop="gainhospitalname">
- <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 label="蹇冩浜″師鍥�" prop="heartdeathreason">
+ <el-input v-model="form.heartdeathreason" :readonly="!isEdit" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
- <el-form-item label="璐熻矗浜�" prop="responsibleusername">
+ <el-form-item label="蹇冩浜℃椂闂�" prop="heartdeathtime">
+ <el-date-picker
+ v-model="form.heartdeathtime"
+ type="datetime"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ style="width: 100%"
+ :disabled="!isEdit"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="鍒ゅ畾鍖荤敓涓�" prop="heartdeathjudgedocto">
<el-input
- v-model="form.responsibleusername"
+ v-model="form.heartdeathjudgedocto"
:readonly="!isEdit"
/>
</el-form-item>
</el-col>
<el-col :span="8">
- <el-form-item label="璁板綍鐘舵��" prop="recordstate">
- <el-tag :type="getStatusTag(form.recordstate)">
- {{ getStatusText(form.recordstate) }}
- </el-tag>
+ <el-form-item label="鍒ゅ畾鍖荤敓浜�" prop="heartdeathjudgedoctt">
+ <el-input
+ v-model="form.heartdeathjudgedoctt"
+ :readonly="!isEdit"
+ />
</el-form-item>
</el-col>
</el-row>
-
- <el-form-item label="姝讳骸鍒ゅ畾璇存槑" prop="judgmentDescription">
- <el-input
- type="textarea"
- :rows="3"
- v-model="form.judgmentDescription"
- :readonly="!isEdit"
- placeholder="璇︾粏璁板綍姝讳骸鍒ゅ畾杩囩▼鍜屼緷鎹�"
- />
- </el-form-item>
</el-form>
- </el-card>
- <!-- 璇勪及琛ㄩ檮浠� -->
- <el-card class="attachment-card">
- <div slot="header" class="clearfix">
- <span class="detail-title">姝讳骸鍒ゅ畾璇勪及琛ㄩ檮浠�</span>
- <!-- <el-button
- v-if="isEdit"
- type="primary"
- size="mini"
- @click="openUploadDialog"
- :loading="uploadLoading"
- >
- 涓婁紶闄勪欢
- </el-button> -->
+ <!-- 蹇冩浜¤瘎浼拌〃闄勪欢 -->
+ <div class="attachment-section">
+ <div class="attachment-header">
+ <h3>蹇冩浜″垽瀹氳瘎浼拌〃闄勪欢</h3>
+ </div>
+
+ <!-- 蹇冩浜¢檮浠剁被鍨嬮�夐」鍗� -->
+ <el-tabs v-model="activeHeartDeathAttachmentType" type="card">
+ <el-tab-pane
+ v-for="type in heartDeathAttachmentTypes"
+ :key="type.value"
+ :label="type.label"
+ :name="type.value"
+ >
+ <div class="attachment-upload-section">
+ <div class="upload-header">
+ <span class="upload-title">{{ type.label }}</span>
+ <el-tooltip content="鐐瑰嚮涓婁紶璇ョ被鍨嬭瘎浼拌〃" placement="top">
+ <el-button
+ size="mini"
+ type="primary"
+ icon="el-icon-plus"
+ @click="openHeartDeathUploadDialog(type.value)"
+ :disabled="!isEdit"
+ >
+ 娣诲姞璇勪及琛�
+ </el-button>
+ </el-tooltip>
+ </div>
+
+ <!-- 蹇冩浜¢檮浠跺垪琛� -->
+ <el-table
+ :data="getHeartDeathAttachmentsByType(type.value)"
+ v-loading="attachmentLoading"
+ style="width: 100%; margin-top: 15px;"
+ >
+ <el-table-column label="鏂囦欢鍚嶇О" min-width="200">
+ <template slot-scope="scope">
+ <div class="file-info">
+ <i
+ class="el-icon-document"
+ style="margin-right: 8px; color: #409EFF;"
+ ></i>
+ <span>{{ scope.row.fileName }}</span>
+ </div>
+ </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>{{ parseTime(scope.row.uploadTime) }}</span>
+ </template>
+ </el-table-column>
+
+ <el-table-column label="涓婁紶浜�" width="100" 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="text"
+ icon="el-icon-view"
+ @click="handlePreview(scope.row)"
+ >棰勮</el-button
+ >
+ <el-button
+ size="mini"
+ type="text"
+ icon="el-icon-download"
+ @click="handleDownload(scope.row)"
+ >涓嬭浇</el-button
+ >
+ <el-button
+ v-if="isEdit"
+ size="mini"
+ type="text"
+ icon="el-icon-delete"
+ style="color: #F56C6C;"
+ @click="handleRemoveHeartDeathAttachment(scope.row)"
+ >鍒犻櫎</el-button
+ >
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <div
+ v-if="getHeartDeathAttachmentsByType(type.value).length === 0"
+ class="empty-attachment"
+ >
+ <el-empty
+ description="鏆傛棤璇勪及琛ㄩ檮浠�"
+ :image-size="80"
+ ></el-empty>
+ </div>
+ </div>
+ </el-tab-pane>
+ </el-tabs>
</div>
-
- <!-- 闄勪欢绫诲瀷閫夐」鍗� -->
- <el-tabs v-model="activeAttachmentType" type="card">
- <el-tab-pane
- v-for="type in attachmentTypes"
- :key="type.value"
- :label="type.label"
- :name="type.value"
- >
- <div class="attachment-upload-section">
- <div class="upload-header">
- <span class="upload-title">{{ type.label }}</span>
- <el-tooltip content="鐐瑰嚮涓婁紶璇ョ被鍨嬭瘎浼拌〃" placement="top">
- <el-button
- size="mini"
- type="primary"
- icon="el-icon-plus"
- @click="openUploadDialog(type.value)"
- :disabled="!isEdit"
- >
- 娣诲姞璇勪及琛�
- </el-button>
- </el-tooltip>
- </div>
-
- <!-- 闄勪欢鍒楄〃 -->
- <el-table
- :data="getAttachmentsByType(type.value)"
- v-loading="attachmentLoading"
- style="width: 100%; margin-top: 15px;"
- >
- <el-table-column label="鏂囦欢鍚嶇О" min-width="200">
- <template slot-scope="scope">
- <div class="file-info">
- <i
- class="el-icon-document"
- style="margin-right: 8px; color: #409EFF;"
- ></i>
- <span>{{ scope.row.fileName }}</span>
- </div>
- </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>{{ parseTime(scope.row.uploadTime) }}</span>
- </template>
- </el-table-column>
-
- <el-table-column label="涓婁紶浜�" width="100" 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="text"
- icon="el-icon-view"
- @click="handlePreview(scope.row)"
- >棰勮</el-button
- >
- <el-button
- size="mini"
- type="text"
- icon="el-icon-download"
- @click="handleDownload(scope.row)"
- >涓嬭浇</el-button
- >
- <el-button
- v-if="isEdit"
- size="mini"
- type="text"
- icon="el-icon-delete"
- style="color: #F56C6C;"
- @click="handleRemoveAttachment(scope.row)"
- >鍒犻櫎</el-button
- >
- </template>
- </el-table-column>
- </el-table>
-
- <div
- v-if="getAttachmentsByType(type.value).length === 0"
- class="empty-attachment"
- >
- <el-empty
- description="鏆傛棤璇勪及琛ㄩ檮浠�"
- :image-size="80"
- ></el-empty>
- </div>
- </div>
- </el-tab-pane>
- </el-tabs>
</el-card>
- <!-- 涓婁紶瀵硅瘽妗� -->
+ <!-- 涓婁紶瀵硅瘽妗嗭紙鑴戞浜★級 -->
<el-dialog
- :title="`涓婁紶${getCurrentTypeLabel}璇勪及琛╜"
+ :title="`涓婁紶${getCurrentBrainDeathTypeLabel}璇勪及琛╜"
:visible.sync="uploadDialogVisible"
width="500px"
:close-on-click-modal="false"
@@ -333,15 +479,66 @@
</el-button>
</div>
</el-dialog>
+
+ <!-- 涓婁紶瀵硅瘽妗嗭紙蹇冩浜★級 -->
+ <el-dialog
+ :title="`涓婁紶${getCurrentHeartDeathTypeLabel}璇勪及琛╜"
+ :visible.sync="heartDeathUploadDialogVisible"
+ width="500px"
+ :close-on-click-modal="false"
+ >
+ <el-upload
+ ref="heartDeathUploadRef"
+ class="upload-demo"
+ drag
+ :action="uploadAction"
+ :headers="headers"
+ multiple
+ :file-list="tempHeartDeathFileList"
+ :before-upload="beforeUpload"
+ :on-change="handleHeartDeathFileChange"
+ :on-remove="handleHeartDeathTempRemove"
+ :on-success="handleHeartDeathUploadSuccess"
+ :auto-upload="false"
+ >
+ <i class="el-icon-upload"></i>
+ <div class="el-upload__text">
+ 灏嗚瘎浼拌〃鏂囦欢鎷栧埌姝ゅ锛屾垨<em>鐐瑰嚮涓婁紶</em>
+ </div>
+ <div class="el-upload__tip" slot="tip">
+ 鏀寔涓婁紶pdf銆乯pg銆乸ng銆乨oc銆乨ocx銆亁ls銆亁lsx鏍煎紡鏂囦欢锛屽崟涓枃浠朵笉瓒呰繃10MB
+ </div>
+ </el-upload>
+
+ <div slot="footer" class="dialog-footer">
+ <el-button @click="heartDeathUploadDialogVisible = false"
+ >鍙栨秷</el-button
+ >
+ <el-button
+ type="primary"
+ @click="submitHeartDeathUpload"
+ :loading="heartDeathUploadLoading"
+ :disabled="tempHeartDeathFileList.length === 0"
+ >
+ 纭涓婁紶
+ </el-button>
+ </div>
+ </el-dialog>
</div>
</template>
<script>
-import { deathinfoedit, queryDathInfoBaseInfo } from "@/api/businessApi";
+import {
+ deathinfoedit,
+ deathinfoadd,
+ queryDathInfoBaseInfo
+} from "@/api/businessApi";
import { getToken } from "@/utils/auth";
+import CaseBasicInfo from "@/components/CaseBasicInfo";
export default {
name: "DeathJudgmentDetail",
+ components: { CaseBasicInfo },
props: {
infoid: {
type: String,
@@ -350,10 +547,13 @@
},
data() {
return {
- // 鏄惁缂栬緫妯″紡
+ caseId: null,
isEdit: false,
- // 淇濆瓨鍔犺浇鐘舵��
saveLoading: false,
+
+ // 鍒ゅ畾绫诲瀷鏍囩
+ activeJudgmentType: "brain", // 榛樿鏄剧ず鑴戞浜�
+
// 琛ㄥ崟鏁版嵁
form: {
id: undefined,
@@ -363,19 +563,28 @@
sex: "",
age: "",
diagnosisname: "",
+ // 鑴戞浜$浉鍏冲瓧娈�
deathreason: "",
deathtime: "",
deathjudgedocto: "",
deathjudgedoctt: "",
+ // 蹇冩浜$浉鍏冲瓧娈�
+ heartdeathtime: "",
+ heartdeathreason: "",
+ heartdeathjudgedocto: "",
+ heartdeathjudgedoctt: "",
+ heartDeathRemark: "",
+ // 鍏叡瀛楁
gainhospitalno: "",
gainhospitalname: "",
isspendremember: 0,
isrestoreremains: 0,
- rememberannex: "",
+ rememberAnnex: "",
+ heartdeathjudgeannex: "", // 鏂板蹇冩浜¢檮浠跺瓧娈�
responsibleuserid: "",
responsibleusername: "",
recordstate: "0",
- judgmentDescription: ""
+ remark: ""
},
// 琛ㄥ崟楠岃瘉瑙勫垯
rules: {
@@ -390,56 +599,98 @@
],
deathjudgedocto: [
{ required: true, message: "鍒ゅ畾鍖荤敓涓�涓嶈兘涓虹┖", trigger: "blur" }
+ ],
+ heartdeathreason: [
+ { required: false, message: "蹇冩浜″師鍥犱笉鑳戒负绌�", trigger: "blur" }
+ ],
+ heartdeathtime: [
+ { required: false, message: "蹇冩浜℃椂闂翠笉鑳戒负绌�", trigger: "change" }
+ ],
+ heartdeathjudgedocto: [
+ {
+ required: false,
+ message: "蹇冩浜″垽瀹氬尰鐢熶竴涓嶈兘涓虹┖",
+ trigger: "blur"
+ }
]
},
// 闄勪欢鐩稿叧鏁版嵁
activeAttachmentType: "1",
+ activeHeartDeathAttachmentType: "heart_1", // 蹇冩浜¢檮浠剁被鍨�
attachmentLoading: false,
uploadDialogVisible: false,
+ heartDeathUploadDialogVisible: false, // 蹇冩浜′笂浼犲璇濇
uploadLoading: false,
+ heartDeathUploadLoading: false, // 蹇冩浜′笂浼犲姞杞界姸鎬�
tempFileList: [],
+ tempHeartDeathFileList: [], // 蹇冩浜′复鏃舵枃浠跺垪琛�
currentUploadType: "",
+ currentHeartDeathUploadType: "", // 褰撳墠蹇冩浜′笂浼犵被鍨�
uploadAction: process.env.VUE_APP_BASE_API + "/common/upload",
headers: {
Authorization: "Bearer " + getToken()
},
- // 璇勪及琛ㄧ被鍨嬪畾涔�
- attachmentTypes: [
+ // 鑴戞浜¤瘎浼拌〃绫诲瀷瀹氫箟
+ brainDeathAttachmentTypes: [
{ value: "1", label: "鑴戞浜″垽瀹氳〃" },
{ value: "2", label: "鑴戠數鍥捐瘎浼拌〃" },
{ value: "3", label: "鐭綔浼忔湡浣撴劅璇卞彂鐢典綅璇勪及琛�" },
{ value: "4", label: "缁忛澶氭櫘鍕掕秴澹拌瘎浼拌褰�" },
{ value: "5", label: "鍗仴濮旇剳鎹熶激璐ㄦ帶涓績 - 涓村簥缁煎悎璇勪及琛�" },
- { value: "6", label: "UW璇勫垎琛�" },
- { value: "7", label: "蹇冩浜″垽瀹氳〃" }
+ { value: "6", label: "UW璇勫垎琛�" }
+ ],
+ // 蹇冩浜¤瘎浼拌〃绫诲瀷瀹氫箟
+ heartDeathAttachmentTypes: [
+ { value: "heart_1", label: "蹇冩浜″垽瀹氳〃" },
+ { value: "heart_2", label: "蹇冪數鍥捐瘎浼拌〃" }
],
// 闄勪欢鍒楄〃鏁版嵁
- attachmentList: []
+ attachmentList: [], // 鑴戞浜¢檮浠�
+ heartDeathAttachmentList: [] // 蹇冩浜¢檮浠�
};
},
computed: {
- getCurrentTypeLabel() {
- const type = this.attachmentTypes.find(
+ getCurrentBrainDeathTypeLabel() {
+ const type = this.brainDeathAttachmentTypes.find(
t => t.value === this.currentUploadType
+ );
+ return type ? type.label : "";
+ },
+ getCurrentHeartDeathTypeLabel() {
+ const type = this.heartDeathAttachmentTypes.find(
+ t => t.value === this.currentHeartDeathUploadType
);
return type ? type.label : "";
}
},
created() {
+ this.caseId = this.infoid;
+ // 浠庤矾鐢卞弬鏁拌幏鍙栭粯璁ゆ樉绀虹被鍨�
+ if (this.$route.query.judgmentType) {
+ this.activeJudgmentType = this.$route.query.type;
+ }
+
this.getDetail(this.infoid);
this.getAttachmentList();
},
methods: {
+ // 鏍囩椤靛垏鎹�
+ handleTabChange(tab) {
+ this.activeJudgmentType = tab.name;
+ // 鍙互鍦ㄨ繖閲屾坊鍔犲叾浠栧垏鎹㈤�昏緫
+ },
+
// 鐢熸垚鎹愮尞鑰呯紪鍙�
generateDonorNo() {
const timestamp = Date.now().toString();
this.form.donorno = "DONOR" + timestamp.slice(-8);
},
+
// 鑾峰彇璇︽儏
- async getDetail(id) {
+ async getDetail(infoid) {
try {
- const response = await queryDathInfoBaseInfo({ infoid: id });
+ const response = await queryDathInfoBaseInfo({ infoid });
let realData = {};
if (response && response.data) {
@@ -462,31 +713,48 @@
};
// 瑙f瀽闄勪欢淇℃伅
- if (realData.rememberannex) {
- this.parseAttachmentData(realData.rememberannex);
+ if (realData.rememberAnnex) {
+ this.parseAttachmentData(realData.rememberAnnex, "brain");
+ }
+
+ // 瑙f瀽蹇冩浜¢檮浠朵俊鎭�
+ if (realData.heartdeathjudgeannex) {
+ this.parseAttachmentData(realData.heartdeathjudgeannex, "heart");
}
} catch (error) {
console.error("鑾峰彇姝讳骸鍒ゅ畾璇︽儏澶辫触:", error);
this.$message.error("鏁版嵁鍔犺浇澶辫触");
}
},
+
// 瑙f瀽闄勪欢鏁版嵁
- parseAttachmentData(attachmentJson) {
+ parseAttachmentData(attachmentJson, type = "brain") {
try {
if (attachmentJson) {
const attachments = JSON.parse(attachmentJson);
if (Array.isArray(attachments)) {
- this.attachmentList = attachments;
+ if (type === "brain") {
+ this.attachmentList = attachments;
+ } else if (type === "heart") {
+ this.heartDeathAttachmentList = attachments;
+ }
}
}
} catch (error) {
console.error("瑙f瀽闄勪欢鏁版嵁澶辫触:", error);
}
},
- // 鏋勫缓闄勪欢JSON鏁版嵁
- buildAttachmentJson() {
+
+ // 鏋勫缓鑴戞浜¢檮浠禞SON鏁版嵁
+ buildBrainDeathAttachmentJson() {
return JSON.stringify(this.attachmentList);
},
+
+ // 鏋勫缓蹇冩浜¢檮浠禞SON鏁版嵁
+ buildHeartDeathAttachmentJson() {
+ return JSON.stringify(this.heartDeathAttachmentList);
+ },
+
// 鑾峰彇鐘舵�佹爣绛炬牱寮�
getStatusTag(status) {
const statusMap = {
@@ -496,6 +764,7 @@
};
return statusMap[status] || "info";
},
+
// 鑾峰彇鐘舵�佹枃鏈�
getStatusText(status) {
const textMap = {
@@ -505,18 +774,25 @@
};
return textMap[status] || "鏈煡鐘舵��";
},
+
// 鑾峰彇闄勪欢鍒楄〃
getAttachmentList() {
this.attachmentLoading = true;
- // 瀹為檯椤圭洰涓粠鎺ュ彛鑾峰彇闄勪欢鏁版嵁
setTimeout(() => {
this.attachmentLoading = false;
}, 500);
},
- // 鏍规嵁绫诲瀷鑾峰彇闄勪欢
+
+ // 鏍规嵁绫诲瀷鑾峰彇鑴戞浜¢檮浠�
getAttachmentsByType(type) {
return this.attachmentList.filter(item => item.type === type);
},
+
+ // 鏍规嵁绫诲瀷鑾峰彇蹇冩浜¢檮浠�
+ getHeartDeathAttachmentsByType(type) {
+ return this.heartDeathAttachmentList.filter(item => item.type === type);
+ },
+
// 鑾峰彇鏂囦欢绫诲瀷
getFileType(fileName) {
const ext = fileName
@@ -535,7 +811,8 @@
};
return typeMap[ext] || ext.toUpperCase();
},
- // 鎵撳紑涓婁紶瀵硅瘽妗�
+
+ // 鎵撳紑鑴戞浜′笂浼犲璇濇
openUploadDialog(type = null) {
this.currentUploadType = type || this.activeAttachmentType;
this.tempFileList = [];
@@ -546,6 +823,20 @@
}
});
},
+
+ // 鎵撳紑蹇冩浜′笂浼犲璇濇
+ openHeartDeathUploadDialog(type = null) {
+ this.currentHeartDeathUploadType =
+ type || this.activeHeartDeathAttachmentType;
+ this.tempHeartDeathFileList = [];
+ this.heartDeathUploadDialogVisible = true;
+ this.$nextTick(() => {
+ if (this.$refs.heartDeathUploadRef) {
+ this.$refs.heartDeathUploadRef.clearFiles();
+ }
+ });
+ },
+
// 涓婁紶鍓嶆牎楠�
beforeUpload(file) {
const allowedTypes = [
@@ -585,24 +876,38 @@
return true;
},
- // 鏂囦欢閫夋嫨鍙樺寲
+
+ // 鑴戞浜℃枃浠堕�夋嫨鍙樺寲
handleFileChange(file, fileList) {
this.tempFileList = fileList;
},
- // 绉婚櫎涓存椂鏂囦欢
+
+ // 蹇冩浜℃枃浠堕�夋嫨鍙樺寲
+ handleHeartDeathFileChange(file, fileList) {
+ this.tempHeartDeathFileList = fileList;
+ },
+
+ // 绉婚櫎鑴戞浜′复鏃舵枃浠�
handleTempRemove(file, fileList) {
this.tempFileList = fileList;
},
- /** 涓婁紶鎴愬姛澶勭悊 */
+
+ // 绉婚櫎蹇冩浜′复鏃舵枃浠�
+ handleHeartDeathTempRemove(file, fileList) {
+ this.tempHeartDeathFileList = fileList;
+ },
+
+ // 鑴戞浜′笂浼犳垚鍔熷鐞�
handleUploadSuccess(response, file, fileList) {
if (response.code === 200) {
file.url = response.data || response.url;
this.$message.success("鏂囦欢涓婁紶鎴愬姛");
+
for (const file of this.tempFileList) {
const newAttachment = {
id: Date.now() + Math.random(),
type: this.currentUploadType,
- typeName: this.getCurrentTypeLabel,
+ typeName: this.getCurrentBrainDeathTypeLabel,
fileName: file.name,
fileSize: file.size,
uploadTime: new Date().toISOString(),
@@ -613,8 +918,8 @@
this.attachmentList.push(newAttachment);
}
- // 鏇存柊闄勪欢JSON鏁版嵁鍒拌〃鍗�
- this.form.rememberannex = this.buildAttachmentJson();
+ // 鏇存柊鑴戞浜¢檮浠禞SON鏁版嵁鍒拌〃鍗�
+ this.form.rememberAnnex = this.buildBrainDeathAttachmentJson();
this.$message.success("鏂囦欢涓婁紶鎴愬姛");
this.uploadDialogVisible = false;
@@ -624,45 +929,60 @@
this.$message.error(response.msg || "鏂囦欢涓婁紶澶辫触");
}
},
- // 鎻愪氦涓婁紶
- async submitUpload() {
+
+ // 蹇冩浜′笂浼犳垚鍔熷鐞�
+ handleHeartDeathUploadSuccess(response, file, fileList) {
+ if (response.code === 200) {
+ file.url = response.data || response.url;
+
+ for (const file of this.tempHeartDeathFileList) {
+ const newAttachment = {
+ id: Date.now() + Math.random(),
+ type: this.currentHeartDeathUploadType,
+ typeName: this.getCurrentHeartDeathTypeLabel,
+ fileName: file.name,
+ fileSize: file.size,
+ uploadTime: new Date().toISOString(),
+ uploader: "褰撳墠鐢ㄦ埛",
+ fileUrl: file.url
+ };
+
+ this.heartDeathAttachmentList.push(newAttachment);
+ }
+
+ // 鏇存柊蹇冩浜¢檮浠禞SON鏁版嵁鍒拌〃鍗�
+ this.form.heartdeathjudgeannex = this.buildHeartDeathAttachmentJson();
+
+ this.$message.success("鏂囦欢涓婁紶鎴愬姛");
+ this.heartDeathUploadDialogVisible = false;
+ this.heartDeathUploadLoading = false;
+ this.tempHeartDeathFileList = [];
+ } else {
+ this.$message.error(response.msg || "鏂囦欢涓婁紶澶辫触");
+ }
+ },
+
+ // 鎻愪氦鑴戞浜′笂浼�
+ submitUpload() {
if (this.tempFileList.length === 0) {
this.$message.warning("璇峰厛閫夋嫨瑕佷笂浼犵殑鏂囦欢");
return;
}
this.$refs.uploadRef.submit();
this.uploadLoading = true;
-
- // try {
- // for (const file of this.tempFileList) {
- // const newAttachment = {
- // id: Date.now() + Math.random(),
- // type: this.currentUploadType,
- // typeName: this.getCurrentTypeLabel,
- // fileName: file.name,
- // fileSize: file.size,
- // uploadTime: new Date().toISOString(),
- // uploader: "褰撳墠鐢ㄦ埛",
- // fileUrl: URL.createObjectURL(file.raw)
- // };
-
- // this.attachmentList.push(newAttachment);
- // }
-
- // // 鏇存柊闄勪欢JSON鏁版嵁鍒拌〃鍗�
- // this.form.rememberannex = this.buildAttachmentJson();
-
- // this.$message.success("鏂囦欢涓婁紶鎴愬姛");
- // this.uploadDialogVisible = false;
- // this.tempFileList = [];
- // } catch (error) {
- // this.$message.error("鏂囦欢涓婁紶澶辫触");
- // console.error("涓婁紶澶辫触:", error);
- // } finally {
- // this.uploadLoading = false;
- // }
},
- // 鍒犻櫎闄勪欢
+
+ // 鎻愪氦蹇冩浜′笂浼�
+ submitHeartDeathUpload() {
+ if (this.tempHeartDeathFileList.length === 0) {
+ this.$message.warning("璇峰厛閫夋嫨瑕佷笂浼犵殑鏂囦欢");
+ return;
+ }
+ this.$refs.heartDeathUploadRef.submit();
+ this.heartDeathUploadLoading = true;
+ },
+
+ // 鍒犻櫎鑴戞浜¢檮浠�
handleRemoveAttachment(attachment) {
this.$confirm("纭畾瑕佸垹闄よ繖涓瘎浼拌〃闄勪欢鍚楋紵", "鎻愮ず", {
confirmButtonText: "纭畾",
@@ -675,13 +995,33 @@
);
if (index !== -1) {
this.attachmentList.splice(index, 1);
- // 鏇存柊闄勪欢JSON鏁版嵁鍒拌〃鍗�
- this.form.rememberannex = this.buildAttachmentJson();
+ this.form.rememberAnnex = this.buildBrainDeathAttachmentJson();
this.$message.success("璇勪及琛ㄥ垹闄ゆ垚鍔�");
}
})
.catch(() => {});
},
+
+ // 鍒犻櫎蹇冩浜¢檮浠�
+ handleRemoveHeartDeathAttachment(attachment) {
+ this.$confirm("纭畾瑕佸垹闄よ繖涓瘎浼拌〃闄勪欢鍚楋紵", "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(() => {
+ const index = this.heartDeathAttachmentList.findIndex(
+ item => item.id === attachment.id
+ );
+ if (index !== -1) {
+ this.heartDeathAttachmentList.splice(index, 1);
+ this.form.heartdeathjudgeannex = this.buildHeartDeathAttachmentJson();
+ this.$message.success("璇勪及琛ㄥ垹闄ゆ垚鍔�");
+ }
+ })
+ .catch(() => {});
+ },
+
// 棰勮闄勪欢
handlePreview(attachment) {
if (attachment.fileName.endsWith(".pdf")) {
@@ -699,6 +1039,7 @@
this.$message.info("璇ユ枃浠剁被鍨嬫殏涓嶆敮鎸佸湪绾块瑙堬紝璇蜂笅杞藉悗鏌ョ湅");
}
},
+
// 涓嬭浇闄勪欢
handleDownload(attachment) {
const link = document.createElement("a");
@@ -707,13 +1048,31 @@
link.click();
this.$message.success(`寮�濮嬩笅杞�: ${attachment.fileName}`);
},
+
// 缂栬緫淇℃伅
handleEdit() {
this.isEdit = true;
},
+ accomplish() {
+ this.$confirm("鏄惁纭瀹屾垚璇ユ渚嬫浜″垽瀹氬叏閮ㄤ俊鎭紵", "鎻愰啋", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(() => {
+ this.form.state = 3;
+ this.handleSave();
+ })
+
+ .catch(() => {});
+ },
// 淇濆瓨淇℃伅
async handleSave() {
- this.$refs.form.validate(async valid => {
+ // 鏍规嵁褰撳墠鏍囩閫夋嫨楠岃瘉瑙勫垯
+ let formRef =
+ this.activeJudgmentType === "brain" ? "brainForm" : "heartForm";
+
+ this.$refs[formRef].validate(async valid => {
if (valid) {
this.saveLoading = true;
@@ -721,16 +1080,28 @@
// 鏋勫缓鎻愪氦鏁版嵁
const submitData = {
...this.form,
+ infoid: this.infoid,
// 纭繚闄勪欢鏁版嵁鏈�鏂�
- rememberannex: this.buildAttachmentJson()
+ rememberAnnex: this.buildBrainDeathAttachmentJson(),
+ heartdeathjudgeannex: this.buildHeartDeathAttachmentJson()
};
+ if (submitData.state == 1 || !submitData.state) {
+ submitData.state = 2;
+ }
+ let response = null;
- const response = await deathinfoedit(submitData);
+ if (submitData.id) {
+ response = await deathinfoedit(submitData);
+ } else {
+ response = await deathinfoadd(submitData);
+ }
if (response.code === 200) {
this.$message.success("淇濆瓨鎴愬姛");
this.isEdit = false;
-
+ if (!this.form.id) {
+ this.form.id = response.data;
+ }
if (this.$route.path.includes("/add")) {
this.$router.push("/case/deathJudgment");
}
@@ -746,6 +1117,7 @@
}
});
},
+
// 鏂囦欢澶у皬鏍煎紡鍖�
formatFileSize(size) {
if (size === 0) return "0 B";
@@ -754,6 +1126,7 @@
const i = Math.floor(Math.log(size) / Math.log(k));
return parseFloat((size / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
},
+
// 鏃堕棿鏍煎紡鍖�
parseTime(time) {
if (!time) return "";
@@ -780,17 +1153,60 @@
padding: 20px;
}
-.detail-card {
+.type-card {
margin-bottom: 20px;
+ border: none;
+ box-shadow: none;
}
-.attachment-card {
+.type-card >>> .el-tabs__item {
+ font-size: 16px;
+ font-weight: bold;
+ padding: 0 20px;
+ height: 50px;
+ line-height: 50px;
+}
+
+.type-card >>> .el-tabs__item.is-active {
+ color: #409eff;
+ border-bottom: 3px solid #409eff;
+}
+
+.detail-card {
margin-bottom: 20px;
+ border: 1px solid #e6ebf5;
+ border-radius: 8px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.common-info-card {
+ border-top: 2px solid #67c23a;
+}
+
+.detail-card >>> .el-card__header {
+ background-color: #f5f7fa;
+ border-bottom: 1px solid #e6ebf5;
+ padding: 15px 20px;
}
.detail-title {
- font-size: 16px;
+ font-size: 18px;
font-weight: bold;
+ color: #303133;
+}
+
+.attachment-section {
+ margin-top: 20px;
+ padding-top: 20px;
+ border-top: 1px solid #e6ebf5;
+}
+
+.attachment-header h3 {
+ font-size: 16px;
+ color: #303133;
+ margin-bottom: 15px;
+ padding-bottom: 10px;
+ border-bottom: 1px solid #eee;
}
.attachment-upload-section {
@@ -802,6 +1218,7 @@
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
+ padding: 10px 0;
}
.upload-title {
@@ -819,6 +1236,9 @@
text-align: center;
padding: 40px 0;
color: #909399;
+ border: 1px dashed #dcdfe6;
+ border-radius: 4px;
+ margin-top: 20px;
}
/* 鍥剧墖棰勮瀵硅瘽妗嗘牱寮� */
diff --git a/src/views/business/course/components/DonationConfirmStage.vue b/src/views/business/course/components/DonationConfirmStage.vue
index 8f69cb6..044817c 100644
--- a/src/views/business/course/components/DonationConfirmStage.vue
+++ b/src/views/business/course/components/DonationConfirmStage.vue
@@ -1,59 +1,14 @@
<template>
<div class="confirmation-detail">
+
<el-card class="detail-card">
<!-- 鍩虹淇℃伅 -->
<div slot="header" class="clearfix">
- <span class="detail-title">鎹愮尞纭鍩烘湰淇℃伅</span>
- <el-button
- type="success"
- style="float: right;"
- @click="handleSave"
- :loading="saveLoading"
- >
- 淇濆瓨纭淇℃伅
- </el-button>
+ <span class="detail-title">鎹愮尞纭淇℃伅</span>
+
</div>
<el-form :model="form" ref="form" label-width="120px">
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="浣忛櫌鍙�" prop="caseNo">
- <el-input v-model="form.caseNo" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鎹愮尞鑰呭鍚�" prop="name">
- <el-input v-model="form.name" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鎬у埆" prop="sex">
- <el-select v-model="form.sex" style="width: 100%">
- <el-option label="鐢�" value="1" />
- <el-option label="濂�" value="2" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="骞撮緞" prop="age">
- <el-input v-model="form.age" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鐤剧梾璇婃柇" prop="diagnosisname">
- <el-input v-model="form.diagnosisname" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鎵�鍦ㄥ尰鐤楁満鏋�" prop="treatmenthospitalname">
- <el-input v-model="form.treatmenthospitalname" />
- </el-form-item>
- </el-col>
- </el-row>
-
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="鍗忚皟鍛�1" prop="coordinatedusernameo">
@@ -91,7 +46,6 @@
<el-date-picker
v-model="form.signdate"
type="datetime"
- value-format="yyyy-MM-dd"
style="width: 100%"
/>
</el-form-item>
@@ -341,15 +295,16 @@
</template>
<script>
-import { relativesList, relativesEdit } from "@/api/businessApi";
+import { relativesList, relativesEdit, relativesAdd } from "@/api/businessApi";
import FilePreviewDialog from "@/components/FilePreviewDialog";
-
+import CaseBasicInfo from "@/components/CaseBasicInfo";
export default {
name: "ConfirmationDetail",
components: {
- FilePreviewDialog
+ FilePreviewDialog,
+ CaseBasicInfo
},
- props: {
+ props: {
infoid: {
type: String,
default: true
@@ -358,6 +313,8 @@
dicts: ["sys_FamilyRelation"],
data() {
return {
+ caseId: null,
+
// 鏄惁缂栬緫妯″紡
isEdit: false,
// 琛ㄥ崟鏁版嵁
@@ -441,12 +398,9 @@
}
},
created() {
+ this.caseId = this.infoid;
this.isEdit = this.$route.query.confirm === "true";
- console.log(this.infoid, "this.infoid");
-
if (this.infoid) {
- console.log(1);
-
this.getDetail(this.infoid);
}
},
@@ -456,10 +410,8 @@
this.loading = true;
try {
const response = await relativesList({ infoid });
- console.log(2);
if (response.code === 200) {
- console.log(3);
this.handleDetailData(response);
} else {
this.$message.error("鑾峰彇璇︽儏澶辫触锛�" + (response.msg || "鏈煡閿欒"));
@@ -495,7 +447,7 @@
this.form = {
...this.form,
id: detailData.id || this.$route.query.id,
- infoid: detailData.infoid || this.infoid,
+ infoid: detailData.infoid || infoid,
caseNo: detailData.caseNo || "",
name: detailData.name || "",
sex: detailData.sex || "",
@@ -800,6 +752,19 @@
.toString()
.padStart(2, "0")}`;
},
+ accomplish() {
+ this.$confirm("鏄惁瀹屾垚璇ユ渚嬫崘鐚‘璁ゆ楠わ紵", "鎻愰啋", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(() => {
+ this.form.state = 3;
+ this.handleSave();
+ })
+
+ .catch(() => {});
+ },
// 淇濆瓨纭淇℃伅
async handleSave() {
@@ -812,12 +777,20 @@
const saveData = {
...this.form,
+ infoid: this.infoid,
organdecision: this.organdecision.join(","),
organdecisionOther: this.organdecisionOther
// assessannex瀛楁宸插湪updateAssessannexField涓洿鏂�
};
-
- const response = await relativesEdit(saveData);
+ if (saveData.state == 1 || !saveData.state) {
+ saveData.state = 2;
+ }
+ let response = null;
+ if (saveData.id) {
+ response = await relativesEdit(saveData);
+ } else {
+ response = await relativesAdd(saveData);
+ }
if (response.code === 200) {
this.$message.success("淇濆瓨鎴愬姛");
diff --git a/src/views/business/course/components/DonorMaintenanceStage.vue b/src/views/business/course/components/DonorMaintenanceStage.vue
index e07bdc9..f30f888 100644
--- a/src/views/business/course/components/DonorMaintenanceStage.vue
+++ b/src/views/business/course/components/DonorMaintenanceStage.vue
@@ -1,171 +1,13 @@
<template>
<div class="maintenance-detail">
- <!-- 鍩虹淇℃伅 -->
- <el-card class="detail-card">
- <div slot="header" class="clearfix">
- <span class="detail-title">渚涜�呭熀鏈俊鎭�</span>
- </div>
-
- <el-form :model="form" ref="form" label-width="120px">
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="浣忛櫌鍙�" prop="caseNo">
- <el-input v-model="form.caseNo" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鎹愮尞鑰呭鍚�" prop="name">
- <el-input v-model="form.name" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鎬у埆" prop="gender">
- <el-select v-model="form.sex" style="width: 100%">
- <el-option label="鐢�" value="0" />
- <el-option label="濂�" value="1" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="骞撮緞" prop="age">
- <el-input v-model="form.age" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鐤剧梾璇婃柇" prop="diagnosisname">
- <el-input v-model="form.diagnosisname" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="棣栬瘖鍖荤枟鏈烘瀯" prop="treatmenthospitalname">
- <el-input v-model="form.treatmenthospitalname" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="鎮h�呯姸鎬�" prop="recordstate">
- <el-select v-model="form.recordstate" style="width: 100%">
- <el-option
- v-for="dict in dict.type.sys_DonationCategory || []"
- :key="dict.value"
- :label="dict.label"
- :value="dict.value"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item
- label="鏈畬鎴愬師鍥�"
- prop="incompleteReason"
- v-if="form.recordstate === '5'"
- >
- <el-input
- v-model="form.incompleteReason"
- placeholder="璇疯緭鍏ユ湭瀹屾垚鎹愮尞鐨勫師鍥�"
- />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="涓婃姤鏃堕棿" prop="reporttime">
- <el-date-picker
- v-model="form.reporttime"
- 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="deathTime">
- <el-date-picker
- v-model="form.deathTime"
- 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="coordinatorName">
- <el-input v-model="form.coordinatorName" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="琛�鍨�" prop="bloodtype">
- <el-select v-model="form.bloodtype" style="width: 100%">
- <el-option
- v-for="dict in dict.type.sys_BloodType"
- :key="dict.value"
- :label="dict.label"
- :value="dict.value"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="Rh(D)" prop="rhYin">
- <el-radio-group v-model="form.rhYin">
- <el-radio
- v-for="dict in dict.type.sys_bloodtype_rhd || []"
- :key="dict.value"
- :label="dict.value"
- >{{ dict.label }}</el-radio
- >
- </el-radio-group>
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-form-item label="鐗规畩鐥呭彶" prop="specialMedicalHistory">
- <el-input
- type="textarea"
- :rows="3"
- v-model="form.specialMedicalHistory"
- placeholder="璁板綍鐗规畩鐥呭彶淇℃伅"
- />
- </el-form-item>
- </el-form>
- </el-card>
-
<el-card class="assessment-card">
- <div slot="header" class="clearfix">
- <span class="detail-title">渚涜�呰瘎浼板悇椤硅褰�</span>
- <el-button
- type="primary"
- size="mini"
- @click="toggleEditMode"
- style="float: right;"
- >
- {{ isEdit ? "瀹屾垚缂栬緫" : "寮�濮嬬紪杈�" }}
- </el-button>
- </div>
-
<el-tabs v-model="activeTab" type="card" @tab-click="handleTabClick">
<!-- 鍩瑰吇缁撴灉璁板綍 -->
<el-tab-pane label="鍩瑰吇缁撴灉" name="culture">
<el-card class="culture-card">
<div slot="header" class="clearfix">
<span class="detail-title">鍩瑰吇缁撴灉璁板綍</span>
- <el-button
- type="primary"
- size="mini"
- icon="el-icon-plus"
- @click="handleAddCulture"
- >
- 鏂板鍩瑰吇璁板綍
- </el-button>
+
</div>
<el-table :data="cultureList" v-loading="cultureLoading">
@@ -231,6 +73,75 @@
</el-table>
</el-card>
</el-tab-pane>
+ <el-tab-pane label="鎶ょ悊鏍告煡璁板綍" name="hlihc">
+ <el-card class="record-card">
+ <div slot="header" class="clearfix">
+ <span class="detail-title">鎶ょ悊鏍告煡璁板綍</span>
+
+ </div>
+
+ <el-table :data="recordList" v-loading="recordLoading">
+ <el-table-column
+ label="鏍告煡鏃堕棿"
+ align="center"
+ prop="recordTime"
+ width="160"
+ />
+ <el-table-column
+ label="鏍告煡浜�"
+ align="center"
+ prop="recorder"
+ width="100"
+ />
+ <el-table-column
+ label="鏍告煡璁板綍"
+ align="center"
+ prop="checkRecord"
+ min-width="200"
+ show-overflow-tooltip
+ />
+ <el-table-column label="闄勪欢" align="center" width="120">
+ <template slot-scope="scope">
+ <el-button
+ v-if="
+ scope.row.attachments && scope.row.attachments.length > 0
+ "
+ size="mini"
+ type="text"
+ @click="handleViewRecordAttachments(scope.row)"
+ >
+ 鏌ョ湅闄勪欢({{ scope.row.attachments.length }})
+ </el-button>
+ <span v-else>鏃犻檮浠�</span>
+ </template>
+ </el-table-column>
+ <el-table-column
+ label="鎿嶄綔"
+ align="center"
+ width="180"
+ class-name="small-padding fixed-width"
+ >
+ <template slot-scope="scope">
+ <el-button
+ size="mini"
+ type="text"
+ icon="el-icon-edit"
+ @click="handleEditRecord(scope.row)"
+ >缂栬緫</el-button
+ >
+ <el-button
+ size="mini"
+ type="text"
+ icon="el-icon-delete"
+ style="color: #F56C6C;"
+ @click="handleDeleteRecord(scope.row)"
+ >鍒犻櫎</el-button
+ >
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-card>
+ </el-tab-pane>
<!-- 鑲濆姛鑳借偩鍔熻兘 -->
<el-tab-pane label="鑲濆姛鑳借偩鍔熻兘" name="liverKidney">
@@ -265,78 +176,6 @@
</el-card>
<!-- 鎶ょ悊鏍告煡璁板綍 -->
- <el-card class="record-card">
- <div slot="header" class="clearfix">
- <span class="detail-title">鎶ょ悊鏍告煡璁板綍</span>
- <el-button
- type="primary"
- size="mini"
- icon="el-icon-plus"
- @click="handleAddRecord"
- >
- 鏂板鏍告煡璁板綍
- </el-button>
- </div>
-
- <el-table :data="recordList" v-loading="recordLoading">
- <el-table-column
- label="鏍告煡鏃堕棿"
- align="center"
- prop="recordTime"
- width="160"
- />
- <el-table-column
- label="鏍告煡浜�"
- align="center"
- prop="recorder"
- width="100"
- />
- <el-table-column
- label="鏍告煡璁板綍"
- align="center"
- prop="checkRecord"
- min-width="200"
- show-overflow-tooltip
- />
- <el-table-column label="闄勪欢" align="center" width="120">
- <template slot-scope="scope">
- <el-button
- v-if="scope.row.attachments && scope.row.attachments.length > 0"
- size="mini"
- type="text"
- @click="handleViewRecordAttachments(scope.row)"
- >
- 鏌ョ湅闄勪欢({{ scope.row.attachments.length }})
- </el-button>
- <span v-else>鏃犻檮浠�</span>
- </template>
- </el-table-column>
- <el-table-column
- label="鎿嶄綔"
- align="center"
- width="180"
- class-name="small-padding fixed-width"
- >
- <template slot-scope="scope">
- <el-button
- size="mini"
- type="text"
- icon="el-icon-edit"
- @click="handleEditRecord(scope.row)"
- >缂栬緫</el-button
- >
- <el-button
- size="mini"
- type="text"
- icon="el-icon-delete"
- style="color: #F56C6C;"
- @click="handleDeleteRecord(scope.row)"
- >鍒犻櫎</el-button
- >
- </template>
- </el-table-column>
- </el-table>
- </el-card>
<!-- 鍩瑰吇璁板綍缂栬緫瀵硅瘽妗� -->
<el-dialog
@@ -483,6 +322,12 @@
<span slot="footer" class="dialog-footer">
<el-button @click="recordDialogVisible = false">鍙栨秷</el-button>
+ <el-button
+ type="primary"
+ @click="handleSaveRecord"
+ :loading="recordSaveLoading"
+ >淇濆瓨</el-button
+ >
</span>
</el-dialog>
@@ -560,6 +405,8 @@
import LiverKidneyPanel from "@/components/MaintainComponents/LiverKidneyPanel.vue";
import BloodRoutinePanel from "@/components/MaintainComponents/BloodRoutinePanel.vue";
import UrineRoutinePanel from "@/components/MaintainComponents/UrineRoutinePanel.vue";
+import CaseBasicInfo from "@/components/CaseBasicInfo";
+import store from "@/store";
import dayjs from "dayjs";
export default {
@@ -570,7 +417,8 @@
FilePreviewDialog,
LiverKidneyPanel,
BloodRoutinePanel,
- UrineRoutinePanel
+ UrineRoutinePanel,
+ CaseBasicInfo
},
dicts: [
"sys_donornode",
@@ -588,7 +436,7 @@
},
data() {
return {
- isEdit: false,
+ isEdit: true,
currentMaintenanceId: null,
isEditMode: false,
form: {
@@ -696,6 +544,8 @@
};
},
created() {
+ this.caseId = this.infoid;
+
this.loadMaintenanceData();
},
watch: {
@@ -710,15 +560,24 @@
this.cultureLoading = true;
this.recordLoading = true;
+ const id = null;
+ const infoid = this.infoid;
const queryParams = {};
- console.log(this.infoid, "this.infoid");
- if (this.infoid) {
- queryParams.infoid = this.infoid;
+ if (id) {
+ queryParams.infoid = infoid;
+ this.currentMaintenanceId = id;
+ this.isEditMode = true;
+ } else if (infoid) {
+ queryParams.infoid = infoid;
+ this.currentMaintenanceId = null;
+ this.isEditMode = false;
} else {
this.$message.error("缂哄皯蹇呰鐨勮矾鐢卞弬鏁�");
return;
}
+
+ queryParams.infoid = infoid;
const response = await maintainList(queryParams);
if (response.code === 200) {
let maintenanceData = response.data[0];
@@ -772,13 +631,74 @@
}
},
+ // 淇濆瓨鎵�鏈夋暟鎹�
+ async handleSave() {
+ try {
+ const saveData = {
+ ...this.form,
+ itemDesc: {
+ liverKidney: this.assessmentData.liverKidney,
+ bloodRoutine: this.assessmentData.bloodRoutine,
+ urineRoutine: this.assessmentData.urineRoutine,
+ cultureResults: this.cultureList,
+ nursingRecords: this.recordList
+ }
+ };
+ if (saveData.state == 1 || !saveData.state) {
+ saveData.state = 2;
+ }
+ this.extracontentinfo.specialMedicalHistory = this.form.specialMedicalHistory;
+ let response;
+ if (this.isEditMode && this.currentMaintenanceId) {
+ saveData.id = this.currentMaintenanceId;
+ response = await maintainedit(saveData);
+ } else {
+ response = await maintainAdd(saveData);
+ }
+
+ if (response.code === 200) {
+ this.$message.success("淇濆瓨鎴愬姛");
+ this.isEdit = false;
+ if (!this.currentMaintenanceId) {
+ this.currentMaintenanceId = response.data;
+ }
+ // this.donatebaseinfoEdit({
+ // id: this.$route.query.infoid,
+ // extracontent: JSON.stringify(this.extracontentinfo)
+ // });
+ if (!this.isEditMode && response.data && response.data.id) {
+ this.currentMaintenanceId = response.data.id;
+ this.isEditMode = true;
+ }
+ } else {
+ this.$message.error("淇濆瓨澶辫触锛�" + (response.msg || "鏈煡閿欒"));
+ }
+ } catch (error) {
+ console.error("淇濆瓨鏁版嵁澶辫触:", error);
+ this.$message.error("淇濆瓨澶辫触");
+ }
+ },
+
// 鍒囨崲缂栬緫妯″紡
toggleEditMode() {
this.isEdit = !this.isEdit;
if (!this.isEdit) {
+ this.handleSave();
}
},
+ accomplish() {
+ this.$confirm("鏄惁瀹屾垚璇ユ渚嬫崘鐚‘璁ゆ楠わ紵", "鎻愰啋", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(() => {
+ this.form.state = 3;
+ this.handleSave();
+ })
+ .catch(() => {});
+ },
// 鍩瑰吇璁板綍鐩稿叧鏂规硶
handleAddCulture() {
this.cultureDialogTitle = "鏂板鍩瑰吇璁板綍";
@@ -863,7 +783,7 @@
.toISOString()
.replace("T", " ")
.substring(0, 19),
- recorder: "褰撳墠鐢ㄦ埛",
+ recorder: store.getters.name,
checkRecord: "",
attachments: []
};
diff --git a/src/views/business/course/components/EthicalReviewStage.vue b/src/views/business/course/components/EthicalReviewStage.vue
index a5b8476..7b874b4 100644
--- a/src/views/business/course/components/EthicalReviewStage.vue
+++ b/src/views/business/course/components/EthicalReviewStage.vue
@@ -1,142 +1,222 @@
<template>
<div class="ethics-review-detail">
+
<el-card class="detail-card">
- <!-- 鍩虹淇℃伅 -->
+ <!-- 浼︾悊瀹℃煡鍩烘湰淇℃伅 -->
<div slot="header" class="clearfix">
<span class="detail-title">浼︾悊瀹℃煡鍩烘湰淇℃伅</span>
+ <div style="float: right;">
+ <el-button type="primary" @click="handleSave" :loading="saveLoading">
+ 淇濆瓨
+ </el-button>
+
+ <el-button
+ type="success"
+ @click="handleCompleteReview"
+ :disabled="form.status == '3' || form.status == '2'"
+ :loading="completeLoading"
+ >
+ 瀹℃煡瀹屾垚
+ </el-button>
+
+ <el-button
+ type="warning"
+ @click="handleSuspendReview"
+ :disabled="form.status == '2' || form.status == '3'"
+ :loading="suspendLoading"
+ >
+ 瀹℃煡涓
+ </el-button>
+
+ <el-button
+ type="danger"
+ @click="handleEndReview"
+ :disabled="form.status == '2'"
+ :loading="endLoading"
+ >
+ 缁撴潫瀹℃煡
+ </el-button>
+ </div>
</div>
<el-form :model="form" ref="form" :rules="rules" label-width="120px">
+ <el-row :gutter="20">
+ <el-col :span="8">
+ <el-form-item label="鍙戣捣涓婚" prop="initiateTheme">
+ <el-input
+ v-model="form.initiateTheme"
+ placeholder="璇疯緭鍏ュ彂璧蜂富棰�"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="鍙戣捣浜�" prop="initiatePerson">
+ <el-input v-model="form.initiatePerson" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="瀹℃煡鐘舵��" prop="status">
+ <el-select v-model="form.status" style="width: 100%">
+ <el-option
+ v-for="dict in dict.type.sys_ethical"
+ :key="dict.value"
+ :label="dict.label"
+ :value="dict.value"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <!-- 涓撳鐩稿叧淇℃伅 -->
<el-row :gutter="20">
<el-col :span="8">
- <el-form-item label="浼︾悊缁撹" prop="ethicsConclusion">
- <el-select v-model="form.ethicsConclusion" style="width: 100%">
- <el-option label="瀹℃煡涓�" value="reviewing" />
- <el-option label="鍚屾剰" value="approved" />
- <el-option
- label="淇敼鍚庡悓鎰�"
- value="approved_with_modifications"
- />
- <el-option label="淇敼鍚庨噸瀹�" value="re-review" />
- <el-option label="涓嶅悓鎰�" value="disapproved" />
- <el-option label="缁堟瀹℃煡" value="terminated" />
+ <el-form-item label="浼︾悊瀹℃煡缁撹" prop="expertConclusion">
+ <el-select v-model="form.expertConclusion" style="width: 100%">
+ <el-option label="鍚屾剰" value="1" />
+ <el-option label="瀹℃煡涓�" value="2" />
+ <el-option label="涓嶅悓鎰�" value="0" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
- <el-form-item label="瀹℃煡鏃堕棿" prop="reviewTime">
+ <el-form-item label="浼︾悊瀹℃煡缁撹鏃堕棿" prop="expertTime">
<el-date-picker
- v-model="form.reviewTime"
+ v-model="form.expertTime"
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="registrant">
- <el-input v-model="form.registrant" />
+ </el-row>
+
+ <el-row :gutter="20">
+ <el-col :span="24">
+ <el-form-item label="瀹℃煡鎰忚" prop="expertOpinion">
+ <el-input
+ type="textarea"
+ :rows="2"
+ v-model="form.expertOpinion"
+ placeholder="璇疯緭鍏ユ剰瑙�"
+ />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
- <el-form-item label="浼︾悊鎰忚" prop="ethicsOpinion">
+ <el-form-item label="澶囨敞" prop="remark">
<el-input
type="textarea"
:rows="3"
- v-model="form.ethicsOpinion"
- placeholder="璇疯緭鍏ヤ鸡鐞嗗鏌ユ剰瑙�"
+ v-model="form.remark"
+ placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
/>
</el-form-item>
</el-col>
</el-row>
-
- <el-form-item label="鐧昏鏃堕棿" prop="registrationTime">
- <el-date-picker
- v-model="form.registrationTime"
- type="datetime"
- value-format="yyyy-MM-dd HH:mm:ss"
- style="width: 100%"
- />
- </el-form-item>
</el-form>
</el-card>
+
<!-- 闄勪欢涓婁紶 -->
<el-card class="attachment-card">
<div slot="header" class="clearfix">
<span class="detail-title">鐩稿叧闄勪欢</span>
- <el-button type="primary" size="mini" @click="handleUploadAttachment">
- 涓婁紶闄勪欢
- </el-button>
</div>
- <el-table :data="attachments" style="width: 100%">
- <el-table-column label="鏂囦欢鍚嶇О" min-width="200">
- <template slot-scope="scope">
- <div class="file-info">
+ <!-- 浣跨敤 UploadAttachment 缁勪欢 -->
+ <UploadAttachment
+ ref="uploadAttachment"
+ :file-list="attachmentFileList"
+ :limit="10"
+ accept=".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx"
+ @change="handleAttachmentChange"
+ @upload-success="handleUploadSuccess"
+ @upload-error="handleUploadError"
+ @remove="handleAttachmentRemove"
+ />
+
+ <!-- 闄勪欢鍒楄〃 -->
+ <div
+ class="attachment-list"
+ v-if="form.annexfilesList && form.annexfilesList.length > 0"
+ >
+ <div class="list-title">
+ 宸蹭笂浼犻檮浠� ({{ form.annexfilesList.length }})
+ </div>
+ <el-table :data="form.annexfilesList" style="width: 100%" size="small">
+ <el-table-column label="鏂囦欢鍚�" min-width="200">
+ <template slot-scope="scope">
<i
class="el-icon-document"
style="margin-right: 8px; color: #409EFF;"
></i>
- <span>{{ scope.row.fileName }}</span>
- </div>
- </template>
- </el-table-column>
+ <span class="file-name">{{ scope.row.fileName }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鏂囦欢绫诲瀷" width="100">
+ <template slot-scope="scope">
+ <el-tag size="small">{{
+ getFileType(scope.row.fileName)
+ }}</el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column label="鍒涘缓鏃堕棿" width="160">
+ <template slot-scope="scope">
+ <span>{{ formatDateTime(scope.row.createTime) }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鎿嶄綔" width="266">
+ <template slot-scope="scope">
+ <el-button
+ size="mini"
+ type="primary"
+ @click="handlePreview(scope.row)"
+ >
+ 棰勮
+ </el-button>
+ <el-button
+ size="mini"
+ type="success"
+ @click="handleDownload(scope.row)"
+ >
+ 涓嬭浇
+ </el-button>
+ <el-button
+ size="mini"
+ type="danger"
+ @click="handleRemoveAttachment(scope.$index)"
+ >
+ 鍒犻櫎
+ </el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
- <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>{{ parseTime(scope.row.uploadTime) }}</span>
- </template>
- </el-table-column>
-
- <el-table-column label="涓婁紶浜�" width="100" align="center">
- <template slot-scope="scope">
- <span>{{ scope.row.uploader }}</span>
- </template>
- </el-table-column>
-
- <el-table-column label="鎿嶄綔" width="120" align="center">
- <template slot-scope="scope">
- <el-button
- size="mini"
- type="text"
- icon="el-icon-view"
- @click="handlePreviewAttachment(scope.row)"
- >棰勮</el-button
- >
- <el-button
- size="mini"
- type="text"
- icon="el-icon-download"
- @click="handleDownloadAttachment(scope.row)"
- >涓嬭浇</el-button
- >
- </template>
- </el-table-column>
- </el-table>
+ <!-- 绌虹姸鎬� -->
+ <div
+ v-if="!form.annexfilesList || form.annexfilesList.length == 0"
+ class="empty-attachment"
+ >
+ <i
+ class="el-icon-folder-opened"
+ style="font-size: 60px; color: #C0C4CC; margin-bottom: 20px;"
+ ></i>
+ <p style="color: #909399; font-size: 14px;">鏆傛棤闄勪欢锛岃涓婁紶鐩稿叧鏂囦欢</p>
+ </div>
</el-card>
+
<!-- 涓撳瀹℃煡鎯呭喌 -->
<el-card class="expert-card">
<div slot="header" class="clearfix">
- <span class="detail-title"
- >涓撳瀹℃煡鎯呭喌 (18浣嶄笓瀹� + 1浣嶄富濮斾笓瀹�)</span
- >
+ <span class="detail-title">涓撳瀹℃煡鎯呭喌</span>
<div style="float: right;">
+ <el-button size="mini" type="primary" @click="handleAddExpert">
+ 娣诲姞涓撳
+ </el-button>
<el-button
size="mini"
type="primary"
@@ -153,17 +233,10 @@
>
鍙戦�佷富濮斾笓瀹�
</el-button>
- <el-button
- size="mini"
- type="warning"
- @click="handleBatchSend"
- :disabled="!canBatchSend"
- >
- 鎵归噺鍙戦��
- </el-button>
</div>
</div>
- <!-- 涓撳缁熻淇℃伅 -->
+
+ <!-- 涓撳缁熻淇℃伅 -->
<div
class="expert-stats"
style="margin-top: 20px; padding: 15px; background: #f5f7fa; border-radius: 4px;"
@@ -171,20 +244,22 @@
<el-row :gutter="20">
<el-col :span="6">
<div class="stat-item">
- <span class="stat-label">涓撳宸插悓鎰�:</span>
- <span class="stat-value">{{ approvedNormalExperts }}/18</span>
+ <span class="stat-label">鏅�氫笓瀹�:</span>
+ <span class="stat-value">{{ normalExpertsCount }}浜�</span>
</div>
</el-col>
<el-col :span="6">
<div class="stat-item">
- <span class="stat-label">涓诲涓撳鐘舵��:</span>
- <span class="stat-value">{{ chiefExpertStatus }}</span>
+ <span class="stat-label">涓诲涓撳:</span>
+ <span class="stat-value">{{ chiefExpertsCount }}浜�</span>
</div>
</el-col>
<el-col :span="6">
<div class="stat-item">
- <span class="stat-label">鎬诲畬鎴愯繘搴�:</span>
- <span class="stat-value">{{ completionRate }}%</span>
+ <span class="stat-label">宸插悓鎰�:</span>
+ <span class="stat-value"
+ >{{ approvedExpertsCount }}/{{ totalExpertsCount }}</span
+ >
</div>
</el-col>
<el-col :span="6">
@@ -199,12 +274,13 @@
</el-col>
</el-row>
</div>
+
<!-- 涓撳瀹℃煡琛ㄦ牸 -->
<el-table
- :data="expertReviews"
+ :data="ethicalreviewopinionsList"
v-loading="expertLoading"
style="width: 100%"
- heiht="300"
+ height="600"
:row-class-name="getExpertRowClassName"
>
<el-table-column label="搴忓彿" width="60" align="center" type="index" />
@@ -216,9 +292,14 @@
fixed="left"
>
<template slot-scope="scope">
- <span>{{ scope.row.expertName }}</span>
+ <span
+ class="expert-name-link"
+ @click="handleViewExpertHistory(scope.row)"
+ >
+ {{ scope.row.expertname }}
+ </span>
<el-tag
- v-if="scope.row.isChief"
+ v-if="scope.row.expertType == '1'"
size="mini"
type="danger"
style="margin-left: 5px;"
@@ -227,18 +308,31 @@
</template>
</el-table-column>
+ <el-table-column label="涓撳缂栧彿" width="120" align="center">
+ <template slot-scope="scope">
+ <span>{{ scope.row.expertNo || "-" }}</span>
+ </template>
+ </el-table-column>
+
<el-table-column label="涓撳绫诲瀷" width="100" align="center">
<template slot-scope="scope">
- <span :class="scope.row.isChief ? 'chief-expert' : 'normal-expert'">
- {{ scope.row.isChief ? "涓诲涓撳" : "涓撳" }}
+ <span
+ :class="
+ scope.row.expertType == '1' ? 'chief-expert' : 'normal-expert'
+ "
+ >
+ {{ getExpertTypeText(scope.row.expertType) }}
</span>
</template>
</el-table-column>
<el-table-column label="瀹℃煡鐘舵��" width="100" align="center">
<template slot-scope="scope">
- <el-tag :type="statusFilter(scope.row.reviewStatus)" size="small">
- {{ statusTextFilter(scope.row.reviewStatus) }}
+ <el-tag
+ :type="getReviewStatusFilter(scope.row.receiveStatus)"
+ size="small"
+ >
+ {{ getReviewStatusText(scope.row.receiveStatus) }}
</el-tag>
</template>
</el-table-column>
@@ -246,11 +340,11 @@
<el-table-column label="涓撳缁撹" width="120" align="center">
<template slot-scope="scope">
<el-tag
- v-if="scope.row.expertConclusion"
- :type="conclusionFilter(scope.row.expertConclusion)"
+ v-if="scope.row.expertconclusion"
+ :type="getConclusionFilter(scope.row.expertconclusion)"
size="small"
>
- {{ conclusionTextFilter(scope.row.expertConclusion) }}
+ {{ getConclusionText(scope.row.expertconclusion) }}
</el-tag>
<span v-else class="no-data">-</span>
</template>
@@ -258,23 +352,41 @@
<el-table-column label="瀹℃煡鎰忚" min-width="200" show-overflow-tooltip>
<template slot-scope="scope">
- <span :class="{ 'expert-opinion': scope.row.expertOpinion }">
- {{ scope.row.expertOpinion || "鏆傛棤鎰忚" }}
+ <span :class="{ 'expert-opinion': scope.row.expertopinion }">
+ {{ scope.row.expertopinion || "鏆傛棤鎰忚" }}
</span>
+ </template>
+ </el-table-column>
+
+ <el-table-column label="缁撹椤哄簭" width="100" align="center">
+ <template slot-scope="scope">
+ <span>{{ scope.row.conclusionorder || "-" }}</span>
+ </template>
+ </el-table-column>
+
+ <el-table-column label="鎴鏃堕棿" width="160" align="center">
+ <template slot-scope="scope">
+ <span>{{
+ scope.row.endTime ? formatDateTime(scope.row.endTime) : "鏈缃�"
+ }}</span>
</template>
</el-table-column>
<el-table-column label="瀹℃煡鏃堕棿" width="160" align="center">
<template slot-scope="scope">
<span>{{
- scope.row.reviewTime ? parseTime(scope.row.reviewTime) : "鏈鏌�"
+ scope.row.conclusiontime
+ ? formatDateTime(scope.row.conclusiontime)
+ : "鏈鏌�"
}}</span>
</template>
</el-table-column>
<el-table-column label="鍙戦�佹椂闂�" width="160" align="center">
<template slot-scope="scope">
<span>{{
- scope.row.reviewTime ? parseTime(scope.row.reviewTime) : "鏈彂閫�"
+ scope.row.startTime
+ ? formatDateTime(scope.row.startTime)
+ : "鏈彂閫�"
}}</span>
</template>
</el-table-column>
@@ -286,68 +398,217 @@
type="text"
icon="el-icon-s-promotion"
@click="handleSendToExpert(scope.row)"
- :disabled="scope.row.reviewStatus === 'submitted'"
- :class="{ 'sent-button': scope.row.reviewStatus === 'submitted' }"
+ :disabled="
+ scope.row.receiveStatus == '2' ||
+ scope.row.receiveStatus == '3' ||
+ scope.row.receiveStatus == '4'
+ "
+ :class="{
+ 'sent-button':
+ scope.row.receiveStatus == '2' ||
+ scope.row.receiveStatus == '3'
+ }"
>
- {{ scope.row.reviewStatus === "submitted" ? "宸插彂閫�" : "鍙戦��" }}
+ {{
+ scope.row.receiveStatus == "2" || scope.row.receiveStatus == "3"
+ ? "宸插彂閫�"
+ : "鍙戦��"
+ }}
</el-button>
<el-button
+ v-if="scope.row.receiveStatus == 0"
size="mini"
type="text"
- icon="el-icon-edit"
- @click="handleEditExpertReview(scope.row)"
- :disabled="scope.row.reviewStatus !== 'submitted'"
+ icon="el-icon-delete"
+ @click="handleDeleteExpertReview(scope.row, scope.$index)"
+ style="color: #f56c6c;"
>
- 缂栬緫
- </el-button>
- <el-button
- size="mini"
- type="text"
- icon="el-icon-view"
- @click="handleViewExpertReview(scope.row)"
- >
- 璇︽儏
+ 鍒犻櫎
</el-button>
</template>
</el-table-column>
</el-table>
-
-
</el-card>
+
+ <!-- 娣诲姞涓撳瀵硅瘽妗� -->
+ <el-dialog
+ title="娣诲姞涓撳"
+ :visible.sync="expertDialogVisible"
+ width="800px"
+ @close="handleExpertDialogClose"
+ >
+ <div style="margin-bottom: 20px;">
+ <el-input
+ v-model="expertSearchQuery"
+ placeholder="璇疯緭鍏ヤ笓瀹跺鍚嶆垨缂栧彿鎼滅储"
+ style="width: 300px; margin-right: 10px;"
+ @keyup.enter.native="handleSearchExperts"
+ >
+ <el-button
+ slot="append"
+ icon="el-icon-search"
+ @click="handleSearchExperts"
+ ></el-button>
+ </el-input>
+ <el-select
+ v-model="filterExpertType"
+ placeholder="涓撳绫诲瀷"
+ style="width: 150px; margin-right: 10px;"
+ @change="handleSearchExperts"
+ >
+ <el-option label="鍏ㄩ儴" value=""></el-option>
+ <el-option label="鏅�氫笓瀹�" value="0"></el-option>
+ <el-option label="涓讳换濮斿憳" value="1"></el-option>
+ </el-select>
+ <el-button type="primary" @click="handleSearchExperts">鎼滅储</el-button>
+ <el-button @click="handleResetSearch">閲嶇疆</el-button>
+ </div>
+
+ <el-table
+ :data="filteredExpertList"
+ v-loading="expertListLoading"
+ style="width: 100%"
+ max-height="400"
+ @selection-change="handleExpertSelectionChange"
+ >
+ <el-table-column type="selection" width="55"></el-table-column>
+ <el-table-column
+ label="涓撳濮撳悕"
+ prop="username"
+ width="120"
+ ></el-table-column>
+ <el-table-column
+ label="涓撳缂栧彿"
+ prop="userno"
+ width="120"
+ ></el-table-column>
+ <el-table-column label="涓撳绫诲瀷" width="100">
+ <template slot-scope="scope">
+ <el-tag
+ size="small"
+ :type="getIsChiefExpert(scope.row) ? 'danger' : ''"
+ >
+ {{ getIsChiefExpert(scope.row) ? "涓讳换濮斿憳" : "鏅�氫笓瀹�" }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column
+ label="鍗曚綅鍚嶇О"
+ prop="unitname"
+ show-overflow-tooltip
+ ></el-table-column>
+ <el-table-column
+ label="鑱岀О"
+ prop="title"
+ width="100"
+ ></el-table-column>
+ <el-table-column
+ label="鑱旂郴鐢佃瘽"
+ prop="telephone"
+ width="120"
+ ></el-table-column>
+ </el-table>
+
+ <div style="margin-top: 20px; text-align: center;">
+ <el-pagination
+ @size-change="handlePageSizeChange"
+ @current-change="handlePageChange"
+ :current-page="expertPage.pageNum"
+ :page-sizes="[10, 20, 50, 100]"
+ :page-size="expertPage.pageSize"
+ layout="total, sizes, prev, pager, next, jumper"
+ :total="filteredExpertTotal"
+ ></el-pagination>
+ </div>
+
+ <div slot="footer">
+ <el-button @click="expertDialogVisible = false">鍙栨秷</el-button>
+ <el-button
+ type="primary"
+ @click="handleConfirmAddExpert"
+ :disabled="selectedExperts.length == 0"
+ >纭畾娣诲姞</el-button
+ >
+ </div>
+ </el-dialog>
<!-- 鍙戦�佷笓瀹跺璇濇 -->
<el-dialog
- title="鍙戦�佷笓瀹跺鏌�"
+ :title="sendDialogTitle"
:visible.sync="sendDialogVisible"
width="500px"
+ @close="handleSendDialogClose"
>
<el-form :model="sendForm" ref="sendForm" label-width="100px">
<el-form-item label="涓撳绫诲瀷" prop="expertType">
- <el-radio-group v-model="sendForm.expertType">
- <el-radio label="normal">涓撳</el-radio>
+ <el-radio-group
+ v-model="sendForm.expertType"
+ @change="handleExpertTypeChange"
+ >
+ <el-radio label="normal">鏅�氫笓瀹�</el-radio>
<el-radio label="chief">涓诲涓撳</el-radio>
</el-radio-group>
</el-form-item>
+
+ <el-form-item label="鍙戦�佹椂闂�" prop="startTime" required>
+ <el-date-picker
+ v-model="sendForm.startTime"
+ type="datetime"
+ placeholder="璇烽�夋嫨鍙戦�佹椂闂�"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ style="width: 100%"
+ />
+ </el-form-item>
+
<el-form-item
- label="閫夋嫨涓撳"
- prop="expertIds"
- v-if="sendForm.expertType === 'normal'"
+ label="鎴鏃堕棿"
+ prop="endTime"
+ :required="sendForm.expertType !== 'chief'"
>
+ <el-date-picker
+ v-model="sendForm.endTime"
+ type="datetime"
+ placeholder="璇烽�夋嫨鎴鏃堕棿"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ style="width: 100%"
+ :disabled="sendForm.expertType === 'chief'"
+ />
+ <div v-if="sendForm.expertType !== 'chief'" style="margin-top: 5px;">
+ <el-button-group>
+ <el-button size="mini" @click="setEndTime(0.5)"
+ >鍗婂皬鏃跺悗</el-button
+ >
+ <el-button size="mini" @click="setEndTime(1)">涓�灏忔椂鍚�</el-button>
+ <el-button size="mini" @click="setEndTime(2)">涓ゅ皬鏃跺悗</el-button>
+ <el-button size="mini" @click="setEndTime(24)">涓�澶╁悗</el-button>
+ </el-button-group>
+ </div>
+ <div
+ v-if="sendForm.expertType === 'chief'"
+ style="font-size: 12px; color: #999; margin-top: 5px;"
+ >
+ 涓诲涓撳鏃犻渶璁剧疆鎴鏃堕棿
+ </div>
+ </el-form-item>
+
+ <el-form-item label="鍙戦�佹柟寮�" prop="sendType" required>
<el-select
- v-model="sendForm.expertIds"
- multiple
- placeholder="璇烽�夋嫨涓撳"
+ v-model="sendForm.sendType"
+ placeholder="璇烽�夋嫨鍙戦�佹柟寮�"
style="width: 100%"
>
- <el-option
- v-for="expert in availableExperts"
- :key="expert.id"
- :label="expert.name"
- :value="expert.id"
- />
+ <el-option label="绯荤粺鍙戦��" value="0"></el-option>
+ <el-option label="閭欢鍙戦��" value="1"></el-option>
+ <el-option label="鐭俊鍙戦��" value="2"></el-option>
+ <el-option label="鍏朵粬鏂瑰紡" value="3"></el-option>
</el-select>
</el-form-item>
- <el-form-item label="鍙戦�佸唴瀹�" prop="content">
+
+ <el-form-item label="鍙戦�佹爣棰�" prop="title" required>
+ <el-input v-model="sendForm.title" placeholder="璇疯緭鍏ュ彂閫佹爣棰�" />
+ </el-form-item>
+
+ <el-form-item label="鍙戦�佸唴瀹�" prop="content" required>
<el-input
type="textarea"
:rows="4"
@@ -355,579 +616,933 @@
placeholder="璇疯緭鍏ュ彂閫佺粰涓撳鐨勫鏌ュ唴瀹硅鏄�"
/>
</el-form-item>
+
+ <el-form-item label="璺宠浆閾炬帴" prop="url">
+ <el-input
+ v-model="sendForm.url"
+ placeholder="璇疯緭鍏ヨ烦杞摼鎺ワ紙鍙�夛級"
+ />
+ </el-form-item>
</el-form>
<div slot="footer">
<el-button @click="sendDialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="handleSendConfirm"
+ <el-button type="primary" @click="handleSendConfirm" :loading="sending"
>纭鍙戦��</el-button
>
</div>
</el-dialog>
+
+ <!-- 涓撳鍘嗗彶瀹℃壒鎯呭喌瀵硅瘽妗� -->
+ <el-dialog
+ title="涓撳鍘嗗彶瀹℃壒鎯呭喌"
+ :visible.sync="expertHistoryDialogVisible"
+ width="600px"
+ >
+ <div v-loading="expertHistoryLoading">
+ <div v-if="expertHistoryData" style="padding: 20px;">
+ <el-row :gutter="20" style="margin-bottom: 20px;">
+ <el-col :span="12">
+ <div class="history-stat-item">
+ <div class="history-stat-label">涓撳濮撳悕</div>
+ <div class="history-stat-value">
+ {{ currentExpertInfo.expertname || "-" }}
+ </div>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="history-stat-item">
+ <div class="history-stat-label">涓撳缂栧彿</div>
+ <div class="history-stat-value">
+ {{ currentExpertInfo.expertNo || "-" }}
+ </div>
+ </div>
+ </el-col>
+ </el-row>
+
+ <el-divider></el-divider>
+
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <div class="history-stat-item">
+ <div class="history-stat-label">鎬诲鎵规暟閲�</div>
+ <div
+ class="history-stat-value"
+ style="font-size: 24px; color: #409EFF;"
+ >
+ {{ expertHistoryData.count || 0 }}
+ </div>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="history-stat-item">
+ <div class="history-stat-label">宸叉帴鏀舵暟閲�</div>
+ <div class="history-stat-value">
+ {{ expertHistoryData.acceptCount || 0 }}
+ </div>
+ </div>
+ </el-col>
+ </el-row>
+
+ <el-row :gutter="20" style="margin-top: 20px;">
+ <el-col :span="12">
+ <div class="history-stat-item">
+ <div class="history-stat-label">鏈帴鏀舵暟閲�</div>
+ <div class="history-stat-value">
+ {{ expertHistoryData.notAcceptCount || 0 }}
+ </div>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="history-stat-item">
+ <div class="history-stat-label">鏈夋剰瑙佹暟閲�</div>
+ <div class="history-stat-value">
+ {{ expertHistoryData.opinionCount || 0 }}
+ </div>
+ </div>
+ </el-col>
+ </el-row>
+
+ <el-row :gutter="20" style="margin-top: 20px;">
+ <el-col :span="12">
+ <div class="history-stat-item">
+ <div class="history-stat-label">鏃犳剰瑙佹暟閲�</div>
+ <div class="history-stat-value">
+ {{ expertHistoryData.notOpinionCount || 0 }}
+ </div>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="history-stat-item">
+ <div class="history-stat-label">鏈夐檮浠舵暟閲�</div>
+ <div class="history-stat-value">
+ {{ expertHistoryData.annexCount || 0 }}
+ </div>
+ </div>
+ </el-col>
+ </el-row>
+
+ <el-row :gutter="20" style="margin-top: 20px;">
+ <el-col :span="12">
+ <div class="history-stat-item">
+ <div class="history-stat-label">鏃犻檮浠舵暟閲�</div>
+ <div class="history-stat-value">
+ {{ expertHistoryData.notAnnexCount || 0 }}
+ </div>
+ </div>
+ </el-col>
+ </el-row>
+ </div>
+ <div v-else style="text-align: center; padding: 40px 0;">
+ <i
+ class="el-icon-info"
+ style="font-size: 60px; color: #C0C4CC; margin-bottom: 20px;"
+ ></i>
+ <p style="color: #909399; font-size: 14px;">鏆傛棤鍘嗗彶瀹℃壒鏁版嵁</p>
+ </div>
+ </div>
+ <div slot="footer">
+ <el-button @click="expertHistoryDialogVisible = false">鍏抽棴</el-button>
+ </div>
+ </el-dialog>
+
+ <!-- 鏂囦欢棰勮寮圭獥 -->
+ <FilePreviewDialog
+ :visible="previewVisible"
+ :file="currentPreviewFile"
+ @close="previewVisible = false"
+ @download="handleDownload"
+ />
</div>
</template>
+
<script>
+import { getToken } from "@/utils/auth";
import {
- getEthicsReviewDetail,
- updateEthicsReview,
- sendExpertReview,
- endEthicsReview,
- uploadAttachment,
- deleteAttachment,
- getAttachments
-} from "./api/ethicsReview";
+ reviewinitiateBaseInfoList,
+ ethicalreviewedit,
+ ethicalreviewadd,
+ ethicalreviewInfo,
+ ethicalreExpertTotal,
+ sendNotification
+} from "@/api/businessApi";
+import { listExternalperson } from "@/api/project/externalperson";
+import CaseBasicInfo from "@/components/CaseBasicInfo";
+import UploadAttachment from "@/components/UploadAttachment";
+import FilePreviewDialog from "@/components/FilePreviewDialog";
+import dayjs from "dayjs";
export default {
name: "EthicsReviewDetail",
+ components: { CaseBasicInfo, UploadAttachment, FilePreviewDialog },
+ dicts: ["sys_user_sex", "sys_ethical", "Review_status"],
+ props: {
+ infoid: {
+ type: String,
+ default: true
+ }
+ },
data() {
return {
+ // 椤甸潰妯″紡
+ isEdit: false,
+ // 鍩烘湰淇℃伅
+ id: undefined,
+ caseId: null,
+ caseNo: "",
+
// 琛ㄥ崟鏁版嵁
form: {
+ // 鍩虹淇℃伅
id: undefined,
- hospitalNo: "",
- donorName: "",
- gender: "",
- age: "",
- diagnosis: "",
- ethicsConclusion: "reviewing",
- ethicsOpinion: "",
- reviewTime: "",
- registrant: "",
- registrationTime: new Date()
- .toISOString()
- .replace("T", " ")
- .substring(0, 19)
+ infoid: undefined,
+ caseNo: "",
+ initiateTheme: "",
+ initiatePerson: "",
+
+ // 鐘舵�佸拰鏃堕棿
+ status: "0", // 0:寰呭鏌�, 1:瀹℃煡涓�, 2:瀹℃煡涓, 3:瀹℃煡瀹屾垚
+ startTime: "",
+ cutOffTime: "",
+ endTime: "",
+
+ // 涓撳淇℃伅
+ expertName: "",
+ expertNo: "",
+ expertType: "0",
+ expertConclusion: "",
+ expertOpinion: "",
+ expertTime: "",
+ orderNo: 1,
+
+ // 澶囨敞
+ remark: "",
+
+ // 闄勪欢淇℃伅
+ annexfilesList: [],
+ filePatch: "",
+
+ // 涓撳瀹℃煡鎰忚鍒楄〃
+ ethicalreviewopinionsList: [],
+
+ // 绯荤粺瀛楁
+ createBy: "",
+ createTime: "",
+ updateBy: "",
+ updateTime: "",
+ delFlag: "0"
},
+
// 琛ㄥ崟楠岃瘉瑙勫垯
rules: {
- donorName: [
- { required: true, message: "鎹愮尞鑰呭鍚嶄笉鑳戒负绌�", trigger: "blur" }
+ initiateTheme: [
+ { required: true, message: "鍙戣捣涓婚涓嶈兘涓虹┖", trigger: "blur" },
+ {
+ min: 2,
+ max: 100,
+ message: "闀垮害鍦� 2 鍒� 100 涓瓧绗�",
+ trigger: "blur"
+ }
],
- ethicsConclusion: [
- { required: true, message: "浼︾悊缁撹涓嶈兘涓虹┖", trigger: "change" }
+ initiatePerson: [
+ { required: true, message: "鍙戣捣浜轰笉鑳戒负绌�", trigger: "blur" }
],
- reviewTime: [
- { required: true, message: "瀹℃煡鏃堕棿涓嶈兘涓虹┖", trigger: "change" }
+ status: [
+ { required: true, message: "瀹℃煡鐘舵�佷笉鑳戒负绌�", trigger: "change" }
+ ],
+ expertName: [
+ { max: 50, message: "闀垮害涓嶈兘瓒呰繃 50 涓瓧绗�", trigger: "blur" }
+ ],
+ expertNo: [
+ { max: 50, message: "闀垮害涓嶈兘瓒呰繃 50 涓瓧绗�", trigger: "blur" }
+ ],
+ expertConclusion: [
+ { max: 2, message: "闀垮害涓嶈兘瓒呰繃 2 涓瓧绗�", trigger: "change" }
+ ],
+ remark: [
+ { max: 500, message: "闀垮害涓嶈兘瓒呰繃 500 涓瓧绗�", trigger: "blur" }
]
},
+
// 淇濆瓨鍔犺浇鐘舵��
saveLoading: false,
+ completeLoading: false,
+ suspendLoading: false,
+ endLoading: false,
+ sending: false,
- // 闄勪欢鏁版嵁
- attachments: [],
- expertReviews: [
- // 涓撳锛�18浣嶏級- 鍒濆鐘舵�佷负鐢宠涓�
- {
- id: 1,
- expertName: "闄舵槉",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 2,
- expertName: "鍒樻枌",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 3,
- expertName: "浜庢捣鍒� ",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 4,
- expertName: "鐜嬬孩姊�",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 5,
- expertName: "鐜嬫槬鍏�",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 6,
- expertName: "鐜嬮潤",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 7,
- expertName: "杈规枃瓒�",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 8,
- expertName: "闂織鍕�",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 9,
- expertName: "璁稿嚖",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 10,
- expertName: "璁镐紶灞�",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 11,
- expertName: "寮犵孩宀�",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 12,
- expertName: "鏉ㄨ嫃姘�",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 13,
- expertName: "瀹嬬帀寮�",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 14,
- expertName: "鍛ㄤ紶鍒�",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 15,
- expertName: "鑽嗗嚒娉�",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 16,
- expertName: "鐭枃鎹�",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 17,
- expertName: "钁i渿",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- {
- id: 18,
- expertName: "钄¢噾璐�",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- // 涓诲涓撳锛�1浣嶏級
- {
- id: 19,
- expertName: "瀛斿績娑�",
- isChief: true,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- }
- ],
+ // 闄勪欢鐩稿叧
+ attachmentFileList: [],
+
+ // 棰勮鐩稿叧
+ previewVisible: false,
+ currentPreviewFile: null,
+
+ // 涓撳瀹℃煡鏁版嵁
+ expertReviews: [],
expertLoading: false,
attachmentLoading: false,
+
+ // 娣诲姞涓撳瀵硅瘽妗�
+ expertDialogVisible: false,
+ expertList: [],
+ expertListLoading: false,
+ expertSearchQuery: "",
+ filterExpertType: "",
+ expertPage: {
+ pageNum: 1,
+ pageSize: 50
+ },
+ expertTotal: 0,
+ selectedExperts: [],
+
// 鍙戦�佸璇濇
sendDialogVisible: false,
sendForm: {
expertType: "normal",
expertIds: [],
- content: ""
+ startTime: "",
+ endTime: "",
+ sendType: "0",
+ title: "浼︾悊瀹℃煡浠诲姟閫氱煡",
+ content: "",
+ url: ""
},
- // 涓婁紶鐩稿叧
- uploadDialogVisible: false,
- uploadLoading: false,
- tempFileList: [],
- // 鍙敤涓撳鍒楄〃
- availableExperts: [
- { id: 1, name: "寮犳暀鎺�", type: "normal" },
- { id: 2, name: "鏉庢暀鎺�", type: "normal" },
- { id: 3, name: "鐜嬫暀鎺�", type: "normal" },
- { id: 4, name: "璧典富濮�", type: "chief" }
- ]
+
+ // 涓撳鍘嗗彶瀹℃壒鎯呭喌
+ expertHistoryDialogVisible: false,
+ expertHistoryLoading: false,
+ expertHistoryData: null,
+ currentExpertInfo: {},
+
+ // 褰撳墠鍙戦�佺殑涓撳
+ currentSendExperts: []
};
},
computed: {
- // 璁$畻灞炴�э細涓撳鍚屾剰鏁伴噺
- approvedNormalExperts() {
- return this.expertReviews.filter(
- expert => !expert.isChief && expert.expertConclusion === "approved"
+ // 璁$畻灞炴�э細鑾峰彇涓撳鍒楄〃锛堢‘淇濆搷搴斿紡锛�
+ ethicalreviewopinionsList() {
+ return this.form.ethicalreviewopinionsList || [];
+ },
+
+ // 璁$畻灞炴�э細鏅�氫笓瀹舵暟閲�
+ normalExpertsCount() {
+ return this.ethicalreviewopinionsList.filter(
+ expert => expert.expertType === "0"
).length;
},
- // 璁$畻灞炴�э細涓诲涓撳鐘舵��
- chiefExpertStatus() {
- const chiefExpert = this.expertReviews.find(expert => expert.isChief);
- return chiefExpert
- ? this.statusTextFilter(chiefExpert.reviewStatus)
- : "鏈垎閰�";
- },
- // 璁$畻灞炴�э細瀹屾垚杩涘害
- completionRate() {
- const totalExperts = this.expertReviews.length;
- const completedExperts = this.expertReviews.filter(
- expert => expert.reviewStatus === "submitted"
+
+ // 璁$畻灞炴�э細涓诲涓撳鏁伴噺
+ chiefExpertsCount() {
+ return this.ethicalreviewopinionsList.filter(
+ expert => expert.expertType === "1"
).length;
- return totalExperts > 0
- ? Math.round((completedExperts / totalExperts) * 100)
- : 0;
},
+
+ // 璁$畻灞炴�э細鎬讳笓瀹舵暟閲�
+ totalExpertsCount() {
+ return this.ethicalreviewopinionsList.length;
+ },
+
+ // 璁$畻灞炴�э細宸插悓鎰忎笓瀹舵暟閲�
+ approvedExpertsCount() {
+ return this.ethicalreviewopinionsList.filter(
+ expert => expert.expertconclusion === "1"
+ ).length;
+ },
+
// 璁$畻灞炴�э細鎬讳綋缁撹
overallConclusionText() {
- if (this.approvedNormalExperts >= 12) {
+ const total = this.totalExpertsCount;
+ const approved = this.approvedExpertsCount;
+
+ if (total === 0) return "鏈鏌�";
+ if (approved >= Math.ceil(total * 0.7)) {
+ // 瓒呰繃70%鍚屾剰
return "閫氳繃";
- } else if (this.approvedNormalExperts >= 9) {
+ } else if (approved >= Math.ceil(total * 0.5)) {
+ // 瓒呰繃50%鍚屾剰
return "淇敼鍚庨�氳繃";
} else {
return "涓嶉�氳繃";
}
},
+
overallConclusionFilter() {
- if (this.approvedNormalExperts >= 12) {
+ const total = this.totalExpertsCount;
+ const approved = this.approvedExpertsCount;
+
+ if (total === 0) return "info";
+ if (approved >= Math.ceil(total * 0.7)) {
return "success";
- } else if (this.approvedNormalExperts >= 9) {
+ } else if (approved >= Math.ceil(total * 0.5)) {
return "warning";
} else {
return "danger";
}
},
- // 鏄惁鍙互鍙戦�佺粰涓撳
+
+ // 鍙彂閫佺殑鏅�氫笓瀹�
+ availableNormalExperts() {
+ return this.ethicalreviewopinionsList.filter(
+ expert =>
+ expert.expertType === "0" &&
+ (!expert.receiveStatus ||
+ expert.receiveStatus === "0" ||
+ expert.receiveStatus === "1")
+ );
+ },
+
+ // 鍙彂閫佺殑涓诲涓撳
+ availableChiefExperts() {
+ return this.ethicalreviewopinionsList.filter(
+ expert =>
+ expert.expertType === "1" &&
+ (!expert.receiveStatus ||
+ expert.receiveStatus === "0" ||
+ expert.receiveStatus === "1")
+ );
+ },
+
+ // 鏄惁鍙互鍙戦�佺粰鏅�氫笓瀹�
canSendToNormalExperts() {
- return (
- this.expertReviews.filter(
- expert => !expert.isChief && expert.reviewStatus === "applying"
- ).length > 0
- );
+ return this.availableNormalExperts.length > 0;
},
- // 鏄惁鍙互鍙戦�佺粰涓诲涓撳锛堥渶瑕佽嚦灏�12涓笓瀹跺悓鎰忥級
+
+ // 鏄惁鍙互鍙戦�佺粰涓诲涓撳锛堥渶瑕佽嚦灏�12涓櫘閫氫笓瀹跺悓鎰忥級
canSendToChiefExpert() {
- return (
- this.approvedNormalExperts >= 12 &&
- this.expertReviews.filter(
- expert => expert.isChief && expert.reviewStatus === "applying"
- ).length > 0
- );
+ const normalApprovedCount = this.ethicalreviewopinionsList.filter(
+ expert => expert.expertType === "0" && expert.expertconclusion === "1"
+ ).length;
+ return this.availableChiefExperts.length > 0 && normalApprovedCount >= 12;
},
- // 鏄惁鍙互鎵归噺鍙戦��
- canBatchSend() {
- return (
- this.expertReviews.filter(expert => expert.reviewStatus === "applying")
- .length > 0
- );
+
+ // 宸插瓨鍦ㄧ殑涓撳缂栧彿鍒楄〃
+ existingExpertNos() {
+ return this.ethicalreviewopinionsList
+ .map(expert => expert.expertNo)
+ .filter(no => no);
},
- // 鏄惁鍙互鍙戦�佷笓瀹跺鏌�
- canSendToExperts() {
- return this.form.id && this.form.ethicsConclusion === "reviewing";
+
+ // 宸插瓨鍦ㄧ殑涓撳濮撳悕鍒楄〃
+ existingExpertNames() {
+ return this.ethicalreviewopinionsList
+ .map(expert => expert.expertname)
+ .filter(name => name);
},
+
+ // 杩囨护鍚庣殑涓撳鍒楄〃锛堟帓闄ゅ凡瀛樺湪鐨勪笓瀹讹級
+ filteredExpertList() {
+ if (!this.expertList.length) return [];
+
+ return this.expertList.filter(expert => {
+ // 濡傛灉涓撳鏈夌紪鍙凤紝妫�鏌ョ紪鍙锋槸鍚﹀凡瀛樺湪
+ if (expert.userno && this.existingExpertNos.includes(expert.userno)) {
+ return false;
+ }
+ // 濡傛灉涓撳鏈夊鍚嶏紝妫�鏌ュ鍚嶆槸鍚﹀凡瀛樺湪
+ if (
+ expert.username &&
+ this.existingExpertNames.includes(expert.username)
+ ) {
+ return false;
+ }
+ return true;
+ });
+ },
+
+ // 杩囨护鍚庣殑涓撳鎬绘暟
+ filteredExpertTotal() {
+ return this.filteredExpertList.length;
+ },
+
// 褰撳墠鐢ㄦ埛淇℃伅
currentUser() {
return JSON.parse(sessionStorage.getItem("user") || "{}");
+ },
+
+ // 鍙戦�佸璇濇鏍囬
+ sendDialogTitle() {
+ if (this.sendForm.expertType === "chief") {
+ return "鍙戦�佷富濮斾笓瀹跺鏌�";
+ } else if (this.sendForm.expertType === "normal") {
+ return "鍙戦�佹櫘閫氫笓瀹跺鏌�";
+ } else {
+ return "鍙戦�佷笓瀹跺鏌�";
+ }
+ }
+ },
+ watch: {
+ // 鐩戝惉琛ㄥ崟涓殑涓撳鍒楄〃鍙樺寲
+ "form.ethicalreviewopinionsList": {
+ handler(newVal) {
+ console.log("涓撳鍒楄〃鍙樺寲:", newVal);
+ },
+ deep: true
}
},
created() {
- const id = this.$route.query.id;
- if (id) {
- this.getDetail(id);
- this.getAttachments(id);
- // 涓嶅啀闇�瑕佷粠鎺ュ彛鑾峰彇涓撳鍒楄〃锛屼娇鐢ㄥ浐瀹氱殑expertReviews鏁版嵁
- } else if (this.$route.path.includes("/add")) {
- this.generateHospitalNo();
- this.form.registrant = this.currentUser.username || "褰撳墠鐢ㄦ埛";
- }
+
+ this.caseId = this.infoid;
+ this.getDetail(this.infoid, this.id);
},
methods: {
- // 鐢熸垚浣忛櫌鍙�
- generateHospitalNo() {
- const timestamp = Date.now().toString();
- this.form.hospitalNo = "D" + timestamp.slice(-6);
+ // 鍒濆鍖栨柊澧炴暟鎹�
+ initNewData() {
+ this.form.infoid = this.infoid;
+ this.form.caseNo = this.$route.query.caseNo || "";
+ this.form.initiatePerson = this.currentUser.username || "褰撳墠鐢ㄦ埛";
+ this.form.startTime = new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19);
+ this.form.createBy = this.currentUser.username || "admin";
},
- getExpertRowClassName({ row }) {
- return row.isChief ? "chief-expert-row" : "normal-expert-row";
- },
+
// 鑾峰彇璇︽儏
- getDetail(id) {
- getEthicsReviewDetail(id)
- .then(response => {
- if (response.code === 200) {
+ async getDetail(infoid, id) {
+ try {
+ this.expertLoading = true;
+ let response = {};
+ if (id) {
+ response = await ethicalreviewInfo(id);
+ } else if (infoid) {
+ response = await reviewinitiateBaseInfoList({ infoid: infoid });
+ }
+
+ if (response.code === 200) {
+ let detailData = {};
+
+ if (response.data && id) {
this.form = response.data;
- }
- })
- .catch(error => {
- console.error("鑾峰彇浼︾悊瀹℃煡璇︽儏澶辫触:", error);
- this.$message.error("鑾峰彇璇︽儏澶辫触");
- });
- },
+ // 瑙f瀽 filePatch 瀛楁
+ this.parseFilePatch(this.form.filePatch);
+ this.initAttachmentFileList();
- // 鑾峰彇涓撳瀹℃煡鍒楄〃
- getExpertReviews(ethicsReviewId) {
- this.expertLoading = true;
- // 妯℃嫙鏁版嵁 - 瀹為檯椤圭洰涓粠鎺ュ彛鑾峰彇
- setTimeout(() => {
- this.expertReviews = [
- // 涓撳锛�18浣嶏級
- {
- id: 1,
- expertName: "寮犳暀鎺�",
- isChief: false,
- reviewStatus: "submitted",
- expertConclusion: "approved",
- expertOpinion: "绗﹀悎浼︾悊瑕佹眰",
- reviewTime: "2025-12-01 10:30:00"
- },
- {
- id: 2,
- expertName: "鏉庢暀鎺�",
- isChief: false,
- reviewStatus: "submitted",
- expertConclusion: "approved",
- expertOpinion: "鏂规璁捐鍚堢悊",
- reviewTime: "2025-12-01 11:20:00"
- },
- {
- id: 3,
- expertName: "鐜嬫暀鎺�",
- isChief: false,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
- },
- // 涓诲涓撳锛�1浣嶏級
- {
- id: 19,
- expertName: "璧典富濮�",
- isChief: true,
- reviewStatus: "applying",
- expertConclusion: "",
- expertOpinion: "",
- reviewTime: ""
+ // 濡傛灉涓撳瀹℃煡鎰忚鍒楄〃涓嶅瓨鍦紝鍒濆鍖栦负绌烘暟缁�
+ if (!this.form.ethicalreviewopinionsList) {
+ this.$set(this.form, "ethicalreviewopinionsList", []);
+ }
+ } else if (response.data && infoid) {
+ this.form = response.data[0];
+ // 瑙f瀽 filePatch 瀛楁
+ this.parseFilePatch(this.form.filePatch);
+ this.initAttachmentFileList();
+
+ // 濡傛灉涓撳瀹℃煡鎰忚鍒楄〃涓嶅瓨鍦紝鍒濆鍖栦负绌烘暟缁�
+ if (!this.form.ethicalreviewopinionsList) {
+ this.$set(this.form, "ethicalreviewopinionsList", []);
+ }
}
- ];
+
+ // 璁剧疆 expertReviews 鐢ㄤ簬琛ㄦ牸鏄剧ず
+ this.expertReviews = this.form.ethicalreviewopinionsList;
+
+ this.$message.success("鏁版嵁鍔犺浇鎴愬姛");
+ } else {
+ this.$message.error("鑾峰彇璇︽儏澶辫触锛�" + (response.msg || "鏈煡閿欒"));
+ }
+ } catch (error) {
+ console.error("鑾峰彇浼︾悊瀹℃煡璇︽儏澶辫触:", error);
+ this.$message.error("鏁版嵁鍔犺浇澶辫触");
+ } finally {
this.expertLoading = false;
- }, 500);
+ }
},
- // 鑾峰彇闄勪欢鍒楄〃
- getAttachments(ethicsReviewId) {
- this.attachmentLoading = true;
- getAttachments(ethicsReviewId)
- .then(response => {
- if (response.code === 200) {
- this.attachments = response.data;
- }
- this.attachmentLoading = false;
- })
- .catch(error => {
- console.error("鑾峰彇闄勪欢鍒楄〃澶辫触:", error);
- this.attachmentLoading = false;
- });
+ // 瑙f瀽 filePatch 瀛楁
+ parseFilePatch(filePatch) {
+ if (!filePatch) {
+ this.form.annexfilesList = [];
+ return;
+ }
+
+ try {
+ this.form.annexfilesList = JSON.parse(filePatch);
+ } catch (error) {
+ console.error("瑙f瀽 filePatch 瀛楁澶辫触:", error);
+ this.form.annexfilesList = [];
+ }
},
- // 鐘舵�佽繃婊ゅ櫒
- statusFilter(status) {
+ // 鍒濆鍖栭檮浠舵枃浠跺垪琛�
+ initAttachmentFileList() {
+ if (this.form.annexfilesList && this.form.annexfilesList.length > 0) {
+ this.attachmentFileList = this.form.annexfilesList.map(item => ({
+ uid:
+ item.id ||
+ Math.random()
+ .toString(36)
+ .substr(2, 9),
+ name: item.fileName,
+ url: item.path || item.fileUrl,
+ status: "success"
+ }));
+ } else {
+ this.attachmentFileList = [];
+ }
+ },
+
+ // 鏋勫缓 filePatch 瀛楁
+ buildFilePatch() {
+ if (!this.form.annexfilesList || this.form.annexfilesList.length === 0) {
+ return "";
+ }
+ return JSON.stringify(this.form.annexfilesList);
+ },
+
+ // 闄勪欢鍙樺寲澶勭悊
+ handleAttachmentChange(fileList) {
+ this.attachmentFileList = fileList;
+ },
+
+ // 闄勪欢绉婚櫎澶勭悊
+ handleAttachmentRemove(file) {
+ if (file.url) {
+ const index = this.form.annexfilesList.findIndex(
+ item => item.path === file.url || item.fileUrl === file.url
+ );
+ if (index > -1) {
+ this.form.annexfilesList.splice(index, 1);
+ }
+ }
+ },
+
+ // 鎵嬪姩鍒犻櫎闄勪欢
+ handleRemoveAttachment(index) {
+ this.form.annexfilesList.splice(index, 1);
+ this.attachmentFileList.splice(index, 1);
+ this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+ },
+
+ // 涓婁紶鎴愬姛澶勭悊
+ handleUploadSuccess({ file, fileList, response }) {
+ if (response.code === 200) {
+ const attachmentObj = {
+ fileName: file.name,
+ path: response.data || file.url,
+ fileUrl: response.data || file.url,
+ type: this.getFileExtension(file.name),
+ createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
+ infoid: this.infoid,
+ delFlag: 0
+ };
+
+ this.form.annexfilesList.push(attachmentObj);
+ this.$message.success("鏂囦欢涓婁紶鎴愬姛");
+ }
+ },
+
+ // 涓婁紶閿欒澶勭悊
+ handleUploadError({ file, fileList, error }) {
+ console.error("闄勪欢涓婁紶澶辫触:", error);
+ this.$message.error("鏂囦欢涓婁紶澶辫触锛岃閲嶈瘯");
+ },
+
+ // 鏂囦欢棰勮
+ handlePreview(file) {
+ this.currentPreviewFile = {
+ fileName: file.fileName,
+ fileUrl: file.path || file.fileUrl,
+ fileType: this.getFileType(file.fileName)
+ };
+ this.previewVisible = true;
+ },
+
+ // 鏂囦欢涓嬭浇
+ handleDownload(file) {
+ const fileUrl = file.path || file.fileUrl;
+ const fileName = file.fileName;
+
+ if (fileUrl) {
+ const link = document.createElement("a");
+ link.href = fileUrl;
+ link.download = fileName;
+ link.style.display = "none";
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ this.$message.success("寮�濮嬩笅杞芥枃浠�");
+ } else {
+ this.$message.warning("鏂囦欢璺緞涓嶅瓨鍦紝鏃犳硶涓嬭浇");
+ }
+ },
+
+ // 鑾峰彇鏂囦欢绫诲瀷
+ getFileType(fileName) {
+ if (!fileName) return "other";
+
+ const extension = fileName
+ .split(".")
+ .pop()
+ .toLowerCase();
+ const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
+ const pdfTypes = ["pdf"];
+ const officeTypes = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"];
+
+ if (imageTypes.includes(extension)) return "image";
+ if (pdfTypes.includes(extension)) return "pdf";
+ if (officeTypes.includes(extension)) return "office";
+ return "other";
+ },
+
+ // 鑾峰彇鏂囦欢鎵╁睍鍚�
+ getFileExtension(filename) {
+ return filename
+ .split(".")
+ .pop()
+ .toLowerCase();
+ },
+
+ // 鏃ユ湡鏃堕棿鏍煎紡鍖�
+ formatDateTime(dateTime) {
+ if (!dateTime) return "";
+
+ try {
+ const date = new Date(dateTime);
+ if (isNaN(date.getTime())) return dateTime;
+
+ const year = date.getFullYear();
+ const month = String(date.getMonth() + 1).padStart(2, "0");
+ const day = String(date.getDate()).padStart(2, "0");
+ const hours = String(date.getHours()).padStart(2, "0");
+ const minutes = String(date.getMinutes()).padStart(2, "0");
+ const seconds = String(date.getSeconds()).padStart(2, "0");
+
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+ } catch (error) {
+ return dateTime;
+ }
+ },
+
+ // 鍒ゆ柇鏄惁涓轰富浠诲鍛�
+ getIsChiefExpert(expert) {
+ // 鑱岀О鍖呭惈"涓讳换濮斿憳"鎴栬�卐xpertType涓�"1"
+ return (
+ (expert.title && expert.title.includes("涓讳换濮斿憳")) ||
+ expert.expertType === "1"
+ );
+ },
+
+ // 涓撳绫诲瀷鏂囨湰杞崲
+ getExpertTypeText(type) {
+ return type === "1" ? "涓诲涓撳" : "鏅�氫笓瀹�";
+ },
+
+ // 瀹℃煡鐘舵�佽繃婊ゅ櫒
+ getReviewStatusFilter(status) {
const statusMap = {
- applying: "info",
- submitted: "success"
+ "0": "info", // 寰呮帴鏀�
+ "1": "warning", // 鏈帴鏀�
+ "2": "success", // 宸叉帴鏀�
+ "3": "danger", // 瓒呮椂
+ "4": "danger", // 涓
+ "5": "success" // 瀹屾垚
};
return statusMap[status] || "info";
},
- statusTextFilter(status) {
+ getReviewStatusText(status) {
const statusMap = {
- applying: "鐢宠涓�",
- submitted: "宸叉彁浜�"
+ "0": "寰呮帴鏀�",
+ "1": "鏈帴鏀�",
+ "2": "宸叉帴鏀�",
+ "3": "瓒呮椂",
+ "4": "涓",
+ "5": "瀹屾垚"
};
return statusMap[status] || "鏈煡";
},
// 缁撹杩囨护鍣�
- conclusionFilter(conclusion) {
+ getConclusionFilter(conclusion) {
const conclusionMap = {
- approved: "success",
- approved_with_modifications: "warning",
- disapproved: "danger"
+ "1": "success", // 鍚屾剰
+ "2": "warning", // 瀹℃煡涓�
+ "0": "danger" // 涓嶅悓鎰�
};
return conclusionMap[conclusion] || "info";
},
- conclusionTextFilter(conclusion) {
+ getConclusionText(conclusion) {
const conclusionMap = {
- approved: "鍚屾剰",
- approved_with_modifications: "淇敼鍚庡悓鎰�",
- disapproved: "涓嶅悓鎰�"
+ "1": "鍚屾剰",
+ "2": "瀹℃煡涓�",
+ "0": "涓嶅悓鎰�"
};
return conclusionMap[conclusion] || "鏈煡";
},
+ // 涓撳琛屾牱寮�
+ getExpertRowClassName({ row }) {
+ return row.expertType === "1" ? "chief-expert-row" : "normal-expert-row";
+ },
+
+ // 鑾峰彇涓撳鍞竴鏍囪瘑
+ getExpertKey(expert) {
+ return expert.id || expert.expertNo || expert.expertname;
+ },
+
+ // 涓撳绫诲瀷鍙樻洿澶勭悊
+ handleExpertTypeChange() {
+ if (this.sendForm.expertType === "chief") {
+ // 涓诲涓撳鏃犻渶璁剧疆鎴鏃堕棿
+ this.sendForm.endTime = "";
+ } else {
+ // 鏅�氫笓瀹堕噸缃埅姝㈡椂闂翠负褰撳墠鏃堕棿
+ this.sendForm.endTime = "";
+ }
+ },
+
+ // 璁剧疆鎴鏃堕棿蹇嵎閿�
+ setEndTime(hours) {
+ const now = new Date();
+ const endTime = new Date(now.getTime() + hours * 60 * 60 * 1000);
+ this.sendForm.endTime = endTime
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19);
+ },
+
// 淇濆瓨淇℃伅
- handleSave() {
- this.$refs.form.validate(valid => {
+ async handleSave() {
+ this.$refs.form.validate(async valid => {
if (valid) {
this.saveLoading = true;
- const apiMethod = this.form.id ? updateEthicsReview : addEthicsReview;
+ // 淇濆瓨娓呯┖id渚夸簬鍚庣鏁翠綋鍒犻櫎鏂板
+ this.form.ethicalreviewopinionsList.forEach(item=>{
+ item.id=null
+ })
+ try {
+ const submitData = {
+ ...this.form,
+ // 纭繚蹇呰瀛楁
+ infoid: this.infoid,
+ caseNo: this.caseNo,
+ // 鏋勫缓 filePatch 瀛楁
+ filePatch: this.buildFilePatch()
+ };
- apiMethod(this.form)
- .then(response => {
- if (response.code === 200) {
- this.$message.success("淇濆瓨鎴愬姛");
- if (!this.form.id) {
- this.form.id = response.data.id;
- this.$router.replace({
- query: { ...this.$route.query, id: this.form.id }
- });
- }
+ let response = null;
+
+ if (submitData.id) {
+ response = await ethicalreviewedit(submitData);
+ } else {
+ response = await ethicalreviewadd(submitData);
+ }
+
+ if (response.code === 200) {
+ this.$message.success("淇濆瓨鎴愬姛");
+ this.isEdit = false;
+ if (!this.form.id && response.data && response.data.id) {
+ this.form.id = response.data.id;
+ this.$router.replace({
+ query: { ...this.$route.query, id: this.form.id }
+ });
}
- })
- .catch(error => {
- console.error("淇濆瓨澶辫触:", error);
- this.$message.error("淇濆瓨澶辫触");
- })
- .finally(() => {
- this.saveLoading = false;
- });
+ } else {
+ this.$message.error("淇濆瓨澶辫触锛�" + (response.msg || "鏈煡閿欒"));
+ }
+ } catch (error) {
+ console.error("淇濆瓨澶辫触:", error);
+ this.$message.error("淇濆瓨澶辫触锛岃閲嶈瘯");
+ } finally {
+ this.saveLoading = false;
+ }
}
});
},
- // 鍙戦�佷笓瀹跺鏌�
- handleSendToExperts() {
- this.sendDialogVisible = true;
- },
-
- // 鍙戦�佺粰涓撳
- handleSendToNormalExperts() {
- const normalExperts = this.expertReviews.filter(
- expert => !expert.isChief && expert.reviewStatus === "applying"
- );
- this.sendForm.expertIds = normalExperts.map(expert => expert.id);
- this.sendForm.expertType = "normal";
- this.sendDialogVisible = true;
- },
-
- // 鍙戦�佺粰涓诲涓撳
- handleSendToChiefExpert() {
- const chiefExpert = this.expertReviews.find(
- expert => expert.isChief && expert.reviewStatus === "applying"
- );
- if (chiefExpert) {
- this.sendForm.expertIds = [chiefExpert.id];
- this.sendForm.expertType = "chief";
- this.sendDialogVisible = true;
- }
- },
-
- // 鎵归噺鍙戦��
- handleBatchSend() {
- const applyingExperts = this.expertReviews.filter(
- expert => expert.reviewStatus === "applying"
- );
- this.sendForm.expertIds = applyingExperts.map(expert => expert.id);
- this.sendForm.expertType = "batch";
- this.sendDialogVisible = true;
- },
-
- // 鍙戦�佺粰鍗曚釜涓撳
- handleSendToExpert(expert) {
- this.sendForm.expertIds = [expert.id];
- this.sendForm.expertType = expert.isChief ? "chief" : "normal";
- this.sendDialogVisible = true;
- },
-
- // 纭鍙戦��
- handleSendConfirm() {
- if (this.sendForm.expertIds.length === 0) {
- this.$message.warning("璇烽�夋嫨瑕佸彂閫佺殑涓撳");
- return;
- }
-
- sendExpertReview({
- ethicsReviewId: this.form.id,
- expertIds: this.sendForm.expertIds,
- content: this.sendForm.content
+ // 瀹℃煡瀹屾垚
+ async handleCompleteReview() {
+ this.$confirm("纭畾瑕佸皢鏈浼︾悊瀹℃煡鐘舵�佽涓哄畬鎴愬悧锛�", "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
})
- .then(response => {
- if (response.code === 200) {
- this.$message.success("鍙戦�佹垚鍔�");
- this.sendDialogVisible = false;
- this.getExpertReviews(this.form.id);
- this.sendForm = {
- expertType: "normal",
- expertIds: [],
- content: ""
+ .then(async () => {
+ this.completeLoading = true;
+ try {
+ const updateData = {
+ ...this.form,
+ status: "3", // 瀹℃煡瀹屾垚
+ endTime: new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19)
};
+
+ const response = await ethicalreviewedit(updateData);
+
+ if (response.code === 200) {
+ this.$message.success("瀹℃煡鐘舵�佸凡鏇存柊涓哄畬鎴�");
+ this.form.status = "3";
+ this.form.endTime = updateData.endTime;
+ } else {
+ this.$message.error("鎿嶄綔澶辫触锛�" + (response.msg || "鏈煡閿欒"));
+ }
+ } catch (error) {
+ console.error("鏇存柊瀹℃煡鐘舵�佸け璐�:", error);
+ this.$message.error("鏇存柊瀹℃煡鐘舵�佸け璐�");
+ } finally {
+ this.completeLoading = false;
}
})
- .catch(error => {
- console.error("鍙戦�佸け璐�:", error);
- this.$message.error("鍙戦�佸け璐�");
- });
+ .catch(() => {});
+ },
+
+ // 瀹℃煡涓
+ async handleSuspendReview() {
+ this.$confirm(
+ "纭畾瑕佷腑姝㈡湰娆′鸡鐞嗗鏌ュ悧锛熸墍鏈変笓瀹剁殑瀹℃煡鐘舵�佸皢鍙樹负涓銆�",
+ "鎻愮ず",
+ {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ }
+ )
+ .then(async () => {
+ this.suspendLoading = true;
+ try {
+ // 鏇存柊鎵�鏈変笓瀹剁殑鎺ユ敹鐘舵�佷负涓
+ if (
+ this.form.ethicalreviewopinionsList &&
+ this.form.ethicalreviewopinionsList.length > 0
+ ) {
+ this.form.ethicalreviewopinionsList.forEach(expert => {
+ expert.receiveStatus = "4"; // 涓鐘舵��
+ expert.updateTime = new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19);
+ });
+ }
+
+ const updateData = {
+ ...this.form,
+ status: "2" // 瀹℃煡涓
+ };
+
+ const response = await ethicalreviewedit(updateData);
+
+ if (response.code === 200) {
+ this.$message.success("瀹℃煡宸蹭腑姝紝鎵�鏈変笓瀹剁姸鎬佸凡鏇存柊");
+ this.form.status = "2";
+ } else {
+ this.$message.error("鎿嶄綔澶辫触锛�" + (response.msg || "鏈煡閿欒"));
+ }
+ } catch (error) {
+ console.error("涓瀹℃煡澶辫触:", error);
+ this.$message.error("涓瀹℃煡澶辫触");
+ } finally {
+ this.suspendLoading = false;
+ }
+ })
+ .catch(() => {});
},
// 缁撴潫瀹℃煡
- handleEndReview() {
+ async handleEndReview() {
this.$confirm(
"纭畾瑕佺粨鏉熸湰娆′鸡鐞嗗鏌ュ悧锛熺粨鏉熷悗灏嗘棤娉曚慨鏀逛笓瀹跺鏌ョ粨鏋溿��",
"鎻愮ず",
@@ -937,238 +1552,410 @@
type: "warning"
}
)
- .then(() => {
- endEthicsReview(this.form.id)
- .then(response => {
- if (response.code === 200) {
- this.$message.success("瀹℃煡宸茬粨鏉�");
- this.form.ethicsConclusion = "terminated";
- }
- })
- .catch(error => {
- console.error("缁撴潫瀹℃煡澶辫触:", error);
- this.$message.error("缁撴潫瀹℃煡澶辫触");
- });
- })
- .catch(() => {});
- },
+ .then(async () => {
+ this.endLoading = true;
+ try {
+ const updateData = {
+ ...this.form,
+ status: "2", // 瀹℃煡涓
+ endTime: new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19)
+ };
- // 缂栬緫涓撳瀹℃煡
- handleEditExpertReview(expert) {
- this.$prompt("璇疯緭鍏ュ鏌ユ剰瑙�", "缂栬緫涓撳瀹℃煡", {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- inputValue: expert.expertOpinion || "",
- inputValidator: value => {
- if (!value || value.trim() === "") {
- return "瀹℃煡鎰忚涓嶈兘涓虹┖";
- }
- return true;
- }
- })
- .then(({ value }) => {
- // 妯℃嫙鏇存柊涓撳瀹℃煡
- const index = this.expertReviews.findIndex(e => e.id === expert.id);
- if (index !== -1) {
- this.expertReviews[index].expertOpinion = value;
- this.$message.success("瀹℃煡鎰忚宸叉洿鏂�");
+ const response = await ethicalreviewedit(updateData);
+
+ if (response.code === 200) {
+ this.$message.success("瀹℃煡宸茬粨鏉�");
+ this.form.status = "2";
+ this.form.endTime = updateData.endTime;
+ } else {
+ this.$message.error("鎿嶄綔澶辫触锛�" + (response.msg || "鏈煡閿欒"));
+ }
+ } catch (error) {
+ console.error("缁撴潫瀹℃煡澶辫触:", error);
+ this.$message.error("缁撴潫瀹℃煡澶辫触");
+ } finally {
+ this.endLoading = false;
}
})
.catch(() => {});
},
- // 鏌ョ湅涓撳瀹℃煡璇︽儏
- handleViewExpertReview(expert) {
- this.$alert(
- `
- <div>
- <p><strong>涓撳濮撳悕锛�</strong>${expert.expertName}</p>
- <p><strong>涓撳绫诲瀷锛�</strong>${
- expert.isChief ? "涓诲涓撳" : "涓撳"
- }</p>
- <p><strong>瀹℃煡鐘舵�侊細</strong>${this.statusTextFilter(
- expert.reviewStatus
- )}</p>
- <p><strong>涓撳缁撹锛�</strong>${
- expert.expertConclusion
- ? this.conclusionTextFilter(expert.expertConclusion)
- : "鏈彁浜�"
- }</p>
- <p><strong>瀹℃煡鎰忚锛�</strong>${expert.expertOpinion || "鏃�"}</p>
- <p><strong>瀹℃煡鏃堕棿锛�</strong>${expert.reviewTime || "鏈鏌�"}</p>
- </div>
- `,
- "涓撳瀹℃煡璇︽儏",
- {
- dangerouslyUseHTMLString: true,
- customClass: "expert-review-detail-dialog"
+ // 鎵撳紑娣诲姞涓撳瀵硅瘽妗�
+ handleAddExpert() {
+ this.expertDialogVisible = true;
+ this.loadExperts();
+ },
+
+ // 鍔犺浇涓撳鍒楄〃
+ async loadExperts() {
+ try {
+ this.expertListLoading = true;
+ const params = {
+ usertype: "浼︾悊涓撳", // 浼︾悊涓撳
+ pageNum: this.expertPage.pageNum,
+ pageSize: this.expertPage.pageSize
+ };
+
+ if (this.expertSearchQuery) {
+ params.username = this.expertSearchQuery;
}
- );
- },
- // 涓婁紶闄勪欢
- handleUploadAttachment() {
- this.uploadDialogVisible = true;
- },
-
- // 涓婁紶鍓嶆牎楠�
- beforeUpload(file) {
- const allowedTypes = [
- "application/pdf",
- "image/jpeg",
- "image/png",
- "application/msword",
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
- "application/vnd.ms-excel",
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
- ];
-
- const maxSize = 10 * 1024 * 1024;
-
- const isTypeOk =
- allowedTypes.includes(file.type) ||
- file.name.endsWith(".pdf") ||
- file.name.endsWith(".jpg") ||
- file.name.endsWith(".jpeg") ||
- file.name.endsWith(".png") ||
- file.name.endsWith(".doc") ||
- file.name.endsWith(".docx") ||
- file.name.endsWith(".xls") ||
- file.name.endsWith(".xlsx");
-
- if (!isTypeOk) {
- this.$message.error("鏂囦欢鏍煎紡涓嶆敮鎸�");
- return false;
+ const response = await listExternalperson(params);
+ if (response.code === 200) {
+ this.expertList = response.rows || [];
+ this.expertTotal = response.total || 0;
+ } else {
+ this.$message.error(
+ "鍔犺浇涓撳鍒楄〃澶辫触锛�" + (response.msg || "鏈煡閿欒")
+ );
+ }
+ } catch (error) {
+ console.error("鍔犺浇涓撳鍒楄〃澶辫触:", error);
+ this.$message.error("鍔犺浇涓撳鍒楄〃澶辫触");
+ } finally {
+ this.expertListLoading = false;
}
-
- if (file.size > maxSize) {
- this.$message.error("鏂囦欢澶у皬涓嶈兘瓒呰繃10MB");
- return false;
- }
-
- return true;
},
- // 鏂囦欢閫夋嫨鍙樺寲
- handleFileChange(file, fileList) {
- this.tempFileList = fileList;
+ // 鎼滅储涓撳
+ handleSearchExperts() {
+ this.expertPage.pageNum = 1;
+ this.loadExperts();
},
- // 鎻愪氦涓婁紶
- submitUpload() {
- if (this.tempFileList.length === 0) {
- this.$message.warning("璇峰厛閫夋嫨瑕佷笂浼犵殑鏂囦欢");
+ // 閲嶇疆鎼滅储
+ handleResetSearch() {
+ this.expertSearchQuery = "";
+ this.filterExpertType = "";
+ this.expertPage.pageNum = 1;
+ this.loadExperts();
+ },
+
+ // 涓撳閫夋嫨鍙樺寲
+ handleExpertSelectionChange(selection) {
+ this.selectedExperts = selection;
+ },
+
+ // 纭娣诲姞涓撳
+ handleConfirmAddExpert() {
+ if (this.selectedExperts.length === 0) {
+ this.$message.warning("璇烽�夋嫨瑕佹坊鍔犵殑涓撳");
return;
}
- this.uploadLoading = true;
+ // 纭繚ethicalreviewopinionsList瀛樺湪
+ if (!this.form.ethicalreviewopinionsList) {
+ this.$set(this.form, "ethicalreviewopinionsList", []);
+ }
- const uploadPromises = this.tempFileList.map(file => {
- const formData = new FormData();
- formData.append("file", file.raw);
- formData.append("ethicsReviewId", this.form.id);
+ // 娣诲姞涓撳鍒板垪琛�
+ this.selectedExperts.forEach(expert => {
+ // 鍒ゆ柇鏄惁涓轰富浠诲鍛�
+ const isChief = this.getIsChiefExpert(expert);
- return uploadAttachment(formData);
+ const expertReview = {
+ id: undefined,
+ infoid: this.infoid,
+ nitiateId: this.form.id || undefined,
+ caseNo: this.form.caseNo,
+ expertname: expert.username,
+ expertNo: expert.userno,
+ expertType: isChief ? "1" : "0", // 涓讳换濮斿憳璁剧疆涓轰富濮斾笓瀹�
+ deptName: expert.unitname || "",
+ title: expert.title || "",
+ deptname: expert.telephone || "",
+ receiveStatus: "0", // 寰呮帴鏀�
+ expertconclusion: "",
+ expertopinion: "",
+ conclusionannex: "",
+ conclusionorder: this.form.ethicalreviewopinionsList.length + 1,
+ conclusiontime: "",
+ startTime: "",
+ endTime: "",
+ sendType: "",
+ createBy: this.currentUser.username || "admin",
+ createTime: new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19),
+ updateBy: this.currentUser.username || "admin",
+ updateTime: new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19),
+ delFlag: "0"
+ };
+
+ // 浣跨敤push娣诲姞锛岀‘淇濆搷搴斿紡
+ this.form.ethicalreviewopinionsList.push(expertReview);
});
- Promise.all(uploadPromises)
- .then(responses => {
- this.$message.success("鏂囦欢涓婁紶鎴愬姛");
- this.uploadDialogVisible = false;
- this.tempFileList = [];
- this.getAttachments(this.form.id);
- })
- .catch(error => {
- console.error("涓婁紶澶辫触:", error);
- this.$message.error("鏂囦欢涓婁紶澶辫触");
- })
- .finally(() => {
- this.uploadLoading = false;
- });
+ this.$message.success(`鎴愬姛娣诲姞 ${this.selectedExperts.length} 浣嶄笓瀹禶);
+ this.expertDialogVisible = false;
+ this.selectedExperts = [];
},
- // 棰勮闄勪欢
- handlePreviewAttachment(attachment) {
- if (attachment.fileName.endsWith(".pdf")) {
- window.open(attachment.fileUrl, "_blank");
- } else if (attachment.fileName.match(/\.(jpg|jpeg|png)$/i)) {
- this.$alert(
- `<img src="${attachment.fileUrl}" style="max-width: 100%;" alt="${attachment.fileName}">`,
- "鍥剧墖棰勮",
- {
- dangerouslyUseHTMLString: true,
- customClass: "image-preview-dialog"
+ // 娣诲姞涓撳瀵硅瘽妗嗗叧闂�
+ handleExpertDialogClose() {
+ this.selectedExperts = [];
+ this.expertSearchQuery = "";
+ this.filterExpertType = "";
+ this.expertPage.pageNum = 1;
+ },
+
+ // 椤电爜鍙樺寲
+ handlePageChange(pageNum) {
+ this.expertPage.pageNum = pageNum;
+ this.loadExperts();
+ },
+
+ // 姣忛〉鏉℃暟鍙樺寲
+ handlePageSizeChange(pageSize) {
+ this.expertPage.pageSize = pageSize;
+ this.expertPage.pageNum = 1;
+ this.loadExperts();
+ },
+
+ // 鍙戦�佺粰鏅�氫笓瀹�
+ handleSendToNormalExperts() {
+ this.currentSendExperts = this.availableNormalExperts;
+ this.sendForm.expertType = "normal";
+ this.sendForm.endTime = ""; // 閲嶇疆鎴鏃堕棿
+ this.sendDialogVisible = true;
+ },
+
+ // 鍙戦�佺粰涓诲涓撳
+ handleSendToChiefExpert() {
+ this.currentSendExperts = this.availableChiefExperts;
+ this.sendForm.expertType = "chief";
+ this.sendForm.endTime = ""; // 涓诲涓撳鏃犻渶鎴鏃堕棿
+ this.sendDialogVisible = true;
+ },
+
+ // 鍙戦�佺粰鍗曚釜涓撳
+ handleSendToExpert(expert) {
+ this.currentSendExperts = [expert];
+ this.sendForm.expertType = expert.expertType === "1" ? "chief" : "normal";
+ this.sendForm.endTime = expert.expertType === "1" ? "" : ""; // 涓诲涓撳鏃犻渶鎴鏃堕棿
+ this.sendDialogVisible = true;
+ },
+
+ // 鍙戦�佸璇濇鍏抽棴
+ handleSendDialogClose() {
+ this.sendForm = {
+ expertType: "normal",
+ expertIds: [],
+ startTime: "",
+ endTime: "",
+ sendType: "0",
+ title: "浼︾悊瀹℃煡浠诲姟閫氱煡",
+ content: "",
+ url: ""
+ };
+ this.currentSendExperts = [];
+ },
+
+ // 纭鍙戦��
+ async handleSendConfirm() {
+ if (!this.sendForm.startTime) {
+ this.$message.warning("璇烽�夋嫨鍙戦�佹椂闂�");
+ return;
+ }
+
+ // 鏅�氫笓瀹堕渶瑕佹埅姝㈡椂闂达紝涓诲涓撳涓嶉渶瑕�
+ if (this.sendForm.expertType !== "chief" && !this.sendForm.endTime) {
+ this.$message.warning("璇烽�夋嫨鎴鏃堕棿");
+ return;
+ }
+
+ if (!this.sendForm.sendType) {
+ this.$message.warning("璇烽�夋嫨鍙戦�佹柟寮�");
+ return;
+ }
+
+ if (!this.sendForm.title) {
+ this.$message.warning("璇疯緭鍏ュ彂閫佹爣棰�");
+ return;
+ }
+
+ if (!this.sendForm.content) {
+ this.$message.warning("璇疯緭鍏ュ彂閫佸唴瀹�");
+ return;
+ }
+
+ if (this.currentSendExperts.length === 0) {
+ this.$message.warning("娌℃湁鎵惧埌鍙彂閫佺殑涓撳");
+ return;
+ }
+
+ this.sending = true;
+ try {
+ // 鍙戦�佺粰姣忎釜涓撳
+ const sendPromises = this.currentSendExperts.map(async expert => {
+ try {
+ // 鏋勫缓鍙戦�佹暟鎹�
+ const sendData = {
+ number: expert.deptname || "", // 鐢ㄦ埛鎵嬫満鍙�
+ title: this.sendForm.title,
+ url: this.sendForm.url || "",
+
+ createTime: new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19)
+ };
+
+ // 璋冪敤鍙戦�侀�氱煡鎺ュ彛
+ const response = await sendNotification(sendData);
+
+ if (response.code === 200) {
+ // 鏇存柊涓撳鐘舵��
+ const index = this.form.ethicalreviewopinionsList.findIndex(
+ e =>
+ e.expertNo === expert.expertNo ||
+ e.expertname === expert.expertname
+ );
+
+ if (index !== -1) {
+ this.form.ethicalreviewopinionsList[index].receiveStatus = "1"; // 宸叉帴鏀�
+ this.form.ethicalreviewopinionsList[
+ index
+ ].startTime = this.sendForm.startTime;
+ this.form.ethicalreviewopinionsList[
+ index
+ ].endTime = this.sendForm.endTime;
+ this.form.ethicalreviewopinionsList[
+ index
+ ].sendType = this.sendForm.sendType;
+ this.form.ethicalreviewopinionsList[
+ index
+ ].updateTime = new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19);
+
+ // 浣跨敤Vue.set纭繚鍝嶅簲寮忔洿鏂�
+ this.$set(
+ this.form.ethicalreviewopinionsList,
+ index,
+ this.form.ethicalreviewopinionsList[index]
+ );
+ }
+
+ return { success: true, expert: expert.expertname };
+ } else {
+ return {
+ success: false,
+ expert: expert.expertname,
+ error: response.msg
+ };
+ }
+ } catch (error) {
+ console.error(`鍙戦�佺粰涓撳 ${expert.expertname} 澶辫触:`, error);
+ return {
+ success: false,
+ expert: expert.expertname,
+ error: error.message
+ };
}
- );
- } else {
- this.$message.info("璇ユ枃浠剁被鍨嬫殏涓嶆敮鎸佸湪绾块瑙堬紝璇蜂笅杞藉悗鏌ョ湅");
+ });
+
+ // 绛夊緟鎵�鏈夊彂閫佸畬鎴�
+ 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("鍙戦�佸け璐ワ紝璇风◢鍚庨噸璇�");
+ }
+
+ this.sendDialogVisible = false;
+ this.sendForm = {
+ expertType: "normal",
+ expertIds: [],
+ startTime: "",
+ endTime: "",
+ sendType: "0",
+ title: "浼︾悊瀹℃煡浠诲姟閫氱煡",
+ content: "",
+ url: ""
+ };
+ this.currentSendExperts = [];
+ } catch (error) {
+ console.error("鍙戦�佸け璐�:", error);
+ this.$message.error("鍙戦�佸け璐ワ紝璇烽噸璇�");
+ } finally {
+ this.sending = false;
}
},
- // 涓嬭浇闄勪欢
- handleDownloadAttachment(attachment) {
- const link = document.createElement("a");
- link.href = attachment.fileUrl;
- link.download = attachment.fileName;
- link.click();
- this.$message.success(`寮�濮嬩笅杞�: ${attachment.fileName}`);
- },
-
- // 鍒犻櫎闄勪欢
- handleRemoveAttachment(attachment) {
- this.$confirm("纭畾瑕佸垹闄よ繖涓檮浠跺悧锛�", "鎻愮ず", {
+ // 鍒犻櫎涓撳瀹℃煡
+ handleDeleteExpertReview(expert, index) {
+ this.$confirm("纭畾瑕佸垹闄よ涓撳鐨勫鏌ヨ褰曞悧锛�", "鎻愮ず", {
confirmButtonText: "纭畾",
cancelButtonText: "鍙栨秷",
type: "warning"
})
.then(() => {
- deleteAttachment(attachment.id)
- .then(response => {
- if (response.code === 200) {
- this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
- this.getAttachments(this.form.id);
- }
- })
- .catch(error => {
- console.error("鍒犻櫎闄勪欢澶辫触:", error);
- this.$message.error("鍒犻櫎闄勪欢澶辫触");
- });
+ // 浠庢暟缁勪腑鍒犻櫎涓撳
+ this.form.ethicalreviewopinionsList.splice(index, 1);
+ this.$message.success("涓撳瀹℃煡璁板綍宸插垹闄�");
})
.catch(() => {});
},
- // 鑾峰彇鏂囦欢绫诲瀷
- getFileType(fileName) {
- const ext = fileName
- .split(".")
- .pop()
- .toLowerCase();
- const typeMap = {
- pdf: "PDF",
- doc: "DOC",
- docx: "DOCX",
- xls: "XLS",
- xlsx: "XLSX",
- jpg: "JPG",
- jpeg: "JPEG",
- png: "PNG"
- };
- return typeMap[ext] || ext.toUpperCase();
- },
+ // 鏌ョ湅涓撳鍘嗗彶瀹℃壒鎯呭喌
+ async handleViewExpertHistory(expert) {
+ if (!expert.expertNo) {
+ this.$message.warning("璇ヤ笓瀹舵病鏈夌紪鍙凤紝鏃犳硶鏌ヨ鍘嗗彶瀹℃壒鎯呭喌");
+ return;
+ }
- // 鏂囦欢澶у皬鏍煎紡鍖�
- formatFileSize(size) {
- if (size === 0) return "0 B";
- const k = 1024;
- const sizes = ["B", "KB", "MB", "GB"];
- const i = Math.floor(Math.log(size) / Math.log(k));
- return parseFloat((size / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
+ this.currentExpertInfo = expert;
+ this.expertHistoryLoading = true;
+ this.expertHistoryDialogVisible = true;
+
+ try {
+ const params = {
+ expertNo: expert.expertNo
+ };
+
+ const response = await ethicalreExpertTotal(params);
+
+ if (response && response.code === 200) {
+ this.expertHistoryData = response.data || response[0] || null;
+ } else {
+ this.$message.error(
+ "鏌ヨ涓撳鍘嗗彶瀹℃壒鎯呭喌澶辫触锛�" + (response?.msg || "鏈煡閿欒")
+ );
+ this.expertHistoryData = null;
+ }
+ } catch (error) {
+ console.error("鏌ヨ涓撳鍘嗗彶瀹℃壒鎯呭喌澶辫触:", error);
+ this.$message.error("鏌ヨ涓撳鍘嗗彶瀹℃壒鎯呭喌澶辫触");
+ this.expertHistoryData = null;
+ } finally {
+ this.expertHistoryLoading = false;
+ }
},
// 鏃堕棿鏍煎紡鍖�
parseTime(time) {
if (!time) return "";
const date = new Date(time);
+ if (isNaN(date.getTime())) return time;
+
return `${date.getFullYear()}-${(date.getMonth() + 1)
.toString()
.padStart(2, "0")}-${date
@@ -1185,6 +1972,7 @@
}
};
</script>
+
<style scoped>
.ethics-review-detail {
padding: 20px;
@@ -1240,22 +2028,6 @@
font-weight: bold;
}
-.upload-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 15px;
- padding: 10px;
- background-color: #f8f9fa;
- border-radius: 4px;
-}
-
-.upload-title {
- font-size: 14px;
- font-weight: 600;
- color: #303133;
-}
-
.file-info {
display: flex;
align-items: center;
@@ -1267,133 +2039,6 @@
color: #909399;
}
-/* 琛ㄥ崟鏍峰紡浼樺寲 */
-:deep(.el-form-item__label) {
- font-weight: 500;
-}
-
-:deep(.el-input__inner) {
- border-radius: 4px;
-}
-
-:deep(.el-textarea__inner) {
- border-radius: 4px;
- resize: vertical;
-}
-
-/* 琛ㄦ牸鏍峰紡浼樺寲 */
-:deep(.el-table) {
- border-radius: 8px;
- overflow: hidden;
-}
-
-:deep(.el-table th) {
- background-color: #f5f7fa;
- color: #606266;
- font-weight: 500;
-}
-
-:deep(.el-table .cell) {
- padding: 8px 12px;
-}
-
-/* 鎸夐挳鏍峰紡浼樺寲 */
-:deep(.el-button--primary) {
- background: linear-gradient(135deg, #409eff 0%, #3375e0 100%);
- border: none;
- border-radius: 4px;
-}
-
-:deep(.el-button--success) {
- background: linear-gradient(135deg, #67c23a 0%, #529b2f 100%);
- border: none;
- border-radius: 4px;
-}
-
-:deep(.el-button--warning) {
- background: linear-gradient(135deg, #e6a23c 0%, #d18c2a 100%);
- border: none;
- border-radius: 4px;
-}
-
-:deep(.el-button--danger) {
- background: linear-gradient(135deg, #f56c6c 0%, #e05b5b 100%);
- border: none;
- border-radius: 4px;
-}
-
-/* 鏍囩鏍峰紡 */
-:deep(.el-tag) {
- border-radius: 12px;
- border: none;
- font-weight: 500;
-}
-
-/* 瀵硅瘽妗嗘牱寮忎紭鍖� */
-:deep(.el-dialog) {
- border-radius: 8px;
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
-}
-
-:deep(.el-dialog__header) {
- background: linear-gradient(135deg, #f5f7fa 0%, #e4e7ed 100%);
- border-bottom: 1px solid #e4e7ed;
- padding: 15px 20px;
-}
-
-:deep(.el-dialog__title) {
- font-weight: 600;
- color: #303133;
-}
-
-/* 涓婁紶缁勪欢鏍峰紡 */
-:deep(.el-upload-dragger) {
- border: 2px dashed #dcdfe6;
- border-radius: 6px;
- background-color: #fafafa;
- transition: all 0.3s ease;
-}
-
-:deep(.el-upload-dragger:hover) {
- border-color: #409eff;
- background-color: #f0f7ff;
-}
-
-/* 鍝嶅簲寮忚璁� */
-@media (max-width: 768px) {
- .ethics-review-detail {
- padding: 10px;
- }
-
- .expert-stats .el-col {
- margin-bottom: 10px;
- }
-
- .upload-header {
- flex-direction: column;
- align-items: flex-start;
- gap: 10px;
- }
-}
-
-/* 鍔ㄧ敾鏁堟灉 */
-.fade-enter-active,
-.fade-leave-active {
- transition: opacity 0.3s ease;
-}
-
-.fade-enter,
-.fade-leave-to {
- opacity: 0;
-}
-
-/* 鍔犺浇鐘舵�� */
-.loading-container {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 200px;
-}
/* 涓撳绫诲瀷鏍峰紡 */
.normal-expert {
color: #409eff;
@@ -1439,49 +2084,108 @@
color: #67c23a !important;
}
-/* 琛ㄦ牸琛屾偓鍋滄晥鏋� */
-:deep(.el-table__row:hover) {
- transform: translateY(-1px);
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- transition: all 0.3s ease;
-}
-/* 鑷畾涔夋粴鍔ㄦ潯 */
-:deep(::-webkit-scrollbar) {
- width: 6px;
- height: 6px;
+/* 涓撳濮撳悕閾炬帴鏍峰紡 */
+.expert-name-link {
+ color: #409eff;
+ cursor: pointer;
+ text-decoration: none;
+ transition: color 0.3s;
}
-:deep(::-webkit-scrollbar-track) {
- background: #f1f1f1;
- border-radius: 3px;
+.expert-name-link:hover {
+ color: #66b1ff;
+ text-decoration: underline;
}
-:deep(::-webkit-scrollbar-thumb) {
- background: #c1c1c1;
- border-radius: 3px;
+/* 鍘嗗彶缁熻鏍峰紡 */
+.history-stat-item {
+ padding: 10px;
+ border-radius: 4px;
+ background-color: #f5f7fa;
+ text-align: center;
}
-:deep(::-webkit-scrollbar-thumb:hover) {
- background: #a8a8a8;
+.history-stat-label {
+ font-size: 12px;
+ color: #909399;
+ margin-bottom: 5px;
}
-/* 涓撳瀹℃煡琛ㄦ牸鐗规畩鏍峰紡 */
-.expert-table-special :deep(.el-table__row) {
- transition: all 0.3s ease;
+.history-stat-value {
+ font-size: 18px;
+ font-weight: bold;
+ color: #303133;
}
-.expert-table-special :deep(.el-table__row:hover) {
- background-color: #f0f7ff;
- transform: translateY(-1px);
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+.form-section {
+ margin-bottom: 16px;
}
-/* 涓诲涓撳琛岄珮浜� */
-:deep(.chief-expert-row) {
- background-color: #fff7e6 !important;
+.section-header {
+ display: flex;
+ align-items: center;
+ font-weight: bold;
+ color: #303133;
}
-:deep(.chief-expert-row:hover) {
- background-color: #ffecc2 !important;
+.dialog-footer {
+ text-align: right;
+ padding: 20px 0 0;
+}
+
+.attachment-section {
+ margin-bottom: 16px;
+}
+
+.attachment-header {
+ display: flex;
+ align-items: center;
+ margin-bottom: 16px;
+ padding: 8px 0;
+ border-bottom: 1px solid #ebeef5;
+}
+
+.attachment-title {
+ font-weight: bold;
+ margin: 0 8px;
+}
+
+.attachment-tip {
+ font-size: 12px;
+ color: #909399;
+}
+
+.attachment-list {
+ margin-top: 16px;
+}
+
+.list-title {
+ font-weight: bold;
+ margin-bottom: 12px;
+ color: #303133;
+}
+
+.file-name {
+ font-size: 13px;
+}
+
+/* 妗堜緥淇℃伅灞曠ず鏍峰紡 */
+.selected-case-info {
+ margin-bottom: 20px;
+}
+
+.case-info-card {
+ border-left: 4px solid #67c23a;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 768px) {
+ .ethics-review-detail {
+ padding: 10px;
+ }
+
+ .expert-stats .el-col {
+ margin-bottom: 10px;
+ }
}
</style>
diff --git a/src/views/business/course/components/MedicalAssessmentStage.vue b/src/views/business/course/components/MedicalAssessmentStage.vue
index e05103c..c579876 100644
--- a/src/views/business/course/components/MedicalAssessmentStage.vue
+++ b/src/views/business/course/components/MedicalAssessmentStage.vue
@@ -1,72 +1,11 @@
<template>
<div class="assessment-detail">
- <el-card class="basic-info-card">
- <div slot="header" class="clearfix">
- <span>妗堜緥鍩烘湰淇℃伅</span>
- <el-button
- style="float: right; padding: 3px 0"
- type="text"
- @click="handleAttachmentPreview"
- >
- <i class="el-icon-folder-opened"></i> 鏌ョ湅闄勪欢
- </el-button>
- </div>
-
- <el-descriptions :column="2" border>
- <el-descriptions-item label="浣忛櫌鍙�">{{
- assessmentData.caseNo
- }}</el-descriptions-item>
- <el-descriptions-item label="娼滃湪鎹愮尞鑰呭鍚�">{{
- assessmentData.name || assessmentData.donorName
- }}</el-descriptions-item>
- <el-descriptions-item label="鎬у埆">
- <dict-tag
- :options="dict.type.sys_user_sex"
- :value="assessmentData.sex"
- />
- </el-descriptions-item>
- <el-descriptions-item label="骞撮緞"
- >{{ assessmentData.age }}宀�</el-descriptions-item
- >
- <el-descriptions-item label="琛�鍨�">
- {{ assessmentData.bloodtype }}
- </el-descriptions-item>
- <el-descriptions-item label="璇佷欢鍙风爜">{{
- assessmentData.idcardno
- }}</el-descriptions-item>
- <el-descriptions-item label="鐤剧梾璇婃柇">{{
- assessmentData.diagnosisname
- }}</el-descriptions-item>
- <el-descriptions-item label="鎵�鍦ㄥ尰鐤楁満鏋�">{{
- assessmentData.treatmenthospitalname
- }}</el-descriptions-item>
- <el-descriptions-item label="鍗忚皟鍛�">{{
- assessmentData.coordinatorName
- }}</el-descriptions-item>
- <el-descriptions-item label="璇勪及鏃堕棿">{{
- assessmentData.assessTime
- }}</el-descriptions-item>
- <el-descriptions-item label="璇勪及鐘舵��">
- <el-tag :type="statusFilter(assessmentData.assessState)">
- {{ statusTextFilter(assessmentData.assessState) }}
- </el-tag>
- </el-descriptions-item>
- </el-descriptions>
- </el-card>
+ <!-- 鍩虹妗堜緥淇℃伅 -->
<el-card class="organ-assessment-card">
<div slot="header" class="clearfix">
<span>鍣ㄥ畼璇勪及琛�</span>
- <el-button
- v-if="isCoordinator && allOrgansAssessed"
- style="float: right; margin-left: 10px"
- type="primary"
- size="mini"
- @click="handleCompleteAssessment"
- :loading="saveLoading"
- >
- 纭瀹屾垚璇勪及
- </el-button>
+
<span v-if="!isCoordinator" class="jstitle">
褰撳墠瑙掕壊锛歿{ currentDepartment }}璇勪及浜哄憳
</span>
@@ -123,7 +62,7 @@
v-for="(assessment, index) in getOrganAssessments(scope.row)"
:key="`${scope.row.organno}_${index}`"
:label="`绗�${index + 1}娆¤瘎浼癭"
- :name="index"
+ :name="String(index)"
>
<organ-assessment-form
:organ-data="scope.row"
@@ -157,153 +96,211 @@
</el-tab-pane>
<!-- 璇勪及姹囨�籘ab -->
- <el-tab-pane label="璇勪及姹囨��" name="summary">
- <div class="assessment-summary">
- <!-- 鍩烘湰淇℃伅姹囨�� -->
- <el-descriptions title="鍩烘湰淇℃伅姹囨��" :column="2" border>
- <el-descriptions-item label="鍣ㄥ畼绫诲瀷">
- <span class="summary-item">{{ getOrganLabel(scope.row.organno) }}</span>
- </el-descriptions-item>
- <el-descriptions-item label="鑾峰彇鏈烘瀯">
- <span class="summary-item">{{ scope.row.gainhospitalname }}</span>
- </el-descriptions-item>
- <el-descriptions-item label="璇勪及娆℃暟" :span="2">
- <el-tag type="info" size="medium">
- {{ getAssessmentCount(scope.row) }}娆�
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鏈�鏂拌瘎浼版椂闂�" :span="2">
- <span class="highlight-text">{{ getLatestAssessmentTime(scope.row) || "-" }}</span>
- </el-descriptions-item>
- </el-descriptions>
+ <el-tab-pane label="璇勪及姹囨��" name="summary">
+ <div class="assessment-summary">
+ <!-- 鍩烘湰淇℃伅姹囨�� -->
+ <el-descriptions title="鍩烘湰淇℃伅姹囨��" :column="2" border>
+ <el-descriptions-item label="鍣ㄥ畼绫诲瀷">
+ <span class="summary-item">{{
+ getOrganLabel(scope.row.organno)
+ }}</span>
+ </el-descriptions-item>
+ <el-descriptions-item label="鑾峰彇鏈烘瀯">
+ <span class="summary-item">{{
+ scope.row.gainhospitalname
+ }}</span>
+ </el-descriptions-item>
+ <el-descriptions-item label="璇勪及娆℃暟" :span="2">
+ <el-tag type="info" size="medium">
+ {{ getAssessmentCount(scope.row) }}娆�
+ </el-tag>
+ </el-descriptions-item>
+ <el-descriptions-item label="鏈�鏂拌瘎浼版椂闂�" :span="2">
+ <span class="highlight-text">{{
+ getLatestAssessmentTime(scope.row) || "-"
+ }}</span>
+ </el-descriptions-item>
+ </el-descriptions>
- <!-- 璇勪及璇︽儏姹囨�� -->
- <el-card header="璇勪及璇︽儏鍒楄〃" style="margin-top: 20px;" class="assessment-detail-card">
- <div v-if="getOrganAssessments(scope.row).length === 0" class="no-assessment">
- <el-empty description="鏆傛棤璇勪及璁板綍"></el-empty>
- </div>
+ <!-- 璇勪及璇︽儏姹囨�� -->
+ <el-card
+ header="璇勪及璇︽儏鍒楄〃"
+ style="margin-top: 20px;"
+ class="assessment-detail-card"
+ >
+ <div
+ v-if="getOrganAssessments(scope.row).length == 0"
+ class="no-assessment"
+ >
+ <el-empty description="鏆傛棤璇勪及璁板綍"></el-empty>
+ </div>
- <div v-else>
- <!-- 姣忔璇勪及璇︽儏 -->
- <div v-for="(assessment, index) in getOrganAssessments(scope.row)"
- :key="index"
- class="assessment-item">
- <el-card shadow="hover" class="assessment-card">
- <div slot="header" class="clearfix">
- <span class="assessment-title">绗瑊{ index + 1 }}娆¤瘎浼�</span>
- <el-tag
- :type="getAssessmentTagType(assessment.status)"
- size="small"
- class="status-tag"
- >
- {{ getAssessmentStatusText(assessment.status) }}
- </el-tag>
- </div>
+ <div v-else>
+ <!-- 姣忔璇勪及璇︽儏 -->
+ <div
+ v-for="(assessment, index) in getOrganAssessments(
+ scope.row
+ )"
+ :key="index"
+ class="assessment-item"
+ >
+ <el-card shadow="hover" class="assessment-card">
+ <div slot="header" class="clearfix">
+ <span class="assessment-title"
+ >绗瑊{ index + 1 }}娆¤瘎浼�</span
+ >
+ <el-tag
+ :type="getAssessmentTagType(assessment.status)"
+ size="small"
+ class="status-tag"
+ >
+ {{ getAssessmentStatusText(assessment.status) }}
+ </el-tag>
+ </div>
- <el-descriptions :column="2" border class="detail-descriptions">
- <el-descriptions-item label="璇勪及鏃堕棿" :span="2">
- <span class="time-text">{{ assessment.assessmentTime || "-" }}</span>
- </el-descriptions-item>
+ <el-descriptions
+ :column="2"
+ border
+ class="detail-descriptions"
+ >
+ <!-- 璇勪及鏃堕棿 -->
+ <el-descriptions-item label="璇勪及鏃堕棿" :span="2">
+ <span class="time-text">
+ {{
+ parseTime(assessment.assessmentTime) ||
+ "鏈缃�"
+ }}
+ </span>
+ </el-descriptions-item>
- <el-descriptions-item label="璇勪及浜�">
- <el-tag type="info" size="small">
- {{ assessment.assessor || "鏈~鍐�" }}
- </el-tag>
- </el-descriptions-item>
+ <!-- 鍘熸湁鐨勮瘎浼颁汉淇℃伅 -->
+ <el-descriptions-item label="璇勪及浜�">
+ <el-tag type="info" size="small">
+ {{ assessment.assessor || "鏈~鍐�" }}
+ </el-tag>
+ </el-descriptions-item>
- <el-descriptions-item label="鍔熻兘鐘舵��">
- <el-tag
- :type="getFunctionStatusTagType(assessment.functionStatus)"
- size="small"
- >
- {{ getFunctionStatusText(assessment.functionStatus) }}
- </el-tag>
- </el-descriptions-item>
+ <!-- 鍔熻兘鐘舵�� -->
+ <el-descriptions-item label="鍔熻兘鐘舵��">
+ <el-tag
+ :type="
+ getFunctionStatusTagType(
+ assessment.functionStatus
+ )
+ "
+ size="small"
+ >
+ {{
+ getFunctionStatusText(
+ assessment.functionStatus
+ )
+ }}
+ </el-tag>
+ </el-descriptions-item>
- <el-descriptions-item label="璇勪及鎰忚" :span="2">
- <div class="opinion-content">
- {{ assessment.assessmentOpinion || "鏆傛棤璇勪及鎰忚" }}
- </div>
- </el-descriptions-item>
+ <!-- 璇勪及鎰忚 -->
+ <el-descriptions-item label="璇勪及鎰忚" :span="2">
+ <div class="opinion-content">
+ {{
+ assessment.assessmentOpinion ||
+ "鏆傛棤璇勪及鎰忚"
+ }}
+ </div>
+ </el-descriptions-item>
- <el-descriptions-item label="闄勪欢鏁伴噺" :span="2" v-if="assessment.attachments && assessment.attachments.length > 0">
- <el-tag type="success" size="small">
- {{ assessment.attachments.length }}涓�
- </el-tag>
- <el-button
- type="text"
- size="mini"
- @click="showAttachmentList(assessment.attachments, index + 1)"
- style="margin-left: 10px;"
- >
- 鏌ョ湅闄勪欢鍒楄〃
- </el-button>
- </el-descriptions-item>
- </el-descriptions>
- </el-card>
- </div>
- </div>
- </el-card>
+ <!-- 闄勪欢鏁伴噺 -->
+ <el-descriptions-item
+ label="闄勪欢鏁伴噺"
+ :span="2"
+ v-if="
+ assessment.attachments &&
+ assessment.attachments.length > 0
+ "
+ >
+ <el-tag type="success" size="small">
+ {{ assessment.attachments.length }}涓�
+ </el-tag>
+ <el-button
+ type="text"
+ size="mini"
+ @click="
+ showAttachmentList(
+ assessment.attachments,
+ index + 1
+ )
+ "
+ style="margin-left: 10px;"
+ >
+ 鏌ョ湅闄勪欢鍒楄〃
+ </el-button>
+ </el-descriptions-item>
+ </el-descriptions>
+ </el-card>
+ </div>
+ </div>
+ </el-card>
- <!-- 鍣ㄥ畼鍩烘湰淇℃伅鍗$墖 -->
- <el-card header="鍣ㄥ畼淇℃伅" style="margin-top: 20px;" class="organ-info-card">
- <el-descriptions :column="2" border>
- <el-descriptions-item label="鑾峰彇鍓嶆椿妫�">
- <el-tag
- :type="
- scope.row.isbiopsybefore === '1'
- ? 'success'
- : 'info'
- "
- size="small"
- >
- {{ scope.row.isbiopsybefore === "1" ? "鏄�" : "鍚�" }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鑾峰彇鍚庢椿妫�">
- <el-tag
- :type="
- scope.row.isbiopsyafter === '1'
- ? 'success'
- : 'info'
- "
- size="small"
- >
- {{ scope.row.isbiopsyafter === "1" ? "鏄�" : "鍚�" }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="杈圭紭鍣ㄥ畼">
- <el-tag
- :type="
- scope.row.ismarginalorgan === '1'
- ? 'warning'
- : 'info'
- "
- size="small"
- >
- {{
- scope.row.ismarginalorgan === "1" ? "鏄�" : "鍚�"
- }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鐥呭師鑿岄槼鎬�">
- <el-tag
- :type="
- scope.row.ispathogenpositive === '1'
- ? 'danger'
- : 'info'
- "
- size="small"
- >
- {{
- scope.row.ispathogenpositive === "1" ? "鏄�" : "鍚�"
- }}
- </el-tag>
- </el-descriptions-item>
- </el-descriptions>
- </el-card>
- </div>
-</el-tab-pane>
+ <!-- 鍣ㄥ畼鍩烘湰淇℃伅鍗$墖 -->
+ <el-card
+ header="鍣ㄥ畼淇℃伅"
+ style="margin-top: 20px;"
+ class="organ-info-card"
+ >
+ <el-descriptions :column="2" border>
+ <el-descriptions-item label="鑾峰彇鍓嶆椿妫�">
+ <el-tag
+ :type="
+ scope.row.isbiopsybefore == '1'
+ ? 'success'
+ : 'info'
+ "
+ size="small"
+ >
+ {{ scope.row.isbiopsybefore == "1" ? "鏄�" : "鍚�" }}
+ </el-tag>
+ </el-descriptions-item>
+ <el-descriptions-item label="鑾峰彇鍚庢椿妫�">
+ <el-tag
+ :type="
+ scope.row.isbiopsyafter == '1'
+ ? 'success'
+ : 'info'
+ "
+ size="small"
+ >
+ {{ scope.row.isbiopsyafter == "1" ? "鏄�" : "鍚�" }}
+ </el-tag>
+ </el-descriptions-item>
+ <el-descriptions-item label="杈圭紭鍣ㄥ畼">
+ <el-tag
+ :type="
+ scope.row.ismarginalorgan == '1'
+ ? 'warning'
+ : 'info'
+ "
+ size="small"
+ >
+ {{ scope.row.ismarginalorgan == "1" ? "鏄�" : "鍚�" }}
+ </el-tag>
+ </el-descriptions-item>
+ <el-descriptions-item label="鐥呭師鑿岄槼鎬�">
+ <el-tag
+ :type="
+ scope.row.ispathogenpositive == '1'
+ ? 'danger'
+ : 'info'
+ "
+ size="small"
+ >
+ {{
+ scope.row.ispathogenpositive == "1" ? "鏄�" : "鍚�"
+ }}
+ </el-tag>
+ </el-descriptions-item>
+ </el-descriptions>
+ </el-card>
+ </div>
+ </el-tab-pane>
</el-tabs>
</div>
</template>
@@ -315,7 +312,11 @@
</template>
</el-table-column>
- <el-table-column label="鍣ㄥ畼缂栧彿" align="center" prop="organnumber" />
+ <el-table-column label="鍣ㄥ畼缂栧彿" align="center" prop="organnumber">
+ <template slot-scope="scope">
+ {{ getOrganvalue(scope.row.organno) }}
+ </template>
+ </el-table-column>
<el-table-column
label="鑾峰彇鏈烘瀯"
@@ -356,9 +357,9 @@
<template slot-scope="scope">
<el-tag
:type="
- getOrganOverallStatus(scope.row) === 'completed'
+ getOrganOverallStatus(scope.row) == 'completed'
? 'success'
- : getOrganOverallStatus(scope.row) === 'assessing'
+ : getOrganOverallStatus(scope.row) == 'assessing'
? 'primary'
: 'warning'
"
@@ -427,14 +428,15 @@
assessedit,
assessAdd
} from "@/api/businessApi/index";
+import CaseBasicInfo from "@/components/CaseBasicInfo";
import FilePreviewDialog from "@/components/FilePreviewDialog";
import OrganAssessmentForm from "@/components/assessInfoComponents/OrganAssessmentForm.vue";
export default {
name: "AssessmentDetail",
- components: { OrganAssessmentForm, FilePreviewDialog },
+ components: { OrganAssessmentForm, FilePreviewDialog, CaseBasicInfo },
dicts: ["sys_user_sex", "sys_Organ", "sys_0_1"],
- props: {
+ props: {
infoid: {
type: String,
default: true
@@ -442,13 +444,13 @@
},
data() {
return {
+ caseId: null,
// 鏄惁缂栬緫妯″紡
isEdit: false,
// 鍔犺浇鐘舵��
assessmentLoading: false,
saveLoading: false,
// 鏁版嵁ID
-
assessmentId: undefined,
// 涓昏鏁版嵁
assessmentData: {},
@@ -501,14 +503,14 @@
},
computed: {
isCoordinator() {
- return this.currentUser.role === "coordinator";
+ return this.currentUser.role == "coordinator";
},
currentDepartment() {
return this.currentUser.department;
},
// 鏍规嵁鎹愮尞鍐冲畾杩囨护鍚庣殑鍣ㄥ畼鍒楄〃
filteredOrganAssessmentList() {
- if (!this.organdecisionValues || this.organdecisionValues.length === 0) {
+ if (!this.organdecisionValues || this.organdecisionValues.length == 0) {
return [];
}
@@ -532,7 +534,7 @@
return (
assessments &&
assessments.length > 0 &&
- assessments.every(assessment => assessment.status === "assessed")
+ assessments.every(assessment => assessment.status == "assessed")
);
});
},
@@ -555,57 +557,65 @@
}
},
created() {
+ this.caseId = this.infoid;
this.assessmentId = this.$route.query.id;
- this.isEdit = this.$route.query.assess === "true";
+ this.isEdit = this.$route.query.assess == "true";
this.getAssessmentDetail();
},
methods: {
// 鏍规嵁瀛楀吀value鑾峰彇label
getOrganLabel(organValue) {
- const dictItem = this.organDict.find(item => item.value === organValue);
+ const dictItem = this.organDict.find(item => item.value == organValue);
return dictItem ? dictItem.label : organValue;
+ },
+ getOrganvalue(organValue) {
+ const dictItem = this.organDict.find(item => item.value == organValue);
+
+ return dictItem ? dictItem.value : organValue;
},
// Tab鐐瑰嚮浜嬩欢
handleTabClick(organ, tab) {
if (tab.name !== "add") {
- this.activeTabMap.set(organ.organno, tab.name);
+ this.activeTabMap.set(organ.organno, String(tab.name));
}
},
-// 鑾峰彇鍔熻兘鐘舵�佹爣绛剧被鍨�
- getFunctionStatusTagType(status) {
- const typeMap = {
- "1": "success", // 姝e父
- "2": "warning", // 杞诲害寮傚父
- "3": "danger", // 閲嶅害寮傚父
- "4": "info" // 鏃犳硶璇勪及
- };
- return typeMap[status] || "info";
- },
+ // 鑾峰彇鍔熻兘鐘舵�佹爣绛剧被鍨�
+ getFunctionStatusTagType(status) {
+ const typeMap = {
+ "1": "success", // 姝e父
+ "2": "warning", // 杞诲害寮傚父
+ "3": "danger", // 閲嶅害寮傚父
+ "4": "info" // 鏃犳硶璇勪及
+ };
+ return typeMap[status] || "info";
+ },
- // 鑾峰彇鍔熻兘鐘舵�佹枃鏈�
- getFunctionStatusText(status) {
- const textMap = {
- "1": "姝e父",
- "2": "杞诲害寮傚父",
- "3": "閲嶅害寮傚父",
- "4": "鏃犳硶璇勪及"
- };
- return textMap[status] || "鏈瘎浼�";
- },
+ // 鑾峰彇鍔熻兘鐘舵�佹枃鏈�
+ getFunctionStatusText(status) {
+ const textMap = {
+ "1": "姝e父",
+ "2": "杞诲害寮傚父",
+ "3": "閲嶅害寮傚父",
+ "4": "鏃犳硶璇勪及"
+ };
+ return textMap[status] || "鏈瘎浼�";
+ },
- // 鏄剧ず闄勪欢鍒楄〃
- showAttachmentList(attachments, assessmentNumber) {
- if (!attachments || attachments.length === 0) {
- this.$message.info(`绗�${assessmentNumber}娆¤瘎浼版殏鏃犻檮浠禶);
- return;
- }
+ // 鏄剧ず闄勪欢鍒楄〃
+ showAttachmentList(attachments, assessmentNumber) {
+ if (!attachments || attachments.length == 0) {
+ this.$message.info(`绗�${assessmentNumber}娆¤瘎浼版殏鏃犻檮浠禶);
+ return;
+ }
- this.$alert(
- `<div>
+ this.$alert(
+ `<div>
<h4>绗�${assessmentNumber}娆¤瘎浼伴檮浠跺垪琛�</h4>
<ul style="list-style: none; padding-left: 0;">
- ${attachments.map((item, index) => `
+ ${attachments
+ .map(
+ (item, index) => `
<li style="margin: 5px 0; padding: 5px; background: #f5f7fa; border-radius: 4px;">
<i class="el-icon-document"></i>
<span style="margin-left: 8px;">${item.fileName}</span>
@@ -618,24 +628,26 @@
涓嬭浇
</el-button>
</li>
- `).join('')}
+ `
+ )
+ .join("")}
</ul>
</div>`,
- '闄勪欢鍒楄〃',
- {
- dangerouslyUseHTMLString: true,
- showConfirmButton: false,
- showCancelButton: true,
- cancelButtonText: '鍏抽棴'
- }
- );
- },
+ "闄勪欢鍒楄〃",
+ {
+ dangerouslyUseHTMLString: true,
+ showConfirmButton: false,
+ showCancelButton: true,
+ cancelButtonText: "鍏抽棴"
+ }
+ );
+ },
// 鑾峰彇鍣ㄥ畼鐨勮瘎浼板垪琛�
getOrganAssessments(organ) {
if (!organ.assesscontent) return [];
try {
const assessData =
- typeof organ.assesscontent === "string"
+ typeof organ.assesscontent == "string"
? JSON.parse(organ.assesscontent)
: organ.assesscontent;
@@ -721,10 +733,10 @@
const saveMethod = this.assessmentData.id ? assessedit : assessAdd;
const response = await saveMethod(saveData);
- if (response.code === 200) {
+ if (response.code == 200) {
this.$message.success("璇勪及琛ㄤ繚瀛樻垚鍔燂紒");
- if (!this.assessmentData.id && response.data && response.data.id) {
- this.assessmentData.id = response.data.id;
+ if (!this.assessmentData.id && response.data) {
+ this.assessmentData.id = response.data;
}
this.refreshKey += 1; // 瑙﹀彂閲嶆柊娓叉煋
} else {
@@ -747,6 +759,7 @@
async handleOrganDecisionChange(newDecision) {
const oldDecision = [...this.prevOrgandecisionValues];
this.autoHandleDecisionChange(newDecision);
+ console.log(newDecision);
const removedDecisions = oldDecision.filter(
item => !newDecision.includes(item)
@@ -759,7 +772,7 @@
this.prevOrgandecisionValues = [...newDecision];
this.$forceUpdate();
- if (newDecision.length === 0) {
+ if (newDecision.length == 0) {
this.expandedRowKeys = [];
}
},
@@ -858,7 +871,7 @@
for (const organValue of relatedOrgans) {
const organIndex = this.organAssessmentList.findIndex(
- organ => organ.organno === organValue && organ.delFlag !== "1"
+ organ => organ.organno == organValue && organ.delFlag !== "1"
);
if (organIndex !== -1) {
@@ -900,7 +913,7 @@
// 纭繚鍣ㄥ畼瀛樺湪
ensureOrganExists(organValue) {
const exists = this.organAssessmentList.some(
- organ => organ.organno === organValue && organ.delFlag !== "1"
+ organ => organ.organno == organValue && organ.delFlag !== "1"
);
if (!exists) {
@@ -932,7 +945,7 @@
try {
const response = await evaluateBaseInfolist({ infoid: this.infoid });
- if (response.code === 200) {
+ if (response.code == 200) {
this.handleResponseData(response);
} else {
this.$message.error("鑾峰彇璇︽儏澶辫触锛�" + (response.msg || "鏈煡閿欒"));
@@ -962,7 +975,6 @@
} else {
detailData = response;
}
-
this.assessmentData = {
id: detailData.id || this.assessmentId,
infoid: detailData.infoid || this.infoid,
@@ -1007,7 +1019,7 @@
const organno = organ.organno;
// 濡傛灉 assesscontent 鏄瓧绗︿覆锛岀‘淇濆畠鏄湁鏁堢殑 JSON
- if (organ.assesscontent && typeof organ.assesscontent === "string") {
+ if (organ.assesscontent && typeof organ.assesscontent == "string") {
try {
JSON.parse(organ.assesscontent);
} catch (error) {
@@ -1023,9 +1035,9 @@
const assessments = this.getOrganAssessments(organ);
const activeTab = this.activeTabMap.has(organno)
- ? this.activeTabMap.get(organno)
+ ? String(this.activeTabMap.get(organno))
: assessments.length > 0
- ? 0
+ ? "0"
: "summary";
return {
@@ -1043,7 +1055,7 @@
return {
index: index,
status: "pending",
- assessmentTime: "",
+ assessmentTime: new Date().toLocaleString("zh-CN"), // 娣诲姞榛樿璇勪及鏃堕棿
assessor: "",
functionStatus: "",
assessmentOpinion: "",
@@ -1067,20 +1079,20 @@
// 鑾峰彇鍣ㄥ畼鏁翠綋鐘舵��
getOrganOverallStatus(organ) {
const assessments = this.getOrganAssessments(organ);
- if (assessments.length === 0) {
+ if (assessments.length == 0) {
return "pending";
}
const validAssessments = assessments.filter(a => a.delFlag !== "1");
- if (validAssessments.length === 0) {
+ if (validAssessments.length == 0) {
return "pending";
}
const allAssessed = validAssessments.every(
- assessment => assessment.status === "assessed"
+ assessment => assessment.status == "assessed"
);
const someAssessed = validAssessments.some(
- assessment => assessment.status === "assessed"
+ assessment => assessment.status == "assessed"
);
if (allAssessed) return "completed";
@@ -1109,7 +1121,7 @@
} else {
this.expandedRowKeys = [key];
this.organAssessmentList.forEach(item => {
- item.expanded = item.organno === key;
+ item.expanded = item.organno == key;
});
}
},
@@ -1127,14 +1139,15 @@
const assessments = this.getOrganAssessments(organ);
const newAssessment = {
...this.getDefaultAssessment(assessments.length),
- assessor: this.currentUser.name
+ assessor: this.currentUser.name,
+ assessmentTime: new Date().toLocaleString("zh-CN") // 璁剧疆鍏蜂綋鐨勮瘎浼版椂闂�
};
const newAssessments = [...assessments, newAssessment];
this.$set(organ, "assesscontent", JSON.stringify(newAssessments));
- organ.activeTab = assessments.length;
- this.activeTabMap.set(organ.organno, assessments.length);
+ organ.activeTab = String(assessments.length);
+ this.activeTabMap.set(organ.organno, String(assessments.length));
this.$message.success("宸叉坊鍔犳柊鐨勮瘎浼�");
},
@@ -1145,32 +1158,25 @@
this.deleteOrganAssessment(organData, assessmentIndex);
},
// 澶勭悊璇勪及淇濆瓨
+ // 鍦� AssessmentDetail.vue 鐨� handleSaveAssessment 鏂规硶涓�
handleSaveAssessment(data) {
const { organData, assessmentData, assessmentIndex } = data;
const assessments = this.getOrganAssessments(organData);
- console.log("淇濆瓨璇勪及鏁版嵁:", data);
-
if (assessments[assessmentIndex]) {
- // 鍒涘缓鏂扮殑璇勪及鏁扮粍
const newAssessments = [...assessments];
newAssessments[assessmentIndex] = {
...assessments[assessmentIndex],
...assessmentData,
- status: "assessed", // 鏍囪涓哄凡璇勪及
- assessmentTime: new Date().toISOString(), // 璁剧疆璇勪及鏃堕棿
- delFlag: "0" // 纭繚鍒犻櫎鏍囧織
+ status: "assessed",
+ assessmentTime:
+ assessmentData.assessmentTime || new Date().toLocaleString("zh-CN"),
+ delFlag: "0"
};
- // 鏇存柊 assesscontent
this.$set(organData, "assesscontent", JSON.stringify(newAssessments));
-
- // 寮哄埗閲嶆柊娓叉煋
this.$forceUpdate();
-
this.$message.success("璇勪及淇濆瓨鎴愬姛");
-
- // 妫�鏌ユ槸鍚﹂渶瑕佽嚜鍔ㄥ垏鎹㈠埌涓嬩竴涓瘎浼�
this.checkAndSwitchTab(organData, assessmentIndex);
}
},
@@ -1180,8 +1186,8 @@
const assessments = this.getOrganAssessments(organData);
if (currentIndex < assessments.length - 1) {
// 濡傛灉杩樻湁涓嬩竴涓瘎浼帮紝鑷姩鍒囨崲鍒颁笅涓�涓�
- organData.activeTab = currentIndex + 1;
- this.activeTabMap.set(organData.organno, currentIndex + 1);
+ organData.activeTab = String(currentIndex + 1);
+ this.activeTabMap.set(organData.organno, String(currentIndex + 1));
} else {
// 濡傛灉娌℃湁涓嬩竴涓瘎浼帮紝鍒囨崲鍒版眹鎬婚〉
organData.activeTab = "summary";
@@ -1221,14 +1227,14 @@
this.$set(organ, "assesscontent", JSON.stringify(newAssessments));
// 澶勭悊tab鍒囨崲
- if (newAssessments.length === 0) {
+ if (newAssessments.length == 0) {
organ.activeTab = "summary";
this.activeTabMap.set(organ.organno, "summary");
- } else if (organ.activeTab === assessmentIndex) {
+ } else if (organ.activeTab == String(assessmentIndex)) {
const newIndex = Math.max(0, assessmentIndex - 1);
- organ.activeTab = newIndex;
- this.activeTabMap.set(organ.organno, newIndex);
- } else if (organ.activeTab === "summary") {
+ organ.activeTab = String(newIndex);
+ this.activeTabMap.set(organ.organno, String(newIndex));
+ } else if (organ.activeTab == "summary") {
this.activeTabMap.set(organ.organno, "summary");
}
@@ -1243,16 +1249,18 @@
// 鑾峰彇鏈�鏂拌瘎浼版椂闂�
getLatestAssessmentTime(organ) {
const assessments = this.getOrganAssessments(organ);
- if (assessments.length === 0) return null;
+ if (assessments.length == 0) return null;
const assessed = assessments.filter(
a => a.assessmentTime && a.delFlag !== "1"
);
- if (assessed.length === 0) return null;
+ if (assessed.length == 0) return null;
- return assessed.sort(
- (a, b) => new Date(b.assessmentTime) - new Date(a.assessmentTime)
- )[0].assessmentTime;
+ return this.parseTime(
+ assessed.sort(
+ (a, b) => new Date(b.assessmentTime) - new Date(a.assessmentTime)
+ )[0].assessmentTime
+ );
},
// 鑾峰彇璇勪及鐘舵�佹爣绛剧被鍨�
@@ -1314,7 +1322,7 @@
if (this.assessmentData.assessannex) {
try {
const annexData =
- typeof this.assessmentData.assessannex === "string"
+ typeof this.assessmentData.assessannex == "string"
? JSON.parse(this.assessmentData.assessannex)
: this.assessmentData.assessannex;
@@ -1332,28 +1340,35 @@
}
},
- // 瀹屾垚璇勪及
- async handleCompleteAssessment() {
+ handleCompleteAssessment() {
+ this.$confirm("鏄惁瀹屾垚璇ユ渚嬫墍鏈夊櫒瀹樼殑璇勪及锛�", "鎻愰啋", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(() => {
+ this.assessmentData.assessState = 3;
+ this.saveAssessment();
+ })
+
+ .catch(() => {});
+ },
+
+ // 淇濆瓨璇勪及
+ async saveAssessment() {
try {
- await this.$confirm(
- "纭瀹屾垚鎵�鏈夊櫒瀹樿瘎浼板悧锛熷畬鎴愬悗灏嗘棤娉曚慨鏀�",
- "纭鎿嶄綔",
- {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning"
- }
- );
-
const updateData = {
- ...this.assessmentData,
- assessState: "3",
- assessTime: new Date().toISOString()
+ ...this.assessmentData
};
-
+ if (
+ this.assessmentData.assessState == 1 ||
+ !this.assessmentData.assessState
+ ) {
+ this.assessmentData.assessState = 2;
+ }
const response = await assessedit(updateData);
- if (response.code === 200) {
+ if (response.code == 200) {
this.$message.success("璇勪及瀹屾垚纭鎴愬姛");
this.assessmentData.assessState = "3";
this.isEdit = false;
@@ -1461,6 +1476,7 @@
.fixed-width .el-button {
margin: 0 2px;
}
+
/* 姹囨�婚〉闈㈡牱寮� */
.assessment-summary {
padding: 10px;
@@ -1472,7 +1488,7 @@
}
.highlight-text {
- color: #409EFF;
+ color: #409eff;
font-weight: 500;
}
@@ -1507,7 +1523,7 @@
.assessment-card:hover {
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
- border-color: #409EFF;
+ border-color: #409eff;
}
.assessment-title {
@@ -1522,7 +1538,7 @@
}
.time-text {
- color: #67C23A;
+ color: #67c23a;
font-weight: 500;
}
@@ -1570,7 +1586,7 @@
background-color: #fafafa;
}
-::v-deep .el-table--enable-row-hover .el-table__body tr:hover>td {
+::v-deep .el-table--enable-row-hover .el-table__body tr:hover > td {
background-color: #ecf5ff;
}
@@ -1640,7 +1656,7 @@
}
::v-deep .el-tabs__item.is-active {
- color: #409EFF;
+ color: #409eff;
font-weight: 600;
}
@@ -1648,7 +1664,7 @@
background-color: #e4e7ed;
}
-::v-deep .el-tabs--card>.el-tabs__header .el-tabs__item.is-active {
+::v-deep .el-tabs--card > .el-tabs__header .el-tabs__item.is-active {
background-color: #fff;
border-bottom-color: #fff;
}
diff --git a/src/views/business/course/components/OrganAllocationStage.vue b/src/views/business/course/components/OrganAllocationStage.vue
index a28a32d..41cbcf9 100644
--- a/src/views/business/course/components/OrganAllocationStage.vue
+++ b/src/views/business/course/components/OrganAllocationStage.vue
@@ -1,447 +1,1373 @@
<template>
- <base-stage :stage-data="stageData" :case-info="caseInfo">
- <template #header>
- <el-alert
- :title="`鍣ㄥ畼鍒嗛厤 - ${getStatusText()}`"
- :type="getAlertType()"
- :description="getAlertDescription()"
- show-icon
- :closable="false"
- />
- </template>
-
- <el-row :gutter="20" style="margin-top: 20px;">
- <el-col :span="8">
- <el-card>
- <div slot="header" class="card-header">
- <span>鍒嗛厤姒傚喌</span>
- </div>
- <div class="allocation-stats">
- <div class="stat-item">
- <span class="label">寰呭垎閰嶅櫒瀹�:</span>
- <span class="value">{{ allocationStats.totalOrgans }} 涓�</span>
- </div>
- <div class="stat-item">
- <span class="label">宸插垎閰嶅櫒瀹�:</span>
- <span class="value">{{ allocationStats.allocatedOrgans }} 涓�</span>
- </div>
- <div class="stat-item">
- <span class="label">鍒嗛厤绯荤粺:</span>
- <span class="value">{{ allocationStats.system }}</span>
- </div>
- <div class="stat-item">
- <span class="label">鍖归厤鎴愬姛鐜�:</span>
- <el-progress
- :percentage="allocationStats.matchRate"
- :status="allocationStats.matchRate > 80 ? 'success' : 'warning'"
- />
- </div>
- </div>
- </el-card>
- </el-col>
-
- <el-col :span="8">
- <el-card>
- <div slot="header" class="card-header">
- <span>鍒嗛厤鏃堕棿绐楀彛</span>
- </div>
- <div class="time-window">
- <div class="time-item">
- <span class="label">鍒嗛厤寮�濮�:</span>
- <span>{{ formatTime(allocationDetails.startTime) }}</span>
- </div>
- <div class="time-item">
- <span class="label">棰勮瀹屾垚:</span>
- <span>{{ formatTime(allocationDetails.estimatedEndTime) }}</span>
- </div>
- <div class="time-item">
- <span class="label">鍣ㄥ畼鑰愬彈鏃堕棿:</span>
- <span>{{ allocationDetails.toleranceTime }}</span>
- </div>
- <div class="time-item">
- <span class="label">鍓╀綑鏃堕棿:</span>
- <el-tag :type="getTimeRemainingType()">
- {{ allocationDetails.timeRemaining }}
- </el-tag>
- </div>
- </div>
- </el-card>
- </el-col>
-
- <el-col :span="8">
- <el-card>
- <div slot="header" class="card-header">
- <span>鍒嗛厤浼樺厛绾�</span>
- </div>
- <el-steps direction="vertical" :active="prioritySteps.active">
- <el-step
- v-for="step in prioritySteps.steps"
- :key="step.title"
- :title="step.title"
- :description="step.description"
- :status="step.status"
- />
- </el-steps>
- </el-card>
- </el-col>
- </el-row>
-
- <el-card style="margin-top: 20px;">
- <div slot="header" class="card-header">
- <span>鍣ㄥ畼鍒嗛厤璇︽儏</span>
- <el-button type="primary" size="small" @click="handleStartAllocation">
- 鍚姩鑷姩鍒嗛厤
- </el-button>
+ <div class="organ-allocation-detail">
+ <!-- 鍩烘湰淇℃伅閮ㄥ垎 -->
+ <el-card class="detail-card">
+ <div slot="header" class="clearfix">
+ <span class="detail-title">鍣ㄥ畼鍒嗛厤鍩烘湰淇℃伅</span>
</div>
- <el-table :data="organAllocationData" border>
- <el-table-column label="鍣ㄥ畼鍚嶇О" prop="organName" width="120" align="center" />
- <el-table-column label="鍣ㄥ畼鐘舵��" width="100" align="center">
- <template slot-scope="scope">
- <el-tag :type="getOrganStatusTag(scope.row.status)" size="small">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鍖归厤鍙椾綋" prop="recipient" width="150" />
- <el-table-column label="琛�鍨嬪尮閰�" width="100" align="center">
- <template slot-scope="scope">
- <el-tag :type="scope.row.bloodMatch ? 'success' : 'warning'">
- {{ scope.row.bloodMatch ? '鍖归厤' : '寰呭尮閰�' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="缁勭粐閰嶅瀷" width="100" align="center">
- <template slot-scope="scope">
- <el-tag :type="scope.row.tissueMatch ? 'success' : 'warning'">
- {{ scope.row.tissueMatch ? '鍚堟牸' : '寰呮娴�' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="绉绘鍖婚櫌" prop="hospital" min-width="200" />
- <el-table-column label="鍒嗛厤鏃堕棿" width="160" align="center">
- <template slot-scope="scope">
- {{ scope.row.allocationTime || '寰呭垎閰�' }}
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="120" align="center">
- <template slot-scope="scope">
- <el-button type="text" size="small" @click="handleViewMatch(scope.row)">
- 鏌ョ湅鍖归厤
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
- <el-card style="margin-top: 20px;">
- <div slot="header" class="card-header">
- <span>鍒嗛厤绠楁硶缁撴灉</span>
- </div>
- <div class="algorithm-results">
+ <el-form :model="form" ref="form" :rules="rules" label-width="120px">
<el-row :gutter="20">
<el-col :span="12">
- <div class="result-item">
- <h4>鍖归厤璇勫垎鎺掑悕</h4>
- <el-table :data="matchRanking" border size="small">
- <el-table-column label="鎺掑悕" width="60" align="center">
+ <el-form-item label="鍒嗛厤鐘舵��" prop="allocationStatus">
+ <el-select
+ v-model="form.allocationStatus"
+ placeholder="璇烽�夋嫨鍒嗛厤鐘舵��"
+ >
+ <el-option
+ v-for="dict in dict.type.organ_allocation_status || []"
+ :key="dict.value"
+ :label="dict.label"
+ :value="dict.value"
+ ></el-option>
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍒嗛厤鏃堕棿" prop="allocationTime">
+ <el-date-picker
+ v-model="form.allocationTime"
+ type="datetime"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ style="width: 100%"
+ :disabled="form.allocationStatus == '1'"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鐧昏浜�" prop="registrationName">
+ <el-input v-model="form.registrationName" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鐧昏鏃堕棿" prop="registrationTime">
+ <el-date-picker
+ v-model="form.registrationTime"
+ type="datetime"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ </el-card>
+
+ <!-- 鍣ㄥ畼鍒嗛厤璁板綍閮ㄥ垎 -->
+ <el-card class="allocation-card">
+ <div slot="header" class="clearfix">
+ <span class="detail-title">鍣ㄥ畼鍒嗛厤璁板綍</span>
+ <div style="float: right;">
+ <el-tag
+ :type="
+ form.allocationStatus == '1'
+ ? 'success'
+ : form.allocationStatus == '2'
+ ? 'danger'
+ : 'warning'
+ "
+ >
+ {{
+ form.allocationStatus == "1"
+ ? "宸插垎閰�"
+ : form.allocationStatus == "2"
+ ? "浣滃簾"
+ : "鏈垎閰�"
+ }}
+ </el-tag>
+ </div>
+ </div>
+
+ <el-form
+ ref="allocationForm"
+ :rules="allocationRules"
+ :model="allocationData"
+ label-position="right"
+ >
+ <el-row>
+ <el-col>
+ <el-form-item label-width="100px" label="鍒嗛厤鍣ㄥ畼">
+ <el-checkbox-group
+ v-model="selectedOrgans"
+ @change="handleOrganSelectionChange"
+ >
+ <el-checkbox
+ v-for="dict in dict.type.sys_Organ || []"
+ :key="dict.value"
+ :label="dict.value"
+ :disabled="form.allocationStatus == '1'"
+ >
+ {{ dict.label }}
+ </el-checkbox>
+ </el-checkbox-group>
+ <el-input
+ v-if="showOtherInput"
+ v-model="otherOrganInput"
+ placeholder="璇疯緭鍏ュ叾浠栧櫒瀹樺悕绉�"
+ style="margin-top: 10px; width: 300px;"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <el-row>
+ <el-col>
+ <el-form-item>
+ <el-table
+ :data="allocationData.serviceDonateorganList"
+ v-loading="loading"
+ border
+ style="width: 100%"
+ :row-class-name="getOrganRowClassName"
+ >
+ <el-table-column
+ label="鍣ㄥ畼鍚嶇О"
+ align="center"
+ width="120"
+ prop="organname"
+ >
<template slot-scope="scope">
- {{ scope.$index + 1 }}
- </template>
- </el-table-column>
- <el-table-column label="鍙椾綋缂栧彿" prop="recipientNo" width="100" />
- <el-table-column label="鍖归厤鍒嗘暟" prop="matchScore" width="100">
- <template slot-scope="scope">
- <el-rate
- v-model="scope.row.matchScore"
- disabled
- show-score
- text-color="#ff9900"
- score-template="{value} 鍒�"
+ <el-input
+ v-model="scope.row.organname"
+ placeholder="鍣ㄥ畼鍚嶇О"
+ :disabled="true"
/>
</template>
</el-table-column>
- <el-table-column label="鎺ㄨ崘鍣ㄥ畼" prop="recommendedOrgan" />
+
+ <el-table-column
+ label="鍒嗛厤绯荤粺缂栧彿"
+ align="center"
+ width="150"
+ prop="caseno"
+ >
+ <template slot-scope="scope">
+ <el-input
+ v-model="scope.row.caseno"
+ placeholder="鍒嗛厤绯荤粺缂栧彿"
+ :disabled="form.allocationStatus == '1'"
+ />
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="鍒嗛厤鎺ユ敹鏃堕棿"
+ align="center"
+ width="180"
+ prop="applicanttime"
+ >
+ <template slot-scope="scope">
+ <el-date-picker
+ clearable
+ size="small"
+ style="width: 100%"
+ v-model="scope.row.applicanttime"
+ type="datetime"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ placeholder="閫夋嫨鍒嗛厤鎺ユ敹鏃堕棿"
+ :disabled="form.allocationStatus == '1'"
+ />
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="鍙椾綋濮撴皬"
+ align="center"
+ width="120"
+ prop="name"
+ >
+ <template slot-scope="scope">
+ <el-input
+ v-model="scope.row.name"
+ placeholder="鍙椾綋濮撴皬"
+ :disabled="form.allocationStatus == '1'"
+ />
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="绉绘鍖婚櫌"
+ align="center"
+ width="200"
+ prop="transplanthospitalno"
+ >
+ <template slot-scope="scope">
+ <div>
+ <org-selecter
+ ref="tranHosSelect"
+ :org-type="'4'"
+ :dataList="dataList"
+ v-model="scope.row.transplanthospitalno"
+ style="width: 100%"
+ />
+ </div>
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="璇存槑"
+ align="center"
+ prop="reallocationreason"
+ min-width="200"
+ >
+ <template slot-scope="scope">
+ <el-input
+ type="textarea"
+ clearable
+ v-model="scope.row.reallocationreason"
+ placeholder="璇疯緭鍏ヨ鏄�"
+ :disabled="form.allocationStatus == '1'"
+ />
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="鎿嶄綔"
+ align="center"
+ width="120"
+ class-name="small-padding fixed-width"
+ v-if="form.allocationStatus !== '1'"
+ >
+ <template slot-scope="scope">
+ <el-button
+ size="mini"
+ type="text"
+ icon="el-icon-copy-document"
+ @click="handleRedistribution(scope.row)"
+ :disabled="!scope.row.caseno"
+ >
+ 閲嶅垎閰�
+ </el-button>
+ </template>
+ </el-table-column>
</el-table>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="result-item">
- <h4>鍒嗛厤鍥犵礌鏉冮噸</h4>
- <div class="weight-distribution">
- <div v-for="factor in allocationFactors" :key="factor.name" class="factor-item">
- <span class="factor-name">{{ factor.name }}</span>
- <el-progress
- :percentage="factor.weight"
- :show-text="false"
- :color="factor.color"
- />
- <span class="factor-percent">{{ factor.weight }}%</span>
- </div>
- </div>
- </div>
+ </el-form-item>
</el-col>
</el-row>
+
+ <!-- 鍒嗛厤缁熻淇℃伅 -->
+ <div
+ class="allocation-stats"
+ v-if="
+ allocationData.serviceDonateorganList &&
+ allocationData.serviceDonateorganList.length > 0
+ "
+ >
+ <el-row :gutter="20">
+ <el-col :span="6">
+ <div class="stat-item">
+ <span class="stat-label">宸插垎閰嶅櫒瀹�:</span>
+ <span class="stat-value"
+ >{{ allocationData.serviceDonateorganList.length }} 涓�</span
+ >
+ </div>
+ </el-col>
+ <el-col :span="6">
+ <div class="stat-item">
+ <span class="stat-label">寰呭畬鍠勪俊鎭�:</span>
+ <span class="stat-value">{{ incompleteRecords }} 涓�</span>
+ </div>
+ </el-col>
+ <el-col :span="6">
+ <div class="stat-item">
+ <span class="stat-label">娑夊強鍖婚櫌:</span>
+ <span class="stat-value">{{ uniqueHospitals }} 瀹�</span>
+ </div>
+ </el-col>
+ <el-col :span="6">
+ <div class="stat-item">
+ <span class="stat-label">鍒嗛厤鐘舵��:</span>
+ <span class="stat-value">
+ <el-tag
+ :type="
+ form.allocationStatus == '1'
+ ? 'success'
+ : form.allocationStatus == '2'
+ ? 'danger'
+ : 'warning'
+ "
+ >
+ {{
+ form.allocationStatus == "1"
+ ? "宸插垎閰�"
+ : form.allocationStatus == "2"
+ ? "浣滃簾"
+ : "鏈垎閰�"
+ }}
+ </el-tag>
+ </span>
+ </div>
+ </el-col>
+ </el-row>
+ </div>
+
+ <div v-else class="empty-allocation">
+ <el-empty description="鏆傛棤鍒嗛厤璁板綍" :image-size="80">
+ <span>璇峰厛閫夋嫨瑕佸垎閰嶇殑鍣ㄥ畼</span>
+ </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>
+
+ <!-- 闄勪欢绠$悊閮ㄥ垎浼樺寲 -->
+ <el-card class="attachment-card">
+ <div class="attachment-header">
+ <i class="el-icon-paperclip"></i>
+ <span class="attachment-title">鐩稿叧闄勪欢</span>
+ <span class="attachment-tip"
+ >鏀寔涓婁紶鍣ㄥ畼鍒嗛厤鐩稿叧鏂囦欢 (鏈�澶歿{ attachmentLimit }}涓�)</span
+ >
+ </div>
+
+ <!-- 浣跨敤 UploadAttachment 缁勪欢 -->
+ <UploadAttachment
+ ref="uploadAttachment"
+ :file-list="attachmentFileList"
+ :limit="attachmentLimit"
+ :accept="attachmentAccept"
+ :multiple="true"
+ @change="handleAttachmentChange"
+ @upload-success="handleUploadSuccess"
+ @upload-error="handleUploadError"
+ @remove="handleAttachmentRemove"
+ />
+
+ <!-- 闄勪欢鍒楄〃灞曠ず -->
+ <div class="attachment-list" v-if="attachments && attachments.length > 0">
+ <div class="list-title">宸蹭笂浼犻檮浠� ({{ attachments.length }})</div>
+ <el-table :data="attachments" style="width: 100%" size="small">
+ <el-table-column label="鏂囦欢鍚�" min-width="200">
+ <template slot-scope="scope">
+ <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="160">
+ <template slot-scope="scope">
+ <span>{{ formatDateTime(scope.row.uploadTime) }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鏂囦欢澶у皬" width="100">
+ <template slot-scope="scope">
+ <span>{{ formatFileSize(scope.row.fileSize) }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鎿嶄綔" width="200" fixed="right">
+ <template slot-scope="scope">
+ <el-button
+ size="mini"
+ type="primary"
+ @click="handlePreview(scope.row)"
+ :disabled="!isPreviewable(scope.row.fileName)"
+ >
+ 棰勮
+ </el-button>
+ <el-button
+ size="mini"
+ type="success"
+ @click="handleDownloadAttachment(scope.row)"
+ >
+ 涓嬭浇
+ </el-button>
+ <el-button
+ size="mini"
+ type="danger"
+ @click="handleRemoveAttachment(scope.$index)"
+ >
+ 鍒犻櫎
+ </el-button>
+ </template>
+ </el-table-column>
+ </el-table>
</div>
</el-card>
- <template #footer>
- <div class="action-buttons" style="margin-top: 20px; text-align: center;">
- <el-button type="primary" @click="handleAutoAllocation">
- 鏅鸿兘鍒嗛厤
- </el-button>
- <el-button type="success" @click="handleConfirmAllocation">
- 纭鍒嗛厤缁撴灉
- </el-button>
- <el-button type="warning" @click="handleManualAdjust">
- 鎵嬪姩璋冩暣
- </el-button>
+ <!-- 閲嶅垎閰嶅璇濇 -->
+ <el-dialog
+ title="鍣ㄥ畼閲嶅垎閰�"
+ :visible.sync="redistributionDialogVisible"
+ width="500px"
+ >
+ <el-form :model="redistributionForm" label-width="100px">
+ <el-form-item label="鍘熷櫒瀹樹俊鎭�">
+ <el-input v-model="redistributionForm.organname" readonly />
+ </el-form-item>
+ <el-form-item label="閲嶅垎閰嶅師鍥�" prop="reason">
+ <el-input
+ type="textarea"
+ :rows="4"
+ v-model="redistributionForm.reason"
+ placeholder="璇疯緭鍏ラ噸鍒嗛厤鍘熷洜"
+ />
+ </el-form-item>
+ </el-form>
+ <div slot="footer">
+ <el-button @click="redistributionDialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleRedistributionConfirm"
+ >纭閲嶅垎閰�</el-button
+ >
</div>
- </template>
- </base-stage>
+ </el-dialog>
+
+ <!-- 闄勪欢棰勮瀵硅瘽妗� -->
+ <FilePreviewDialog
+ :visible="filePreviewVisible"
+ :file="currentPreviewFile"
+ @close="filePreviewVisible = false"
+ @download="handleDownloadAttachment"
+ />
+ </div>
</template>
<script>
-import BaseStage from './BaseStage.vue';
+import {
+ allocationList,
+ allocationadd,
+ allocationedit,
+ donateorganBaseinfoInfo
+} from "@/api/businessApi";
+import UploadAttachment from "@/components/UploadAttachment";
+import FilePreviewDialog from "@/components/FilePreviewDialog";
+import OrgSelecter from "@/views/project/components/orgselect";
+import CaseBasicInfo from "@/components/CaseBasicInfo";
+import dayjs from "dayjs";
export default {
- name: 'OrganAllocationStage',
- components: { BaseStage },
+ name: "OrganAllocationDetail",
+ components: {
+ UploadAttachment,
+ OrgSelecter,
+ FilePreviewDialog,
+ CaseBasicInfo
+ },
+ dicts: [
+ "sys_BloodType",
+ "sys_DonationCategory",
+ "sys_RecordState",
+ "sys_Organ",
+ "organ_allocation_status"
+ ],
props: {
- stageData: {
- type: Object,
- default: () => ({})
- },
- caseInfo: {
- type: Object,
- default: () => ({})
+ infoid: {
+ type: String,
+ default: true
}
},
data() {
return {
- allocationStats: {
- totalOrgans: 3,
- allocatedOrgans: 0,
- system: '涓浗浜轰綋鍣ㄥ畼鍒嗛厤涓庡叡浜绠楁満绯荤粺',
- matchRate: 0
+ caseId: null,
+
+ // 琛ㄥ崟鏁版嵁
+ form: {
+ id: undefined,
+ infoid: undefined,
+ donationcategory: "",
+ caseNo: "",
+ donorno: "",
+ treatmenthospitalname: "",
+ treatmenthospitalno: "",
+ sex: "",
+ name: "",
+ age: "",
+ bloodtype: "",
+ idcardno: "",
+ diagnosisname: "",
+ allocationStatus: "0", // 0:鏈垎閰嶏紱1锛氬凡鍒嗛厤锛�2浣滃簾
+ allocationTime: "",
+ registrationCode: "",
+ registrationName: "",
+ registrationTime: "",
+ attachments: [] // 娣诲姞闄勪欢瀛楁
},
- allocationDetails: {
- startTime: '2025-12-04 10:00:00',
- estimatedEndTime: '2025-12-04 12:00:00',
- toleranceTime: '鑲濊剰:12灏忔椂,鑲捐剰:24灏忔椂,蹇冭剰:8灏忔椂,鑲鸿剰:12灏忔椂',
- timeRemaining: '2灏忔椂'
- },
- prioritySteps: {
- active: 3,
- steps: [
- {
- title: '鐥呮儏鍗遍噸浼樺厛',
- description: '鏍规嵁鎮h�呯梾鎯呭嵄閲嶇▼搴﹀垎閰峓1](@ref)',
- status: 'finish'
- },
- {
- title: '缁勭粐閰嶅瀷浼樺厛',
- description: '缁勭粐閰嶅瀷鍖归厤搴﹂珮鐨勬偅鑰呬紭鍏�',
- status: 'finish'
- },
- {
- title: '琛�鍨嬬浉鍚屼紭鍏�',
- description: '琛�鍨嬪尮閰嶇殑鎮h�呬紭鍏堣�冭檻',
- status: 'finish'
- },
- {
- title: '鍎跨鍖归厤浼樺厛',
- description: '鍎跨鎮h�呬韩鏈変紭鍏堝垎閰嶆潈',
- status: 'wait'
- }
+ // 闄勪欢棰勮鐩稿叧
+ attachmentPreviewVisible: false,
+ currentAttachmentList: [],
+ attachmentPreviewTitle: "",
+ dataList: [],
+ // 琛ㄥ崟楠岃瘉瑙勫垯
+ rules: {
+ name: [
+ { required: true, message: "鎹愮尞鑰呭鍚嶄笉鑳戒负绌�", trigger: "blur" }
+ ],
+ diagnosisname: [
+ { required: true, message: "鐤剧梾璇婃柇涓嶈兘涓虹┖", trigger: "blur" }
]
},
- organAllocationData: [
- {
- organName: '鑲濊剰',
- status: '寰呭垎閰�',
- recipient: '',
- bloodMatch: false,
- tissueMatch: false,
- hospital: '',
- allocationTime: ''
- },
- {
- organName: '鑲捐剰',
- status: '寰呭垎閰�',
- recipient: '',
- bloodMatch: false,
- tissueMatch: false,
- hospital: '',
- allocationTime: ''
- },
- {
- organName: '蹇冭剰',
- status: '寰呭垎閰�',
- recipient: '',
- bloodMatch: false,
- tissueMatch: false,
- hospital: '',
- allocationTime: ''
- }
- ],
- matchRanking: [
- {
- recipientNo: 'R202512001',
- matchScore: 4.8,
- recommendedOrgan: '鑲濊剰'
- },
- {
- recipientNo: 'R202512002',
- matchScore: 4.5,
- recommendedOrgan: '鑲捐剰'
- },
- {
- recipientNo: 'R202512003',
- matchScore: 4.3,
- recommendedOrgan: '蹇冭剰'
- }
- ],
- allocationFactors: [
- { name: '鐥呮儏鍗遍噸绋嬪害', weight: 35, color: '#f56c6c' },
- { name: '缁勭粐閰嶅瀷鍖归厤', weight: 25, color: '#e6a23c' },
- { name: '绛夊緟鏃堕棿', weight: 15, color: '#5cb87a' },
- { name: '鍦扮悊鍥犵礌', weight: 10, color: '#6f7ad3' },
- { name: '骞撮緞鍥犵礌', weight: 15, color: '#8e44ad' }
- ]
+ // 鍒嗛厤璁板綍楠岃瘉瑙勫垯
+ allocationRules: {},
+ // 淇濆瓨鍔犺浇鐘舵��
+ saveLoading: false,
+ confirmLoading: false,
+ // 鍔犺浇鐘舵��
+ loading: false,
+ // 閫変腑鐨勫櫒瀹橈紙瀛樺偍瀛楀吀value锛�
+ selectedOrgans: [],
+ // 鍏朵粬鍣ㄥ畼杈撳叆
+ otherOrganInput: "",
+ // 鍖婚櫌鍒楄〃
+ hospitalList: [],
+ // 鍒嗛厤璁板綍鏁版嵁
+ allocationData: {
+ serviceDonateorganList: []
+ },
+ // 闄勪欢鏁版嵁
+ attachments: [],
+ attachmentFileList: [],
+ // 闄勪欢鐩稿叧閰嶇疆
+ attachmentLimit: 10,
+ attachmentAccept:
+ ".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt",
+ // 閲嶅垎閰嶅璇濇
+ redistributionDialogVisible: false,
+ redistributionForm: {
+ organname: "",
+ reason: ""
+ },
+ currentRedistributeRecord: null,
+ // 鏂囦欢棰勮鐩稿叧
+ filePreviewVisible: false,
+ currentPreviewFile: null,
+ filePreviewTitle: ""
};
},
- methods: {
- getStatusText() {
- const status = this.stageData.status;
- return status === 'completed' ? '宸插畬鎴�' :
- status === 'in_progress' ? '杩涜涓�' : '鏈紑濮�';
+ computed: {
+ // 褰撳墠鐢ㄦ埛淇℃伅
+ currentUser() {
+ return JSON.parse(sessionStorage.getItem("user") || "{}");
},
- getAlertType() {
- const status = this.stageData.status;
- return status === 'completed' ? 'success' :
- status === 'in_progress' ? 'warning' : 'info';
+ // 涓嶅畬鏁寸殑璁板綍鏁伴噺
+ incompleteRecords() {
+ if (!this.allocationData.serviceDonateorganList) return 0;
+ return this.allocationData.serviceDonateorganList.filter(
+ record =>
+ !record.caseno ||
+ !record.applicanttime ||
+ !record.name ||
+ !record.transplanthospitalno
+ ).length;
},
- getAlertDescription() {
- const status = this.stageData.status;
- if (status === 'completed') {
- return '鍣ㄥ畼鍒嗛厤宸插畬鎴愶紝鎵�鏈夊櫒瀹樺潎宸叉垚鍔熷尮閰嶅彈浣�';
- } else if (status === 'in_progress') {
- return '鍣ㄥ畼鍒嗛厤杩涜涓紝绯荤粺姝e湪鑷姩鍖归厤鏈�浣冲彈浣�';
+ // 鍞竴鍖婚櫌鏁伴噺
+ uniqueHospitals() {
+ if (!this.allocationData.serviceDonateorganList) return 0;
+ const hospitals = this.allocationData.serviceDonateorganList
+ .map(record => record.transplanthospitalno)
+ .filter(Boolean);
+ return new Set(hospitals).size;
+ },
+ // 鑾峰彇鍣ㄥ畼瀛楀吀
+ organDict() {
+ return this.dict.type.sys_Organ || [];
+ },
+ // 鍒ゆ柇鏄惁闇�瑕佹樉绀哄叾浠栬緭鍏ユ
+ showOtherInput() {
+ return this.selectedOrgans.includes("C01"); // 鍋囪"鍏朵粬"鐨勫瓧鍏稿�兼槸C01
+ }
+ },
+ watch: {
+ // 鐩戝惉闄勪欢鏁版嵁鍙樺寲
+ attachments: {
+ handler(newAttachments) {
+ this.attachmentFileList = newAttachments.map(item => ({
+ uid: item.id || Math.random(),
+ name: item.fileName,
+ fileSize: item.fileSize,
+ url: item.path || item.fileUrl,
+ uploadTime: item.uploadTime,
+ status: "success"
+ }));
+ },
+ deep: true
+ },
+ // 鐩戝惉鍏朵粬鍣ㄥ畼杈撳叆鍙樺寲
+ otherOrganInput(newValue) {
+ if (newValue && this.selectedOrgans.includes("C01")) {
+ // 鏇存柊鍣ㄥ畼瀛楀吀涓殑"鍏朵粬"鏍囩鏄剧ず
+ const otherRecord = this.allocationData.serviceDonateorganList.find(
+ item => item.organname && item.organname.includes("鍏朵粬")
+ );
+ if (otherRecord) {
+ otherRecord.organname = `鍏朵粬(${newValue})`;
+ }
}
- return '绛夊緟寮�濮嬪櫒瀹樺垎閰嶆祦绋�';
+ }
+ },
+ created() {
+ this.caseId = this.infoid;
+ this.initData();
+ },
+ methods: {
+ // 鏍规嵁瀛楀吀value鑾峰彇label
+ getOrganLabel(organValue) {
+ const dictItem = this.organDict.find(item => item.value == organValue);
+ return dictItem ? dictItem.label : organValue;
},
- getOrganStatusTag(status) {
- const map = {
- '宸插垎閰�': 'success',
- '鍒嗛厤涓�': 'warning',
- '寰呭垎閰�': 'info'
+
+ // 鍒濆鍖栨暟鎹�
+ initData() {
+ const id = null;
+ const infoid = this.infoid;
+
+ if (!infoid) {
+ this.$message.error("缂哄皯蹇呰鐨勮矾鐢卞弬鏁� infoid");
+ this.$router.back();
+ return;
+ }
+
+ this.form.infoid = infoid;
+ this.form.registrationName =
+ this.currentUser.nickName || this.currentUser.username || "褰撳墠鐢ㄦ埛";
+ this.form.registrationTime = new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19);
+
+ if (infoid) {
+ this.getDetail(infoid, id);
+ } else {
+ this.generateDonorNo();
+ }
+
+ this.getHospitalData();
+ },
+ // 鐢熸垚鎹愮尞鑰呯紪鍙�
+ generateDonorNo() {
+ const timestamp = Date.now().toString();
+ this.form.donorno = "D" + timestamp.slice(-8);
+ this.form.caseNo = "CASE" + timestamp.slice(-6);
+ },
+
+ // 瑙f瀽 filePatch 瀛楁
+ parseFilePatch(filePatch) {
+ if (!filePatch) {
+ this.form.attachments = [];
+ return;
+ }
+
+ try {
+ this.form.attachments = JSON.parse(filePatch);
+ } catch (error) {
+ console.error("瑙f瀽 filePatch 瀛楁澶辫触:", error);
+ 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) {
+ const data = response.data[0];
+
+ data.allocationStatus = JSON.stringify(data.allocationStatus);
+ // 濉厖琛ㄥ崟鏁版嵁
+ Object.assign(this.form, data);
+ // 杞崲闄勪欢涓洪泦鍚�
+ this.parseFilePatch(this.form.fileName);
+
+ // 鍒濆鍖栭檮浠�
+ if (this.form.attachments) {
+ this.attachments = Array.isArray(this.form.attachments)
+ ? [...this.form.attachments]
+ : [];
+ }
+
+ // 澶勭悊鍒嗛厤璁板綍
+ if (data.serviceDonateorganList) {
+ this.allocationData.serviceDonateorganList = Array.isArray(
+ data.serviceDonateorganList
+ )
+ ? data.serviceDonateorganList
+ : [];
+
+ // 鏇存柊閫変腑鐨勫櫒瀹�
+ this.selectedOrgans = this.allocationData.serviceDonateorganList
+ .map(item => {
+ // 浠庡悗绔暟鎹腑鑾峰彇鍣ㄥ畼鐨剉alue
+ if (item.organno) {
+ return item.organno;
+ }
+
+ // 濡傛灉鍚庣鍙湁鍣ㄥ畼鍚嶇О锛屽皾璇曚粠瀛楀吀涓尮閰�
+ if (item.organname) {
+ const dictItem = this.organDict.find(
+ org =>
+ org.label == item.organname ||
+ (item.organname && item.organname.includes(org.label))
+ );
+ return dictItem ? dictItem.value : null;
+ }
+
+ return null;
+ })
+ .filter(Boolean);
+
+ // 澶勭悊"鍏朵粬"鍣ㄥ畼
+ const otherRecord = this.allocationData.serviceDonateorganList.find(
+ item => item.organname && item.organname.includes("鍏朵粬(")
+ );
+ if (otherRecord) {
+ const match = otherRecord.organname.match(/鍏朵粬\((.*?)\)/);
+ if (match) {
+ this.otherOrganInput = match[1];
+ }
+ }
+ }
+
+ this.$message.success("鏁版嵁鍔犺浇鎴愬姛");
+ } else {
+ this.$message.warning("鏈壘鍒板搴旂殑鍣ㄥ畼鍒嗛厤鏁版嵁");
+ }
+ } catch (error) {
+ console.error("鑾峰彇鍣ㄥ畼鍒嗛厤璇︽儏澶辫触:", error);
+ this.$message.error("鑾峰彇璇︽儏澶辫触");
+ } finally {
+ this.loading = false;
+ }
+ },
+ // 鑾峰彇鍖婚櫌鏁版嵁
+ async getHospitalData() {
+ try {
+ // TODO: 鏇挎崲涓哄疄闄呯殑鍖婚櫌鍒楄〃鎺ュ彛
+ // 鏆傛椂浣跨敤妯℃嫙鏁版嵁
+ this.hospitalList = [
+ { hospitalNo: "H001", hospitalName: "鍖椾含鍗忓拰鍖婚櫌" },
+ { hospitalNo: "H002", hospitalName: "涓婃捣鍗庡北鍖婚櫌" },
+ { hospitalNo: "H003", hospitalName: "骞垮窞涓北鍖婚櫌" },
+ { hospitalNo: "H004", hospitalName: "姝︽眽鍚屾祹鍖婚櫌" },
+ { hospitalNo: "H005", hospitalName: "鎴愰兘鍗庤タ鍖婚櫌" }
+ ];
+ } catch (error) {
+ console.error("鑾峰彇鍖婚櫌鏁版嵁澶辫触:", error);
+ this.$message.error("鑾峰彇鍖婚櫌鏁版嵁澶辫触");
+ }
+ },
+ // 鍣ㄥ畼閫夋嫨鐘舵�佸彉鍖�
+ handleOrganSelectionChange(selectedValues) {
+ if (!this.allocationData.serviceDonateorganList) {
+ this.allocationData.serviceDonateorganList = [];
+ }
+
+ const currentOrganValues = this.allocationData.serviceDonateorganList.map(
+ item => item.organno
+ );
+
+ // 澶勭悊浜掓枼閫昏緫锛堝弬鑰冩崘鐚喅瀹氶〉闈級
+ this.handleExclusiveSelections(selectedValues);
+
+ // 鏂板閫夋嫨鐨勫櫒瀹�
+ selectedValues.forEach(organValue => {
+ if (!currentOrganValues.includes(organValue)) {
+ this.createOrganRecord(organValue);
+ }
+ });
+
+ // 绉婚櫎鍙栨秷閫夋嫨鐨勫櫒瀹�
+ this.allocationData.serviceDonateorganList = this.allocationData.serviceDonateorganList.filter(
+ record => {
+ if (selectedValues.includes(record.organno)) {
+ return true;
+ } else {
+ if (record.id) {
+ this.$confirm(
+ "鍒犻櫎鍣ㄥ畼鍒嗛厤鏁版嵁鍚庡皢鏃犳硶鎭㈠锛屾偍纭鍒犻櫎璇ユ潯璁板綍鍚楋紵",
+ "鎻愮ず",
+ {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ }
+ )
+ .then(() => {
+ this.allocationData.serviceDonateorganList = this.allocationData.serviceDonateorganList.filter(
+ r => r.organno !== record.organno
+ );
+ this.$message.success("鍒犻櫎鎴愬姛");
+ })
+ .catch(() => {
+ this.selectedOrgans.push(record.organno);
+ });
+ return true; // 绛夊緟鐢ㄦ埛纭
+ } else {
+ return false; // 鐩存帴鍒犻櫎鏂拌褰�
+ }
+ }
+ }
+ );
+ },
+
+ // 澶勭悊浜掓枼閫夋嫨锛堝弬鑰冩崘鐚喅瀹氶〉闈級
+ handleExclusiveSelections(selectedValues) {
+ // 濡傛灉閫夋嫨浜�"鍙岃偩"(鍋囪瀛楀吀鍊间负C64)锛岃嚜鍔ㄥ彇娑堝崟鐙殑"宸﹁偩"(C64L)鍜�"鍙宠偩"(C64R)閫夋嫨
+ if (selectedValues.includes("C64")) {
+ this.selectedOrgans = selectedValues.filter(
+ item => item !== "C64L" && item !== "C64R"
+ );
+ }
+ // 濡傛灉閫夋嫨浜�"宸﹁偩"鎴�"鍙宠偩"锛屽彇娑�"鍙岃偩"閫夋嫨
+ else if (
+ selectedValues.includes("C64L") ||
+ selectedValues.includes("C64R")
+ ) {
+ this.selectedOrgans = selectedValues.filter(item => item !== "C64");
+ }
+
+ // 濡傛灉閫夋嫨浜�"鍏ㄨ偤"(鍋囪瀛楀吀鍊间负C34)锛岃嚜鍔ㄥ彇娑堝崟鐙殑"宸﹁偤"(C34L)鍜�"鍙宠偤"(C34R)閫夋嫨
+ if (selectedValues.includes("C34")) {
+ this.selectedOrgans = selectedValues.filter(
+ item => item !== "C34L" && item !== "C34R"
+ );
+ }
+ // 濡傛灉閫夋嫨浜�"宸﹁偤"鎴�"鍙宠偤"锛屽彇娑�"鍏ㄨ偤"閫夋嫨
+ else if (
+ selectedValues.includes("C34L") ||
+ selectedValues.includes("C34R")
+ ) {
+ this.selectedOrgans = selectedValues.filter(item => item !== "C34");
+ }
+ },
+
+ // 鍒涘缓鍣ㄥ畼璁板綍
+ createOrganRecord(organValue) {
+ let organName = this.getOrganLabel(organValue);
+
+ // 濡傛灉鏄�"鍏朵粬"鍣ㄥ畼涓旀湁杈撳叆鍊�
+ if (organValue == "C01" && this.otherOrganInput) {
+ organName = `鍏朵粬(${this.otherOrganInput})`;
+ }
+
+ this.allocationData.serviceDonateorganList.push({
+ id: null,
+ organname: organName,
+ organno: organValue,
+ caseno: "",
+ applicanttime: "",
+ name: "",
+ transplanthospitalno: "",
+ transplantHospitalName: "",
+ reallocationreason: "",
+ organState: 1
+ });
+ },
+
+ // 鍖婚櫌閫夋嫨鍙樺寲
+ handleHospitalChange(row, hospitalNo) {
+ const hospital = this.hospitalList.find(
+ item => item.hospitalNo == hospitalNo
+ );
+ if (hospital) {
+ row.transplantHospitalName = hospital.hospitalName;
+ }
+ },
+ // 閲嶅垎閰嶆搷浣�
+ handleRedistribution(row) {
+ this.currentRedistributeRecord = row;
+ this.redistributionForm.organname = row.organname;
+ this.redistributionForm.reason = row.reallocationreason || "";
+ 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;
+ }
+ },
+ // 鍣ㄥ畼琛屾牱寮�
+ getOrganRowClassName({ row }) {
+ if (
+ !row.caseno ||
+ !row.applicanttime ||
+ !row.name ||
+ !row.transplanthospitalno
+ ) {
+ return "warning-row";
+ }
+ return "";
+ },
+ // 鏋勫缓 filePatch 瀛楁
+ buildFilePatch() {
+ if (!this.attachments || this.attachments.length == 0) {
+ return "";
+ }
+ return JSON.stringify(this.attachments);
+ },
+ // 淇濆瓨鍩烘湰淇℃伅
+ async handleSave() {
+ this.$refs.form.validate(async valid => {
+ if (!valid) {
+ this.$message.warning("璇峰畬鍠勮〃鍗曚俊鎭�");
+ return;
+ }
+
+ this.saveLoading = true;
+ try {
+ const saveData = {
+ ...this.form,
+ 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;
+ });
+ const apiMethod = this.form.id ? allocationedit : allocationadd;
+ const response = await apiMethod(saveData);
+
+ if (response.code == 200) {
+ 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 || "鏈煡閿欒"));
+ }
+ } catch (error) {
+ console.error("淇濆瓨澶辫触:", error);
+ this.$message.error("淇濆瓨澶辫触");
+ } finally {
+ this.saveLoading = false;
+ }
+ });
+ },
+ // 淇濆瓨鍒嗛厤璁板綍
+ 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) {
+ this.$message.warning("璇峰厛瀹屽杽鎵�鏈夊垎閰嶈褰曠殑淇℃伅");
+ return;
+ }
+
+ this.$confirm("纭瀹屾垚鍣ㄥ畼鍒嗛厤鍚楋紵瀹屾垚鍚庡皢鏃犳硶淇敼鍒嗛厤淇℃伅銆�", "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(async () => {
+ this.confirmLoading = true;
+ this.form.allocationStatus = "3";
+ this.form.allocationTime = new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19);
+
+ 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 || "鏈煡閿欒")
+ );
+ this.form.allocationStatus = "0";
+ this.form.allocationTime = "";
+ }
+ } catch (error) {
+ console.error("纭鍒嗛厤澶辫触:", error);
+ this.$message.error("纭鍒嗛厤澶辫触");
+ this.form.allocationStatus = "0";
+ this.form.allocationTime = "";
+ } finally {
+ this.confirmLoading = false;
+ }
+ })
+ .catch(() => {});
+ },
+
+ // 闄勪欢鐩稿叧鏂规硶
+ /** 闄勪欢鍙樺寲澶勭悊 */
+ handleAttachmentChange(fileList) {
+ this.attachmentFileList = fileList;
+ },
+
+ /** 闄勪欢绉婚櫎澶勭悊 */
+ handleAttachmentRemove(file) {
+ if (file.url) {
+ const index = this.attachments.findIndex(
+ item => item.path == file.url || item.fileUrl == file.url
+ );
+ if (index > -1) {
+ this.attachments.splice(index, 1);
+ this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+ }
+ }
+ },
+
+ /** 涓婁紶鎴愬姛澶勭悊 */
+ handleUploadSuccess({ file, fileList, response }) {
+ if (response.code == 200) {
+ const attachmentObj = {
+ fileName: file.name,
+ path: response.fileUrl || file.url,
+ fileUrl: response.fileUrl || file.url,
+ fileType: this.getFileExtension(file.name),
+ fileSize: file.size,
+ uploadTime: dayjs().format("YYYY-MM-DD HH:mm:ss")
+ };
+
+ if (!Array.isArray(this.attachments)) {
+ this.attachments = [];
+ }
+
+ this.attachments.push(attachmentObj);
+ this.attachmentFileList = fileList;
+ this.$message.success("鏂囦欢涓婁紶鎴愬姛");
+ }
+ },
+
+ /** 涓婁紶閿欒澶勭悊 */
+ handleUploadError({ file, fileList, error }) {
+ console.error("闄勪欢涓婁紶澶辫触:", error);
+ this.$message.error("鏂囦欢涓婁紶澶辫触锛岃閲嶈瘯");
+ },
+
+ /** 鎵嬪姩鍒犻櫎闄勪欢 */
+ handleRemoveAttachment(index) {
+ this.attachments.splice(index, 1);
+ this.attachmentFileList.splice(index, 1);
+ this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+ },
+
+ /** 鏂囦欢棰勮 */
+ handlePreview(file) {
+ this.currentPreviewFile = {
+ fileName: file.fileName,
+ fileUrl: file.path || file.fileUrl,
+ fileType: this.getFileType(file.fileName)
};
- return map[status] || 'info';
+ // this.filePreviewTitle = file.fileName;
+ this.filePreviewVisible = true;
},
- getTimeRemainingType() {
- return this.allocationDetails.timeRemaining.includes('灏忔椂') ? 'success' : 'danger';
+ handleDownloadAttachment(file) {
+ const fileUrl = file.path || file.fileUrl;
+ const fileName = file.fileName;
+
+ if (fileUrl) {
+ const link = document.createElement("a");
+ link.href = fileUrl;
+ link.download = fileName;
+ link.style.display = "none";
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ this.$message.success("寮�濮嬩笅杞芥枃浠�");
+ } else {
+ this.$message.warning("鏂囦欢璺緞涓嶅瓨鍦紝鏃犳硶涓嬭浇");
+ }
},
- handleStartAllocation() {
- this.$confirm('纭鍚姩鑷姩鍣ㄥ畼鍒嗛厤鍚楋紵', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- this.$message.success('宸插惎鍔ㄨ嚜鍔ㄥ垎閰嶇畻娉�');
- // 妯℃嫙鍒嗛厤杩囩▼
- this.allocationStats.allocatedOrgans = 3;
- this.allocationStats.matchRate = 95;
- this.organAllocationData.forEach(organ => {
- organ.status = '宸插垎閰�';
- organ.allocationTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
- });
- });
+
+ /** 鑾峰彇鏂囦欢绫诲瀷 */
+ getFileType(fileName) {
+ if (!fileName) return "other";
+ const extension = fileName
+ .split(".")
+ .pop()
+ .toLowerCase();
+ const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
+ const pdfTypes = ["pdf"];
+ const officeTypes = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"];
+ if (imageTypes.includes(extension)) return "image";
+ if (pdfTypes.includes(extension)) return "pdf";
+ if (officeTypes.includes(extension)) return "office";
+ return "other";
},
- handleAutoAllocation() {
- this.$message.info('鎵ц鏅鸿兘鍒嗛厤绠楁硶');
+
+ /** 鑾峰彇鏂囦欢鍥炬爣棰滆壊 */
+ getFileIconColor(fileName) {
+ const type = this.getFileType(fileName);
+ const colorMap = {
+ image: "#67C23A",
+ pdf: "#F56C6C",
+ office: "#409EFF",
+ other: "#909399"
+ };
+ return colorMap[type] || "#909399";
},
- handleConfirmAllocation() {
- this.$confirm('纭鏈�缁堝垎閰嶇粨鏋滃悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'success'
- }).then(() => {
- this.$message.success('鍣ㄥ畼鍒嗛厤缁撴灉宸茬‘璁�');
- });
+
+ /** 鑾峰彇鏂囦欢鏍囩绫诲瀷 */
+ getFileTagType(fileName) {
+ const type = this.getFileType(fileName);
+ const typeMap = {
+ image: "success",
+ pdf: "danger",
+ office: "primary",
+ other: "info"
+ };
+ return typeMap[type] || "info";
},
- handleManualAdjust() {
- this.$message.info('杩涘叆鎵嬪姩璋冩暣妯″紡');
+
+ /** 鑾峰彇鏂囦欢绫诲瀷鏂囨湰 */
+ getFileTypeText(fileName) {
+ const type = this.getFileType(fileName);
+ const textMap = {
+ image: "鍥剧墖",
+ pdf: "PDF",
+ office: "鏂囨。",
+ other: "鍏朵粬"
+ };
+ return textMap[type] || "鏈煡";
},
- handleViewMatch(row) {
- this.$message.info(`鏌ョ湅${row.organName}鐨勫尮閰嶈鎯卄);
+
+ /** 妫�鏌ユ槸鍚﹀彲棰勮 */
+ isPreviewable(fileName) {
+ const type = this.getFileType(fileName);
+ return ["image", "pdf"].includes(type);
+ },
+
+ /** 鑾峰彇鏂囦欢鎵╁睍鍚� */
+ getFileExtension(filename) {
+ return filename
+ .split(".")
+ .pop()
+ .toLowerCase();
+ },
+
+ /** 鏍煎紡鍖栨枃浠跺ぇ灏� */
+ formatFileSize(bytes) {
+ if (!bytes || bytes == 0) return "0 B";
+ const k = 1024;
+ const sizes = ["B", "KB", "MB", "GB"];
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
+ },
+
+ /** 鏃ユ湡鏃堕棿鏍煎紡鍖� */
+ formatDateTime(dateTime) {
+ if (!dateTime) return "";
+ try {
+ const date = new Date(dateTime);
+ if (isNaN(date.getTime())) return dateTime;
+ const year = date.getFullYear();
+ const month = String(date.getMonth() + 1).padStart(2, "0");
+ const day = String(date.getDate()).padStart(2, "0");
+ const hours = String(date.getHours()).padStart(2, "0");
+ const minutes = String(date.getMinutes()).padStart(2, "0");
+ return `${year}-${month}-${day} ${hours}:${minutes}`;
+ } catch (error) {
+ return dateTime;
+ }
}
}
};
</script>
<style scoped>
-.allocation-stats, .time-window {
- padding: 10px 0;
+.organ-allocation-detail {
+ padding: 20px;
+ background-color: #f5f7fa;
}
-.stat-item, .time-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 15px;
- padding: 8px 0;
- border-bottom: 1px solid #f0f0f0;
-}
-
-.stat-item .label, .time-item .label {
- color: #606266;
- font-weight: 500;
- min-width: 100px;
-}
-
-.stat-item .value {
- font-weight: 600;
- color: #409EFF;
-}
-
-.algorithm-results {
- padding: 15px 0;
-}
-
-.result-item {
+.detail-card {
margin-bottom: 20px;
+ border-radius: 8px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
-.result-item h4 {
- margin-bottom: 15px;
+.allocation-card {
+ margin-bottom: 20px;
+ border-radius: 8px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.attachment-card {
+ margin-bottom: 20px;
+ border-radius: 8px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+ padding: 20px;
+ background: #fafafa;
+}
+
+.attachment-header {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 16px;
+ padding-bottom: 8px;
+ border-bottom: 1px solid #ebeef5;
+}
+
+.attachment-title {
+ font-weight: 600;
color: #303133;
}
-.weight-distribution {
- padding: 10px 0;
+.attachment-tip {
+ font-size: 12px;
+ color: #909399;
+ margin-left: auto;
}
-.factor-item {
- display: flex;
- align-items: center;
+.attachment-list {
+ margin-top: 16px;
+}
+
+.list-title {
+ font-weight: bold;
margin-bottom: 12px;
-}
-
-.factor-name {
- width: 120px;
- color: #606266;
+ color: #303133;
font-size: 14px;
}
-.factor-item .el-progress {
- flex: 1;
- margin: 0 15px;
+.file-name {
+ font-size: 13px;
+ margin-left: 8px;
}
-.factor-percent {
- width: 40px;
- text-align: right;
+.detail-title {
+ font-size: 18px;
+ font-weight: 600;
+ color: #303133;
+}
+
+/* 缁熻淇℃伅鏍峰紡 */
+.allocation-stats {
+ margin-top: 20px;
+ padding: 15px;
+ background: linear-gradient(135deg, #9eb7e5 0%, #53519c 100%);
+ border-radius: 8px;
+ color: white;
+ font-size: 18px;
+}
+
+.stat-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 10px;
+}
+
+.stat-label {
+ opacity: 0.9;
+ margin-bottom: 5px;
+}
+
+.stat-value {
+ font-size: 20px;
+ font-weight: bold;
+}
+
+/* 绌虹姸鎬佹牱寮� */
+.empty-allocation {
+ text-align: center;
+ padding: 40px 0;
color: #909399;
- font-size: 12px;
+}
+
+/* 瀵硅瘽妗嗗簳閮ㄦ寜閽� */
+.dialog-footer {
+ margin-top: 20px;
+ text-align: center;
+ padding-top: 20px;
+ border-top: 1px solid #e4e7ed;
+}
+
+/* 琛ㄦ牸琛屾牱寮� */
+:deep(.warning-row) {
+ background-color: #fff7e6;
+}
+
+:deep(.warning-row:hover) {
+ background-color: #ffecc2;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 768px) {
+ .organ-allocation-detail {
+ padding: 10px;
+ }
+
+ .allocation-stats .el-col {
+ margin-bottom: 10px;
+ }
}
</style>
diff --git a/src/views/business/course/components/OrganProcurementStage.vue b/src/views/business/course/components/OrganProcurementStage.vue
index f16237d..4bbbf52 100644
--- a/src/views/business/course/components/OrganProcurementStage.vue
+++ b/src/views/business/course/components/OrganProcurementStage.vue
@@ -1,499 +1,1584 @@
<template>
- <base-stage :stage-data="stageData" :case-info="caseInfo">
- <template #header>
- <el-alert
- :title="`鍣ㄥ畼鑾峰彇 - ${getStatusText()}`"
- :type="getAlertType()"
- :description="getAlertDescription()"
- show-icon
- :closable="false"
- />
- </template>
+ <div class="organ-procurement-detail">
- <el-row :gutter="20" style="margin-top: 20px;">
- <el-col :span="8">
- <el-card>
- <div slot="header" class="card-header">
- <span>鑾峰彇鎵嬫湳淇℃伅</span>
- </div>
- <el-descriptions :column="1" border size="small">
- <el-descriptions-item label="鎵嬫湳鏃堕棿">
- {{ formatTime(procurementDetails.surgeryTime) }}
- </el-descriptions-item>
- <el-descriptions-item label="鎵嬫湳鍦扮偣">
- {{ procurementDetails.location }}
- </el-descriptions-item>
- <el-descriptions-item label="涓诲垁鍖荤敓">
- {{ procurementDetails.surgeon }}
- </el-descriptions-item>
- <el-descriptions-item label="楹婚唹鍖荤敓">
- {{ procurementDetails.anesthesiologist }}
- </el-descriptions-item>
- <el-descriptions-item label="鎵嬫湳鐘舵��">
- <el-tag :type="procurementDetails.status === 'completed' ? 'success' : 'warning'">
- {{ procurementDetails.status === 'completed' ? '宸插畬鎴�' : '杩涜涓�' }}
- </el-tag>
- </el-descriptions-item>
- </el-descriptions>
- </el-card>
- </el-col>
+ <!-- 鍩烘湰淇℃伅 -->
+ <el-card class="detail-card">
+ <div slot="header" class="clearfix">
+ <span class="detail-title">鍣ㄥ畼鑾峰彇鍩烘湰淇℃伅</span>
- <el-col :span="8">
- <el-card>
- <div slot="header" class="card-header">
- <span>鍣ㄥ畼鑾峰彇缁熻</span>
- </div>
- <div class="procurement-stats">
- <div class="stat-item">
- <span class="label">璁″垝鑾峰彇:</span>
- <span class="value">{{ procurementStats.planned }} 涓�</span>
- </div>
- <div class="stat-item">
- <span class="label">瀹為檯鑾峰彇:</span>
- <span class="value">{{ procurementStats.actual }} 涓�</span>
- </div>
- <div class="stat-item">
- <span class="label">鑾峰彇鎴愬姛鐜�:</span>
- <el-progress
- :percentage="procurementStats.successRate"
- :status="procurementStats.successRate > 90 ? 'success' : 'warning'"
- />
- </div>
- <div class="stat-item">
- <span class="label">璐ㄩ噺璇勪及:</span>
- <el-rate
- v-model="procurementStats.qualityRating"
- disabled
- show-score
- text-color="#ff9900"
- score-template="{value} 鏄�"
- />
- </div>
- </div>
- </el-card>
- </el-col>
-
- <el-col :span="8">
- <el-card>
- <div slot="header" class="card-header">
- <span>淇濆瓨涓庤繍杈�</span>
- </div>
- <div class="preservation-info">
- <div class="info-item">
- <span class="label">淇濆瓨鏂瑰紡:</span>
- <span>{{ preservationDetails.method }}</span>
- </div>
- <div class="info-item">
- <span class="label">淇濆瓨娓╁害:</span>
- <span>{{ preservationDetails.temperature }}</span>
- </div>
- <div class="info-item">
- <span class="label">鐏屾敞娑�:</span>
- <span>{{ preservationDetails.perfusionSolution }}</span>
- </div>
- <div class="info-item">
- <span class="label">棰勮瀛樻椿鏃堕棿:</span>
- <el-tag :type="getSurvivalTimeType()">
- {{ preservationDetails.survivalTime }}
- </el-tag>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
-
- <el-card style="margin-top: 20px;">
- <div slot="header" class="card-header">
- <span>鍣ㄥ畼鑾峰彇璇︽儏</span>
- <el-button type="primary" size="small" @click="handleStartProcurement">
- 寮�濮嬭幏鍙栨墜鏈�
- </el-button>
</div>
- <el-table :data="organProcurementData" border>
- <el-table-column label="鍣ㄥ畼鍚嶇О" prop="organName" width="120" align="center" />
- <el-table-column label="鑾峰彇鐘舵��" width="100" align="center">
- <template slot-scope="scope">
- <el-tag :type="getProcurementStatusTag(scope.row.status)">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鑾峰彇鏃堕棿" width="160" align="center">
- <template slot-scope="scope">
- {{ formatTime(scope.row.procurementTime) || '-' }}
- </template>
- </el-table-column>
- <el-table-column label="閲嶉噺(g)" prop="weight" width="100" align="center" />
- <el-table-column label="璐ㄩ噺璇勪及" width="120" align="center">
- <template slot-scope="scope">
- <el-rate
- v-model="scope.row.qualityScore"
- disabled
- show-score
- text-color="#ff9900"
- score-template="{value}"
- />
- </template>
- </el-table-column>
- <el-table-column label="鐏屾敞鎯呭喌" width="100" align="center">
- <template slot-scope="scope">
- <el-tag :type="scope.row.perfusionStatus ? 'success' : 'warning'">
- {{ scope.row.perfusionStatus ? '宸插畬鎴�' : '寰呯亴娉�' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="淇濆瓨鏂瑰紡" prop="preservationMethod" width="120" />
- <el-table-column label="鎿嶄綔" width="150" align="center">
- <template slot-scope="scope">
- <el-button type="text" size="small" @click="handleViewOrgan(scope.row)">
- 鏌ョ湅璇︽儏
- </el-button>
- <el-button
- v-if="scope.row.status !== '宸茶幏鍙�'"
- type="text"
- size="small"
- @click="handleRecordProcurement(scope.row)"
+
+ <el-form :model="form" ref="form" :rules="rules" label-width="120px">
+ <!-- 鎵嬫湳鐩稿叧淇℃伅 -->
+ <el-divider content-position="left">鎵嬫湳淇℃伅</el-divider>
+
+ <el-row :gutter="20">
+ <el-col :span="8">
+ <el-form-item label="鎵嬫湳鍖荤敓" prop="operationdoctor">
+ <el-input v-model="form.operationdoctor" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="鎵嬫湳寮�濮嬫椂闂�" prop="operationbegtime">
+ <el-date-picker
+ v-model="form.operationbegtime"
+ 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="operationendtime">
+ <el-date-picker
+ v-model="form.operationendtime"
+ type="datetime"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <el-row :gutter="20">
+ <el-col :span="8">
+ <el-form-item
+ label="鑵逛富鍔ㄨ剦鎻掔鏃堕棿"
+ prop="abdominalaortacannulatime"
>
- 璁板綍鑾峰彇
- </el-button>
- </template>
- </el-table-column>
- </el-table>
+ <el-date-picker
+ v-model="form.abdominalaortacannulatime"
+ 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="abdominalaortaperfusiontime"
+ >
+ <el-date-picker
+ v-model="form.abdominalaortaperfusiontime"
+ type="datetime"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <el-row :gutter="20">
+ <el-col :span="8">
+ <el-form-item label="闂ㄩ潤鑴夋彃绠℃椂闂�" prop="portalveincannulatime">
+ <el-date-picker
+ v-model="form.portalveincannulatime"
+ type="datetime"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="闂ㄩ潤鑴夌亴娉ㄦ椂闂�" prop="portalveinperfusiontime">
+ <el-date-picker
+ v-model="form.portalveinperfusiontime"
+ type="datetime"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <!-- 鍗忚皟鍛樹俊鎭� -->
+ <el-divider content-position="left">鍗忚皟鍛樹俊鎭�</el-divider>
+
+ <el-row :gutter="20">
+ <!-- <el-col :span="8">
+ <el-form-item label="鍗忚皟鍛樺鍚�" prop="coordinatorName">
+ <el-input v-model="form.coordinatorName" />
+ </el-form-item>
+ </el-col> -->
+ <el-col :span="8">
+ <el-form-item label="杩涙墜鏈鏃堕棿" prop="coordinatorInOperating">
+ <el-date-picker
+ v-model="form.coordinatorInOperating"
+ 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="coordinatorOutOperating">
+ <el-date-picker
+ v-model="form.coordinatorOutOperating"
+ type="datetime"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <el-row :gutter="20">
+ <el-col :span="8">
+ <el-form-item label="鍗忚皟鍛樼瀛�" prop="coordinatorSign">
+ <el-input v-model="form.coordinatorSign" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <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-row>
+
+ <!-- 璐熻矗浜轰俊鎭� -->
+ <el-divider content-position="left">璐熻矗浜轰俊鎭�</el-divider>
+
+ <el-row :gutter="20">
+ <el-col :span="8">
+ <el-form-item label="璐熻矗浜哄鍚�" prop="responsibleusername">
+ <el-input v-model="form.responsibleusername" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <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-input v-model="form.coordinatedusernamet" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <!-- 鑾峰彇鏈烘瀯淇℃伅 -->
+ <el-divider content-position="left">鑾峰彇鏈烘瀯淇℃伅</el-divider>
+
+ <el-row :gutter="20">
+ <el-col :span="8">
+ <el-form-item label="鑾峰彇鏈烘瀯鍚嶇О" prop="gainhospitalname">
+ <el-input
+ v-model="form.gainhospitalname"
+ placeholder="璇疯緭鍏ヨ幏鍙栨満鏋勫悕绉�"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="鑾峰彇鏈烘瀯缂栫爜" prop="gainhospitalno">
+ <el-input
+ v-model="form.gainhospitalno"
+ placeholder="璇疯緭鍏ヨ幏鍙栨満鏋勭紪鐮�"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
</el-card>
- <el-card style="margin-top: 20px;">
- <div slot="header" class="card-header">
- <span>鎵嬫湳璁板綍涓庡奖鍍�</span>
+ <!-- 鍣ㄥ畼鑾峰彇璁板綍閮ㄥ垎 -->
+ <el-card class="procurement-card">
+ <div slot="header" class="clearfix">
+ <span class="detail-title">鍣ㄥ畼鑾峰彇璁板綍</span>
+ <div style="float: right;">
+
+ <dict-tag
+ :options="dict.type.Obtain_status"
+ :value="form.witnessState"
+ />
+ </div>
</div>
- <el-tabs v-model="activeMedicalTab">
- <el-tab-pane label="鎵嬫湳璁板綍" name="surgeryRecord">
- <div class="surgery-record">
- <el-timeline>
- <el-timeline-item
- v-for="record in surgeryRecords"
- :key="record.time"
- :timestamp="formatTime(record.time)"
- :type="record.type"
- :icon="record.icon"
+
+ <el-form
+ ref="procurementForm"
+ :rules="procurementRules"
+ :model="procurementData"
+ label-position="right"
+ >
+ <el-row>
+ <el-col>
+ <el-form-item label-width="100px" label="鎹愮尞鍣ㄥ畼">
+ <el-checkbox-group
+ v-model="selectedOrgans"
+ @change="handleOrganSelectionChange"
>
- <p>{{ record.content }}</p>
- <div v-if="record.images && record.images.length > 0" class="record-images">
- <el-image
- v-for="(img, index) in record.images"
- :key="index"
- :src="img"
- :preview-src-list="record.images"
- style="width: 100px; height: 100px; margin-right: 10px;"
- />
- </div>
- </el-timeline-item>
- </el-timeline>
- </div>
- </el-tab-pane>
+ <el-checkbox
+ v-for="dict in dict.type.sys_Organ || []"
+ :key="dict.value"
+ :label="dict.value"
+ >
+ {{ dict.label }}
+ </el-checkbox>
+ </el-checkbox-group>
+ </el-form-item>
+ </el-col>
+ </el-row>
- <el-tab-pane label="鍣ㄥ畼褰卞儚" name="organImages">
- <div class="organ-images">
- <el-row :gutter="15">
- <el-col v-for="organ in organImages" :key="organ.name" :span="8">
- <el-card shadow="hover">
- <div slot="header" class="image-header">
- <span>{{ organ.name }}</span>
- </div>
- <el-image
- :src="organ.image"
- :preview-src-list="[organ.image]"
- fit="cover"
- style="width: 100%; height: 200px;"
- />
- <div style="padding: 10px;">
- <p>{{ organ.description }}</p>
- <el-tag size="small">{{ organ.status }}</el-tag>
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
- </el-tab-pane>
+ <el-row>
+ <el-col>
+ <el-form-item>
+ <el-table
+ :data="procurementData.serviceDonationwitnessorgans"
+ v-loading="loading"
+ border
+ style="width: 100%"
+ :row-class-name="getOrganRowClassName"
+ >
+ <el-table-column
+ label="鍣ㄥ畼鍚嶇О"
+ align="center"
+ width="120"
+ prop="organname"
+ >
+ <template slot-scope="scope">
+ <el-input
+ v-model="scope.row.organname"
+ placeholder="鍣ㄥ畼鍚嶇О"
+ :disabled="true"
+ />
+ </template>
+ </el-table-column>
- <el-tab-pane label="璐ㄩ噺妫�娴嬫姤鍛�" name="qualityReport">
- <div class="quality-report">
- <el-table :data="qualityReports" border>
- <el-table-column label="妫�娴嬮」鐩�" prop="item" width="150" />
- <el-table-column label="妫�娴嬬粨鏋�" prop="result" width="120">
- <template slot-scope="scope">
- <el-tag :type="scope.row.pass ? 'success' : 'danger'">
- {{ scope.row.pass ? '鍚堟牸' : '涓嶅悎鏍�' }}
+ <el-table-column
+ label="鑾峰彇寮�濮嬫椂闂�"
+ align="center"
+ width="180"
+ prop="organStartTime"
+ >
+ <template slot-scope="scope">
+ <el-date-picker
+ clearable
+ size="small"
+ style="width: 100%"
+ v-model="scope.row.organStartTime"
+ type="datetime"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ placeholder="閫夋嫨鑾峰彇寮�濮嬫椂闂�"
+ />
+ </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="閫夋嫨鍣ㄥ畼绂讳綋鏃堕棿"
+ />
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="鑾峰彇鍖婚櫌"
+ align="center"
+ width="200"
+ prop="gainhospitalno"
+ >
+ <template slot-scope="scope">
+ <el-select
+ v-model="scope.row.gainhospitalno"
+ placeholder="璇烽�夋嫨鑾峰彇鍖婚櫌"
+ style="width: 100%"
+ @change="handleHospitalChange(scope.row, $event)"
+ >
+ <el-option
+ v-for="hospital in hospitalList"
+ :key="hospital.hospitalNo"
+ :label="hospital.hospitalName"
+ :value="hospital.hospitalNo"
+ />
+ </el-select>
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="鑾峰彇鍖诲笀"
+ align="center"
+ width="120"
+ prop="organgetdoct"
+ >
+ <template slot-scope="scope">
+ <el-input
+ v-model="scope.row.organgetdoct"
+ placeholder="鑾峰彇鍖诲笀"
+ />
+ </template>
+ </el-table-column>
+
+ <!-- <el-table-column
+ label="鍔╂墜"
+ align="center"
+ width="120"
+ prop="assistant"
+ >
+ <template slot-scope="scope">
+ <el-input
+ v-model="scope.row.assistant"
+ placeholder="鍔╂墜"
+
+ />
+ </template>
+ </el-table-column> -->
+
+ <!-- <el-table-column
+ label="鑾峰彇鎶ゅ+"
+ align="center"
+ width="120"
+ prop="procurementNurse"
+ >
+ <template slot-scope="scope">
+ <el-input
+ v-model="scope.row.procurementNurse"
+ placeholder="鑾峰彇鎶ゅ+"
+
+ />
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="鎵嬫湳瀹ゆ姢澹�"
+ align="center"
+ width="120"
+ prop="operatingRoomNurse"
+ >
+ <template slot-scope="scope">
+ <el-input
+ v-model="scope.row.operatingRoomNurse"
+ placeholder="鎵嬫湳瀹ゆ姢澹�"
+
+ />
+ </template>
+ </el-table-column> -->
+
+ <el-table-column
+ label="鑾峰彇鐘舵��"
+ align="center"
+ width="120"
+ prop="organstate"
+ >
+ <template slot-scope="scope">
+ <el-select
+ v-model="scope.row.organstate"
+ placeholder="璇烽�夋嫨鑾峰彇鐘舵��"
+ style="width: 100%"
+ >
+ <el-option
+ v-for="dict in dict.type.Obtain_status"
+ :key="dict.value"
+ :label="dict.label"
+ :value="dict.value"
+ />
+ </el-select>
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="璇存槑"
+ align="center"
+ prop="notgetreason"
+ min-width="200"
+ >
+ <template slot-scope="scope">
+ <el-input
+ type="textarea"
+ clearable
+ v-model="scope.row.notgetreason"
+ placeholder="璇疯緭鍏ユ湭鑾峰彇璇存槑"
+ />
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="鎿嶄綔"
+ align="center"
+ width="120"
+ class-name="small-padding fixed-width"
+ >
+ <template slot-scope="scope">
+ <el-button
+ size="mini"
+ type="text"
+ icon="el-icon-edit"
+ @click="handleEditProcurement(scope.row)"
+ >
+ 缂栬緫
+ </el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <!-- 鑾峰彇缁熻淇℃伅 -->
+ <!-- <div
+ class="procurement-stats"
+ v-if="
+ procurementData.serviceDonationwitnessorgans &&
+ procurementData.serviceDonationwitnessorgans.length > 0
+ "
+ >
+ <el-row :gutter="20">
+ <el-col :span="6">
+ <div class="stat-item">
+ <span class="stat-label">宸茶幏鍙栧櫒瀹�:</span>
+ <span class="stat-value"
+ >{{
+ procurementData.serviceDonationwitnessorgans.length
+ }}
+ 涓�</span
+ >
+ </div>
+ </el-col>
+ <el-col :span="6">
+ <div class="stat-item">
+ <span class="stat-label">寰呭畬鍠勪俊鎭�:</span>
+ <span class="stat-value">{{ incompleteRecords }} 涓�</span>
+ </div>
+ </el-col>
+ <el-col :span="6">
+ <div class="stat-item">
+ <span class="stat-label">娑夊強鍖婚櫌:</span>
+ <span class="stat-value">{{ uniqueHospitals }} 瀹�</span>
+ </div>
+ </el-col>
+ <el-col :span="6">
+ <div class="stat-item">
+ <span class="stat-label">鑾峰彇鐘舵��:</span>
+ <span class="stat-value">
+ <el-tag
+ :type="
+ form.witnessState === 'completed' ? 'success' : 'warning'
+ "
+ >
+ {{ form.witnessState === "completed" ? "宸插畬鎴�" : "杩涜涓�" }}
</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鍙傝�冭寖鍥�" prop="reference" width="120" />
- <el-table-column label="妫�娴嬪��" prop="value" width="100" />
- <el-table-column label="妫�娴嬫椂闂�" width="160">
- <template slot-scope="scope">
- {{ formatTime(scope.row.testTime) }}
- </template>
- </el-table-column>
- <el-table-column label="妫�娴嬪尰鐢�" prop="doctor" width="120" />
- </el-table>
- </div>
- </el-tab-pane>
- </el-tabs>
+ </span>
+ </div>
+ </el-col>
+ </el-row>
+ </div> -->
+
+ <div
+ v-if="!procurementData.serviceDonationwitnessorgans"
+ class="empty-procurement"
+ >
+ <el-empty description="鏆傛棤鑾峰彇璁板綍" :image-size="80">
+ <span>璇峰厛閫夋嫨瑕佽幏鍙栫殑鍣ㄥ畼</span>
+ </el-empty>
+ </div>
+ </el-form>
</el-card>
- <template #footer>
- <div class="action-buttons" style="margin-top: 20px; text-align: center;">
- <el-button type="primary" @click="handleCompleteProcurement">
- 瀹屾垚鍣ㄥ畼鑾峰彇
- </el-button>
- <el-button type="success" @click="handleGenerateReport">
- 鐢熸垚鑾峰彇鎶ュ憡
- </el-button>
- <el-button type="warning" @click="handleUploadEvidence">
- 涓婁紶鎵嬫湳璇佹嵁
- </el-button>
+ <!-- 闄勪欢绠$悊閮ㄥ垎浼樺寲 -->
+ <el-card class="attachment-card">
+ <div class="attachment-header">
+ <i class="el-icon-paperclip"></i>
+ <span class="attachment-title">鐩稿叧闄勪欢</span>
+ <span class="attachment-tip"
+ >鏀寔涓婁紶鍣ㄥ畼鑾峰彇鐩稿叧鏂囦欢 (鏈�澶歿{ attachmentLimit }}涓�)</span
+ >
</div>
- </template>
- </base-stage>
+
+ <!-- 浣跨敤 UploadAttachment 缁勪欢 -->
+ <UploadAttachment
+ ref="uploadAttachment"
+ :file-list="attachmentFileList"
+ :limit="attachmentLimit"
+ :accept="attachmentAccept"
+ :multiple="true"
+ @change="handleAttachmentChange"
+ @upload-success="handleUploadSuccess"
+ @upload-error="handleUploadError"
+ @remove="handleAttachmentRemove"
+ />
+
+ <!-- 闄勪欢鍒楄〃灞曠ず -->
+ <div class="attachment-list" v-if="attachments && attachments.length > 0">
+ <div class="list-title">宸蹭笂浼犻檮浠� ({{ attachments.length }})</div>
+ <el-table :data="attachments" style="width: 100%" size="small">
+ <el-table-column label="鏂囦欢鍚�" min-width="200">
+ <template slot-scope="scope">
+ <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="160">
+ <template slot-scope="scope">
+ <span>{{ formatDateTime(scope.row.uploadTime) }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鏂囦欢澶у皬" width="100">
+ <template slot-scope="scope">
+ <span>{{ formatFileSize(scope.row.fileSize) }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鎿嶄綔" width="200" fixed="right">
+ <template slot-scope="scope">
+ <el-button
+ size="mini"
+ type="primary"
+ @click="handlePreview(scope.row)"
+ :disabled="!isPreviewable(scope.row.fileName)"
+ >
+ 棰勮
+ </el-button>
+ <el-button
+ size="mini"
+ type="success"
+ @click="handleDownload(scope.row)"
+ >
+ 涓嬭浇
+ </el-button>
+ <el-button
+ size="mini"
+ type="danger"
+ @click="handleRemoveAttachment(scope.$index)"
+ >
+ 鍒犻櫎
+ </el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+ </el-card>
+
+ <!-- 缂栬緫鑾峰彇璁板綍瀵硅瘽妗� -->
+ <el-dialog
+ title="缂栬緫鍣ㄥ畼鑾峰彇璁板綍"
+ :visible.sync="editDialogVisible"
+ width="600px"
+ >
+ <el-form :model="currentRecord" label-width="120px">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鍣ㄥ畼鍚嶇О">
+ <el-input v-model="currentRecord.organname" readonly />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鑾峰彇鐘舵��">
+ <el-select v-model="currentRecord.organstate" style="width: 100%">
+ <el-option
+ v-for="dict in dict.type.Obtain_status"
+ :key="dict.value"
+ :label="dict.label"
+ :value="dict.value"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鑾峰彇鍖诲笀">
+ <el-input
+ v-model="currentRecord.organgetdoct"
+ placeholder="璇疯緭鍏ヨ幏鍙栧尰甯�"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍔╂墜">
+ <el-input
+ v-model="currentRecord.assistant"
+ placeholder="璇疯緭鍏ュ姪鎵嬪鍚�"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鑾峰彇鎶ゅ+">
+ <el-input
+ v-model="currentRecord.procurementNurse"
+ placeholder="璇疯緭鍏ヨ幏鍙栨姢澹�"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鎵嬫湳瀹ゆ姢澹�">
+ <el-input
+ v-model="currentRecord.operatingRoomNurse"
+ placeholder="璇疯緭鍏ユ墜鏈鎶ゅ+"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <el-form-item label="楹婚唹鍖荤敓">
+ <el-input
+ v-model="currentRecord.anesthesiologist"
+ placeholder="璇疯緭鍏ラ夯閱夊尰鐢�"
+ />
+ </el-form-item>
+
+ <el-form-item
+ label="鏈幏鍙栬鏄�"
+ v-if="currentRecord.organstate === '0'"
+ >
+ <el-input
+ type="textarea"
+ :rows="3"
+ v-model="currentRecord.notgetreason"
+ placeholder="璇疯緭鍏ユ湭鑾峰彇鐨勫師鍥犺鏄�"
+ />
+ </el-form-item>
+ </el-form>
+
+ <div slot="footer">
+ <el-button @click="editDialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleEditConfirm">纭</el-button>
+ </div>
+ </el-dialog>
+
+ <!-- 鏂囦欢棰勮寮圭獥 -->
+ <el-dialog
+ :title="filePreviewTitle"
+ :visible.sync="filePreviewVisible"
+ width="800px"
+ @close="filePreviewVisible = false"
+ >
+ <div v-if="currentPreviewFile">
+ <div v-if="currentPreviewFile.fileType === 'image'">
+ <img
+ :src="currentPreviewFile.fileUrl"
+ style="max-width: 100%; max-height: 500px;"
+ />
+ </div>
+ <div v-else-if="currentPreviewFile.fileType === 'pdf'">
+ <iframe
+ :src="currentPreviewFile.fileUrl"
+ width="100%"
+ height="500px"
+ ></iframe>
+ </div>
+ <div v-else>
+ <p>涓嶆敮鎸侀瑙堟鏂囦欢绫诲瀷锛岃涓嬭浇鏌ョ湅</p>
+ </div>
+ </div>
+ </el-dialog>
+ </div>
</template>
<script>
-import BaseStage from './BaseStage.vue';
+import { witnessList, witnessadd, witnessedit } from "@/api/businessApi";
+import UploadAttachment from "@/components/UploadAttachment";
+import CaseBasicInfo from "@/components/CaseBasicInfo";
+import dayjs from "dayjs";
export default {
- name: 'OrganProcurementStage',
- components: { BaseStage },
- props: {
- stageData: {
- type: Object,
- default: () => ({})
- },
- caseInfo: {
- type: Object,
- default: () => ({})
+ name: "OrganProcurementDetail",
+ components: {
+ UploadAttachment,
+ CaseBasicInfo
+ },
+ dicts: [
+ "sys_BloodType",
+ "sys_DonationCategory",
+ "sys_Organ",
+ "Obtain_status"
+ ],
+ props: {
+ infoid: {
+ type: String,
+ default: true
}
},
data() {
return {
- activeMedicalTab: 'surgeryRecord',
- procurementDetails: {
- surgeryTime: '2025-12-04 14:00:00',
- location: '鎵嬫湳瀹や竴鍙�',
- surgeon: '寮犱富浠�',
- anesthesiologist: '鐜嬪尰鐢�',
- status: 'in_progress'
+ caseId: null,
+ // 琛ㄥ崟鏁版嵁
+ form: {
+ id: undefined,
+ infoid: undefined,
+ name: "",
+ inpatientno: "",
+ witnessState: "2",
+ caseNo: "",
+ donorno: "",
+ treatmenthospitalname: "",
+ treatmenthospitalno: "",
+ sex: "",
+ age: "",
+ bloodtype: "",
+ idcardno: "",
+ diagnosisname: "",
+ coordinatorName: "",
+ gainhospitalno: "",
+ gainhospitalname: "",
+ deathtime: "",
+ deathreason: "",
+ deathjudgedocto: "",
+ deathjudgedoctt: "",
+ deathjudgeannex: "",
+ operationbegtime: "",
+ operationendtime: "",
+ operationdoctor: "",
+ isspendremember: 1,
+ isrestoreremains: 1,
+ rememberannex: "",
+ responsibleuserid: "",
+ responsibleusername: "",
+ coordinateduserido: "",
+ coordinatedusernameo: "",
+ coordinateduseridt: "",
+ coordinatedusernamet: "",
+ abdominalaortacannulatime: "",
+ abdominalaortaperfusiontime: "",
+ portalveincannulatime: "",
+ portalveinperfusiontime: "",
+ pulmonaryarterycannulatime: "",
+ pulmonaryarteryperfusiontime: "",
+ aortacannulatime: "",
+ aortaperfusiontime: "",
+ organdonation: "",
+ organdonationOther: "",
+ donationcategory: "",
+ coordinatorInOperating: "",
+ coordinatorOutOperating: "",
+ coordinatorSign: "",
+ coordinatorSignTime: "",
+ attachments: []
},
- procurementStats: {
- planned: 3,
- actual: 0,
- successRate: 0,
- qualityRating: 0
+ // 琛ㄥ崟楠岃瘉瑙勫垯
+ rules: {
+ name: [
+ { required: true, message: "鎹愮尞鑰呭鍚嶄笉鑳戒负绌�", trigger: "blur" }
+ ],
+ diagnosisname: [
+ { required: true, message: "鐤剧梾璇婃柇涓嶈兘涓虹┖", trigger: "blur" }
+ ],
+ donationcategory: [
+ { required: true, message: "鎹愮尞绫诲埆涓嶈兘涓虹┖", trigger: "change" }
+ ],
+ operationdoctor: [
+ { required: true, message: "鎵嬫湳鍖荤敓涓嶈兘涓虹┖", trigger: "blur" }
+ ]
},
- preservationDetails: {
- method: '浣庢俯鏈烘鐏屾敞[9](@ref)',
- temperature: '4掳C',
- perfusionSolution: 'UW淇濆瓨娑�',
- survivalTime: '鑲濊剰12灏忔椂[1](@ref)'
+ // 鑾峰彇璁板綍楠岃瘉瑙勫垯
+ procurementRules: {},
+ // 淇濆瓨鍔犺浇鐘舵��
+ saveLoading: false,
+ confirmLoading: false,
+ // 鍔犺浇鐘舵��
+ loading: false,
+ // 閫変腑鐨勫櫒瀹�
+ selectedOrgans: [],
+ // 鍖婚櫌鍒楄〃
+ hospitalList: [],
+ // 鑾峰彇璁板綍鏁版嵁
+ procurementData: {
+ serviceDonationwitnessorgans: []
},
- organProcurementData: [
- {
- organName: '鑲濊剰',
- status: '鑾峰彇涓�',
- procurementTime: '',
- weight: 1500,
- qualityScore: 0,
- perfusionStatus: false,
- preservationMethod: '浣庢俯淇濆瓨'
- },
- {
- organName: '鑲捐剰',
- status: '寰呰幏鍙�',
- procurementTime: '',
- weight: 0,
- qualityScore: 0,
- perfusionStatus: false,
- preservationMethod: ''
- },
- {
- organName: '蹇冭剰',
- status: '寰呰幏鍙�',
- procurementTime: '',
- weight: 0,
- qualityScore: 0,
- perfusionStatus: false,
- preservationMethod: ''
- }
- ],
- surgeryRecords: [
- {
- time: '2025-12-04 14:00:00',
- content: '鎵嬫湳寮�濮嬶紝鎮h�呬綋浣嶆憜鏀撅紝娑堟瘨閾哄肪',
- type: 'primary',
- icon: 'el-icon-video-play'
- },
- {
- time: '2025-12-04 14:30:00',
- content: '寮�鑵规墜鏈紝鏆撮湶鑵硅厰鍣ㄥ畼',
- type: 'success',
- icon: 'el-icon-scissors'
- },
- {
- time: '2025-12-04 15:00:00',
- content: '鑲濊剰娓哥锛岃绠¤В鍓栧垎绂�',
- type: 'warning',
- icon: 'el-icon-medal'
- }
- ],
- organImages: [
- {
- name: '鑲濊剰',
- image: '/images/liver-procurement.jpg',
- description: '鑾峰彇鐨勮倽鑴忓櫒瀹橈紝褰㈡�佸畬鏁�',
- status: '璐ㄩ噺鑹ソ'
- }
- ],
- qualityReports: [
- {
- item: '鑲濆姛鑳介叾瀛�',
- result: true,
- reference: '<40 U/L',
- value: '35 U/L',
- testTime: '2025-12-04 16:00:00',
- doctor: '鏉庢楠屽笀'
- },
- {
- item: '缁勭粐瀹屾暣鎬�',
- result: true,
- reference: '瀹屾暣',
- value: '瀹屾暣',
- testTime: '2025-12-04 16:15:00',
- doctor: '寮犵梾鐞嗗笀'
- }
- ]
+ // 闄勪欢鏁版嵁
+ attachments: [],
+ attachmentFileList: [],
+ // 闄勪欢鐩稿叧閰嶇疆
+ attachmentLimit: 10,
+ attachmentAccept:
+ ".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt",
+ // 缂栬緫瀵硅瘽妗�
+ editDialogVisible: false,
+ currentRecord: {},
+ currentEditIndex: -1,
+ // 鏂囦欢棰勮鐩稿叧
+ filePreviewVisible: false,
+ currentPreviewFile: null,
+ filePreviewTitle: ""
};
},
+ computed: {
+ // 褰撳墠鐢ㄦ埛淇℃伅
+ currentUser() {
+ return JSON.parse(sessionStorage.getItem("user") || "{}");
+ },
+ // 涓嶅畬鏁寸殑璁板綍鏁伴噺
+ incompleteRecords() {
+ if (!this.procurementData.serviceDonationwitnessorgans) return 0;
+ return this.procurementData.serviceDonationwitnessorgans.filter(
+ record =>
+ !record.organStartTime ||
+ !record.organgettime ||
+ !record.gainhospitalno ||
+ !record.organgetdoct
+ ).length;
+ },
+ // 鍞竴鍖婚櫌鏁伴噺
+ uniqueHospitals() {
+ if (!this.procurementData.serviceDonationwitnessorgans) return 0;
+ const hospitals = this.procurementData.serviceDonationwitnessorgans
+ .map(record => record.gainhospitalno)
+ .filter(Boolean);
+ return new Set(hospitals).size;
+ },
+ // 鑾峰彇鍣ㄥ畼瀛楀吀
+ organDict() {
+ return this.dict.type.sys_Organ || [];
+ }
+ },
+ watch: {
+ // 鐩戝惉闄勪欢鏁版嵁鍙樺寲
+ attachments: {
+ handler(newAttachments) {
+ this.attachmentFileList = newAttachments.map(item => ({
+ uid: item.id || Math.random(),
+ name: item.fileName,
+ fileSize: item.fileSize,
+ url: item.path || item.fileUrl,
+ uploadTime: item.uploadTime,
+ status: "success"
+ }));
+ },
+ deep: true
+ }
+ },
+ created() {
+ this.caseId = this.infoid;
+
+ this.initData();
+ },
methods: {
- getStatusText() {
- const status = this.stageData.status;
- return status === 'completed' ? '宸插畬鎴�' :
- status === 'in_progress' ? '杩涜涓�' : '鏈紑濮�';
+ // 鏍规嵁瀛楀吀value鑾峰彇label
+ getOrganLabel(organValue) {
+ const dictItem = this.organDict.find(item => item.value === organValue);
+ return dictItem ? dictItem.label : organValue;
},
- getAlertType() {
- const status = this.stageData.status;
- return status === 'completed' ? 'success' :
- status === 'in_progress' ? 'warning' : 'info';
- },
- getAlertDescription() {
- const status = this.stageData.status;
- if (status === 'completed') {
- return '鍣ㄥ畼鑾峰彇鎵嬫湳宸插畬鎴愶紝鎵�鏈夊櫒瀹樺潎宸叉垚鍔熻幏鍙栧苟淇濆瓨';
- } else if (status === 'in_progress') {
- return '鍣ㄥ畼鑾峰彇鎵嬫湳杩涜涓紝璇峰瘑鍒囧叧娉ㄦ墜鏈繘灞�';
+
+ // 鍒濆鍖栨暟鎹�
+ initData() {
+ const id = null;
+ const infoid = this.infoid;
+
+ if (!infoid) {
+ this.$message.error("缂哄皯蹇呰鐨勮矾鐢卞弬鏁� infoid");
+ this.$router.back();
+ return;
}
- return '绛夊緟寮�濮嬪櫒瀹樿幏鍙栨墜鏈�';
- },
- getProcurementStatusTag(status) {
- const map = {
- '宸茶幏鍙�': 'success',
- '鑾峰彇涓�': 'warning',
- '寰呰幏鍙�': 'info'
- };
- return map[status] || 'info';
- },
- getSurvivalTimeType() {
- return this.preservationDetails.survivalTime.includes('灏忔椂') ? 'success' : 'danger';
- },
- handleStartProcurement() {
- this.$confirm('纭寮�濮嬪櫒瀹樿幏鍙栨墜鏈悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- this.$message.success('鍣ㄥ畼鑾峰彇鎵嬫湳宸插紑濮�');
- });
- },
- handleRecordProcurement(row) {
- this.$prompt('璇疯緭鍏ュ櫒瀹橀噸閲�(g)', '璁板綍鍣ㄥ畼鑾峰彇', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- inputPattern: /^\d+$/,
- inputErrorMessage: '璇疯緭鍏ユ湁鏁堢殑閲嶉噺鏁板瓧'
- }).then(({ value }) => {
- row.status = '宸茶幏鍙�';
- row.procurementTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
- row.weight = parseInt(value);
- row.qualityScore = 4.5;
- row.perfusionStatus = true;
- this.procurementStats.actual++;
- this.procurementStats.successRate = Math.round(
- (this.procurementStats.actual / this.procurementStats.planned) * 100
+ this.form.infoid = infoid;
+ // this.generateDonorNo();
+
+ if (infoid) {
+ this.getDetail(infoid);
+ }
+
+ 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);
+ // },
+ // 鑾峰彇璇︽儏
+ async getDetail(infoid) {
+ this.loading = true;
+ try {
+ const response = await witnessList({ infoid });
+ if (
+ response.code === 200 &&
+ response.data &&
+ response.data.length > 0
+ ) {
+ const data = response.data[0];
+ if (!data.witnessState || data.witnessState == 1) {
+ data.witnessState = "2";
+ }
+
+ // 濉厖琛ㄥ崟鏁版嵁
+ Object.assign(this.form, data);
+
+ // 鍒濆鍖栭檮浠�
+ if (this.form.deathjudgeannex) {
+ this.form.attachments = JSON.parse(this.form.deathjudgeannex);
+ this.attachments = Array.isArray(this.form.attachments)
+ ? [...this.form.attachments]
+ : [];
+ }
+
+ // 澶勭悊鎹愮尞鍣ㄥ畼瀛楁
+ if (data.organdonation) {
+ const organArray = Array.isArray(data.organdonation)
+ ? data.organdonation
+ : (data.organdonation || "").split(",").filter(item => item);
+ this.selectedOrgans = organArray;
+ this.form.organdonationOther = data.organdonationOther || "";
+ }
+
+ // 澶勭悊鍣ㄥ畼鑾峰彇璁板綍
+ if (data.serviceDonationwitnessorgans) {
+ this.procurementData.serviceDonationwitnessorgans = Array.isArray(
+ data.serviceDonationwitnessorgans
+ )
+ ? data.serviceDonationwitnessorgans
+ : [];
+ }
+
+ this.$message.success("鏁版嵁鍔犺浇鎴愬姛");
+ } else {
+ this.$message.warning("鏈壘鍒板搴旂殑鍣ㄥ畼鑾峰彇鏁版嵁");
+ }
+ } catch (error) {
+ console.error("鑾峰彇鍣ㄥ畼鑾峰彇璇︽儏澶辫触:", error);
+ this.$message.error("鑾峰彇璇︽儏澶辫触");
+ } finally {
+ this.loading = false;
+ }
+ },
+ // 鑾峰彇鍖婚櫌鏁版嵁
+ async getHospitalData() {
+ try {
+ // TODO: 鏇挎崲涓哄疄闄呯殑鍖婚櫌鍒楄〃鎺ュ彛
+ // 鏆傛椂浣跨敤妯℃嫙鏁版嵁
+ this.hospitalList = [
+ { hospitalNo: "H001", hospitalName: "鍖椾含鍗忓拰鍖婚櫌" },
+ { hospitalNo: "H002", hospitalName: "涓婃捣鍗庡北鍖婚櫌" },
+ { hospitalNo: "H003", hospitalName: "骞垮窞涓北鍖婚櫌" },
+ { hospitalNo: "H004", hospitalName: "姝︽眽鍚屾祹鍖婚櫌" },
+ { hospitalNo: "H005", hospitalName: "鎴愰兘鍗庤タ鍖婚櫌" }
+ ];
+ } catch (error) {
+ console.error("鑾峰彇鍖婚櫌鏁版嵁澶辫触:", error);
+ this.$message.error("鑾峰彇鍖婚櫌鏁版嵁澶辫触");
+ }
+ },
+ // 鍣ㄥ畼閫夋嫨鐘舵�佸彉鍖�
+ handleOrganSelectionChange(selectedValues) {
+ if (!this.procurementData.serviceDonationwitnessorgans) {
+ this.procurementData.serviceDonationwitnessorgans = [];
+ }
+
+ const currentOrganValues = this.procurementData.serviceDonationwitnessorgans.map(
+ item => item.organno
+ );
+
+ // 澶勭悊浜掓枼閫昏緫
+ this.handleExclusiveSelections(selectedValues);
+
+ // 鏇存柊鎹愮尞鍣ㄥ畼瀛楁
+ this.form.organdonation = selectedValues.join(",");
+
+ // 鏂板閫夋嫨鐨勫櫒瀹�
+ selectedValues.forEach(organValue => {
+ if (!currentOrganValues.includes(organValue)) {
+ this.createOrganRecord(organValue);
+ }
+ });
+
+ // 绉婚櫎鍙栨秷閫夋嫨鐨勫櫒瀹�
+ this.procurementData.serviceDonationwitnessorgans = this.procurementData.serviceDonationwitnessorgans.filter(
+ record => {
+ if (selectedValues.includes(record.organno)) {
+ return true;
+ } else {
+ if (record.id) {
+ this.$confirm(
+ "鍒犻櫎鍣ㄥ畼鑾峰彇鏁版嵁鍚庡皢鏃犳硶鎭㈠锛屾偍纭鍒犻櫎璇ユ潯璁板綍鍚楋紵",
+ "鎻愮ず",
+ {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ }
+ )
+ .then(() => {
+ this.procurementData.serviceDonationwitnessorgans = this.procurementData.serviceDonationwitnessorgans.filter(
+ r => r.organno !== record.organno
+ );
+ this.$message.success("鍒犻櫎鎴愬姛");
+ })
+ .catch(() => {
+ this.selectedOrgans.push(record.organno);
+ });
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ );
+ },
+
+ // 澶勭悊浜掓枼閫夋嫨
+ handleExclusiveSelections(selectedValues) {
+ // 濡傛灉閫夋嫨浜�"鍙岃偩"(鍋囪瀛楀吀鍊间负C64)锛岃嚜鍔ㄥ彇娑堝崟鐙殑"宸﹁偩"(C64L)鍜�"鍙宠偩"(C64R)閫夋嫨
+ if (selectedValues.includes("C64")) {
+ this.selectedOrgans = selectedValues.filter(
+ item => item !== "C64L" && item !== "C64R"
);
- this.procurementStats.qualityRating = 4.2;
+ }
+ // 濡傛灉閫夋嫨浜�"宸﹁偩"鎴�"鍙宠偩"锛屽彇娑�"鍙岃偩"閫夋嫨
+ else if (
+ selectedValues.includes("C64L") ||
+ selectedValues.includes("C64R")
+ ) {
+ this.selectedOrgans = selectedValues.filter(item => item !== "C64");
+ }
- this.$message.success(`${row.organName}鑾峰彇璁板綍宸蹭繚瀛榒);
+ // 濡傛灉閫夋嫨浜�"鍏ㄨ偤"(鍋囪瀛楀吀鍊间负C34)锛岃嚜鍔ㄥ彇娑堝崟鐙殑"宸﹁偤"(C34L)鍜�"鍙宠偤"(C34R)閫夋嫨
+ if (selectedValues.includes("C34")) {
+ this.selectedOrgans = selectedValues.filter(
+ item => item !== "C34L" && item !== "C34R"
+ );
+ }
+ // 濡傛灉閫夋嫨浜�"宸﹁偤"鎴�"鍙宠偤"锛屽彇娑�"鍏ㄨ偤"閫夋嫨
+ else if (
+ selectedValues.includes("C34L") ||
+ selectedValues.includes("C34R")
+ ) {
+ this.selectedOrgans = selectedValues.filter(item => item !== "C34");
+ }
+ },
+
+ // 鍒涘缓鍣ㄥ畼璁板綍
+ createOrganRecord(organValue) {
+ const organName = this.getOrganLabel(organValue);
+
+ this.procurementData.serviceDonationwitnessorgans.push({
+ id: null,
+ organname: organName,
+ organno: organValue,
+ organStartTime: "",
+ organgettime: "",
+ gainhospitalno: "",
+ gainhospitalname: "",
+ organgetdoct: "",
+ assistant: "",
+ procurementNurse: "",
+ operatingRoomNurse: "",
+ anesthesiologist: "",
+ organstate: "1",
+ notgetreason: ""
});
},
- handleViewOrgan(row) {
- this.$message.info(`鏌ョ湅${row.organName}鐨勮缁嗕俊鎭痐);
+
+ // 鍖婚櫌閫夋嫨鍙樺寲
+ handleHospitalChange(row, hospitalNo) {
+ const hospital = this.hospitalList.find(
+ item => item.hospitalNo === hospitalNo
+ );
+ if (hospital) {
+ row.gainhospitalname = hospital.hospitalName;
+ }
},
- handleCompleteProcurement() {
- this.$confirm('纭瀹屾垚鎵�鏈夊櫒瀹樿幏鍙栧悧锛�', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'success'
- }).then(() => {
- this.$message.success('鍣ㄥ畼鑾峰彇闃舵宸插畬鎴�');
+ // 缂栬緫鑾峰彇璁板綍
+ handleEditProcurement(row) {
+ const index = this.procurementData.serviceDonationwitnessorgans.findIndex(
+ item => item.organno === row.organno
+ );
+ if (index !== -1) {
+ this.currentRecord = { ...row };
+ this.currentEditIndex = index;
+ this.editDialogVisible = true;
+ }
+ },
+ // 纭缂栬緫
+ handleEditConfirm() {
+ if (this.currentEditIndex !== -1) {
+ this.procurementData.serviceDonationwitnessorgans[
+ this.currentEditIndex
+ ] = {
+ ...this.currentRecord
+ };
+ this.$message.success("鑾峰彇璁板綍鏇存柊鎴愬姛");
+ this.editDialogVisible = false;
+ }
+ },
+ // 鍣ㄥ畼琛屾牱寮�
+ getOrganRowClassName({ row }) {
+ if (
+ !row.organStartTime ||
+ !row.organgettime ||
+ !row.gainhospitalno ||
+ !row.organgetdoct
+ ) {
+ return "warning-row";
+ }
+ return "";
+ },
+ // 淇濆瓨鍩烘湰淇℃伅
+ async handleSave() {
+ this.$refs.form.validate(async valid => {
+ if (valid) {
+ this.saveLoading = true;
+ try {
+ const saveData = {
+ ...this.form,
+ deathjudgeannex: JSON.stringify(this.attachments),
+ organdonation: this.selectedOrgans.join(","),
+ serviceDonationwitnessorganList:
+ this.procurementData.serviceDonationwitnessorgans || []
+ };
+
+ const apiMethod = this.form.id ? witnessedit : witnessadd;
+ const response = await apiMethod(saveData);
+
+ if (response.code === 200) {
+ this.$message.success("淇濆瓨鎴愬姛");
+ if (!this.form.id && response.data && response.data.id) {
+ this.form.id = response.data.id;
+ this.$router.replace({
+ query: { ...this.$route.query, id: this.form.id }
+ });
+ }
+ } else {
+ this.$message.error("淇濆瓨澶辫触锛�" + (response.msg || "鏈煡閿欒"));
+ }
+ } catch (error) {
+ console.error("淇濆瓨澶辫触:", error);
+ this.$message.error("淇濆瓨澶辫触");
+ } finally {
+ this.saveLoading = false;
+ }
+ }
});
},
- handleGenerateReport() {
- this.$message.info('鐢熸垚鍣ㄥ畼鑾峰彇鎶ュ憡');
+ // 淇濆瓨鑾峰彇璁板綍
+ async handleSaveProcurement() {
+ if (!this.form.id) {
+ this.$message.warning("璇峰厛淇濆瓨鍩烘湰淇℃伅");
+ return;
+ }
+
+ this.saveLoading = true;
+ try {
+ const saveData = {
+ ...this.form,
+ attachments: this.attachments,
+ organdonation: this.selectedOrgans.join(","),
+ serviceDonationwitnessorgans:
+ this.procurementData.serviceDonationwitnessorgans || []
+ };
+
+ const response = await witnessedit(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;
+ }
},
- handleUploadEvidence() {
- this.$message.info('涓婁紶鎵嬫湳璇佹嵁鏉愭枡');
+ // 纭瀹屾垚鑾峰彇
+ async handleConfirmProcurement() {
+ if (this.incompleteRecords > 0) {
+ this.$message.warning("璇峰厛瀹屽杽鎵�鏈夎幏鍙栬褰曠殑淇℃伅");
+ return;
+ }
+
+ this.$confirm("纭瀹屾垚鍣ㄥ畼鑾峰彇鍚楋紵瀹屾垚鍚庡皢鏃犳硶淇敼鑾峰彇淇℃伅銆�", "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(async () => {
+ this.confirmLoading = true;
+ this.form.witnessState = "3";
+ this.form.operationendtime =
+ this.form.operationendtime ||
+ new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19);
+
+ try {
+ const saveData = {
+ ...this.form,
+ attachments: this.attachments,
+ organdonation: this.selectedOrgans.join(","),
+ serviceDonationwitnessorgans:
+ this.procurementData.serviceDonationwitnessorgans || []
+ };
+
+ const response = await witnessedit(saveData);
+
+ if (response.code === 200) {
+ this.$message.success("鍣ㄥ畼鑾峰彇宸插畬鎴�");
+ } else {
+ this.$message.error(
+ "纭鑾峰彇澶辫触锛�" + (response.msg || "鏈煡閿欒")
+ );
+ this.form.witnessState = "2";
+ this.form.operationendtime = "";
+ }
+ } catch (error) {
+ console.error("纭鑾峰彇澶辫触:", error);
+ this.$message.error("纭鑾峰彇澶辫触");
+ this.form.witnessState = "2";
+ this.form.operationendtime = "";
+ } finally {
+ this.confirmLoading = false;
+ }
+ })
+ .catch(() => {});
+ },
+ // 纭鑾峰彇鎸夐挳鍒悕
+ handleProcure() {
+ this.handleConfirmProcurement();
+ },
+
+ // 闄勪欢鐩稿叧鏂规硶
+ /** 闄勪欢鍙樺寲澶勭悊 */
+ handleAttachmentChange(fileList) {
+ this.attachmentFileList = fileList;
+ },
+
+ /** 闄勪欢绉婚櫎澶勭悊 */
+ handleAttachmentRemove(file) {
+ if (file.url) {
+ const index = this.attachments.findIndex(
+ item => item.path === file.url || item.fileUrl === file.url
+ );
+ if (index > -1) {
+ this.attachments.splice(index, 1);
+ this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+ }
+ }
+ },
+
+ /** 涓婁紶鎴愬姛澶勭悊 */
+ handleUploadSuccess({ file, fileList, response }) {
+ if (response.code === 200) {
+ const attachmentObj = {
+ fileName: file.name,
+ path: response.fileUrl || file.url,
+ fileUrl: response.fileUrl || file.url,
+ fileType: this.getFileExtension(file.name),
+ fileSize: file.size,
+ uploadTime: dayjs().format("YYYY-MM-DD HH:mm:ss")
+ };
+
+ if (!Array.isArray(this.attachments)) {
+ this.attachments = [];
+ }
+
+ this.attachments.push(attachmentObj);
+ this.attachmentFileList = fileList;
+ this.$message.success("鏂囦欢涓婁紶鎴愬姛");
+ }
+ },
+
+ /** 涓婁紶閿欒澶勭悊 */
+ handleUploadError({ file, fileList, error }) {
+ console.error("闄勪欢涓婁紶澶辫触:", error);
+ this.$message.error("鏂囦欢涓婁紶澶辫触锛岃閲嶈瘯");
+ },
+
+ /** 鎵嬪姩鍒犻櫎闄勪欢 */
+ handleRemoveAttachment(index) {
+ this.attachments.splice(index, 1);
+ this.attachmentFileList.splice(index, 1);
+ this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+ },
+
+ /** 鏂囦欢棰勮 */
+ handlePreview(file) {
+ this.currentPreviewFile = {
+ fileName: file.fileName,
+ fileUrl: file.path || file.fileUrl,
+ fileType: this.getFileType(file.fileName)
+ };
+ this.filePreviewTitle = file.fileName;
+ this.filePreviewVisible = true;
+ },
+
+ /** 鏂囦欢涓嬭浇 */
+ handleDownload(file) {
+ const fileUrl = file.path || file.fileUrl;
+ const fileName = file.fileName;
+
+ if (fileUrl) {
+ const link = document.createElement("a");
+ link.href = fileUrl;
+ link.download = fileName;
+ link.style.display = "none";
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ this.$message.success("寮�濮嬩笅杞芥枃浠�");
+ } else {
+ this.$message.warning("鏂囦欢璺緞涓嶅瓨鍦紝鏃犳硶涓嬭浇");
+ }
+ },
+
+ /** 鑾峰彇鏂囦欢绫诲瀷 */
+ getFileType(fileName) {
+ if (!fileName) return "other";
+ const extension = fileName
+ .split(".")
+ .pop()
+ .toLowerCase();
+ const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
+ const pdfTypes = ["pdf"];
+ const officeTypes = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"];
+ if (imageTypes.includes(extension)) return "image";
+ if (pdfTypes.includes(extension)) return "pdf";
+ if (officeTypes.includes(extension)) return "office";
+ return "other";
+ },
+
+ /** 鑾峰彇鏂囦欢鍥炬爣棰滆壊 */
+ getFileIconColor(fileName) {
+ const type = this.getFileType(fileName);
+ const colorMap = {
+ image: "#67C23A",
+ pdf: "#F56C6C",
+ office: "#409EFF",
+ other: "#909399"
+ };
+ return colorMap[type] || "#909399";
+ },
+
+ /** 鑾峰彇鏂囦欢鏍囩绫诲瀷 */
+ getFileTagType(fileName) {
+ const type = this.getFileType(fileName);
+ const typeMap = {
+ image: "success",
+ pdf: "danger",
+ office: "primary",
+ other: "info"
+ };
+ return typeMap[type] || "info";
+ },
+
+ /** 鑾峰彇鏂囦欢绫诲瀷鏂囨湰 */
+ getFileTypeText(fileName) {
+ const type = this.getFileType(fileName);
+ const textMap = {
+ image: "鍥剧墖",
+ pdf: "PDF",
+ office: "鏂囨。",
+ other: "鍏朵粬"
+ };
+ return textMap[type] || "鏈煡";
+ },
+
+ /** 妫�鏌ユ槸鍚﹀彲棰勮 */
+ isPreviewable(fileName) {
+ const type = this.getFileType(fileName);
+ return ["image", "pdf"].includes(type);
+ },
+
+ /** 鑾峰彇鏂囦欢鎵╁睍鍚� */
+ getFileExtension(filename) {
+ return filename
+ .split(".")
+ .pop()
+ .toLowerCase();
+ },
+
+ /** 鏍煎紡鍖栨枃浠跺ぇ灏� */
+ formatFileSize(bytes) {
+ if (!bytes || bytes === 0) return "0 B";
+ const k = 1024;
+ const sizes = ["B", "KB", "MB", "GB"];
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
+ },
+
+ /** 鏃ユ湡鏃堕棿鏍煎紡鍖� */
+ formatDateTime(dateTime) {
+ if (!dateTime) return "";
+ try {
+ const date = new Date(dateTime);
+ if (isNaN(date.getTime())) return dateTime;
+ const year = date.getFullYear();
+ const month = String(date.getMonth() + 1).padStart(2, "0");
+ const day = String(date.getDate()).padStart(2, "0");
+ const hours = String(date.getHours()).padStart(2, "0");
+ const minutes = String(date.getMinutes()).padStart(2, "0");
+ return `${year}-${month}-${day} ${hours}:${minutes}`;
+ } catch (error) {
+ return dateTime;
+ }
}
}
};
</script>
<style scoped>
-.procurement-stats, .preservation-info {
- padding: 10px 0;
-}
-
-.stat-item, .info-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 15px;
- padding: 8px 0;
- border-bottom: 1px solid #f0f0f0;
-}
-
-.stat-item .label, .info-item .label {
- color: #606266;
- font-weight: 500;
- min-width: 100px;
-}
-
-.stat-item .value {
- font-weight: 600;
- color: #409EFF;
-}
-
-.surgery-record {
+.organ-procurement-detail {
padding: 20px;
+ background-color: #f5f7fa;
+ min-height: 100vh;
}
-.record-images {
- margin-top: 10px;
+.detail-card {
+ margin-bottom: 20px;
+ border-radius: 8px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+ border: 1px solid #e4e7ed;
}
-.image-header {
+.procurement-card {
+ margin-bottom: 20px;
+ border-radius: 8px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+ border: 1px solid #e4e7ed;
+}
+
+.attachment-card {
+ margin-bottom: 20px;
+ border-radius: 8px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+ border: 1px solid #e4e7ed;
+ padding: 20px;
+ background: #fafafa;
+}
+
+.attachment-header {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 16px;
+ padding-bottom: 8px;
+ border-bottom: 1px solid #ebeef5;
+}
+
+.attachment-title {
font-weight: 600;
color: #303133;
}
-.quality-report {
- padding: 10px 0;
+.attachment-tip {
+ font-size: 12px;
+ color: #909399;
+ margin-left: auto;
+}
+
+.attachment-list {
+ margin-top: 16px;
+}
+
+.list-title {
+ font-weight: bold;
+ margin-bottom: 12px;
+ color: #303133;
+ font-size: 14px;
+}
+
+.file-name {
+ font-size: 13px;
+ margin-left: 8px;
+}
+
+.detail-title {
+ font-size: 18px;
+ font-weight: 600;
+ color: #303133;
+ line-height: 1.4;
+}
+
+/* 缁熻淇℃伅鏍峰紡 */
+.procurement-stats {
+ margin-top: 20px;
+ padding: 15px;
+ background: linear-gradient(135deg, #a6b2e7 0%, #8a66ad 100%);
+ border-radius: 8px;
+ color: white;
+}
+
+.stat-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 10px;
+ text-align: center;
+}
+
+.stat-label {
+ font-size: 12px;
+ opacity: 0.9;
+ margin-bottom: 5px;
+ color: rgba(255, 255, 255, 0.9);
+}
+
+.stat-value {
+ font-size: 18px;
+ font-weight: bold;
+ color: white;
+}
+
+/* 绌虹姸鎬佹牱寮� */
+.empty-procurement {
+ text-align: center;
+ padding: 40px 0;
+ color: #909399;
+ background: #fafafa;
+ border-radius: 4px;
+ margin: 20px 0;
+}
+
+/* 瀵硅瘽妗嗗簳閮ㄦ寜閽� */
+.dialog-footer {
+ margin-top: 20px;
+ text-align: center;
+ padding-top: 20px;
+ border-top: 1px solid #e4e7ed;
+}
+
+.dialog-footer .el-button {
+ margin: 0 10px;
+ min-width: 120px;
+}
+
+/* 琛ㄦ牸琛屾牱寮� */
+:deep(.warning-row) {
+ background-color: #fff7e6 !important;
+}
+
+:deep(.warning-row:hover) {
+ background-color: #ffecc2 !important;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 768px) {
+ .organ-procurement-detail {
+ padding: 10px;
+ }
+
+ .procurement-stats .el-col {
+ margin-bottom: 10px;
+ }
}
</style>
diff --git a/src/views/business/course/components/OrganUtilizationStage.vue b/src/views/business/course/components/OrganUtilizationStage.vue
index e3c02d8..233eabe 100644
--- a/src/views/business/course/components/OrganUtilizationStage.vue
+++ b/src/views/business/course/components/OrganUtilizationStage.vue
@@ -1,812 +1,1851 @@
<template>
- <base-stage :stage-data="stageData" :case-info="caseInfo">
- <!-- 澶撮儴璀﹀憡淇℃伅 -->
- <template #header>
- <el-alert
- :title="`鍣ㄥ畼鍒╃敤 - ${getStatusText()}`"
- :type="getAlertType()"
- :description="getAlertDescription()"
- show-icon
- :closable="false"
- />
- </template>
+ <div class="organ-utilization-detail">
+ <el-form :model="form" ref="form" :rules="rules" label-width="120px">
+ <!-- 鍩烘湰淇℃伅 -->
+ <el-card class="detail-card">
+ <div slot="header" class="clearfix">
+ <span class="detail-title">鍣ㄥ畼鍒╃敤鍩烘湰淇℃伅</span>
- <!-- 缁熻姒傝琛� -->
- <el-row :gutter="20" style="margin-top: 20px;">
- <el-col :span="6">
- <el-card>
- <div slot="header" class="card-header">
- <span>鍒╃敤姒傚喌</span>
- </div>
- <div class="utilization-overview">
- <div class="overview-item">
- <div class="overview-icon" style="color: #67C23A;">
- <i class="el-icon-success"></i>
- </div>
- <div class="overview-content">
- <div class="value">{{ utilizationStats.transplanted }}</div>
- <div class="label">宸茬Щ妞嶅櫒瀹�</div>
- </div>
- </div>
- <div class="overview-item">
- <div class="overview-icon" style="color: #E6A23C;">
- <i class="el-icon-time"></i>
- </div>
- <div class="overview-content">
- <div class="value">{{ utilizationStats.inProgress }}</div>
- <div class="label">绉绘涓�</div>
- </div>
- </div>
- <div class="overview-item">
- <div class="overview-icon" style="color: #F56C6C;">
- <i class="el-icon-warning"></i>
- </div>
- <div class="overview-content">
- <div class="value">{{ utilizationStats.failed }}</div>
- <div class="label">绉绘澶辫触</div>
- </div>
- </div>
- </div>
- </el-card>
- </el-col>
+ </div>
- <el-col :span="6">
- <el-card>
- <div slot="header" class="card-header">
- <span>鎴愬姛鐜囩粺璁�</span>
- </div>
- <div class="success-stats">
- <div class="success-item">
- <span class="label">绉绘鎴愬姛鐜�:</span>
- <el-progress
- :percentage="utilizationStats.successRate"
- :status="utilizationStats.successRate > 85 ? 'success' : 'warning'"
+ <el-row :gutter="20">
+ <el-col :span="6">
+ <el-form-item label="璐熻矗浜�" prop="responsibleusername">
+ <el-input
+ v-model="form.responsibleusername"
+ placeholder="璇疯緭鍏ヨ礋璐d汉濮撳悕"
/>
- </div>
- <div class="success-item">
- <span class="label">鍣ㄥ畼鍒╃敤鐜�:</span>
- <el-progress
- :percentage="utilizationStats.utilizationRate"
- status="success"
+ </el-form-item>
+ </el-col>
+ <el-col :span="6">
+ <el-form-item label="鍗忚皟鍛樹竴" prop="coordinatedusernameo">
+ <el-input
+ v-model="form.coordinatedusernameo"
+ placeholder="璇疯緭鍏ュ崗璋冨憳涓�濮撳悕"
/>
- </div>
- <div class="success-item">
- <span class="label">鎮h�呭瓨娲荤巼:</span>
- <el-progress
- :percentage="utilizationStats.survivalRate"
- status="success"
+ </el-form-item>
+ </el-col>
+ <el-col :span="6">
+ <el-form-item label="鍗忚皟鍛樹簩" prop="coordinatedusernamet">
+ <el-input
+ v-model="form.coordinatedusernamet"
+ placeholder="璇疯緭鍏ュ崗璋冨憳浜屽鍚�"
/>
- </div>
- </div>
- </el-card>
- </el-col>
-
- <el-col :span="6">
- <el-card>
- <div slot="header" class="card-header">
- <span>鏃堕棿璺熻釜</span>
- </div>
- <div class="time-tracking">
- <div class="time-item">
- <span class="label">鑾峰彇鍒扮Щ妞�:</span>
- <span class="value">{{ timeTracking.procurementToTransplant }}</span>
- </div>
- <div class="time-item">
- <span class="label">鍐风己琛�鏃堕棿:</span>
- <span class="value">{{ timeTracking.coldIschemiaTime }}</span>
- </div>
- <div class="time-item">
- <span class="label">鎵嬫湳鏃堕暱:</span>
- <span class="value">{{ timeTracking.surgeryDuration }}</span>
- </div>
- <div class="time-item">
- <span class="label">ICU鍋滅暀:</span>
- <span class="value">{{ timeTracking.icuStay }}</span>
- </div>
- </div>
- </el-card>
- </el-col>
-
- <el-col :span="6">
- <el-card>
- <div slot="header" class="card-header">
- <span>璐ㄩ噺璇勪及</span>
- </div>
- <div class="quality-assessment">
- <div class="quality-item">
- <span class="label">鍣ㄥ畼璐ㄩ噺璇勫垎:</span>
- <el-rate
- v-model="qualityStats.organQuality"
- disabled
- show-score
- text-color="#ff9900"
- score-template="{value}"
+ </el-form-item>
+ </el-col>
+ <el-col :span="6">
+ <el-form-item label="瀹屾垚鏃堕棿" prop="completetime">
+ <el-date-picker
+ v-model="form.completetime"
+ type="datetime"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ style="width: 100%"
/>
- </div>
- <div class="quality-item">
- <span class="label">鎵嬫湳璐ㄩ噺:</span>
- <el-rate
- v-model="qualityStats.surgeryQuality"
- disabled
- show-score
- text-color="#ff9900"
- score-template="{value}"
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鐧昏浜�" prop="createBy">
+ <el-input v-model="form.createBy" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鐧昏鏃堕棿" prop="createTime">
+ <el-date-picker
+ v-model="form.createTime"
+ type="datetime"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ style="width: 100%"
/>
- </div>
- <div class="quality-item">
- <span class="label">闅忚瀹屾垚鐜�:</span>
- <el-progress
- :percentage="qualityStats.followupCompletionRate"
- status="success"
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-card>
+ <el-card class="detail-card">
+ <div slot="header" class="clearfix">
+ <span class="detail-title">閬椾綋鎹愮尞淇℃伅</span>
+ </div>
+ <el-row :gutter="20">
+ <el-col :span="6">
+ <el-form-item align="left" label="閬椾綋鎹愮尞" prop="isbodydonation">
+ <el-radio-group v-model="form.isbodydonation">
+ <el-radio
+ v-for="dict in dict.type.sys_0_1 || []"
+ :key="dict.value"
+ :label="dict.value"
+ >{{ dict.label }}</el-radio
+ >
+ </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="璇疯緭鍏ユ帴鏀跺崟浣�"
/>
- </div>
- </div>
- </el-card>
- </el-col>
- </el-row>
-
- <!-- 鏁版嵁鍙鍖栭儴鍒� -->
- <el-row :gutter="20" style="margin-top: 20px;">
- <!-- 鍣ㄥ畼鍒╃敤鍒嗗竷鍥� -->
- <el-col :span="12">
- <el-card>
- <div slot="header" class="card-header">
- <span>鍣ㄥ畼鍒╃敤鍒嗗竷</span>
- <el-radio-group v-model="chartView" size="small" @change="updateCharts">
- <el-radio-button label="bar">鏌辩姸鍥�</el-radio-button>
- <el-radio-button label="pie">楗煎浘</el-radio-button>
- </el-radio-group>
- </div>
- <div class="chart-container">
- <div ref="organDistributionChart" style="width: 100%; height: 300px;"></div>
- </div>
- </el-card>
- </el-col>
-
- <!-- 鎴愬姛鐜囪秼鍔垮浘 -->
- <el-col :span="12">
- <el-card>
- <div slot="header" class="card-header">
- <span>绉绘鎴愬姛鐜囪秼鍔�</span>
- </div>
- <div class="chart-container">
- <div ref="successTrendChart" style="width: 100%; height: 300px;"></div>
- </div>
- </el-card>
- </el-col>
- </el-row>
-
- <el-row :gutter="20" style="margin-top: 20px;">
- <!-- 闅忚鏁版嵁缁熻 -->
- <el-col :span="12">
- <el-card>
- <div slot="header" class="card-header">
- <span>闅忚鏁版嵁缁熻</span>
- </div>
- <div class="chart-container">
- <div ref="followupStatsChart" style="width: 100%; height: 300px;"></div>
- </div>
- </el-card>
- </el-col>
-
- <!-- 骞跺彂鐥囧垎鏋� -->
- <el-col :span="12">
- <el-card>
- <div slot="header" class="card-header">
- <span>骞跺彂鐥囧垎鏋�</span>
- </div>
- <div class="chart-container">
- <div ref="complicationChart" style="width: 100%; height: 300px;"></div>
- </div>
- </el-card>
- </el-col>
- </el-row>
-
- <!-- 璇︾粏鏁版嵁琛ㄦ牸 -->
- <el-card style="margin-top: 20px;">
- <div slot="header" class="card-header">
- <span>鍣ㄥ畼鍒╃敤璇︽儏</span>
- <el-button type="primary" size="small" @click="exportData">
- 瀵煎嚭鏁版嵁
- </el-button>
+ </el-form-item>
+ </el-col>
+ <el-col :span="8" v-else>
+ <el-form-item align="left" label="鎺ユ敹瀹跺睘" prop="relationname">
+ <el-input
+ v-model="form.relationname"
+ placeholder="璇疯緭鍏ユ帴鏀跺灞�"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-card>
+ </el-form>
+ <!-- 鍣ㄥ畼鍒╃敤璁板綍閮ㄥ垎 - 鏁村悎鍙楄�呰鎯� -->
+ <el-card class="utilization-card">
+ <div slot="header" class="clearfix">
+ <span class="detail-title">鍣ㄥ畼鍒╃敤璁板綍</span>
+ <div style="float: right;">
+ <dict-tag
+ :options="dict.type.utilize_statue"
+ :value="form.completeState"
+ />
+ </div>
</div>
- <el-table :data="organUtilizationData" v-loading="loading" border>
- <el-table-column label="鍣ㄥ畼鍚嶇О" prop="organName" width="120" align="center" />
- <el-table-column label="绉绘鐘舵��" width="100" align="center">
- <template slot-scope="scope">
- <el-tag :type="getTransplantStatusTag(scope.row.status)">
- {{ scope.row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鍙椾綋淇℃伅" width="150">
- <template slot-scope="scope">
- <div>{{ scope.row.recipientName }}</div>
- <div style="font-size: 12px; color: #909399;">{{ scope.row.recipientAge }}宀�/{{ scope.row.recipientGender }}</div>
- </template>
- </el-table-column>
- <el-table-column label="绉绘鍖婚櫌" prop="hospital" min-width="180" />
- <el-table-column label="绉绘鏃堕棿" width="160" align="center">
- <template slot-scope="scope">
- {{ formatTime(scope.row.transplantTime) }}
- </template>
- </el-table-column>
- <el-table-column label="闅忚娆℃暟" width="100" align="center">
- <template slot-scope="scope">
- <el-tag :type="scope.row.followupCount > 0 ? 'success' : 'info'">
- {{ scope.row.followupCount }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="褰撳墠鐘舵��" width="120" align="center">
- <template slot-scope="scope">
- <el-tag :type="getRecipientStatusTag(scope.row.recipientStatus)">
- {{ scope.row.recipientStatus }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="150" align="center">
- <template slot-scope="scope">
- <el-button type="text" size="small" @click="handleViewDetails(scope.row)">
- 鏌ョ湅璇︽儏
- </el-button>
- <el-button type="text" size="small" @click="handleAddFollowup(scope.row)">
- 娣诲姞闅忚
- </el-button>
- </template>
- </el-table-column>
- </el-table>
+ <el-form
+ ref="utilizationForm"
+ :rules="utilizationRules"
+ :model="utilizationData"
+ label-position="right"
+ >
+ <el-row>
+ <el-col>
+ <el-form-item label-width="100px" label="绉绘鍣ㄥ畼">
+ <el-checkbox-group
+ v-model="selectedOrgans"
+ @change="handleOrganSelectionChange"
+ >
+ <el-checkbox
+ v-for="dict in dict.type.sys_Organ || []"
+ :key="dict.value"
+ :label="dict.value"
+ >
+ {{ dict.label }}
+ </el-checkbox>
+ </el-checkbox-group>
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <el-row>
+ <el-col>
+ <el-form-item>
+ <el-table
+ :data="utilizationData.serviceDonatecomporganList"
+ v-loading="loading"
+ border
+ style="width: 100%"
+ :row-class-name="getOrganRowClassName"
+ :expand-row-keys="expandedRows"
+ @expand-change="handleExpandChange"
+ row-key="organno"
+ >
+ <el-table-column type="expand" width="60">
+ <template slot-scope="scope">
+ <!-- 灞曞紑琛屽唴瀹� - 鍙楄�呰缁嗕俊鎭� -->
+ <div class="recipient-detail-expand">
+ <div class="recipient-header">
+ <span class="recipient-title">鍙楄�呰缁嗕俊鎭�</span>
+ <el-tag
+ v-if="scope.row.transplantstate === '1'"
+ type="success"
+ size="small"
+ >
+ 宸茬Щ妞�
+ </el-tag>
+ <el-tag
+ v-else-if="scope.row.transplantstate === '0'"
+ type="warning"
+ size="small"
+ >
+ 鏈Щ妞�
+ </el-tag>
+ <el-tag v-else type="info" size="small">
+ 绉绘涓�
+ </el-tag>
+ </div>
+
+ <el-form
+ :model="scope.row"
+ label-width="140px"
+ class="recipient-form"
+ >
+ <!-- 鍩烘湰淇℃伅閮ㄥ垎 -->
+ <div class="form-section">
+ <h4 class="section-title">鍩烘湰淇℃伅</h4>
+ <el-row :gutter="20">
+ <el-col :span="8">
+ <el-form-item label="鍙楄�呭鍚�">
+ <el-input
+ v-model="scope.row.name"
+ placeholder="璇疯緭鍏ュ彈鑰呭鍚�"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="鍑虹敓鏃ユ湡">
+ <el-date-picker
+ v-model="scope.row.birthday"
+ type="date"
+ value-format="yyyy-MM-dd"
+ placeholder="閫夋嫨鍑虹敓鏃ユ湡"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="鎬у埆">
+ <el-select
+ v-model="scope.row.sex"
+ placeholder="璇烽�夋嫨鎬у埆"
+ style="width: 100%"
+ >
+ <el-option label="鐢�" :value="0" />
+ <el-option label="濂�" :value="1" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <el-row :gutter="20">
+ <el-col :span="8">
+ <el-form-item label="骞撮緞">
+ <el-input
+ v-model="scope.row.age"
+ placeholder="骞撮緞"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="璇佷欢绫诲瀷">
+ <el-select
+ v-model="scope.row.idcardtype"
+ placeholder="璇烽�夋嫨璇佷欢绫诲瀷"
+ style="width: 100%"
+ >
+ <el-option label="韬唤璇�" :value="1" />
+ <el-option label="鎶ょ収" :value="2" />
+ <el-option label="鍐涘畼璇�" :value="3" />
+ <el-option label="鍏朵粬" :value="4" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="璇佷欢鍙风爜">
+ <el-input
+ v-model="scope.row.idcardno"
+ placeholder="璇佷欢鍙风爜"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </div>
+
+ <!-- 鑱旂郴淇℃伅閮ㄥ垎 -->
+ <div class="form-section">
+ <h4 class="section-title">鑱旂郴淇℃伅</h4>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="绉绘涓績鍚嶇О">
+ <el-input
+ v-model="scope.row.hospitalname"
+ placeholder="璇疯緭鍏ョЩ妞嶄腑蹇冨悕绉�"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鑱旂郴鐢佃瘽">
+ <el-input
+ v-model="scope.row.phone"
+ placeholder="鑱旂郴鐢佃瘽"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <el-row :gutter="20">
+ <el-col :span="24">
+ <el-form-item label="鐜颁綇鍦板潃">
+ <el-input
+ type="textarea"
+ :rows="2"
+ v-model="scope.row.residenceaddress"
+ placeholder="璇疯緭鍏ヨ缁嗗湴鍧�"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </div>
+
+ <!-- 绉绘淇℃伅閮ㄥ垎 -->
+ <div
+ class="form-section"
+ v-if="scope.row.transplantstate === '1'"
+ >
+ <h4 class="section-title">绉绘淇℃伅</h4>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="绉绘鏃堕棿">
+ <el-date-picker
+ v-model="scope.row.transplanttime"
+ type="datetime"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ placeholder="閫夋嫨绉绘鏃ユ湡"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="绉绘鍖荤敓">
+ <el-input
+ v-model="scope.row.transplantdoct"
+ placeholder="璇疯緭鍏ョЩ妞嶅尰鐢�"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </div>
+
+ <!-- 鏈Щ妞嶅師鍥� -->
+ <div
+ class="form-section"
+ v-if="scope.row.transplantstate === '0'"
+ >
+ <h4 class="section-title">鏈Щ妞嶄俊鎭�</h4>
+ <el-row :gutter="20">
+ <el-col :span="24">
+ <el-form-item label="鏈Щ妞嶅師鍥�">
+ <el-input
+ type="textarea"
+ :rows="3"
+ v-model="scope.row.abandonreason"
+ placeholder="璇疯緭鍏ユ湭绉绘鍘熷洜"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </div>
+ </el-form>
+ </div>
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="鍣ㄥ畼鍚嶇О"
+ align="center"
+ prop="organname"
+ >
+ <template slot-scope="scope">
+ <el-input
+ v-model="scope.row.organname"
+ placeholder="鍣ㄥ畼鍚嶇О"
+ :disabled="true"
+ />
+ </template>
+ </el-table-column>
+
+ <el-table-column label="绯荤粺缂栧彿" align="center" prop="caseNo">
+ <template slot-scope="scope">
+ <el-input
+ v-model="scope.row.caseNo"
+ placeholder="绯荤粺缂栧彿"
+ />
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="绉绘鍖婚櫌"
+ align="center"
+ width="260"
+ prop="hospitalno"
+ >
+ <template slot-scope="scope">
+ <el-select
+ v-model="scope.row.hospitalno"
+ placeholder="璇烽�夋嫨绉绘鍖婚櫌"
+ style="width: 100%"
+ @change="handleHospitalChange(scope.row, $event)"
+ >
+ <el-option
+ v-for="hospital in hospitalList"
+ :key="hospital.hospitalNo"
+ :label="hospital.hospitalName"
+ :value="hospital.hospitalNo"
+ />
+ </el-select>
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="绉绘鐘舵��"
+ align="center"
+ prop="transplantstate"
+ >
+ <template slot-scope="scope">
+ <el-select
+ v-model="scope.row.transplantstate"
+ placeholder="璇烽�夋嫨绉绘鐘舵��"
+ style="width: 100%"
+ @change="handleTransplantStatusChange(scope.row, $event)"
+ >
+ <el-option
+ v-for="dict in transplantStatusList"
+ :key="dict.value"
+ :label="dict.label"
+ :value="dict.value"
+ />
+ </el-select>
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="绉绘鏃堕棿"
+ align="center"
+ width="220"
+ prop="transplanttime"
+ >
+ <template slot-scope="scope">
+ <el-date-picker
+ clearable
+ size="small"
+ style="width: 100%"
+ v-model="scope.row.transplanttime"
+ type="datetime"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ placeholder="閫夋嫨绉绘鏃堕棿"
+ />
+ </template>
+ </el-table-column>
+
+ <el-table-column
+ label="绉绘鍖荤敓"
+ align="center"
+ prop="transplantdoct"
+ >
+ <template slot-scope="scope">
+ <el-input
+ v-model="scope.row.transplantdoct"
+ placeholder="鍖诲笀濮撳悕"
+ />
+ </template>
+ </el-table-column>
+
+ <el-table-column label="鍙楄�呭鍚�" align="center" prop="name">
+ <template slot-scope="scope">
+ <el-input v-model="scope.row.name" placeholder="鍙楄�呭鍚�" />
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <!-- 缁熻淇℃伅 -->
+
+ <div
+ v-if="
+ !utilizationData.serviceDonatecomporganList ||
+ utilizationData.serviceDonatecomporganList.length == 0
+ "
+ class="empty-utilization"
+ >
+ <el-empty description="鏆傛棤鍒╃敤璁板綍" :image-size="80">
+ <span>璇峰厛閫夋嫨瑕佸埄鐢ㄧ殑鍣ㄥ畼</span>
+ </el-empty>
+ </div>
+ </el-form>
</el-card>
- <!-- 琛屽姩鎸夐挳 -->
- <template #footer>
- <div class="action-buttons" style="margin-top: 20px; text-align: center;">
- <el-button type="primary" @click="handleGenerateReport">
- 鐢熸垚鍒╃敤鎶ュ憡
- </el-button>
- <el-button type="success" @click="handleCompleteUtilization">
- 瀹屾垚鍣ㄥ畼鍒╃敤
- </el-button>
- <el-button type="warning" @click="handleStatistics">
- 缁熻鏁版嵁鍒嗘瀽
- </el-button>
+ <!-- 闄勪欢绠$悊閮ㄥ垎 -->
+ <!-- 闄勪欢绠$悊閮ㄥ垎 - 浼樺寲涓哄畬鏁村姛鑳� -->
+ <el-card class="attachment-card">
+ <div class="attachment-header">
+ <i class="el-icon-paperclip"></i>
+ <span class="attachment-title">鐩稿叧闄勪欢</span>
+ <span class="attachment-tip"
+ >鏀寔涓婁紶鍣ㄥ畼鍒╃敤鐩稿叧鏂囦欢 (鏈�澶歿{ attachmentLimit }}涓�)</span
+ >
</div>
- </template>
- </base-stage>
+
+ <!-- 浣跨敤 UploadAttachment 缁勪欢 -->
+ <UploadAttachment
+ ref="uploadAttachment"
+ :file-list="attachmentFileList"
+ :limit="attachmentLimit"
+ :accept="attachmentAccept"
+ :multiple="true"
+ @change="handleAttachmentChange"
+ @upload-success="handleUploadSuccess"
+ @upload-error="handleUploadError"
+ @remove="handleAttachmentRemove"
+ />
+
+ <!-- 闄勪欢鍒楄〃灞曠ず -->
+ <div class="attachment-list" v-if="attachments && attachments.length > 0">
+ <div class="list-title">宸蹭笂浼犻檮浠� ({{ attachments.length }})</div>
+ <el-table :data="attachments" style="width: 100%" size="small">
+ <el-table-column label="鏂囦欢鍚�" min-width="200">
+ <template slot-scope="scope">
+ <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="200">
+ <template slot-scope="scope">
+ <span>{{ formatDateTime(scope.row.uploadTime) }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鏂囦欢澶у皬" width="180">
+ <template slot-scope="scope">
+ <span>{{ formatFileSize(scope.row.fileSize) }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鎿嶄綔" width="260" fixed="right">
+ <template slot-scope="scope">
+ <el-button
+ size="mini"
+ type="primary"
+ @click="handlePreview(scope.row)"
+ :disabled="!isPreviewable(scope.row.fileName)"
+ >
+ 棰勮
+ </el-button>
+ <el-button
+ size="mini"
+ type="success"
+ @click="handleDownloadAttachment(scope.row)"
+ >
+ 涓嬭浇
+ </el-button>
+ <el-button
+ size="mini"
+ type="danger"
+ @click="handleRemoveAttachment(scope.$index)"
+ >
+ 鍒犻櫎
+ </el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+ </el-card>
+
+ <!-- 鏂囦欢棰勮瀵硅瘽妗� -->
+ <FilePreviewDialog
+ :visible="filePreviewVisible"
+ :file="currentPreviewFile"
+ @close="filePreviewVisible = false"
+ @download="handleDownloadAttachment"
+ />
+ </div>
</template>
<script>
-import BaseStage from './BaseStage.vue';
-import * as echarts from 'echarts';
+import {
+ completionList,
+ completionadd,
+ completionedit
+} from "@/api/businessApi";
+import UploadAttachment from "@/components/UploadAttachment"; // 鏂板瀵煎叆
+import FilePreviewDialog from "@/components/FilePreviewDialog"; // 鏂板瀵煎叆
+import CaseBasicInfo from "@/components/CaseBasicInfo";
+import dayjs from "dayjs"; // 鏂板瀵煎叆锛岀敤浜庢椂闂村鐞�
export default {
- name: 'OrganUtilizationStage',
- components: { BaseStage },
- props: {
- stageData: {
- type: Object,
- default: () => ({})
- },
- caseInfo: {
- type: Object,
- default: () => ({})
+ name: "OrganUtilizationDetail",
+ components: {
+ UploadAttachment,
+ FilePreviewDialog,
+ CaseBasicInfo
+ },
+ dicts: ["sys_BloodType", "sys_Organ", "sys_0_1", "utilize_statue"],
+ props: {
+ infoid: {
+ type: String,
+ default: true
}
},
data() {
return {
- chartView: 'bar',
+ caseId: null,
+
+ // 琛ㄥ崟鏁版嵁 - 鏍规嵁鎺ュ彛鍙傛暟璋冩暣
+ form: {
+ id: undefined,
+ infoid: undefined,
+ inpatientno: "",
+ completeState: "2",
+ caseNo: "",
+ donorno: "",
+ treatmenthospitalname: "",
+ treatmenthospitalno: "",
+ sex: "",
+ name: "",
+ age: "",
+ bloodtype: "",
+ idcardno: "",
+ diagnosisname: "",
+ completetime: "",
+ responsibleuserid: "",
+ responsibleusername: "",
+ coordinateduserido: "",
+ coordinatedusernameo: "",
+ coordinateduseridt: "",
+ coordinatedusernamet: "",
+ assessannex: "",
+ donateorgan: "",
+ isbodydonation: "0",
+ receivingunitname: "",
+ createBy: "",
+ createTime: "",
+ updateBy: "",
+ updateTime: "",
+ attachments: []
+ },
+ // 琛ㄥ崟楠岃瘉瑙勫垯
+ rules: {
+ name: [
+ { required: true, message: "鎹愮尞鑰呭鍚嶄笉鑳戒负绌�", trigger: "blur" }
+ ],
+ diagnosisname: [
+ { required: true, message: "鐤剧梾璇婃柇涓嶈兘涓虹┖", trigger: "blur" }
+ ],
+ donorno: [
+ { required: true, message: "鎹愮尞鑰呯紪鍙蜂笉鑳戒负绌�", trigger: "blur" }
+ ]
+ },
+ // 鍒╃敤璁板綍楠岃瘉瑙勫垯
+ utilizationRules: {},
+ // 淇濆瓨鍔犺浇鐘舵��
+ saveLoading: false,
+ confirmLoading: false,
+ // 鍔犺浇鐘舵��
loading: false,
- utilizationStats: {
- transplanted: 3,
- inProgress: 0,
- failed: 0,
- successRate: 95,
- utilizationRate: 100,
- survivalRate: 92
- },
- timeTracking: {
- procurementToTransplant: '4.5灏忔椂',
- coldIschemiaTime: '鑲濊剰:6h,鑲捐剰:8h,蹇冭剰:3h',
- surgeryDuration: '鑲濊剰:4h,鑲捐剰:3h,蹇冭剰:5h',
- icuStay: '鑲濊剰:3澶�,鑲捐剰:2澶�,蹇冭剰:5澶�'
- },
- qualityStats: {
- organQuality: 4.5,
- surgeryQuality: 4.8,
- followupCompletionRate: 85
- },
- organUtilizationData: [
- {
- organName: '鑲濊剰',
- status: '绉绘鎴愬姛',
- recipientName: '鐜嬪厛鐢�',
- recipientAge: 45,
- recipientGender: '鐢�',
- hospital: '闈掑矝澶у闄勫睘鍖婚櫌绉绘涓績',
- transplantTime: '2025-12-04 16:00:00',
- followupCount: 3,
- recipientStatus: '鎭㈠鑹ソ'
- },
- {
- organName: '鑲捐剰',
- status: '绉绘鎴愬姛',
- recipientName: '鏉庡コ澹�',
- recipientAge: 38,
- recipientGender: '濂�',
- hospital: '涓婃捣鐟為噾鍖婚櫌绉绘涓績',
- transplantTime: '2025-12-04 17:30:00',
- followupCount: 2,
- recipientStatus: '绋冲畾鎭㈠'
- },
- {
- organName: '蹇冭剰',
- status: '绉绘鎴愬姛',
- recipientName: '闄堝厛鐢�',
- recipientAge: 52,
- recipientGender: '鐢�',
- hospital: '骞垮窞涓北鍖婚櫌蹇冭剰涓績',
- transplantTime: '2025-12-04 18:15:00',
- followupCount: 1,
- recipientStatus: '瀵嗗垏瑙傚療'
- }
+ // 閫変腑鐨勫櫒瀹�
+ selectedOrgans: [],
+ // 鍖婚櫌鍒楄〃
+ hospitalList: [],
+ // 绉绘鐘舵�佸垪琛�
+ transplantStatusList: [
+ { value: "1", label: "宸茬Щ妞�" },
+ { value: "0", label: "鏈Щ妞�" },
+ { value: "2", label: "绉绘涓�" }
],
- // 鍥捐〃瀹炰緥
- organDistributionChart: null,
- successTrendChart: null,
- followupStatsChart: null,
- complicationChart: null
+ // 鍒╃敤璁板綍鏁版嵁
+ utilizationData: {
+ serviceDonatecomporganList: []
+ },
+ // 闅忚璁板綍鏁版嵁
+ followupData: {
+ records: []
+ },
+ // 闄勪欢鏁版嵁
+ attachments: [],
+ // 灞曞紑鐨勮keys
+ expandedRows: [],
+ // 缂栬緫瀵硅瘽妗�
+ editDialogVisible: false,
+ currentRecord: {},
+ currentEditIndex: -1,
+ // 闄勪欢鐩稿叧閰嶇疆 - 鏂板
+ attachmentFileList: [],
+ attachmentLimit: 10,
+ attachmentAccept:
+ ".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt",
+
+ // 鏂囦欢棰勮鐩稿叧 - 鏂板
+ filePreviewVisible: false,
+ currentPreviewFile: null,
+ currentFollowup: {},
+ isEditingFollowup: false
};
},
- mounted() {
- this.$nextTick(() => {
- this.initCharts();
- });
+ computed: {
+ // 褰撳墠鐢ㄦ埛淇℃伅
+ currentUser() {
+ return JSON.parse(sessionStorage.getItem("user") || "{}");
+ },
+ // 宸茬Щ妞嶆暟閲�
+ transplantedCount() {
+ if (!this.utilizationData.serviceDonatecomporganList) return 0;
+ return this.utilizationData.serviceDonatecomporganList.filter(
+ record => record.transplantstate === "1"
+ ).length;
+ },
+ // 鍞竴鍖婚櫌鏁伴噺
+ uniqueHospitals() {
+ if (!this.utilizationData.serviceDonatecomporganList) return 0;
+ const hospitals = this.utilizationData.serviceDonatecomporganList
+ .map(record => record.hospitalno)
+ .filter(Boolean);
+ return new Set(hospitals).size;
+ },
+ // 鑾峰彇鍣ㄥ畼瀛楀吀
+ organDict() {
+ return this.dict.type.sys_Organ || [];
+ }
},
- beforeDestroy() {
- // 閿�姣佸浘琛ㄥ疄渚�
- if (this.organDistributionChart) {
- this.organDistributionChart.dispose();
- }
- if (this.successTrendChart) {
- this.successTrendChart.dispose();
- }
- if (this.followupStatsChart) {
- this.followupStatsChart.dispose();
- }
- if (this.complicationChart) {
- this.complicationChart.dispose();
+ created() {
+ this.initData();
+ },
+ watch: {
+ // 鐩戝惉闄勪欢鏁版嵁鍙樺寲 - 鏂板
+ attachments: {
+ handler(newAttachments) {
+ this.attachmentFileList = newAttachments.map(item => ({
+ uid: item.id || Math.random(),
+ name: item.fileName,
+ fileSize: item.fileSize,
+ url: item.path || item.fileUrl,
+ uploadTime: item.uploadTime,
+ status: "success"
+ }));
+ },
+ deep: true
}
},
methods: {
- // 鍒濆鍖栧浘琛�
- initCharts() {
- this.initOrganDistributionChart();
- this.initSuccessTrendChart();
- this.initFollowupStatsChart();
- this.initComplicationChart();
+ // 鍒濆鍖栨暟鎹�
+ initData() {
+ this.caseId = this.infoid;
+
+ if (!this.caseId) {
+ this.$message.error("缂哄皯蹇呰鐨勮矾鐢卞弬鏁� infoid");
+ this.$router.back();
+ return;
+ }
+
+ this.form.infoid = this.caseId;
+ this.form.createBy =
+ this.currentUser.username || this.currentUser.name || "褰撳墠鐢ㄦ埛";
+ this.form.createTime = new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19);
+
+ this.generateDonorNo();
+ this.getDetail();
+ this.getHospitalData();
},
- // 鍒濆鍖栧櫒瀹樺垎甯冨浘琛�
- initOrganDistributionChart() {
- this.organDistributionChart = echarts.init(this.$refs.organDistributionChart);
- const option = {
- tooltip: {
- trigger: 'item',
- formatter: '{a} <br/>{b}: {c} ({d}%)'
- },
- legend: {
- orient: 'vertical',
- right: 10,
- top: 'center',
- data: ['鑲濊剰', '鑲捐剰', '蹇冭剰', '鑲鸿剰', '瑙掕啘', '鍏朵粬']
- },
- series: [
- {
- name: '鍣ㄥ畼鍒╃敤',
- type: 'pie',
- radius: ['50%', '70%'],
- avoidLabelOverlap: false,
- label: {
- show: false,
- position: 'center'
- },
- emphasis: {
- label: {
- show: true,
- fontSize: '18',
- fontWeight: 'bold'
- }
- },
- labelLine: {
- show: false
- },
- data: [
- { value: 35, name: '鑲濊剰' },
- { value: 30, name: '鑲捐剰' },
- { value: 15, name: '蹇冭剰' },
- { value: 10, name: '鑲鸿剰' },
- { value: 8, name: '瑙掕啘' },
- { value: 2, name: '鍏朵粬' }
- ]
- }
- ]
- };
- this.organDistributionChart.setOption(option);
+ // 鐢熸垚鎹愮尞鑰呯紪鍙�
+ 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);
},
- // 鍒濆鍖栨垚鍔熺巼瓒嬪娍鍥捐〃
- initSuccessTrendChart() {
- this.successTrendChart = echarts.init(this.$refs.successTrendChart);
- const option = {
- tooltip: {
- trigger: 'axis'
- },
- legend: {
- data: ['鑲濊剰绉绘', '鑲捐剰绉绘', '蹇冭剰绉绘', '骞冲潎鎴愬姛鐜�']
- },
- grid: {
- left: '3%',
- right: '4%',
- bottom: '3%',
- containLabel: true
- },
- xAxis: {
- type: 'category',
- boundaryGap: false,
- data: ['1鏈�', '2鏈�', '3鏈�', '4鏈�', '5鏈�', '6鏈�', '7鏈�']
- },
- yAxis: {
- type: 'value',
- min: 80,
- max: 100
- },
- series: [
- {
- name: '鑲濊剰绉绘',
- type: 'line',
- smooth: true,
- data: [92, 93, 94, 95, 96, 95, 96]
- },
- {
- name: '鑲捐剰绉绘',
- type: 'line',
- smooth: true,
- data: [94, 95, 95, 96, 95, 96, 97]
- },
- {
- name: '蹇冭剰绉绘',
- type: 'line',
- smooth: true,
- data: [88, 89, 90, 91, 92, 91, 92]
- },
- {
- name: '骞冲潎鎴愬姛鐜�',
- type: 'line',
- smooth: true,
- lineStyle: {
- type: 'dashed'
- },
- data: [91.3, 92.3, 93, 94, 94.3, 94, 95]
+ // 鑾峰彇璇︽儏
+ async getDetail() {
+ this.loading = true;
+ try {
+ const response = await completionList({ infoid: this.caseId });
+ if (
+ response.code === 200 &&
+ response.data &&
+ response.data.length > 0
+ ) {
+ const data = response.data[0];
+ if (!data.completeState || data.completeState == 1) {
+ data.completeState = "2";
}
- ]
- };
- this.successTrendChart.setOption(option);
- },
+ // 濉厖琛ㄥ崟鏁版嵁
+ Object.assign(this.form, data);
- // 鍒濆鍖栭殢璁跨粺璁″浘琛�
- initFollowupStatsChart() {
- this.followupStatsChart = echarts.init(this.$refs.followupStatsChart);
- const option = {
- tooltip: {
- trigger: 'axis',
- axisPointer: {
- type: 'shadow'
+ // 澶勭悊鎹愮尞鍣ㄥ畼瀛楁
+ if (data.donateorgan) {
+ const organArray = Array.isArray(data.donateorgan)
+ ? data.donateorgan
+ : (data.donateorgan || "").split(",").filter(item => item);
+ this.selectedOrgans = organArray;
}
- },
- legend: {
- data: ['璁″垝闅忚', '宸插畬鎴�', '閫炬湡鏈畬鎴�']
- },
- grid: {
- left: '3%',
- right: '4%',
- bottom: '3%',
- containLabel: true
- },
- xAxis: {
- type: 'value'
- },
- yAxis: {
- type: 'category',
- data: ['1涓湀', '3涓湀', '6涓湀', '1骞�', '2骞�', '5骞�']
- },
- series: [
- {
- name: '璁″垝闅忚',
- type: 'bar',
- stack: 'total',
- label: {
- show: true
- },
- emphasis: {
- focus: 'series'
- },
- data: [120, 132, 101, 134, 90, 60]
- },
- {
- name: '宸插畬鎴�',
- type: 'bar',
- stack: 'total',
- label: {
- show: true
- },
- emphasis: {
- focus: 'series'
- },
- data: [115, 125, 95, 120, 85, 55]
- },
- {
- name: '閫炬湡鏈畬鎴�',
- type: 'bar',
- stack: 'total',
- label: {
- show: true
- },
- emphasis: {
- focus: 'series'
- },
- data: [5, 7, 6, 14, 5, 5]
- }
- ]
- };
- this.followupStatsChart.setOption(option);
- },
- // 鍒濆鍖栧苟鍙戠棁鍒嗘瀽鍥捐〃
- initComplicationChart() {
- this.complicationChart = echarts.init(this.$refs.complicationChart);
- const option = {
- tooltip: {
- trigger: 'axis',
- axisPointer: {
- type: 'shadow'
+ // 澶勭悊鍣ㄥ畼鍒╃敤璁板綍
+ if (data.serviceDonatecomporganList) {
+ this.utilizationData.serviceDonatecomporganList = Array.isArray(
+ data.serviceDonatecomporganList
+ )
+ ? data.serviceDonatecomporganList.map(record => ({
+ ...record,
+ transplanttime: record.transplanttime || "",
+ transplantstate: record.transplantstate
+ ? record.transplantstate.toString()
+ : "1"
+ }))
+ : [];
}
- },
- radar: {
- indicator: [
- { name: '鎰熸煋椋庨櫓', max: 100 },
- { name: '鎺掓枼鍙嶅簲', max: 100 },
- { name: '琛�绠″苟鍙戠棁', max: 100 },
- { name: '鑳嗛亾骞跺彂鐥�', max: 100 },
- { name: '浠h阿寮傚父', max: 100 },
- { name: '鍏朵粬骞跺彂鐥�', max: 100 }
- ]
- },
- series: [
- {
- type: 'radar',
- data: [
- {
- value: [85, 90, 78, 82, 75, 70],
- name: '鑲濊剰绉绘',
- areaStyle: {}
- },
- {
- value: [78, 85, 72, 65, 80, 68],
- name: '鑲捐剰绉绘',
- areaStyle: {}
- },
- {
- value: [90, 88, 85, 60, 82, 75],
- name: '蹇冭剰绉绘',
- areaStyle: {}
- }
- ]
- }
- ]
- };
- this.complicationChart.setOption(option);
- },
+ console.log(this.utilizationData.serviceDonatecomporganList);
- // 鏇存柊鍥捐〃瑙嗗浘
- updateCharts() {
- if (this.chartView === 'bar') {
- this.updateToBarChart();
- } else {
- this.initOrganDistributionChart(); // 鍒囧洖楗煎浘
+ // 鍒濆鍖栭檮浠�
+ if (this.form.assessannex) {
+ this.form.attachments = JSON.parse(this.form.assessannex);
+ this.attachments = Array.isArray(this.form.attachments)
+ ? [...this.form.attachments]
+ : [];
+ }
+
+ this.$message.success("鏁版嵁鍔犺浇鎴愬姛");
+ } else {
+ this.$message.warning("鏈壘鍒板搴旂殑鍣ㄥ畼鍒╃敤鏁版嵁");
+ }
+ } catch (error) {
+ console.error("鑾峰彇鍣ㄥ畼鍒╃敤璇︽儏澶辫触:", error);
+ this.$message.error("鑾峰彇璇︽儏澶辫触");
+ } finally {
+ this.loading = false;
}
},
- // 鏇存柊涓烘煴鐘跺浘
- updateToBarChart() {
- const option = {
- tooltip: {
- trigger: 'axis',
- axisPointer: {
- type: 'shadow'
- }
- },
- grid: {
- left: '3%',
- right: '4%',
- bottom: '3%',
- containLabel: true
- },
- xAxis: {
- type: 'category',
- data: ['鑲濊剰', '鑲捐剰', '蹇冭剰', '鑲鸿剰', '瑙掕啘', '鍏朵粬']
- },
- yAxis: {
- type: 'value',
- name: '鏁伴噺'
- },
- series: [
- {
- name: '鍣ㄥ畼鍒╃敤鏁伴噺',
- type: 'bar',
- data: [35, 30, 15, 10, 8, 2],
- itemStyle: {
- color: function(params) {
- const colorList = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272'];
- return colorList[params.dataIndex];
- }
+ // 鑾峰彇鍖婚櫌鏁版嵁
+ async getHospitalData() {
+ try {
+ // TODO: 鏇挎崲涓哄疄闄呯殑鍖婚櫌鍒楄〃鎺ュ彛
+ // 鏆傛椂浣跨敤妯℃嫙鏁版嵁
+ this.hospitalList = [
+ { hospitalNo: "H001", hospitalName: "鍖椾含鍗忓拰鍖婚櫌" },
+ { hospitalNo: "H002", hospitalName: "涓婃捣鍗庡北鍖婚櫌" },
+ { hospitalNo: "H003", hospitalName: "涓婃捣鐟為噾鍖婚櫌" },
+ { hospitalNo: "H004", hospitalName: "骞垮窞涓北鍖婚櫌" },
+ { hospitalNo: "H005", hospitalName: "姝︽眽鍚屾祹鍖婚櫌" },
+ { hospitalNo: "H006", hospitalName: "鎴愰兘鍗庤タ鍖婚櫌" }
+ ];
+ } catch (error) {
+ console.error("鑾峰彇鍖婚櫌鏁版嵁澶辫触:", error);
+ this.$message.error("鑾峰彇鍖婚櫌鏁版嵁澶辫触");
+ }
+ },
+
+ // 鍣ㄥ畼閫夋嫨鐘舵�佸彉鍖�
+ handleOrganSelectionChange(selectedValues) {
+ if (!this.utilizationData.serviceDonatecomporganList) {
+ this.utilizationData.serviceDonatecomporganList = [];
+ }
+
+ const currentOrganValues = this.utilizationData.serviceDonatecomporganList.map(
+ item => item.organno
+ );
+
+ // 澶勭悊浜掓枼閫昏緫
+ this.handleExclusiveSelections(selectedValues);
+
+ // 鏇存柊鎹愮尞鍣ㄥ畼瀛楁
+ this.form.donateorgan = selectedValues.join(",");
+
+ // 鏂板閫夋嫨鐨勫櫒瀹�
+ selectedValues.forEach(organValue => {
+ if (!currentOrganValues.includes(organValue)) {
+ this.createOrganRecord(organValue);
+ }
+ });
+
+ // 绉婚櫎鍙栨秷閫夋嫨鐨勫櫒瀹�
+ this.utilizationData.serviceDonatecomporganList = this.utilizationData.serviceDonatecomporganList.filter(
+ record => {
+ if (selectedValues.includes(record.organno)) {
+ return true;
+ } else {
+ if (record.id) {
+ this.$confirm(
+ "鍒犻櫎鍣ㄥ畼鍒╃敤鏁版嵁鍚庡皢鏃犳硶鎭㈠锛屾偍纭鍒犻櫎璇ユ潯璁板綍鍚楋紵",
+ "鎻愮ず",
+ {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ }
+ )
+ .then(() => {
+ this.utilizationData.serviceDonatecomporganList = this.utilizationData.serviceDonatecomporganList.filter(
+ r => r.organno !== record.organno
+ );
+ this.$message.success("鍒犻櫎鎴愬姛");
+ })
+ .catch(() => {
+ this.selectedOrgans.push(record.organno);
+ });
+ return true;
+ } else {
+ return false;
}
}
- ]
- };
- this.organDistributionChart.setOption(option);
+ }
+ );
},
- // 鑾峰彇鐘舵�佹枃鏈�
- getStatusText() {
- const status = this.stageData.status;
- return status === 'completed' ? '宸插畬鎴�' :
- status === 'in_progress' ? '杩涜涓�' : '鏈紑濮�';
- },
-
- // 鑾峰彇璀﹀憡绫诲瀷
- getAlertType() {
- const status = this.stageData.status;
- return status === 'completed' ? 'success' :
- status === 'in_progress' ? 'warning' : 'info';
- },
-
- // 鑾峰彇璀﹀憡鎻忚堪
- getAlertDescription() {
- const status = this.stageData.status;
- if (status === 'completed') {
- return '鍣ㄥ畼鍒╃敤闃舵宸插畬鎴愶紝鎵�鏈夊櫒瀹樺潎宸叉垚鍔熺Щ妞嶅苟寮�濮嬮殢璁�';
- } else if (status === 'in_progress') {
- return '鍣ㄥ畼鍒╃敤杩涜涓紝绉绘鎵嬫湳宸插畬鎴愶紝姝e湪杩涜鏈悗闅忚';
+ // 澶勭悊浜掓枼閫夋嫨
+ handleExclusiveSelections(selectedValues) {
+ // 濡傛灉閫夋嫨浜�"鍙岃偩"(鍋囪瀛楀吀鍊间负C64)锛岃嚜鍔ㄥ彇娑堝崟鐙殑"宸﹁偩"(C64L)鍜�"鍙宠偩"(C64R)閫夋嫨
+ if (selectedValues.includes("C64")) {
+ this.selectedOrgans = selectedValues.filter(
+ item => item !== "C64L" && item !== "C64R"
+ );
}
- return '绛夊緟寮�濮嬪櫒瀹樺埄鐢ㄦ祦绋�';
+ // 濡傛灉閫夋嫨浜�"宸﹁偩"鎴�"鍙宠偩"锛屽彇娑�"鍙岃偩"閫夋嫨
+ else if (
+ selectedValues.includes("C64L") ||
+ selectedValues.includes("C64R")
+ ) {
+ this.selectedOrgans = selectedValues.filter(item => item !== "C64");
+ }
+
+ // 濡傛灉閫夋嫨浜�"鍏ㄨ偤"(鍋囪瀛楀吀鍊间负C34)锛岃嚜鍔ㄥ彇娑堝崟鐙殑"宸﹁偤"(C34L)鍜�"鍙宠偤"(C34R)閫夋嫨
+ if (selectedValues.includes("C34")) {
+ this.selectedOrgans = selectedValues.filter(
+ item => item !== "C34L" && item !== "C34R"
+ );
+ }
+ // 濡傛灉閫夋嫨浜�"宸﹁偤"鎴�"鍙宠偤"锛屽彇娑�"鍏ㄨ偤"閫夋嫨
+ else if (
+ selectedValues.includes("C34L") ||
+ selectedValues.includes("C34R")
+ ) {
+ this.selectedOrgans = selectedValues.filter(item => item !== "C34");
+ }
},
- // 鑾峰彇绉绘鐘舵�佹爣绛�
- getTransplantStatusTag(status) {
- const map = {
- '绉绘鎴愬姛': 'success',
- '绉绘涓�': 'warning',
- '绉绘澶辫触': 'danger'
- };
- return map[status] || 'info';
- },
+ // 鍒涘缓鍣ㄥ畼璁板綍
+ createOrganRecord(organValue) {
+ const organName = this.getOrganLabel(organValue);
- // 鑾峰彇鍙椾綋鐘舵�佹爣绛�
- getRecipientStatusTag(status) {
- const map = {
- '鎭㈠鑹ソ': 'success',
- '绋冲畾鎭㈠': 'warning',
- '瀵嗗垏瑙傚療': 'danger'
- };
- return map[status] || 'info';
- },
-
- // 鏌ョ湅璇︽儏
- handleViewDetails(row) {
- this.$message.info(`鏌ョ湅${row.organName}绉绘璇︽儏`);
- },
-
- // 娣诲姞闅忚
- handleAddFollowup(row) {
- this.$message.info(`涓�${row.recipientName}娣诲姞闅忚璁板綍`);
- },
-
- // 鐢熸垚鎶ュ憡
- handleGenerateReport() {
- this.$message.info('鐢熸垚鍣ㄥ畼鍒╃敤鍒嗘瀽鎶ュ憡');
- },
-
- // 瀹屾垚鍒╃敤
- handleCompleteUtilization() {
- this.$confirm('纭瀹屾垚鍣ㄥ畼鍒╃敤闃舵鍚楋紵', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'success'
- }).then(() => {
- this.$message.success('鍣ㄥ畼鍒╃敤闃舵宸插畬鎴�');
+ this.utilizationData.serviceDonatecomporganList.push({
+ organname: organName,
+ organno: organValue,
+ caseNo: "",
+ hospitalno: "",
+ hospitalname: "",
+ name: "",
+ transplantdoct: "",
+ transplanttime: "",
+ transplantstate: "1",
+ abandonreason: "",
+ sex: "",
+ age: "",
+ birthday: "",
+ phone: "",
+ residenceaddress: "",
+ residenceprovince: "",
+ residenceprovincename: "",
+ residencecity: "",
+ residencecityname: "",
+ residencetown: "",
+ residencetownname: "",
+ residencecommunity: "",
+ residencecommunityname: "",
+ residencecountycode: "",
+ residencecountyname: "",
+ idcardtype: "",
+ idcardno: "",
+ ageunit: ""
});
},
- // 缁熻鏁版嵁鍒嗘瀽
- handleStatistics() {
- this.$message.info('鎵撳紑缁熻鍒嗘瀽闈㈡澘');
+ // 鏍规嵁瀛楀吀value鑾峰彇label
+ getOrganLabel(organValue) {
+ const dictItem = this.organDict.find(item => item.value === organValue);
+ return dictItem ? dictItem.label : organValue;
},
- // 瀵煎嚭鏁版嵁
- exportData() {
- this.$message.info('瀵煎嚭鍣ㄥ畼鍒╃敤鏁版嵁');
+ // 鍖婚櫌閫夋嫨鍙樺寲
+ handleHospitalChange(row, hospitalNo) {
+ const hospital = this.hospitalList.find(
+ item => item.hospitalNo === hospitalNo
+ );
+ if (hospital) {
+ row.hospitalname = hospital.hospitalName;
+ }
+ },
+
+ // 绉绘鐘舵�佸彉鍖栧鐞�
+ handleTransplantStatusChange(row, status) {
+ if (status === "0") {
+ // 濡傛灉鐘舵�佷负鏈Щ妞嶏紝娓呴櫎鐩稿叧瀛楁
+ // row.transplanttime = "";
+ // row.transplantdoct = "";
+ // row.hospitalno = "";
+ // row.hospitalname = "";
+ } else if (status === "1") {
+ // 濡傛灉鐘舵�佷负宸茬Щ妞嶏紝鑷姩璁剧疆绉绘鏃堕棿涓哄綋鍓嶆椂闂�
+ if (!row.transplanttime) {
+ row.transplanttime = new Date().toISOString().split("T")[0];
+ }
+ }
+ },
+
+ // 琛屽睍寮�浜嬩欢
+ handleExpandChange(row, expandedRows) {
+ this.expandedRows = expandedRows.map(item => item.organno);
+ },
+
+ // 鍒犻櫎鍣ㄥ畼璁板綍
+ handleRemoveOrgan(index) {
+ this.$confirm("纭鍒犻櫎杩欐潯鍣ㄥ畼璁板綍鍚楋紵", "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(() => {
+ const organno = this.utilizationData.serviceDonatecomporganList[index]
+ .organno;
+ this.utilizationData.serviceDonatecomporganList.splice(index, 1);
+
+ // 浠庨�変腑鐨勫櫒瀹樹腑绉婚櫎
+ const idx = this.selectedOrgans.indexOf(organno);
+ if (idx > -1) {
+ this.selectedOrgans.splice(idx, 1);
+ }
+
+ this.$message.success("鍣ㄥ畼璁板綍鍒犻櫎鎴愬姛");
+ })
+ .catch(() => {});
+ },
+
+ // 鍣ㄥ畼琛屾牱寮�
+ getOrganRowClassName({ row }) {
+ if (
+ row.transplantstate === "1" &&
+ (!row.caseNo || !row.hospitalno || !row.name || !row.transplanttime)
+ ) {
+ return "warning-row";
+ }
+ if (row.transplantstate === "0" && !row.abandonreason) {
+ return "warning-row";
+ }
+ return "";
+ },
+
+ // 鑾峰彇鐘舵�佹爣绛剧被鍨�
+ getStatusTagType(status) {
+ const typeMap = {
+ 3: "success",
+ 2: "warning",
+ 1: "info"
+ };
+ return typeMap[status] || "info";
+ },
+
+ // 鑾峰彇鐘舵�佹枃鏈�
+ getStatusText(status) {
+ const textMap = {
+ 3: "宸插畬鎴�",
+ 2: "杩涜涓�",
+ 1: "寰呭鐞�"
+ };
+ return textMap[status] || "鏈煡";
+ },
+
+ // 鑾峰彇闅忚绫诲瀷鏍囩
+ getFollowupTypeTag(type) {
+ const typeMap = {
+ routine: "success",
+ emergency: "danger",
+ special: "warning"
+ };
+ return typeMap[type] || "info";
+ },
+
+ // 鑾峰彇闅忚绫诲瀷鏂囨湰
+ getFollowupTypeText(type) {
+ const textMap = {
+ routine: "甯歌闅忚",
+ emergency: "绱ф�ラ殢璁�",
+ special: "鐗规畩闅忚"
+ };
+ return textMap[type] || "鏈煡";
+ },
+
+ // 淇濆瓨鍩烘湰淇℃伅
+ async handleSave() {
+ this.$refs.form.validate(async valid => {
+ if (valid) {
+ this.saveLoading = true;
+ try {
+ const saveData = {
+ ...this.form,
+ assessannex: JSON.stringify(this.attachments),
+ donateorgan: this.selectedOrgans.join(","),
+ serviceDonatecomporganList:
+ this.utilizationData.serviceDonatecomporganList || []
+ };
+
+ const apiMethod = this.form.id ? completionedit : completionadd;
+ const response = await apiMethod(saveData);
+
+ if (response.code === 200) {
+ this.$message.success("淇濆瓨鎴愬姛");
+ if (!this.form.id && response.data && response.data.id) {
+ this.form.id = response.data.id;
+ this.$router.replace({
+ query: { ...this.$route.query, id: this.form.id }
+ });
+ }
+ } else {
+ this.$message.error("淇濆瓨澶辫触锛�" + (response.msg || "鏈煡閿欒"));
+ }
+ } catch (error) {
+ console.error("淇濆瓨澶辫触:", error);
+ this.$message.error("淇濆瓨澶辫触");
+ } finally {
+ this.saveLoading = false;
+ }
+ }
+ });
+ },
+
+ // 淇濆瓨鍒╃敤璁板綍
+ async handleSaveUtilization() {
+ if (
+ !this.utilizationData.serviceDonatecomporganList ||
+ this.utilizationData.serviceDonatecomporganList.length === 0
+ ) {
+ this.$message.warning("璇峰厛娣诲姞鍒╃敤璁板綍");
+ return;
+ }
+
+ this.saveLoading = true;
+ try {
+ const saveData = {
+ ...this.form,
+ attachments: this.attachments,
+ donateorgan: this.selectedOrgans.join(","),
+ serviceDonatecomporganList:
+ this.utilizationData.serviceDonatecomporganList || []
+ };
+
+ const response = await completionedit(saveData);
+
+ if (response.code === 200) {
+ this.$message.success("鍒╃敤璁板綍淇濆瓨鎴愬姛");
+ } else {
+ this.$message.error(
+ "淇濆瓨鍒╃敤璁板綍澶辫触锛�" + (response.msg || "鏈煡閿欒")
+ );
+ }
+ } catch (error) {
+ console.error("淇濆瓨鍒╃敤璁板綍澶辫触:", error);
+ this.$message.error("淇濆瓨鍒╃敤璁板綍澶辫触");
+ } finally {
+ this.saveLoading = false;
+ }
+ },
+
+ // 纭瀹屾垚鍒╃敤
+ async handleConfirmUtilization() {
+ // 妫�鏌ュ埄鐢ㄨ褰曟槸鍚﹀畬鏁�
+ const incompleteRecords = this.utilizationData.serviceDonatecomporganList.filter(
+ record => {
+ if (record.transplantstate === "1") {
+ return (
+ !record.caseNo ||
+ !record.hospitalno ||
+ !record.name ||
+ !record.transplanttime
+ );
+ } else if (record.transplantstate === "0") {
+ return !record.abandonreason;
+ }
+ return false;
+ }
+ );
+
+
+ if (incompleteRecords.length > 0) {
+ this.$message.warning("璇峰厛瀹屽杽鎵�鏈夊埄鐢ㄨ褰曠殑淇℃伅");
+ return;
+ }
+
+ this.$confirm("纭瀹屾垚鍣ㄥ畼鍒╃敤鍚楋紵瀹屾垚鍚庡皢鏃犳硶淇敼鍒╃敤淇℃伅銆�", "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(async () => {
+ this.confirmLoading = true;
+ this.form.completeState = "3";
+ this.form.completetime =
+ this.form.completetime ||
+ new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19);
+
+ try {
+ const saveData = {
+ ...this.form,
+ attachments: this.attachments,
+ donateorgan: this.selectedOrgans.join(","),
+ serviceDonatecomporganList:
+ this.utilizationData.serviceDonatecomporganList || []
+ };
+
+ const response = await completionedit(saveData);
+
+ if (response.code === 200) {
+ this.$message.success("鍣ㄥ畼鍒╃敤宸插畬鎴�");
+ } else {
+ this.$message.error(
+ "纭鍒╃敤澶辫触锛�" + (response.msg || "鏈煡閿欒")
+ );
+ this.form.completeState = "2";
+ this.form.completetime = "";
+ }
+ } catch (error) {
+ console.error("纭鍒╃敤澶辫触:", error);
+ this.$message.error("纭鍒╃敤澶辫触");
+ this.form.completeState = "2";
+ this.form.completetime = "";
+ } finally {
+ this.confirmLoading = false;
+ }
+ })
+ .catch(() => {});
+ },
+
+ // 瀹屾垚鍒╃敤
+ handleComplete() {
+ this.handleConfirmUtilization();
+ },
+
+ // 淇濆瓨闅忚璁板綍
+ handleSaveFollowup() {
+ if (!this.currentFollowup.organNo) {
+ this.$message.warning("璇烽�夋嫨鍣ㄥ畼");
+ return;
+ }
+
+ if (!this.currentFollowup.followupTime) {
+ this.$message.warning("璇烽�夋嫨闅忚鏃堕棿");
+ return;
+ }
+
+ this.saveLoading = true;
+
+ // 鑾峰彇鍣ㄥ畼鍚嶇О
+ const organRecord = this.utilizationData.serviceDonatecomporganList.find(
+ item => item.organno === this.currentFollowup.organNo
+ );
+ const organName = organRecord ? organRecord.organname : "";
+
+ const followupData = {
+ ...this.currentFollowup,
+ organName: organName,
+ utilizationId: this.form.id
+ };
+
+ // TODO: 鏇挎崲涓哄疄闄呯殑闅忚璁板綍淇濆瓨鎺ュ彛
+ setTimeout(() => {
+ if (this.isEditingFollowup) {
+ // 鏇存柊鐜版湁璁板綍
+ const index = this.followupData.records.findIndex(
+ item => item.id === this.currentFollowup.id
+ );
+ if (index !== -1) {
+ this.followupData.records[index] = {
+ ...followupData,
+ id: this.currentFollowup.id
+ };
+ }
+ } else {
+ // 娣诲姞鏂拌褰�
+ this.followupData.records.push({ ...followupData, id: Date.now() });
+ }
+ this.$message.success("闅忚璁板綍淇濆瓨鎴愬姛");
+ this.followupDialogVisible = false;
+ this.saveLoading = false;
+ }, 1000);
+ },
+ /** 闄勪欢鍙樺寲澶勭悊 */
+ handleAttachmentChange(fileList) {
+ this.attachmentFileList = fileList;
+ },
+
+ /** 闄勪欢绉婚櫎澶勭悊 */
+ handleAttachmentRemove(file) {
+ if (file.url) {
+ const index = this.attachments.findIndex(
+ item => item.path === file.url || item.fileUrl === file.url
+ );
+ if (index > -1) {
+ this.attachments.splice(index, 1);
+ this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+ }
+ }
+ },
+ /** 涓婁紶鎴愬姛澶勭悊 */
+ handleUploadSuccess({ file, fileList, response }) {
+ if (response.code === 200) {
+ const attachmentObj = {
+ fileName: file.name,
+ path: response.fileUrl || file.url,
+ fileUrl: response.fileUrl || file.url,
+ fileType: this.getFileExtension(file.name),
+ fileSize: file.size,
+ uploadTime: dayjs().format("YYYY-MM-DD HH:mm:ss")
+ };
+
+ if (!Array.isArray(this.attachments)) {
+ this.attachments = [];
+ }
+
+ this.attachments.push(attachmentObj);
+ this.attachmentFileList = fileList;
+ this.$message.success("鏂囦欢涓婁紶鎴愬姛");
+ }
+ },
+
+ /** 涓婁紶閿欒澶勭悊 */
+ handleUploadError({ file, fileList, error }) {
+ console.error("闄勪欢涓婁紶澶辫触:", error);
+ this.$message.error("鏂囦欢涓婁紶澶辫触锛岃閲嶈瘯");
+ },
+
+ /** 鎵嬪姩鍒犻櫎闄勪欢 */
+ handleRemoveAttachment(index) {
+ this.attachments.splice(index, 1);
+ this.attachmentFileList.splice(index, 1);
+ this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+ },
+
+ /** 鏂囦欢棰勮 */
+ handlePreview(file) {
+ this.currentPreviewFile = {
+ fileName: file.fileName,
+ fileUrl: file.path || file.fileUrl,
+ fileType: this.getFileType(file.fileName)
+ };
+ this.filePreviewVisible = true;
+ },
+ /** 鏂囦欢涓嬭浇 */
+ handleDownloadAttachment(file) {
+ const fileUrl = file.path || file.fileUrl;
+ const fileName = file.fileName;
+
+ if (fileUrl) {
+ const link = document.createElement("a");
+ link.href = fileUrl;
+ link.download = fileName;
+ link.style.display = "none";
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ this.$message.success("寮�濮嬩笅杞芥枃浠�");
+ } else {
+ this.$message.warning("鏂囦欢璺緞涓嶅瓨鍦紝鏃犳硶涓嬭浇");
+ }
+ },
+
+ /** 鑾峰彇鏂囦欢绫诲瀷 */
+ getFileType(fileName) {
+ if (!fileName) return "other";
+ const extension = fileName
+ .split(".")
+ .pop()
+ .toLowerCase();
+ const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
+ const pdfTypes = ["pdf"];
+ const officeTypes = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"];
+ if (imageTypes.includes(extension)) return "image";
+ if (pdfTypes.includes(extension)) return "pdf";
+ if (officeTypes.includes(extension)) return "office";
+ return "other";
+ },
+
+ /** 鑾峰彇鏂囦欢鍥炬爣棰滆壊 */
+ getFileIconColor(fileName) {
+ const type = this.getFileType(fileName);
+ const colorMap = {
+ image: "#67C23A",
+ pdf: "#F56C6C",
+ office: "#409EFF",
+ other: "#909399"
+ };
+ return colorMap[type] || "#909399";
+ },
+
+ /** 鑾峰彇鏂囦欢鏍囩绫诲瀷 */
+ getFileTagType(fileName) {
+ const type = this.getFileType(fileName);
+ const typeMap = {
+ image: "success",
+ pdf: "danger",
+ office: "primary",
+ other: "info"
+ };
+ return typeMap[type] || "info";
+ },
+
+ /** 鑾峰彇鏂囦欢绫诲瀷鏂囨湰 */
+ getFileTypeText(fileName) {
+ const type = this.getFileType(fileName);
+ const textMap = {
+ image: "鍥剧墖",
+ pdf: "PDF",
+ office: "鏂囨。",
+ other: "鍏朵粬"
+ };
+ return textMap[type] || "鏈煡";
+ },
+
+ /** 妫�鏌ユ槸鍚﹀彲棰勮 */
+ isPreviewable(fileName) {
+ const type = this.getFileType(fileName);
+ return ["image", "pdf"].includes(type);
+ },
+
+ /** 鑾峰彇鏂囦欢鎵╁睍鍚� */
+ getFileExtension(filename) {
+ return filename
+ .split(".")
+ .pop()
+ .toLowerCase();
+ },
+
+ /** 鏍煎紡鍖栨枃浠跺ぇ灏� */
+ formatFileSize(bytes) {
+ if (!bytes || bytes === 0) return "0 B";
+ const k = 1024;
+ const sizes = ["B", "KB", "MB", "GB"];
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
+ },
+
+ /** 鏃ユ湡鏃堕棿鏍煎紡鍖� */
+ formatDateTime(dateTime) {
+ if (!dateTime) return "";
+ try {
+ const date = new Date(dateTime);
+ if (isNaN(date.getTime())) return dateTime;
+ const year = date.getFullYear();
+ const month = String(date.getMonth() + 1).padStart(2, "0");
+ const day = String(date.getDate()).padStart(2, "0");
+ const hours = String(date.getHours()).padStart(2, "0");
+ const minutes = String(date.getMinutes()).padStart(2, "0");
+ return `${year}-${month}-${day} ${hours}:${minutes}`;
+ } catch (error) {
+ return dateTime;
+ }
}
}
};
</script>
-<style scoped>
-.utilization-overview {
- padding: 10px 0;
+<style lang="scss" scoped>
+.organ-utilization-detail {
+ padding: 20px;
+ background-color: #f5f7fa;
+ min-height: 100vh;
}
-.overview-item {
+.detail-card,
+.utilization-card,
+.followup-card,
+.attachment-card {
+ margin-bottom: 20px;
+ border-radius: 8px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+ border: 1px solid #e4e7ed;
+}
+
+/* 鏂板闄勪欢澶撮儴鏍峰紡 */
+.attachment-header {
display: flex;
align-items: center;
- margin-bottom: 15px;
- padding: 8px 0;
- border-bottom: 1px solid #f0f0f0;
+ gap: 8px;
+ margin-bottom: 16px;
+ padding-bottom: 8px;
+ border-bottom: 1px solid #ebeef5;
}
-.overview-icon {
- font-size: 24px;
- margin-right: 15px;
-}
-
-.overview-content .value {
- font-size: 24px;
- font-weight: bold;
+.attachment-title {
+ font-weight: 600;
color: #303133;
+ font-size: 16px;
}
-.overview-content .label {
+.attachment-tip {
font-size: 12px;
color: #909399;
+ margin-left: auto;
}
-.success-stats, .time-tracking, .quality-assessment {
- padding: 10px 0;
-}
-
-.success-item, .time-item, .quality-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 15px;
-}
-
-.success-item .label, .time-item .label, .quality-item .label {
- color: #606266;
- font-size: 14px;
- min-width: 80px;
-}
-
-.time-item .value {
- font-weight: 600;
- color: #409EFF;
-}
-
-.chart-container {
- position: relative;
- min-height: 300px;
-}
-
-.action-buttons {
- display: flex;
- justify-content: center;
- gap: 15px;
+.attachment-list {
margin-top: 20px;
}
-.card-header {
+.list-title {
+ font-weight: bold;
+ margin-bottom: 12px;
+ color: #303133;
+ font-size: 14px;
+}
+
+.file-name {
+ font-size: 13px;
+ margin-left: 8px;
+ color: #606266;
+}
+
+/* 鏂囦欢鍥炬爣鏍峰紡 */
+.el-icon-document {
+ font-size: 16px;
+ vertical-align: middle;
+}
+
+/* 淇濇寔鍘熸湁鏍峰紡 */
+.detail-title {
+ font-size: 18px;
+ font-weight: 600;
+ color: #303133;
+ line-height: 1.4;
+}
+
+/* 琛ㄦ牸鏁翠綋鏍峰紡 */
+:deep(.el-table) {
+ border-radius: 8px;
+ overflow: hidden;
+}
+
+:deep(.el-table th) {
+ background-color: #f5f7fa;
+ color: #606266;
+ font-weight: 600;
+}
+
+:deep(.el-table .cell) {
+ padding: 12px 8px;
+ line-height: 1.5;
+}
+
+/* 鏂戦┈绾硅〃鏍艰 */
+:deep(.el-table__row.warning-row) {
+ background-color: #fdf6ec;
+}
+
+:deep(.el-table__row.default-row) {
+ background-color: #f0f9ff;
+}
+
+/* 榧犳爣鎮仠鏁堟灉 */
+:deep(.el-table--enable-row-hover .el-table__body tr:hover > td) {
+ background-color: #f5f7fa !important;
+}
+
+/* 缁熻淇℃伅鏍峰紡 */
+.utilization-stats {
+ margin-top: 20px;
+ padding: 15px;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ border-radius: 8px;
+ color: white;
+}
+
+.stat-item {
display: flex;
- justify-content: space-between;
+ flex-direction: column;
align-items: center;
+ padding: 10px;
+ text-align: center;
+}
+
+.stat-label {
+ font-size: 12px;
+ opacity: 0.9;
+ margin-bottom: 5px;
+ color: rgba(255, 255, 255, 0.9);
+}
+
+.stat-value {
+ font-size: 18px;
+ font-weight: bold;
+ color: white;
+}
+
+/* 灞曞紑琛屾牱寮� */
+.recipient-detail-expand {
+ padding: 20px;
+ background: #fafafa;
+ border-radius: 8px;
+ margin: 10px 0;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+}
+
+.recipient-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 20px;
+ padding-bottom: 15px;
+ border-bottom: 2px solid #e4e7ed;
+}
+
+.recipient-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #303133;
+}
+
+/* 琛ㄥ崟閮ㄥ垎鏍峰紡 */
+.recipient-form {
+ background: white;
+ padding: 20px;
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+}
+
+/* 琛ㄥ崟閮ㄥ垎鏍囬 */
+.form-section {
+ margin-bottom: 25px;
+ padding-bottom: 20px;
+ border-bottom: 1px solid #f0f0f0;
+
+ &:last-child {
+ margin-bottom: 0;
+ padding-bottom: 0;
+ border-bottom: none;
+ }
+}
+
+.section-title {
+ font-size: 15px;
+ font-weight: 600;
+ color: #409eff;
+ margin: 0 0 15px 0;
+ padding-left: 10px;
+ border-left: 4px solid #409eff;
+ line-height: 1.2;
+}
+
+/* 琛ㄥ崟琛岄棿璺� */
+:deep(.el-form-item) {
+ margin-bottom: 20px;
+
+ .el-form-item__label {
+ font-weight: 500;
+ color: #606266;
+ padding-right: 10px;
+ }
+
+ .el-form-item__content {
+ line-height: 1.5;
+ }
+}
+
+/* 琛ㄥ崟杈撳叆妗嗘牱寮� */
+:deep(.el-input__inner) {
+ height: 36px;
+ line-height: 36px;
+ border-radius: 4px;
+ transition: all 0.3s ease;
+
+ &:focus {
+ border-color: #409eff;
+ box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
+ }
+
+ &:disabled {
+ background-color: #f5f7fa;
+ border-color: #e4e7ed;
+ color: #c0c4cc;
+ cursor: not-allowed;
+ }
+}
+
+/* 鏂囨湰鍩熸牱寮� */
+:deep(.el-textarea__inner) {
+ min-height: 80px;
+ border-radius: 4px;
+ transition: all 0.3s ease;
+
+ &:focus {
+ border-color: #409eff;
+ box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
+ }
+
+ &:disabled {
+ background-color: #f5f7fa;
+ border-color: #e4e7ed;
+ color: #c0c4cc;
+ cursor: not-allowed;
+ }
+}
+
+/* 閫夋嫨妗嗘牱寮� */
+:deep(.el-select) {
+ width: 100%;
+
+ .el-input__inner {
+ border-radius: 4px;
+ }
+
+ &.is-disabled {
+ .el-input__inner {
+ background-color: #f5f7fa;
+ border-color: #e4e7ed;
+ color: #c0c4cc;
+ }
+ }
+}
+
+/* 鏃ユ湡閫夋嫨鍣ㄦ牱寮� */
+:deep(.el-date-editor) {
+ width: 100%;
+
+ &.el-input__inner {
+ border-radius: 4px;
+ }
+
+ &.is-disabled {
+ .el-input__inner {
+ background-color: #f5f7fa;
+ border-color: #e4e7ed;
+ color: #c0c4cc;
+ }
+ }
+}
+
+/* 鍝嶅簲寮忚皟鏁� */
+@media (max-width: 768px) {
+ .recipient-detail-expand {
+ padding: 15px;
+ }
+
+ .recipient-form {
+ padding: 15px;
+ }
+
+ .attachment-header {
+ flex-wrap: wrap;
+ }
+
+ .attachment-tip {
+ width: 100%;
+ margin-top: 8px;
+ margin-left: 0;
+ }
+
+ .form-section {
+ margin-bottom: 20px;
+ padding-bottom: 15px;
+ }
+
+ :deep(.el-form-item) {
+ margin-bottom: 15px;
+ }
+
+ .section-title {
+ font-size: 14px;
+ margin-bottom: 12px;
+ }
+}
+
+:deep(.el-divider) {
+ margin: 20px 0;
+ background-color: #e4e7ed;
+}
+
+/* 琛ㄥ崟鏍囩鍜岃緭鍏ユ鏍峰紡 */
+:deep(.el-form-item__label) {
+ font-weight: 500;
+ color: #606266;
+}
+
+:deep(.el-input__inner:focus) {
+ border-color: #409eff;
+ box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
+}
+
+/* 鎸夐挳鏍峰紡浼樺寲 */
+:deep(.el-button--primary) {
+ background: linear-gradient(135deg, #409eff 0%, #3375e0 100%);
+ border: none;
+ border-radius: 4px;
+ transition: all 0.3s ease;
+}
+
+:deep(.el-button--primary:hover) {
+ transform: translateY(-1px);
+ box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4);
+}
+
+/* 搴曢儴鎿嶄綔鎸夐挳 */
+.dialog-footer {
+ margin-top: 20px;
+ text-align: center;
+ padding-top: 20px;
+ border-top: 1px solid #e4e7ed;
+}
+
+.dialog-footer .el-button {
+ margin: 0 10px;
+ min-width: 120px;
+}
+
+/* 绌虹姸鎬佹牱寮� */
+.empty-utilization {
+ text-align: center;
+ padding: 40px 0;
+ color: #909399;
+ background: #fafafa;
+ border-radius: 4px;
+ margin: 20px 0;
+}
+
+/* 鏂囦欢淇℃伅鏍峰紡 */
+.file-info {
+ display: flex;
+ align-items: center;
+ padding: 5px 0;
+}
+
+.file-info i {
+ font-size: 18px;
+ margin-right: 10px;
+}
+
+/* 骞虫澘璁惧閫傞厤 */
+@media (max-width: 1024px) {
+ .organ-utilization-detail {
+ padding: 15px;
+ }
+
+ :deep(.el-col) {
+ margin-bottom: 10px;
+ }
+}
+
+/* 鎵嬫満璁惧閫傞厤 */
+
+/* 瓒呭皬灞忓箷璁惧 */
+@media (max-width: 480px) {
+ .organ-utilization-detail {
+ padding: 5px;
+ }
+
+ :deep(.el-card__header) {
+ padding: 10px 15px;
+ }
}
</style>
diff --git a/src/views/business/course/index.vue b/src/views/business/course/index.vue
index 96c0531..dcbb645 100644
--- a/src/views/business/course/index.vue
+++ b/src/views/business/course/index.vue
@@ -70,64 +70,7 @@
<!-- 鍙充晶鍐呭鍖哄煙 - 鐙珛婊氬姩 -->
<div class="content-section">
<!-- 妗堜緥鍩烘湰淇℃伅 - 鍥哄畾楂樺害锛屽彲婊氬姩 -->
- <div class="basic-info-section">
- <div class="section-header">
- <h3>妗堜緥鍩烘湰淇℃伅</h3>
- <el-button
- type="primary"
- size="small"
- @click="handleEditBasicInfo"
- >
- 缂栬緫淇℃伅
- </el-button>
- </div>
-
- <div class="basic-info-content">
- <el-descriptions :column="2" border>
- <el-descriptions-item label="浣忛櫌鍙�">
- {{ caseInfo.caseNo }}
- </el-descriptions-item>
- <el-descriptions-item label="浣忛櫌鍙�">
- {{ caseInfo.hospitalNo }}
- </el-descriptions-item>
- <el-descriptions-item label="鎹愮尞鑰呭鍚�">
- {{ caseInfo.donorName }}
- </el-descriptions-item>
- <el-descriptions-item label="鎬у埆">
- <dict-tag
- :options="dict.type.sys_user_sex"
- :value="parseInt(caseInfo.gender)"
- />
- </el-descriptions-item>
- <el-descriptions-item label="骞撮緞">
- {{ caseInfo.age }} 宀�
- </el-descriptions-item>
- <el-descriptions-item label="琛�鍨�">
- <dict-tag
- :options="dict.type.sys_BloodType"
- :value="caseInfo.bloodType"
- />
- </el-descriptions-item>
- <el-descriptions-item label="鐤剧梾璇婃柇">
- {{ caseInfo.diagnosis }}
- </el-descriptions-item>
- <el-descriptions-item label="妗堜緥鐘舵��">
- <el-tag :type="getOverallStatusTag(caseInfo.status)">
- {{ getStatusText(caseInfo.status) }}
- </el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="鍒涘缓鏃堕棿">
- {{ formatTime(caseInfo.createTime) }}
- </el-descriptions-item>
- <el-descriptions-item label="鐧昏浜�">
- {{ caseInfo.registrant }}
- </el-descriptions-item>
- <el-descriptions-item label="褰撳墠闃舵">
- {{ getCurrentStageName() }}
- </el-descriptions-item>
- </el-descriptions>
- </div>
- </div>
+ <case-basic-info :case-id="caseId" :show-attachment="true" />
<!-- 闃舵璇︽儏鍐呭 - 鑷�傚簲楂樺害锛屽彲婊氬姩 -->
<div class="stage-detail-section">
@@ -163,6 +106,8 @@
import OrganAllocationStage from "./components/OrganAllocationStage";
import OrganProcurementStage from "./components/OrganProcurementStage";
import OrganUtilizationStage from "./components/OrganUtilizationStage";
+import CaseBasicInfo from "@/components/CaseBasicInfo";
+
import dayjs from "dayjs";
export default {
@@ -175,13 +120,14 @@
EthicalReviewStage,
OrganAllocationStage,
OrganProcurementStage,
- OrganUtilizationStage
+ OrganUtilizationStage,
+ CaseBasicInfo
},
dicts: ["sys_user_sex", "sys_BloodType", "sys_0_1"],
data() {
return {
caseId: null,
- infoid:null,
+ infoid: null,
caseInfo: {
id: "",
caseNo: "",
@@ -248,13 +194,13 @@
{
key: "organ_procurement",
name: "鍣ㄥ畼鑾峰彇",
- status: "pending",
+ status: "in_progress",
operator: "寰呭垎閰�"
},
{
key: "organ_utilization",
name: "鍣ㄥ畼鍒╃敤",
- status: "pending",
+ status: "in_progress",
operator: "寰呭垎閰�"
}
],
diff --git a/src/views/business/decide/DecideInfo.vue b/src/views/business/decide/DecideInfo.vue
index ee6b80a..0e262e8 100644
--- a/src/views/business/decide/DecideInfo.vue
+++ b/src/views/business/decide/DecideInfo.vue
@@ -1,7 +1,7 @@
<template>
<div class="death-judgment-detail">
<case-basic-info :case-id="caseId" :show-attachment="true" />
-<!-- 鍏叡淇℃伅妯″潡锛堢嫭绔嬫樉绀猴級 -->
+ <!-- 鍏叡淇℃伅妯″潡锛堢嫭绔嬫樉绀猴級 -->
<!-- 鍒ゅ畾绫诲瀷鏍囩椤� -->
<el-card class="type-card">
@@ -24,7 +24,7 @@
</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>
@@ -87,6 +87,15 @@
淇濆瓨淇℃伅
</el-button>
<el-button
+ v-if="isEdit"
+ style="float: right; margin-left: 10px;"
+ type="success"
+ @click="accomplish"
+ :loading="saveLoading"
+ >
+ 瀹屾垚鍒ゅ畾
+ </el-button>
+ <el-button
v-else
style="float: right; margin-left: 10px;"
type="primary"
@@ -103,7 +112,6 @@
<el-input v-model="form.deathreason" :readonly="!isEdit" />
</el-form-item>
</el-col>
-
</el-row>
<el-row :gutter="20">
@@ -430,8 +438,6 @@
</div>
</el-card>
-
-
<!-- 涓婁紶瀵硅瘽妗嗭紙鑴戞浜★級 -->
<el-dialog
:title="`涓婁紶${getCurrentBrainDeathTypeLabel}璇勪及琛╜"
@@ -659,7 +665,7 @@
this.infoid = this.$route.query.infoid;
this.caseId = this.infoid;
this.isEdit = this.$route.query.isEdit === "true";
-
+ this.activeJudgmentType = this.$route.query.type;
// 浠庤矾鐢卞弬鏁拌幏鍙栭粯璁ゆ樉绀虹被鍨�
if (this.$route.query.judgmentType) {
this.activeJudgmentType = this.$route.query.judgmentType;
@@ -1047,7 +1053,19 @@
handleEdit() {
this.isEdit = true;
},
+ accomplish() {
+ this.$confirm("鏄惁纭瀹屾垚璇ユ渚嬫浜″垽瀹氬叏閮ㄤ俊鎭紵", "鎻愰啋", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(() => {
+ this.form.state = 3;
+ this.handleSave();
+ })
+ .catch(() => {});
+ },
// 淇濆瓨淇℃伅
async handleSave() {
// 鏍规嵁褰撳墠鏍囩閫夋嫨楠岃瘉瑙勫垯
@@ -1067,6 +1085,9 @@
rememberAnnex: this.buildBrainDeathAttachmentJson(),
heartdeathjudgeannex: this.buildHeartDeathAttachmentJson()
};
+ if (submitData.state == 1 || !submitData.state) {
+ submitData.state = 2;
+ }
let response = null;
if (submitData.id) {
diff --git a/src/views/business/decide/index.vue b/src/views/business/decide/index.vue
index 8440ea5..9ccf9f2 100644
--- a/src/views/business/decide/index.vue
+++ b/src/views/business/decide/index.vue
@@ -62,11 +62,20 @@
<el-card class="tool-card">
<el-row :gutter="10">
<el-col :span="16">
- <!-- <el-button type="primary" icon="el-icon-plus" @click="handleCreate"
- >鏂板缓姝讳骸鍒ゅ畾</el-button
+ <!-- <el-button
+ type="primary"
+ icon="el-icon-plus"
+ @click="handleCreate"
+ >鏂板鑴戞浜″垽瀹�</el-button
>
<el-button
type="success"
+ icon="el-icon-plus"
+ @click="handleCreateHeartDeath"
+ >鏂板蹇冩浜″垽瀹�</el-button
+ >
+ <el-button
+ type="warning"
icon="el-icon-edit"
:disabled="single"
@click="handleUpdate"
@@ -93,37 +102,32 @@
v-loading="loading"
:data="deathJudgmentList"
@selection-change="handleSelectionChange"
+ :header-cell-style="{ background: '#f5f7fa', 'font-weight': 'bold' }"
>
<el-table-column type="selection" width="55" align="center" />
- <!--
- <el-table-column
- label="妗堜緥缂栧彿"
- align="center"
- prop="caseNo"
- width="120"
- />
- <el-table-column
- label="娌荤枟鍖婚櫌"
- align="center"
- prop="treatmenthospitalname"
- width="180"
- show-overflow-tooltip
- />
- -->
-
+
+ <!-- 鍩虹淇℃伅鍒� -->
<el-table-column
label="浣忛櫌鍙�"
align="center"
prop="inpatientno"
width="120"
+ fixed="left"
/>
<el-table-column
label="濮撳悕"
align="center"
prop="name"
- width="120"
+ width="100"
+ fixed="left"
/>
- <el-table-column label="鎬у埆" align="center" prop="sex" width="80">
+ <el-table-column
+ label="鎬у埆"
+ align="center"
+ prop="sex"
+ width="80"
+ fixed="left"
+ >
<template slot-scope="scope">
<dict-tag
:options="dict.type.sys_user_sex"
@@ -131,8 +135,14 @@
/>
</template>
</el-table-column>
- <el-table-column label="骞撮緞" align="center" prop="age" width="80" />
-
+ <el-table-column
+ label="骞撮緞"
+ align="center"
+ prop="age"
+ width="80"
+ fixed="left"
+ />
+
<el-table-column
label="鐤剧梾璇婃柇"
align="center"
@@ -140,56 +150,124 @@
min-width="200"
show-overflow-tooltip
/>
- <el-table-column
- label="姝讳骸鍘熷洜"
- align="center"
- prop="deathreason"
- width="120"
- >
- <template slot-scope="scope">
- <el-tag :type="reasonFilter(scope.row.deathreason)">
- {{ reasonTextFilter(scope.row.deathreason) }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column
- label="姝讳骸鏃堕棿"
- align="center"
- prop="deathtime"
- width="160"
- >
- <template slot-scope="scope">
- <span>{{
- scope.row.deathtime
- ? parseTime(scope.row.deathtime, "{y}-{m}-{d} {h}:{i}")
- : "-"
- }}</span>
- </template>
- </el-table-column>
- <el-table-column
- label="鍒ゅ畾鍖荤敓涓�"
- align="center"
- prop="deathjudgedocto"
- width="120"
- />
- <el-table-column
- label="鍒ゅ畾鍖荤敓浜�"
- align="center"
- prop="deathjudgedoctt"
- width="120"
- />
+ <!-- 鐘舵�佷俊鎭� -->
<el-table-column
label="鍒ゅ畾鐘舵��"
align="center"
- prop="recordstate"
+ prop="state"
width="100"
>
<template slot-scope="scope">
- <el-tag :type="statusFilter(scope.row.recordstate)">
- {{ statusTextFilter(scope.row.recordstate) }}
- </el-tag>
+ <dict-tag
+ :options="dict.type.decide_type"
+ :value="scope.row.state"
+ />
</template>
</el-table-column>
+ <!-- 鑴戞浜″垽瀹氫俊鎭� -->
+ <el-table-column label="鑴戞浜″垽瀹�" align="center">
+ <el-table-column
+ label="姝讳骸鍘熷洜"
+ align="center"
+ prop="deathreason"
+ width="120"
+ >
+ <template slot-scope="scope">
+ <el-tag
+ v-if="scope.row.deathreason"
+ :type="getDeathReasonTagType(scope.row.deathreason)"
+ >
+ {{ getDeathReasonText(scope.row.deathreason) }}
+ </el-tag>
+ <span v-else>-</span>
+ </template>
+ </el-table-column>
+ <el-table-column
+ label="姝讳骸鏃堕棿"
+ align="center"
+ prop="deathtime"
+ width="160"
+ >
+ <template slot-scope="scope">
+ <span>{{
+ scope.row.deathtime ? formatTime(scope.row.deathtime) : "-"
+ }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column
+ label="鍒ゅ畾鍖荤敓涓�"
+ align="center"
+ prop="deathjudgedocto"
+ width="120"
+ >
+ <template slot-scope="scope">
+ {{ scope.row.deathjudgedocto || "-" }}
+ </template>
+ </el-table-column>
+ <el-table-column
+ label="鍒ゅ畾鍖荤敓浜�"
+ align="center"
+ prop="deathjudgedoctt"
+ width="120"
+ >
+ <template slot-scope="scope">
+ {{ scope.row.deathjudgedoctt || "-" }}
+ </template>
+ </el-table-column>
+ </el-table-column>
+
+ <!-- 蹇冩浜″垽瀹氫俊鎭� -->
+ <el-table-column label="蹇冩浜″垽瀹�" align="center">
+ <el-table-column
+ label="姝讳骸鍘熷洜"
+ align="center"
+ prop="heartdeathreason"
+ width="120"
+ >
+ <template slot-scope="scope">
+ <el-tag v-if="scope.row.heartdeathreason" type="danger">
+ {{ getHeartDeathReasonText(scope.row.heartdeathreason) }}
+ </el-tag>
+ <span v-else>-</span>
+ </template>
+ </el-table-column>
+ <el-table-column
+ label="姝讳骸鏃堕棿"
+ align="center"
+ prop="heartdeathtime"
+ width="160"
+ >
+ <template slot-scope="scope">
+ <span>{{
+ scope.row.heartdeathtime
+ ? formatTime(scope.row.heartdeathtime)
+ : "-"
+ }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column
+ label="鍒ゅ畾鍖荤敓涓�"
+ align="center"
+ prop="heartdeathjudgedocto"
+ width="120"
+ >
+ <template slot-scope="scope">
+ {{ scope.row.heartdeathjudgedocto || "-" }}
+ </template>
+ </el-table-column>
+ <el-table-column
+ label="鍒ゅ畾鍖荤敓浜�"
+ align="center"
+ prop="heartdeathjudgedoctt"
+ width="120"
+ >
+ <template slot-scope="scope">
+ {{ scope.row.heartdeathjudgedoctt || "-" }}
+ </template>
+ </el-table-column>
+ </el-table-column>
+
+ <!-- 鍒ゅ畾鏃堕棿鍜屾搷浣滃垪 -->
<el-table-column
label="鍒ゅ畾鏃堕棿"
align="center"
@@ -198,16 +276,15 @@
>
<template slot-scope="scope">
<span>{{
- scope.row.createTime
- ? parseTime(scope.row.createTime, "{y}-{m}-{d} {h}:{i}")
- : "-"
+ scope.row.createTime ? formatTime(scope.row.createTime) : "-"
}}</span>
</template>
</el-table-column>
+
<el-table-column
label="鎿嶄綔"
align="center"
- width="180"
+ width="200"
fixed="right"
class-name="small-padding fixed-width"
>
@@ -219,13 +296,23 @@
@click="handleView(scope.row)"
>璇︽儏</el-button
>
- <el-button
+ <el-dropdown
size="mini"
- type="text"
- icon="el-icon-edit"
- @click="handleUpdate(scope.row)"
- >淇敼</el-button
+ @command="command => handleUpdateDropdown(scope.row, command)"
>
+ <el-button
+ size="mini"
+ type="text"
+ icon="el-icon-edit"
+ class="el-button--text"
+ >
+ 淇敼<i class="el-icon-arrow-down el-icon--right"></i>
+ </el-button>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item command="brainDeath">鑴戞浜�</el-dropdown-item>
+ <el-dropdown-item command="heartDeath">蹇冩浜�</el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
</template>
</el-table-column>
</el-table>
@@ -253,7 +340,7 @@
export default {
name: "DeathJudgmentList",
components: { Pagination },
- dicts: ["sys_user_sex"],
+ dicts: ["sys_user_sex", "decide_type"],
data() {
return {
// 閬僵灞�
@@ -278,49 +365,63 @@
deathTimeRange: []
},
// 鎵�鏈夋暟鎹紙鐢ㄤ簬鍓嶇绛涢�夛級
- allTableData: []
+ allTableData: [],
+ // 姝讳骸鍘熷洜鏄犲皠
+ deathReasonMap: {
+ brain_death: { text: "鑴戞浜�", type: "primary" },
+ heart_death: { text: "蹇冩浜�", type: "danger" },
+ other: { text: "鍏朵粬", type: "info" }
+ },
+ // 蹇冩浜″師鍥犳槧灏�
+ heartDeathReasonMap: {
+ cardiac_arrest: { text: "蹇冩悘楠ゅ仠", type: "danger" },
+ myocardial_infarction: { text: "蹇冭倢姊楁", type: "danger" },
+ heart_failure: { text: "蹇冨姏琛扮", type: "danger" },
+ other: { text: "鍏朵粬", type: "info" }
+ },
+ // 鐘舵�佹槧灏�
+ statusMap: {
+ "0": { text: "缁存姢涓�", type: "warning" },
+ "1": { text: "宸插畬鎴�", type: "success" },
+ "2": { text: "瀹℃牳涓�", type: "info" },
+ "99": { text: "宸茬粓姝�", type: "danger" }
+ }
};
},
created() {
this.getList();
},
methods: {
- // 姝讳骸鍘熷洜杩囨护鍣�
- reasonFilter(reason) {
- const reasonMap = {
- brain_death: "primary",
- heart_death: "danger",
- other: "info"
- };
- return reasonMap[reason] || "info";
+ // 鑾峰彇姝讳骸鍘熷洜鏍囩绫诲瀷
+ getDeathReasonTagType(reason) {
+ return this.deathReasonMap[reason]?.type || "info";
},
- reasonTextFilter(reason) {
- const reasonMap = {
- brain_death: "鑴戞浜�",
- heart_death: "蹇冩浜�",
- other: "鍏朵粬"
- };
- return reasonMap[reason] || "鏈煡";
+ // 鑾峰彇姝讳骸鍘熷洜鏂囨湰
+ getDeathReasonText(reason) {
+ return this.deathReasonMap[reason]?.text || "鏈煡";
},
- // 璁板綍鐘舵�佽繃婊ゅ櫒
- statusFilter(status) {
- const statusMap = {
- "0": "warning", // 缁存姢涓�
- "1": "success", // 宸插畬鎴�
- "99": "danger" // 宸茬粓姝�
- };
- return statusMap[status] || "info";
+ // 鑾峰彇蹇冩浜″師鍥犳枃鏈�
+ getHeartDeathReasonText(reason) {
+ if (!reason) return "-";
+ return this.heartDeathReasonMap[reason]?.text || reason;
},
- statusTextFilter(status) {
- const statusMap = {
- "0": "缁存姢涓�",
- "1": "宸插畬鎴�",
- "99": "宸茬粓姝�"
- };
- return statusMap[status] || "鏈煡鐘舵��";
+ // 鑾峰彇鐘舵�佹爣绛剧被鍨�
+ getStatusTagType(status) {
+ return this.statusMap[status]?.type || "info";
+ },
+
+ // 鑾峰彇鐘舵�佹枃鏈�
+ getStatusText(status) {
+ return this.statusMap[status]?.text || "鏈煡鐘舵��";
+ },
+
+ // 鏍煎紡鍖栨椂闂�
+ formatTime(time) {
+ if (!time) return "-";
+ return this.parseTime(time, "{y}-{m}-{d} {h}:{i}");
},
// 鏌ヨ姝讳骸鍒ゅ畾鍒楄〃
@@ -331,21 +432,13 @@
// 鏍规嵁瀹為檯鎺ュ彛杩斿洖缁撴瀯璋冩暣
let realData = [];
- realData = response.data;
- this.total = response.total;
- // if (Array.isArray(response)) {
- // realData = response;
- // } else if (response && response.data) {
- // realData = response.data;
- // } else if (response && response.rows) {
- // realData = response.rows;
- // this.total = response.total || response.rows.length;
- // } else if (response && response.code === 200) {
- // realData = response.data.rows || response.data;
- // this.total = response.data.total || realData.length;
- // } else {
- // realData = [];
- // }
+ if (response.code === 200) {
+ realData = response.rows || response.data || [];
+ this.total = response.total || realData.length;
+ } else {
+ realData = [];
+ this.total = 0;
+ }
// 瀛樺偍鎵�鏈夋暟鎹敤浜庡墠绔瓫閫�
this.allTableData = realData;
@@ -354,12 +447,14 @@
let filteredData = this.applyFrontendFilter(realData);
// 鍓嶇鍒嗛〉澶勭悊锛堝鏋滄帴鍙d笉鏀寔鍚庣鍒嗛〉锛�
- if (!response.total && !response.data) {
+ if (
+ this.total === filteredData.length &&
+ this.total > this.queryParams.pageSize
+ ) {
const startIndex =
(this.queryParams.pageNum - 1) * this.queryParams.pageSize;
const endIndex = startIndex + this.queryParams.pageSize;
this.deathJudgmentList = filteredData.slice(startIndex, endIndex);
- this.total = filteredData.length;
} else {
// 鎺ュ彛宸插垎椤碉紝鐩存帴浣跨敤杩斿洖鏁版嵁
this.deathJudgmentList = filteredData;
@@ -383,22 +478,33 @@
filteredData = filteredData.filter(
item =>
item.inpatientno &&
- item.inpatientno.includes(this.queryParams.inpatientno)
+ item.inpatientno
+ .toString()
+ .toLowerCase()
+ .includes(this.queryParams.inpatientno.toLowerCase())
);
}
// 濮撳悕绛涢��
if (this.queryParams.name) {
filteredData = filteredData.filter(
- item => item.name && item.name.includes(this.queryParams.name)
+ item =>
+ item.name &&
+ item.name
+ .toLowerCase()
+ .includes(this.queryParams.name.toLowerCase())
);
}
// 姝讳骸鍘熷洜绛涢��
if (this.queryParams.deathreason) {
- filteredData = filteredData.filter(
- item => item.deathreason === this.queryParams.deathreason
- );
+ filteredData = filteredData.filter(item => {
+ // 鍚屾椂绛涢�夎剳姝讳骸鍜屽績姝讳骸鍘熷洜
+ return (
+ item.deathreason === this.queryParams.deathreason ||
+ item.heartdeathreason === this.queryParams.deathreason
+ );
+ });
}
// 姝讳骸鏃堕棿鑼冨洿绛涢��
@@ -408,11 +514,24 @@
) {
const [startDate, endDate] = this.queryParams.deathTimeRange;
filteredData = filteredData.filter(item => {
- if (!item.deathtime) return false;
- const deathTime = new Date(item.deathtime).getTime();
+ // 鍚屾椂绛涢�夎剳姝讳骸鏃堕棿鍜屽績姝讳骸鏃堕棿
+ const brainDeathTime = item.deathtime
+ ? new Date(item.deathtime).getTime()
+ : null;
+ const heartDeathTime = item.heartdeathtime
+ ? new Date(item.heartdeathtime).getTime()
+ : null;
const startTime = new Date(startDate).getTime();
const endTime = new Date(endDate + " 23:59:59").getTime();
- return deathTime >= startTime && deathTime <= endTime;
+
+ return (
+ (brainDeathTime &&
+ brainDeathTime >= startTime &&
+ brainDeathTime <= endTime) ||
+ (heartDeathTime &&
+ heartDeathTime >= startTime &&
+ heartDeathTime <= endTime)
+ );
});
}
@@ -443,25 +562,71 @@
handleView(row) {
this.$router.push({
path: "/case/DecideInfo",
- query: { id: row.id,infoid:row.infoid }
+ query: {
+ id: row.id,
+ infoid: row.infoid,
+ type: this.getDeathType(row) // 浼犻�掓浜$被鍨�
+ }
});
},
- // 鏂板鎸夐挳鎿嶄綔
- handleCreate() {
- this.$router.push("/case/DecideInfo");
+ // 鑾峰彇姝讳骸绫诲瀷
+ getDeathType(row) {
+ if (row.deathreason && row.deathreason.includes("brain")) {
+ return "brain";
+ } else if (row.heartdeathreason) {
+ return "heart";
+ }
+ return "brain"; // 榛樿鑴戞浜�
},
- // 淇敼鎸夐挳鎿嶄綔
- handleUpdate(row) {
- const id = row.id || this.ids[0];
+ // 鏂板鑴戞浜″垽瀹�
+ handleCreate() {
this.$router.push({
path: "/case/DecideInfo",
- query: { id: id,infoid:row.infoid, isEdit: true }
+ query: { type: "brain" }
});
},
- // 瀵煎嚭鎸夐挳鎿嶄綔锛堟ā鎷熻皟鐢級
+ // 鏂板蹇冩浜″垽瀹�
+ handleCreateHeartDeath() {
+ this.$router.push({
+ path: "/case/DecideInfo",
+ query: { type: "heart" }
+ });
+ },
+
+ // 淇敼鎸夐挳鎿嶄綔锛堜笅鎷夎彍鍗曪級
+ handleUpdateDropdown(row, command) {
+ const id = row.id;
+ const infoid = row.infoid;
+
+ if (command === "brainDeath") {
+ // 淇敼鑴戞浜″垽瀹�
+ this.$router.push({
+ path: "/case/DecideInfo",
+ query: {
+ id: id,
+ infoid: infoid,
+ type: "brain",
+ isEdit: true
+ }
+ });
+ } else if (command === "heartDeath") {
+ // 淇敼蹇冩浜″垽瀹�
+ this.$router.push({
+ path: "/case/DecideInfo",
+ query: {
+ id: id,
+ infoid: infoid,
+ type: "heart",
+ isEdit: true
+ }
+ });
+ }
+ },
+
+ // 瀵煎嚭鎸夐挳鎿嶄綔
handleExport() {
this.$confirm("鏄惁纭瀵煎嚭鎵�鏈夋浜″垽瀹氭暟鎹紵", "璀﹀憡", {
confirmButtonText: "纭畾",
@@ -470,19 +635,13 @@
})
.then(() => {
this.loading = true;
- // 妯℃嫙瀵煎嚭鎿嶄綔
- return new Promise(resolve => {
- setTimeout(() => {
- resolve({ code: 200 });
- }, 1000);
- });
+ // 杩欓噷璋冪敤瀵煎嚭鎺ュ彛
+ return this.exportData();
})
.then(response => {
if (response.code === 200) {
this.$message.success("瀵煎嚭鎴愬姛");
- // 瀹為檯椤圭洰涓繖閲屽鐞嗘枃浠朵笅杞�
- // 鍙互娣诲姞浠ヤ笅浠g爜鏉ヨЕ鍙戞枃浠朵笅杞�
- // this.downloadFile();
+ this.downloadExportFile(response);
}
this.loading = false;
})
@@ -491,18 +650,34 @@
});
},
- // 鏂囦欢涓嬭浇鏂规硶锛堥鐣欙級
- downloadFile() {
- // 瀹為檯椤圭洰涓殑鏂囦欢涓嬭浇閫昏緫
- const link = document.createElement("a");
- link.style.display = "none";
- link.href = "/api/export/death-judgment"; // 鏇挎崲涓哄疄闄呭鍑烘帴鍙�
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
+ // 瀵煎嚭鏁版嵁
+ async exportData() {
+ try {
+ // 璋冪敤瀵煎嚭鎺ュ彛
+ const response = await exportDeathJudgment(this.queryParams);
+ return response;
+ } catch (error) {
+ console.error("瀵煎嚭澶辫触:", error);
+ this.$message.error("瀵煎嚭澶辫触");
+ throw error;
+ }
},
- // 鏃堕棿鏍煎紡鍖�
+ // 涓嬭浇瀵煎嚭鏂囦欢
+ downloadExportFile(response) {
+ // 鍋囪鎺ュ彛杩斿洖鏂囦欢涓嬭浇鍦板潃
+ if (response.data && response.data.fileUrl) {
+ const link = document.createElement("a");
+ link.style.display = "none";
+ link.href = response.data.fileUrl;
+ link.download = "姝讳骸鍒ゅ畾鏁版嵁.xlsx";
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ }
+ },
+
+ // 鏃堕棿鏍煎紡鍖栧伐鍏峰嚱鏁�
parseTime(time, pattern) {
if (!time) return "";
const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}";
@@ -557,16 +732,73 @@
}
.fixed-width .el-button {
- margin: 0 5px;
+ margin: 0 2px;
}
/* 琛ㄦ牸鏍峰紡浼樺寲 */
-::v-deep .el-table .cell {
- padding: 8px 4px;
+::v-deep .el-table {
+ border: 1px solid #ebeef5;
+ border-radius: 4px;
}
::v-deep .el-table th {
background-color: #f5f7fa;
font-weight: bold;
+ color: #333;
+}
+
+::v-deep .el-table .cell {
+ padding: 8px 4px;
+ line-height: 1.5;
+}
+
+::v-deep .el-table--border td,
+::v-deep .el-table--border th {
+ border-right: 1px solid #ebeef5;
+}
+
+::v-deep .el-table--border {
+ border: 1px solid #ebeef5;
+ border-bottom: none;
+}
+
+/* 澶氱骇琛ㄥご鏍峰紡 */
+::v-deep .el-table .el-table__header-wrapper tr:first-child th {
+ background-color: #f8f9fa;
+ border-bottom: 2px solid #409eff;
+}
+
+::v-deep .el-table .el-table__header-wrapper tr:nth-child(2) th {
+ background-color: #f0f7ff;
+}
+
+/* 鎿嶄綔鍒楁寜閽牱寮� */
+.el-dropdown-link {
+ cursor: pointer;
+ color: #409eff;
+}
+
+.el-dropdown-link:hover {
+ color: #66b1ff;
+}
+
+/* 鏍囩鏍峰紡浼樺寲 */
+::v-deep .el-tag {
+ margin: 2px;
+ border-radius: 12px;
+ font-size: 12px;
+ padding: 0 8px;
+ height: 24px;
+ line-height: 22px;
+}
+
+/* 鍒嗛〉鏍峰紡 */
+.pagination-container {
+ margin-top: 20px;
+ padding: 10px 0;
+ background: #fff;
+ border: 1px solid #ebeef5;
+ border-top: none;
+ border-radius: 0 0 4px 4px;
}
</style>
diff --git a/src/views/business/ethicalReview/ethicalReviewInfo.vue b/src/views/business/ethicalReview/ethicalReviewInfo.vue
index 1c4b908..c783e46 100644
--- a/src/views/business/ethicalReview/ethicalReviewInfo.vue
+++ b/src/views/business/ethicalReview/ethicalReviewInfo.vue
@@ -234,14 +234,6 @@
>
鍙戦�佷富濮斾笓瀹�
</el-button>
- <el-button
- size="mini"
- type="warning"
- @click="handleBatchSend"
- :disabled="!canBatchSend"
- >
- 鎵归噺鍙戦��
- </el-button>
</div>
</div>
@@ -373,6 +365,14 @@
</template>
</el-table-column>
+ <el-table-column label="鎴鏃堕棿" width="160" align="center">
+ <template slot-scope="scope">
+ <span>{{
+ scope.row.endTime ? formatDateTime(scope.row.endTime) : "鏈缃�"
+ }}</span>
+ </template>
+ </el-table-column>
+
<el-table-column label="瀹℃煡鏃堕棿" width="160" align="center">
<template slot-scope="scope">
<span>{{
@@ -392,7 +392,7 @@
</template>
</el-table-column>
- <el-table-column label="鎿嶄綔" width="280" align="center" fixed="right">
+ <el-table-column label="鎿嶄綔" width="180" align="center" fixed="right">
<template slot-scope="scope">
<el-button
size="mini"
@@ -417,27 +417,11 @@
}}
</el-button>
<el-button
- size="mini"
- type="text"
- icon="el-icon-edit"
- @click="handleEditExpertReview(scope.row)"
- :disabled="!['2', '3'].includes(scope.row.receiveStatus)"
- >
- 缂栬緫
- </el-button>
- <el-button
- size="mini"
- type="text"
- icon="el-icon-view"
- @click="handleViewExpertReview(scope.row)"
- >
- 璇︽儏
- </el-button>
- <el-button
+ v-if="scope.row.receiveStatus == 0"
size="mini"
type="text"
icon="el-icon-delete"
- @click="handleDeleteExpertReview(scope.$index)"
+ @click="handleDeleteExpertReview(scope.row, scope.$index)"
style="color: #f56c6c;"
>
鍒犻櫎
@@ -482,7 +466,7 @@
</div>
<el-table
- :data="expertList"
+ :data="filteredExpertList"
v-loading="expertListLoading"
style="width: 100%"
max-height="400"
@@ -534,7 +518,7 @@
:page-sizes="[10, 20, 50, 100]"
:page-size="expertPage.pageSize"
layout="total, sizes, prev, pager, next, jumper"
- :total="expertTotal"
+ :total="filteredExpertTotal"
></el-pagination>
</div>
@@ -554,6 +538,7 @@
:title="sendDialogTitle"
:visible.sync="sendDialogVisible"
width="500px"
+ @close="handleSendDialogClose"
>
<el-form :model="sendForm" ref="sendForm" label-width="100px">
<el-form-item label="涓撳绫诲瀷" prop="expertType">
@@ -589,6 +574,16 @@
style="width: 100%"
:disabled="sendForm.expertType === 'chief'"
/>
+ <div v-if="sendForm.expertType !== 'chief'" style="margin-top: 5px;">
+ <el-button-group>
+ <el-button size="mini" @click="setEndTime(0.5)"
+ >鍗婂皬鏃跺悗</el-button
+ >
+ <el-button size="mini" @click="setEndTime(1)">涓�灏忔椂鍚�</el-button>
+ <el-button size="mini" @click="setEndTime(2)">涓ゅ皬鏃跺悗</el-button>
+ <el-button size="mini" @click="setEndTime(24)">涓�澶╁悗</el-button>
+ </el-button-group>
+ </div>
<div
v-if="sendForm.expertType === 'chief'"
style="font-size: 12px; color: #999; margin-top: 5px;"
@@ -610,36 +605,23 @@
</el-select>
</el-form-item>
- <el-form-item
- label="閫夋嫨涓撳"
- prop="expertIds"
- v-if="sendForm.expertType == 'normal'"
- >
- <el-select
- v-model="sendForm.expertIds"
- multiple
- placeholder="璇烽�夋嫨涓撳"
- style="width: 100%"
- >
- <el-option
- v-for="expert in availableNormalExperts"
- :key="getExpertKey(expert)"
- :label="
- `${expert.expertname}${
- expert.expertNo ? '(' + expert.expertNo + ')' : ''
- }`
- "
- :value="getExpertKey(expert)"
- />
- </el-select>
+ <el-form-item label="鍙戦�佹爣棰�" prop="title" required>
+ <el-input v-model="sendForm.title" placeholder="璇疯緭鍏ュ彂閫佹爣棰�" />
</el-form-item>
- <el-form-item label="鍙戦�佸唴瀹�" prop="content">
+ <el-form-item label="鍙戦�佸唴瀹�" prop="content" required>
<el-input
type="textarea"
:rows="4"
v-model="sendForm.content"
placeholder="璇疯緭鍏ュ彂閫佺粰涓撳鐨勫鏌ュ唴瀹硅鏄�"
+ />
+ </el-form-item>
+
+ <el-form-item label="璺宠浆閾炬帴" prop="url">
+ <el-input
+ v-model="sendForm.url"
+ placeholder="璇疯緭鍏ヨ烦杞摼鎺ワ紙鍙�夛級"
/>
</el-form-item>
</el-form>
@@ -781,7 +763,8 @@
ethicalreviewedit,
ethicalreviewadd,
ethicalreviewInfo,
- ethicalreExpertTotal
+ ethicalreExpertTotal,
+ sendNotification
} from "@/api/businessApi";
import { listExternalperson } from "@/api/project/externalperson";
import CaseBasicInfo from "@/components/CaseBasicInfo";
@@ -917,7 +900,9 @@
startTime: "",
endTime: "",
sendType: "0",
- content: ""
+ title: "浼︾悊瀹℃煡浠诲姟閫氱煡",
+ content: "",
+ url: ""
},
// 涓撳鍘嗗彶瀹℃壒鎯呭喌
@@ -926,8 +911,8 @@
expertHistoryData: null,
currentExpertInfo: {},
- // 鍐呴儴鐘舵�佽窡韪�
- internalExpertList: []
+ // 褰撳墠鍙戦�佺殑涓撳
+ currentSendExperts: []
};
},
computed: {
@@ -1028,12 +1013,43 @@
return this.availableChiefExperts.length > 0 && normalApprovedCount >= 12;
},
- // 鏄惁鍙互鎵归噺鍙戦��
- canBatchSend() {
- return (
- this.availableNormalExperts.length > 0 ||
- this.availableChiefExperts.length > 0
- );
+ // 宸插瓨鍦ㄧ殑涓撳缂栧彿鍒楄〃
+ existingExpertNos() {
+ return this.ethicalreviewopinionsList
+ .map(expert => expert.expertNo)
+ .filter(no => no);
+ },
+
+ // 宸插瓨鍦ㄧ殑涓撳濮撳悕鍒楄〃
+ existingExpertNames() {
+ return this.ethicalreviewopinionsList
+ .map(expert => expert.expertname)
+ .filter(name => name);
+ },
+
+ // 杩囨护鍚庣殑涓撳鍒楄〃锛堟帓闄ゅ凡瀛樺湪鐨勪笓瀹讹級
+ filteredExpertList() {
+ if (!this.expertList.length) return [];
+
+ return this.expertList.filter(expert => {
+ // 濡傛灉涓撳鏈夌紪鍙凤紝妫�鏌ョ紪鍙锋槸鍚﹀凡瀛樺湪
+ if (expert.userno && this.existingExpertNos.includes(expert.userno)) {
+ return false;
+ }
+ // 濡傛灉涓撳鏈夊鍚嶏紝妫�鏌ュ鍚嶆槸鍚﹀凡瀛樺湪
+ if (
+ expert.username &&
+ this.existingExpertNames.includes(expert.username)
+ ) {
+ return false;
+ }
+ return true;
+ });
+ },
+
+ // 杩囨护鍚庣殑涓撳鎬绘暟
+ filteredExpertTotal() {
+ return this.filteredExpertList.length;
},
// 褰撳墠鐢ㄦ埛淇℃伅
@@ -1057,8 +1073,6 @@
"form.ethicalreviewopinionsList": {
handler(newVal) {
console.log("涓撳鍒楄〃鍙樺寲:", newVal);
- // 寮哄埗瑙﹀彂璁$畻灞炴�ф洿鏂�
- this.$forceUpdate();
},
deep: true
}
@@ -1371,7 +1385,20 @@
if (this.sendForm.expertType === "chief") {
// 涓诲涓撳鏃犻渶璁剧疆鎴鏃堕棿
this.sendForm.endTime = "";
+ } else {
+ // 鏅�氫笓瀹堕噸缃埅姝㈡椂闂翠负褰撳墠鏃堕棿
+ this.sendForm.endTime = "";
}
+ },
+
+ // 璁剧疆鎴鏃堕棿蹇嵎閿�
+ setEndTime(hours) {
+ const now = new Date();
+ const endTime = new Date(now.getTime() + hours * 60 * 60 * 1000);
+ this.sendForm.endTime = endTime
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19);
},
// 淇濆瓨淇℃伅
@@ -1379,6 +1406,10 @@
this.$refs.form.validate(async valid => {
if (valid) {
this.saveLoading = true;
+ // 淇濆瓨娓呯┖id渚夸簬鍚庣鏁翠綋鍒犻櫎鏂板
+ this.form.ethicalreviewopinionsList.forEach(item=>{
+ item.id=null
+ })
try {
const submitData = {
...this.form,
@@ -1495,9 +1526,6 @@
if (response.code === 200) {
this.$message.success("瀹℃煡宸蹭腑姝紝鎵�鏈変笓瀹剁姸鎬佸凡鏇存柊");
this.form.status = "2";
-
- // 瑙﹀彂璁$畻灞炴�ф洿鏂�
- this.$forceUpdate();
} else {
this.$message.error("鎿嶄綔澶辫触锛�" + (response.msg || "鏈煡閿欒"));
}
@@ -1575,8 +1603,8 @@
const response = await listExternalperson(params);
if (response.code === 200) {
- this.expertList = response.rows;
- this.expertTotal = response.total;
+ this.expertList = response.rows || [];
+ this.expertTotal = response.total || 0;
} else {
this.$message.error(
"鍔犺浇涓撳鍒楄〃澶辫触锛�" + (response.msg || "鏈煡閿欒")
@@ -1621,21 +1649,8 @@
this.$set(this.form, "ethicalreviewopinionsList", []);
}
- // 杩囨护宸插瓨鍦ㄧ殑涓撳
- const existingExpertIds = this.form.ethicalreviewopinionsList.map(
- expert => expert.expertNo || expert.expertname
- );
- const newExperts = this.selectedExperts.filter(expert => {
- return !existingExpertIds.includes(expert.userno || expert.username);
- });
-
- if (newExperts.length === 0) {
- this.$message.warning("閫夋嫨鐨勪笓瀹跺凡瀛樺湪");
- return;
- }
-
// 娣诲姞涓撳鍒板垪琛�
- newExperts.forEach(expert => {
+ this.selectedExperts.forEach(expert => {
// 鍒ゆ柇鏄惁涓轰富浠诲鍛�
const isChief = this.getIsChiefExpert(expert);
@@ -1649,7 +1664,7 @@
expertType: isChief ? "1" : "0", // 涓讳换濮斿憳璁剧疆涓轰富濮斾笓瀹�
deptName: expert.unitname || "",
title: expert.title || "",
- telephone: expert.telephone || "",
+ deptname: expert.telephone || "",
receiveStatus: "0", // 寰呮帴鏀�
expertconclusion: "",
expertopinion: "",
@@ -1672,22 +1687,11 @@
delFlag: "0"
};
- // 浣跨敤Vue.set纭繚鍝嶅簲寮�
+ // 浣跨敤push娣诲姞锛岀‘淇濆搷搴斿紡
this.form.ethicalreviewopinionsList.push(expertReview);
});
- // 瑙﹀彂璁$畻灞炴�ф洿鏂�
- this.$forceUpdate();
-
- console.log(
- "娣诲姞涓撳鍚庯紝褰撳墠涓撳鍒楄〃:",
- this.form.ethicalreviewopinionsList
- );
- console.log("鏅�氫笓瀹舵暟閲�:", this.normalExpertsCount);
- console.log("涓诲涓撳鏁伴噺:", this.chiefExpertsCount);
- console.log("鍙彂閫佹櫘閫氫笓瀹�:", this.availableNormalExperts);
-
- this.$message.success(`鎴愬姛娣诲姞 ${newExperts.length} 浣嶄笓瀹禶);
+ this.$message.success(`鎴愬姛娣诲姞 ${this.selectedExperts.length} 浣嶄笓瀹禶);
this.expertDialogVisible = false;
this.selectedExperts = [];
},
@@ -1715,9 +1719,7 @@
// 鍙戦�佺粰鏅�氫笓瀹�
handleSendToNormalExperts() {
- this.sendForm.expertIds = this.availableNormalExperts.map(expert =>
- this.getExpertKey(expert)
- );
+ this.currentSendExperts = this.availableNormalExperts;
this.sendForm.expertType = "normal";
this.sendForm.endTime = ""; // 閲嶇疆鎴鏃堕棿
this.sendDialogVisible = true;
@@ -1725,34 +1727,33 @@
// 鍙戦�佺粰涓诲涓撳
handleSendToChiefExpert() {
- this.sendForm.expertIds = this.availableChiefExperts.map(expert =>
- this.getExpertKey(expert)
- );
+ this.currentSendExperts = this.availableChiefExperts;
this.sendForm.expertType = "chief";
this.sendForm.endTime = ""; // 涓诲涓撳鏃犻渶鎴鏃堕棿
this.sendDialogVisible = true;
},
- // 鎵归噺鍙戦��
- handleBatchSend() {
- const allAvailableExperts = [
- ...this.availableNormalExperts,
- ...this.availableChiefExperts
- ];
- this.sendForm.expertIds = allAvailableExperts.map(expert =>
- this.getExpertKey(expert)
- );
- this.sendForm.expertType = "batch";
- this.sendForm.endTime = ""; // 閲嶇疆鎴鏃堕棿
- this.sendDialogVisible = true;
- },
-
// 鍙戦�佺粰鍗曚釜涓撳
handleSendToExpert(expert) {
- this.sendForm.expertIds = [this.getExpertKey(expert)];
+ this.currentSendExperts = [expert];
this.sendForm.expertType = expert.expertType === "1" ? "chief" : "normal";
this.sendForm.endTime = expert.expertType === "1" ? "" : ""; // 涓诲涓撳鏃犻渶鎴鏃堕棿
this.sendDialogVisible = true;
+ },
+
+ // 鍙戦�佸璇濇鍏抽棴
+ handleSendDialogClose() {
+ this.sendForm = {
+ expertType: "normal",
+ expertIds: [],
+ startTime: "",
+ endTime: "",
+ sendType: "0",
+ title: "浼︾悊瀹℃煡浠诲姟閫氱煡",
+ content: "",
+ url: ""
+ };
+ this.currentSendExperts = [];
},
// 纭鍙戦��
@@ -1773,47 +1774,110 @@
return;
}
- if (this.sendForm.expertIds.length === 0) {
- this.$message.warning("璇烽�夋嫨瑕佸彂閫佺殑涓撳");
+ if (!this.sendForm.title) {
+ this.$message.warning("璇疯緭鍏ュ彂閫佹爣棰�");
+ return;
+ }
+
+ if (!this.sendForm.content) {
+ this.$message.warning("璇疯緭鍏ュ彂閫佸唴瀹�");
+ return;
+ }
+
+ if (this.currentSendExperts.length === 0) {
+ this.$message.warning("娌℃湁鎵惧埌鍙彂閫佺殑涓撳");
return;
}
this.sending = true;
try {
- // 妯℃嫙鍙戦�佽繃绋�
- await new Promise(resolve => setTimeout(resolve, 1000));
+ // 鍙戦�佺粰姣忎釜涓撳
+ const sendPromises = this.currentSendExperts.map(async expert => {
+ try {
+ // 鏋勫缓鍙戦�佹暟鎹�
+ const sendData = {
+ number: expert.deptname || "", // 鐢ㄦ埛鎵嬫満鍙�
+ title: this.sendForm.title,
+ url: this.sendForm.url || "",
- // 鏇存柊涓撳鐘舵��
- this.sendForm.expertIds.forEach(expertKey => {
- const index = this.form.ethicalreviewopinionsList.findIndex(
- expert => this.getExpertKey(expert) === expertKey
- );
- if (index !== -1) {
- this.form.ethicalreviewopinionsList[index].receiveStatus = "2"; // 宸叉帴鏀�
- this.form.ethicalreviewopinionsList[
- index
- ].startTime = this.sendForm.startTime;
- this.form.ethicalreviewopinionsList[
- index
- ].endTime = this.sendForm.endTime;
- this.form.ethicalreviewopinionsList[
- index
- ].sendType = this.sendForm.sendType;
- this.form.ethicalreviewopinionsList[index].updateTime = new Date()
- .toISOString()
- .replace("T", " ")
- .substring(0, 19);
+ createTime: new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19)
+ };
- // 浣跨敤Vue.set纭繚鍝嶅簲寮�
- this.$set(
- this.form.ethicalreviewopinionsList,
- index,
- this.form.ethicalreviewopinionsList[index]
- );
+ // 璋冪敤鍙戦�侀�氱煡鎺ュ彛
+ const response = await sendNotification(sendData);
+
+ if (response.code === 200) {
+ // 鏇存柊涓撳鐘舵��
+ const index = this.form.ethicalreviewopinionsList.findIndex(
+ e =>
+ e.expertNo === expert.expertNo ||
+ e.expertname === expert.expertname
+ );
+
+ if (index !== -1) {
+ this.form.ethicalreviewopinionsList[index].receiveStatus = "1"; // 宸叉帴鏀�
+ this.form.ethicalreviewopinionsList[
+ index
+ ].startTime = this.sendForm.startTime;
+ this.form.ethicalreviewopinionsList[
+ index
+ ].endTime = this.sendForm.endTime;
+ this.form.ethicalreviewopinionsList[
+ index
+ ].sendType = this.sendForm.sendType;
+ this.form.ethicalreviewopinionsList[
+ index
+ ].updateTime = new Date()
+ .toISOString()
+ .replace("T", " ")
+ .substring(0, 19);
+
+ // 浣跨敤Vue.set纭繚鍝嶅簲寮忔洿鏂�
+ this.$set(
+ this.form.ethicalreviewopinionsList,
+ index,
+ this.form.ethicalreviewopinionsList[index]
+ );
+ }
+
+ return { success: true, expert: expert.expertname };
+ } else {
+ return {
+ success: false,
+ expert: expert.expertname,
+ error: response.msg
+ };
+ }
+ } catch (error) {
+ console.error(`鍙戦�佺粰涓撳 ${expert.expertname} 澶辫触:`, error);
+ return {
+ success: false,
+ expert: expert.expertname,
+ error: error.message
+ };
}
});
- this.$message.success("鍙戦�佹垚鍔�");
+ // 绛夊緟鎵�鏈夊彂閫佸畬鎴�
+ 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("鍙戦�佸け璐ワ紝璇风◢鍚庨噸璇�");
+ }
+
this.sendDialogVisible = false;
this.sendForm = {
expertType: "normal",
@@ -1821,11 +1885,11 @@
startTime: "",
endTime: "",
sendType: "0",
- content: ""
+ title: "浼︾悊瀹℃煡浠诲姟閫氱煡",
+ content: "",
+ url: ""
};
-
- // 瑙﹀彂璁$畻灞炴�ф洿鏂�
- this.$forceUpdate();
+ this.currentSendExperts = [];
} catch (error) {
console.error("鍙戦�佸け璐�:", error);
this.$message.error("鍙戦�佸け璐ワ紝璇烽噸璇�");
@@ -1834,48 +1898,23 @@
}
},
- // 缂栬緫涓撳瀹℃煡
- handleEditExpertReview(expert) {
- this.$prompt("璇疯緭鍏ュ鏌ユ剰瑙�", "缂栬緫涓撳瀹℃煡", {
+ // 鍒犻櫎涓撳瀹℃煡
+ handleDeleteExpertReview(expert, index) {
+ this.$confirm("纭畾瑕佸垹闄よ涓撳鐨勫鏌ヨ褰曞悧锛�", "鎻愮ず", {
confirmButtonText: "纭畾",
cancelButtonText: "鍙栨秷",
- inputValue: expert.expertopinion || "",
- inputPlaceholder: "璇疯緭鍏ュ鏌ユ剰瑙�",
- inputValidator: value => {
- if (!value || value.trim() === "") {
- return "瀹℃煡鎰忚涓嶈兘涓虹┖";
- }
- return true;
- }
+ type: "warning"
})
- .then(({ value }) => {
- const index = this.form.ethicalreviewopinionsList.findIndex(
- e => e.id === expert.id || e.expertNo === expert.expertNo
- );
- if (index !== -1) {
- this.form.ethicalreviewopinionsList[index].expertopinion = value;
- this.form.ethicalreviewopinionsList[index].updateTime = new Date()
- .toISOString()
- .replace("T", " ")
- .substring(0, 19);
-
- // 浣跨敤Vue.set纭繚鍝嶅簲寮�
- this.$set(
- this.form.ethicalreviewopinionsList,
- index,
- this.form.ethicalreviewopinionsList[index]
- );
-
- this.$message.success("瀹℃煡鎰忚宸叉洿鏂�");
- }
+ .then(() => {
+ // 浠庢暟缁勪腑鍒犻櫎涓撳
+ this.form.ethicalreviewopinionsList.splice(index, 1);
+ this.$message.success("涓撳瀹℃煡璁板綍宸插垹闄�");
})
.catch(() => {});
},
// 鏌ョ湅涓撳鍘嗗彶瀹℃壒鎯呭喌
async handleViewExpertHistory(expert) {
- console.log(12);
-
if (!expert.expertNo) {
this.$message.warning("璇ヤ笓瀹舵病鏈夌紪鍙凤紝鏃犳硶鏌ヨ鍘嗗彶瀹℃壒鎯呭喌");
return;
@@ -1889,16 +1928,14 @@
const params = {
expertNo: expert.expertNo
};
- console.log(11);
const response = await ethicalreExpertTotal(params);
- console.log(response);
- if (response) {
- this.expertHistoryData = response[0];
+ if (response && response.code === 200) {
+ this.expertHistoryData = response.data || response[0] || null;
} else {
this.$message.error(
- "鏌ヨ涓撳鍘嗗彶瀹℃壒鎯呭喌澶辫触锛�" + (response.msg || "鏈煡閿欒")
+ "鏌ヨ涓撳鍘嗗彶瀹℃壒鎯呭喌澶辫触锛�" + (response?.msg || "鏈煡閿欒")
);
this.expertHistoryData = null;
}
@@ -1911,78 +1948,12 @@
}
},
- // 鏌ョ湅涓撳瀹℃煡璇︽儏
- handleViewExpertReview(expert) {
- this.$alert(
- `
- <div style="line-height: 1.6;">
- <p><strong>涓撳濮撳悕锛�</strong>${expert.expertname}</p>
- <p><strong>涓撳缂栧彿锛�</strong>${expert.expertNo || "-"}</p>
- <p><strong>涓撳绫诲瀷锛�</strong>${this.getExpertTypeText(
- expert.expertType
- )}</p>
- <p><strong>绉戝鍚嶇О锛�</strong>${expert.deptName || "-"}</p>
- <p><strong>鑱岀О锛�</strong>${expert.title || "-"}</p>
- <p><strong>鑱旂郴鐢佃瘽锛�</strong>${expert.telephone || "-"}</p>
- <p><strong>瀹℃煡鐘舵�侊細</strong>${this.getReviewStatusText(
- expert.receiveStatus
- )}</p>
- <p><strong>涓撳缁撹锛�</strong>${
- expert.expertconclusion
- ? this.getConclusionText(expert.expertconclusion)
- : "鏈彁浜�"
- }</p>
- <p><strong>瀹℃煡鎰忚锛�</strong>${expert.expertopinion || "鏃�"}</p>
- <p><strong>缁撹椤哄簭锛�</strong>${expert.conclusionorder || "-"}</p>
- <p><strong>瀹℃煡鏃堕棿锛�</strong>${expert.conclusiontime || "鏈鏌�"}</p>
- <p><strong>鍙戦�佹椂闂达細</strong>${expert.startTime || "鏈彂閫�"}</p>
- <p><strong>鎴鏃堕棿锛�</strong>${expert.endTime || "-"}</p>
- <p><strong>鍙戦�佹柟寮忥細</strong>${
- expert.sendType
- ? expert.sendType === "0"
- ? "绯荤粺鍙戦��"
- : expert.sendType === "1"
- ? "閭欢鍙戦��"
- : expert.sendType === "2"
- ? "鐭俊鍙戦��"
- : "鍏朵粬鏂瑰紡"
- : "-"
- }</p>
- </div>
- `,
- "涓撳瀹℃煡璇︽儏",
- {
- dangerouslyUseHTMLString: true,
- customClass: "expert-review-detail-dialog",
- showConfirmButton: false,
- showCancelButton: true,
- cancelButtonText: "鍏抽棴"
- }
- );
- },
-
- // 鍒犻櫎涓撳瀹℃煡
- handleDeleteExpertReview(index) {
- this.$confirm("纭畾瑕佸垹闄よ涓撳鐨勫鏌ヨ褰曞悧锛�", "鎻愮ず", {
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷",
- type: "warning"
- })
- .then(() => {
- this.form.ethicalreviewopinionsList.splice(index, 1);
-
- // 瑙﹀彂璁$畻灞炴�ф洿鏂�
- this.$forceUpdate();
-
- this.$message.success("涓撳瀹℃煡璁板綍宸插垹闄�");
- })
- .catch(() => {});
- },
-
// 鏃堕棿鏍煎紡鍖�
parseTime(time) {
if (!time) return "";
const date = new Date(time);
+ if (isNaN(date.getTime())) return time;
+
return `${date.getFullYear()}-${(date.getMonth() + 1)
.toString()
.padStart(2, "0")}-${date
diff --git a/src/views/business/ethicalReview/index.vue b/src/views/business/ethicalReview/index.vue
index 6b6a66e..9cc3b6a 100644
--- a/src/views/business/ethicalReview/index.vue
+++ b/src/views/business/ethicalReview/index.vue
@@ -137,48 +137,7 @@
</template>
</el-table-column>
<el-table-column label="骞撮緞" align="center" prop="age" width="80" />
- <!--
- <el-table-column
- label="妗堜緥缂栧彿"
- align="center"
- prop="caseNo"
- width="120"
- />
- <el-table-column
- label="鎹愮尞鑰呯紪鍙�"
- align="center"
- prop="donorno"
- width="120"
- />
- <el-table-column
- label="琛�鍨�"
- align="center"
- prop="bloodtype"
- width="80"
- />
- <el-table-column
- label="璇佷欢鍙风爜"
- align="center"
- prop="idcardno"
- width="180"
- />
-
- <el-table-column
- label="鍖荤枟鏈烘瀯"
- align="center"
- prop="treatmenthospitalname"
- min-width="150"
- show-overflow-tooltip
- />
-
- <el-table-column
- label="涓撳濮撳悕"
- align="center"
- prop="expertName"
- width="100"
- />
- -->
<el-table-column
label="鐤剧梾璇婃柇"
align="center"
diff --git a/src/views/business/maintain/index.vue b/src/views/business/maintain/index.vue
index 6c4f9e4..65f602c 100644
--- a/src/views/business/maintain/index.vue
+++ b/src/views/business/maintain/index.vue
@@ -159,36 +159,6 @@
min-width="180"
show-overflow-tooltip
/>
-<<<<<<< HEAD
-
-=======
- <el-table-column
- label="棣栬瘖鍖荤枟鏈烘瀯"
- align="center"
- prop="treatmenthospitalname"
- width="150"
- show-overflow-tooltip
- />
-
- <!-- <el-table-column
- label="璁板綍鐘舵��"
- align="center"
- prop="recordstate"
- width="120"
- >
- <template slot-scope="scope">
- <el-tag :type="statusFilter(scope.row.recordstate)">
- {{ statusTextFilter(scope.row.recordstate) }}
- </el-tag>
- </template>
- </el-table-column> -->
- <el-table-column
- label="鍗忚皟鍛�"
- align="center"
- prop="coordinatorName"
- width="100"
- />
->>>>>>> 059398ad3ad81ea49dfb75ac09f268bc0b0f6145
<!-- <el-table-column
label="缁存姢椤圭洰"
align="center"
@@ -196,6 +166,19 @@
width="120"
show-overflow-tooltip
/> -->
+ <el-table-column
+ label="缁存姢鐘舵��"
+ align="center"
+ prop="state"
+ width="100"
+ >
+ <template slot-scope="scope">
+ <dict-tag
+ :options="dict.type.maintain_type"
+ :value="scope.row.state"
+ />
+ </template>
+ </el-table-column>
<el-table-column
label="棣栨缁存姢鏃堕棿"
align="center"
@@ -298,7 +281,7 @@
export default {
name: "MaintenanceList",
components: { Pagination },
- dicts: ["sys_user_sex",'sys_BloodType'],
+ dicts: ["sys_user_sex",'sys_BloodType','maintain_type'],
data() {
return {
// 閬僵灞�
diff --git a/src/views/business/maintain/maintainInfo.vue b/src/views/business/maintain/maintainInfo.vue
index 4e03dca..78cd766 100644
--- a/src/views/business/maintain/maintainInfo.vue
+++ b/src/views/business/maintain/maintainInfo.vue
@@ -1,147 +1,6 @@
<template>
<div class="maintenance-detail">
<case-basic-info :case-id="caseId" :show-attachment="true" />
- <!-- 鍩虹淇℃伅 -->
- <!-- <el-card class="detail-card">
- <div slot="header" class="clearfix">
- <span class="detail-title">渚涜�呭熀鏈俊鎭�</span>
- <el-button type="success" style="float: right;" @click="handleSave">
- 淇濆瓨淇℃伅
- </el-button>
- </div>
-
- <el-form :model="form" ref="form" label-width="120px">
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="浣忛櫌鍙�" prop="caseNo">
- <el-input v-model="form.caseNo" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鎹愮尞鑰呭鍚�" prop="name">
- <el-input v-model="form.name" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鎬у埆" prop="gender">
- <el-select v-model="form.sex" style="width: 100%">
- <el-option label="鐢�" value="0" />
- <el-option label="濂�" value="1" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="骞撮緞" prop="age">
- <el-input v-model="form.age" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鐤剧梾璇婃柇" prop="diagnosisname">
- <el-input v-model="form.diagnosisname" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="棣栬瘖鍖荤枟鏈烘瀯" prop="treatmenthospitalname">
- <el-input v-model="form.treatmenthospitalname" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="鎮h�呯姸鎬�" prop="recordstate">
- <el-select v-model="form.recordstate" style="width: 100%">
- <el-option
- v-for="dict in dict.type.sys_DonationCategory || []"
- :key="dict.value"
- :label="dict.label"
- :value="dict.value"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item
- label="鏈畬鎴愬師鍥�"
- prop="incompleteReason"
- v-if="form.recordstate === '5'"
- >
- <el-input
- v-model="form.incompleteReason"
- placeholder="璇疯緭鍏ユ湭瀹屾垚鎹愮尞鐨勫師鍥�"
- />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="涓婃姤鏃堕棿" prop="reporttime">
- <el-date-picker
- v-model="form.reporttime"
- 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="deathTime">
- <el-date-picker
- v-model="form.deathTime"
- 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="coordinatorName">
- <el-input v-model="form.coordinatorName" />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="琛�鍨�" prop="bloodtype">
- <el-select v-model="form.bloodtype" style="width: 100%">
- <el-option
- v-for="dict in dict.type.sys_BloodType"
- :key="dict.value"
- :label="dict.label"
- :value="dict.value"
- ></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="Rh(D)" prop="rhYin">
- <el-radio-group v-model="form.rhYin">
- <el-radio
- v-for="dict in dict.type.sys_bloodtype_rhd || []"
- :key="dict.value"
- :label="dict.value"
- >{{ dict.label }}</el-radio
- >
- </el-radio-group>
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-form-item label="鐗规畩鐥呭彶" prop="specialMedicalHistory">
- <el-input
- type="textarea"
- :rows="3"
- v-model="form.specialMedicalHistory"
- placeholder="璁板綍鐗规畩鐥呭彶淇℃伅"
- />
- </el-form-item>
- </el-form>
- </el-card> -->
<el-card class="assessment-card">
<div slot="header" class="clearfix">
@@ -150,9 +9,17 @@
type="primary"
size="mini"
@click="toggleEditMode"
- style="float: right;"
+ style="float: right;margin-left: 20px;"
>
- {{ isEdit ? "瀹屾垚缂栬緫" : "寮�濮嬬紪杈�" }}
+ 淇濆瓨缂栬緫
+ </el-button>
+ <el-button
+ type="success"
+ size="mini"
+ @click="accomplish"
+ style="float: right;margin-left: 20px;"
+ >
+ 瀹屾垚缂栬緫
</el-button>
</div>
@@ -808,6 +675,9 @@
nursingRecords: this.recordList
}
};
+ if (saveData.state == 1 || !saveData.state) {
+ saveData.state = 2;
+ }
this.extracontentinfo.specialMedicalHistory = this.form.specialMedicalHistory;
let response;
if (this.isEditMode && this.currentMaintenanceId) {
@@ -847,7 +717,19 @@
this.handleSave();
}
},
+ accomplish() {
+ this.$confirm("鏄惁瀹屾垚璇ユ渚嬫崘鐚‘璁ゆ楠わ紵", "鎻愰啋", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(() => {
+ this.form.state = 3;
+ this.handleSave();
+ })
+ .catch(() => {});
+ },
// 鍩瑰吇璁板綍鐩稿叧鏂规硶
handleAddCulture() {
this.cultureDialogTitle = "鏂板鍩瑰吇璁板綍";
--
Gitblit v1.9.3