<template>
|
<div class="followup-detail">
|
<!-- 案例基本信息组件 -->
|
<case-basic-info
|
:case-id="caseId"
|
:show-attachment="true"
|
/>
|
|
<!-- 随访记录管理 -->
|
<el-card>
|
<div slot="header" class="clearfix">
|
<span>随访记录管理</span>
|
<el-button style="float: right; padding: 3px 0" type="text" @click="goBack">返回列表</el-button>
|
</div>
|
|
<!-- 操作按钮区域 -->
|
<div class="operation-bar">
|
<el-button
|
type="primary"
|
icon="el-icon-plus"
|
@click="handleAddFollowup"
|
v-hasPermi="['system:followup:add']"
|
>
|
新增随访
|
</el-button>
|
<el-button
|
type="danger"
|
icon="el-icon-delete"
|
:disabled="!selectedFollowup"
|
@click="handleDeleteFollowup"
|
v-hasPermi="['system:followup:remove']"
|
>
|
删除选中
|
</el-button>
|
<el-button
|
type="warning"
|
icon="el-icon-refresh"
|
@click="getFollowupList"
|
>
|
刷新列表
|
</el-button>
|
</div>
|
|
<!-- 随访记录列表 -->
|
<el-table
|
v-loading="loading"
|
:data="followupList"
|
highlight-current-row
|
@row-click="handleRowClick"
|
style="width: 100%; margin-top: 20px;"
|
:default-sort="{prop: 'followuptime', order: 'descending'}"
|
>
|
<el-table-column
|
label="随访序号"
|
align="center"
|
prop="seqno"
|
width="120"
|
>
|
<template slot-scope="scope">
|
<span>第{{ scope.row.seqno || 1 }}次</span>
|
</template>
|
</el-table-column>
|
<el-table-column
|
label="随访时间"
|
align="center"
|
prop="followuptime"
|
|
sortable
|
>
|
<template slot-scope="scope">
|
<span>{{ parseTime(scope.row.followuptime, "{y}-{m}-{d}") }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column
|
label="器官受体者"
|
align="center"
|
prop="recipientname"
|
|
/>
|
<el-table-column
|
label="移植医院"
|
align="center"
|
prop="hospitalname"
|
show-overflow-tooltip
|
/>
|
<el-table-column
|
label="随访医生"
|
align="center"
|
prop="doctorname"
|
|
/>
|
<el-table-column
|
label="捐献结果"
|
align="center"
|
prop="donateresult"
|
>
|
<template slot-scope="scope">
|
<el-tag :type="resultTypeFilter(scope.row.donateresult)" size="small">
|
{{ resultTextFilter(scope.row.donateresult) }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column
|
label="随访者"
|
align="center"
|
prop="followupno"
|
/>
|
<el-table-column
|
label="创建时间"
|
align="center"
|
prop="createTime"
|
|
>
|
<template slot-scope="scope">
|
<span>{{ parseTime(scope.row.createTime, "{y}-{m}-{d}") }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column
|
label="操作"
|
align="center"
|
|
fixed="right"
|
>
|
<template slot-scope="scope">
|
<el-button
|
size="mini"
|
type="text"
|
icon="el-icon-delete"
|
@click="handleDeleteSingle(scope.row)"
|
v-hasPermi="['system:followup:remove']"
|
>
|
删除
|
</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
|
<!-- 分页组件 -->
|
<pagination
|
v-show="total > 0"
|
:total="total"
|
:page.sync="queryParams.pageNum"
|
:limit.sync="queryParams.pageSize"
|
@pagination="getFollowupList"
|
/>
|
</el-card>
|
|
<!-- 编辑/新增区域 - 始终显示 -->
|
<el-card class="edit-area-card">
|
<div slot="header" class="clearfix">
|
<span>{{ editForm.id ? '编辑随访记录' : '新增随访记录' }}</span>
|
<div style="float: right;">
|
<el-button
|
type="text"
|
@click="handleReset"
|
v-if="editForm.id"
|
>
|
重置
|
</el-button>
|
</div>
|
</div>
|
|
<el-form
|
ref="editFormRef"
|
:model="editForm"
|
:rules="editRules"
|
label-width="120px"
|
>
|
<el-row>
|
<el-col :span="12">
|
<el-form-item label="随访序号" prop="seqno">
|
<el-input-number
|
v-model="editForm.seqno"
|
:min="1"
|
:max="20"
|
placeholder="请输入随访序号"
|
style="width: 200px"
|
/>
|
<span style="margin-left: 10px; color: #999;">(第{{ editForm.seqno || 1 }}次随访)</span>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="随访时间" prop="followuptime">
|
<el-date-picker
|
v-model="editForm.followuptime"
|
type="datetime"
|
placeholder="选择随访时间"
|
value-format="yyyy-MM-dd HH:mm:ss"
|
style="width: 200px"
|
/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<el-row>
|
<el-col :span="12">
|
<el-form-item label="器官受体者姓名" prop="recipientname">
|
<el-input
|
v-model="editForm.recipientname"
|
placeholder="请输入器官受体者姓名"
|
maxlength="50"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="受体电话" prop="recipientphone">
|
<el-input
|
v-model="editForm.recipientphone"
|
placeholder="请输入器官受体者电话"
|
maxlength="20"
|
/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<el-row>
|
<el-col :span="12">
|
<el-form-item label="移植医院名称" prop="hospitalname">
|
<el-input
|
v-model="editForm.hospitalname"
|
placeholder="请输入移植医院名称"
|
maxlength="100"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="移植科室" prop="hospitaldept">
|
<el-input
|
v-model="editForm.hospitaldept"
|
placeholder="请输入移植医院科室"
|
maxlength="50"
|
/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<el-row>
|
<el-col :span="12">
|
<el-form-item label="随访医生姓名" prop="doctorname">
|
<el-input
|
v-model="editForm.doctorname"
|
placeholder="请输入接受随访医生姓名"
|
maxlength="50"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="医生电话" prop="doctorphone">
|
<el-input
|
v-model="editForm.doctorphone"
|
placeholder="请输入接受随访医生电话"
|
maxlength="20"
|
/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<el-row>
|
<el-col :span="12">
|
<el-form-item label="捐献结果" prop="donateresult">
|
<el-select
|
v-model="editForm.donateresult"
|
placeholder="请选择捐献结果"
|
style="width: 200px"
|
>
|
<el-option label="成功" value="1" />
|
<el-option label="失败" value="0" />
|
<el-option label="进行中" value="2" />
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="随访者" prop="followupno">
|
<el-input
|
v-model="editForm.followupno"
|
placeholder="请输入随访者"
|
maxlength="50"
|
/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<el-form-item label="随访描述" prop="followupdescribe">
|
<el-input
|
v-model="editForm.followupdescribe"
|
type="textarea"
|
placeholder="请输入随访描述"
|
maxlength="1000"
|
:rows="3"
|
show-word-limit
|
/>
|
</el-form-item>
|
|
<el-form-item label="医生描述" prop="doctordescribe">
|
<el-input
|
v-model="editForm.doctordescribe"
|
type="textarea"
|
placeholder="请输入医生描述"
|
maxlength="500"
|
:rows="3"
|
show-word-limit
|
/>
|
</el-form-item>
|
|
<el-form-item label="受体者描述" prop="recipientdescribe">
|
<el-input
|
v-model="editForm.recipientdescribe"
|
type="textarea"
|
placeholder="请输入器官受体者描述"
|
maxlength="500"
|
:rows="3"
|
show-word-limit
|
/>
|
</el-form-item>
|
|
<el-form-item label="备注" prop="remark">
|
<el-input
|
v-model="editForm.remark"
|
type="textarea"
|
placeholder="请输入备注"
|
maxlength="500"
|
:rows="3"
|
show-word-limit
|
/>
|
</el-form-item>
|
|
<el-form-item>
|
<el-button type="primary" @click="submitEditForm">
|
{{ editForm.id ? '保存修改' : '创建随访' }}
|
</el-button>
|
<el-button @click="resetEditForm">重置</el-button>
|
</el-form-item>
|
</el-form>
|
</el-card>
|
</div>
|
</template>
|
|
<script>
|
import {
|
listFollowup,
|
getFollowup,
|
addFollowup,
|
updateFollowup,
|
delFollowup
|
} from "@/api/businessApi/followup";
|
import CaseBasicInfo from "@/components/CaseBasicInfo";
|
import Pagination from "@/components/Pagination";
|
|
export default {
|
name: "FollowupDetail",
|
components: {
|
CaseBasicInfo,
|
Pagination
|
},
|
data() {
|
return {
|
// 案例ID
|
caseId: null,
|
// 加载状态
|
loading: false,
|
// 随访记录列表
|
followupList: [],
|
// 总条数
|
total: 0,
|
// 查询参数
|
queryParams: {
|
pageNum: 1,
|
pageSize: 10
|
},
|
// 当前选中的随访记录
|
selectedFollowup: null,
|
// 编辑表单
|
editForm: {
|
id: undefined,
|
infoid: null,
|
organid: undefined,
|
recipientname: "",
|
recipientphone: "",
|
recipientdescribe: "",
|
hospitalname: "",
|
hospitaldept: "",
|
hospitalno: "",
|
doctorname: "",
|
doctorphone: "",
|
doctordescribe: "",
|
donateresult: "",
|
followuptime: undefined,
|
followupno: "",
|
followupdescribe: "",
|
seqno: 1,
|
remark: ""
|
},
|
// 编辑表单校验规则
|
editRules: {
|
seqno: [
|
{ required: true, message: "随访序号不能为空", trigger: "blur" },
|
{ type: "number", min: 1, max: 20, message: "随访序号范围为1-20", trigger: "blur" }
|
],
|
followuptime: [
|
{ required: true, message: "随访时间不能为空", trigger: "change" }
|
],
|
recipientname: [
|
{ required: true, message: "器官受体者姓名不能为空", trigger: "blur" },
|
{ max: 50, message: "长度不能超过50个字符", trigger: "blur" }
|
],
|
hospitalname: [
|
{ required: true, message: "移植医院名称不能为空", trigger: "blur" },
|
{ max: 100, message: "长度不能超过100个字符", trigger: "blur" }
|
],
|
followupno: [
|
{ required: true, message: "随访者不能为空", trigger: "blur" },
|
{ max: 50, message: "长度不能超过50个字符", trigger: "blur" }
|
],
|
donateresult: [
|
{ required: true, message: "捐献结果不能为空", trigger: "change" }
|
]
|
}
|
};
|
},
|
created() {
|
this.caseId = this.$route.query.infoid;
|
if (this.caseId) {
|
this.getFollowupList();
|
} else {
|
this.$message.error("参数错误");
|
this.goBack();
|
}
|
},
|
methods: {
|
// 获取当前案例下的随访记录列表
|
async getFollowupList() {
|
this.loading = true;
|
try {
|
const params = {
|
...this.queryParams,
|
infoid: this.caseId
|
};
|
|
const response = await listFollowup(params);
|
if (response.code === 200) {
|
this.handleResponseData(response);
|
|
// 如果有数据,默认选中第一条
|
if (this.followupList.length > 0) {
|
this.selectFirstRecord();
|
} else {
|
// 没有数据时,设置新增状态
|
this.resetEditForm();
|
}
|
} else {
|
this.$message.error("获取随访记录失败:" + (response.msg || "未知错误"));
|
this.followupList = [];
|
this.total = 0;
|
this.resetEditForm();
|
}
|
} catch (error) {
|
console.error("获取随访记录失败:", error);
|
this.$message.error("获取数据失败");
|
this.followupList = [];
|
this.total = 0;
|
this.resetEditForm();
|
} finally {
|
this.loading = false;
|
}
|
},
|
// 处理接口响应数据
|
handleResponseData(response) {
|
if (response.data) {
|
if (Array.isArray(response.data)) {
|
this.followupList = response.data;
|
this.total = response.data.length;
|
} else if (response.data.rows) {
|
this.followupList = response.data.rows;
|
this.total = response.data.total;
|
} else if (Array.isArray(response.data.list)) {
|
this.followupList = response.data.list;
|
this.total = response.data.total || response.data.list.length;
|
} else {
|
this.followupList = response.data;
|
this.total = response.total || response.data.length;
|
}
|
} else {
|
if (Array.isArray(response.rows)) {
|
this.followupList = response.rows;
|
this.total = response.total;
|
} else if (Array.isArray(response.list)) {
|
this.followupList = response.list;
|
this.total = response.total;
|
} else {
|
this.followupList = [];
|
this.total = 0;
|
}
|
}
|
},
|
// 选择第一条记录
|
selectFirstRecord() {
|
if (this.followupList.length > 0) {
|
const firstRecord = this.followupList[0];
|
this.selectedFollowup = firstRecord;
|
this.loadFollowupData(firstRecord);
|
}
|
},
|
// 加载随访数据到编辑表单
|
loadFollowupData(record) {
|
this.editForm = { ...record };
|
|
// 确保数据类型正确
|
if (this.editForm.seqno) {
|
this.editForm.seqno = Number(this.editForm.seqno);
|
}
|
|
// 清空表单验证
|
if (this.$refs.editFormRef) {
|
this.$nextTick(() => {
|
this.$refs.editFormRef.clearValidate();
|
});
|
}
|
},
|
// 结果类型过滤器
|
resultTypeFilter(result) {
|
const resultMap = {
|
"1": "success", // 成功
|
"0": "danger", // 失败
|
"2": "primary" // 进行中
|
};
|
return resultMap[result] || "info";
|
},
|
resultTextFilter(result) {
|
const resultMap = {
|
"1": "成功",
|
"0": "失败",
|
"2": "进行中"
|
};
|
return resultMap[result] || "未知";
|
},
|
// 行点击事件
|
handleRowClick(row) {
|
this.selectedFollowup = row;
|
this.loadFollowupData(row);
|
},
|
// 新增随访
|
handleAddFollowup() {
|
this.resetEditForm();
|
this.selectedFollowup = null;
|
},
|
// 计算下一个随访序号
|
calculateNextSeqNo() {
|
if (this.followupList.length === 0) {
|
return 1;
|
}
|
const maxSeqNo = Math.max(...this.followupList.map(item => Number(item.seqno) || 1));
|
return maxSeqNo + 1;
|
},
|
// 提交编辑表单
|
submitEditForm() {
|
this.$refs.editFormRef.validate(async (valid) => {
|
if (valid) {
|
try {
|
// 确保infoid正确
|
this.editForm.infoid = this.caseId;
|
|
let response;
|
if (this.editForm.id) {
|
// 修改
|
response = await updateFollowup(this.editForm);
|
} else {
|
// 新增
|
response = await addFollowup(this.editForm);
|
}
|
|
if (response.code === 200) {
|
this.$message.success(this.editForm.id ? "修改成功" : "新增成功");
|
this.getFollowupList();
|
|
// 新增成功后,清空表单
|
if (!this.editForm.id) {
|
this.resetEditForm();
|
}
|
} else {
|
this.$message.error(response.msg || "操作失败");
|
}
|
} catch (error) {
|
console.error("操作失败:", error);
|
this.$message.error("操作失败");
|
}
|
}
|
});
|
},
|
// 重置编辑表单
|
resetEditForm() {
|
this.editForm = {
|
id: undefined,
|
infoid: this.caseId,
|
organid: undefined,
|
recipientname: "",
|
recipientphone: "",
|
recipientdescribe: "",
|
hospitalname: "",
|
hospitaldept: "",
|
hospitalno: "",
|
doctorname: "",
|
doctorphone: "",
|
doctordescribe: "",
|
donateresult: "",
|
followuptime: undefined,
|
followupno: "",
|
followupdescribe: "",
|
seqno: this.calculateNextSeqNo(),
|
remark: ""
|
};
|
|
if (this.$refs.editFormRef) {
|
this.$refs.editFormRef.clearValidate();
|
}
|
},
|
// 重置
|
handleReset() {
|
if (this.selectedFollowup) {
|
this.loadFollowupData(this.selectedFollowup);
|
} else {
|
this.resetEditForm();
|
}
|
},
|
// 删除选中随访
|
async handleDeleteFollowup() {
|
if (!this.selectedFollowup) {
|
this.$message.warning("请先选择要删除的随访记录");
|
return;
|
}
|
|
await this.deleteFollowupRecord(this.selectedFollowup.id);
|
},
|
// 删除单条随访
|
async handleDeleteSingle(row, event) {
|
event.stopPropagation(); // 阻止事件冒泡
|
await this.deleteFollowupRecord(row.id);
|
},
|
// 删除随访记录
|
async deleteFollowupRecord(id) {
|
try {
|
await this.$confirm('确认删除该随访记录吗?', "警告", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning"
|
});
|
|
const response = await delFollowup([id]);
|
if (response.code === 200) {
|
this.$message.success("删除成功");
|
|
// 如果删除的是当前选中的记录
|
if (this.selectedFollowup && this.selectedFollowup.id === id) {
|
this.selectedFollowup = null;
|
this.resetEditForm();
|
}
|
|
this.getFollowupList();
|
} else {
|
this.$message.error("删除失败:" + response.msg);
|
}
|
} catch (error) {
|
if (error !== "cancel") {
|
console.error("删除失败:", error);
|
}
|
}
|
},
|
// 返回列表页
|
goBack() {
|
this.$router.go(-1);
|
},
|
// 时间格式化
|
parseTime(time, pattern) {
|
if (!time) return "";
|
const date = new Date(time);
|
if (pattern) {
|
if (pattern === "{y}-{m}-{d}") {
|
return `${date.getFullYear()}-${(date.getMonth() + 1)
|
.toString()
|
.padStart(2, "0")}-${date
|
.getDate()
|
.toString()
|
.padStart(2, "0")}`;
|
}
|
}
|
return `${date.getFullYear()}-${(date.getMonth() + 1)
|
.toString()
|
.padStart(2, "0")}-${date
|
.getDate()
|
.toString()
|
.padStart(2, "0")} ${date
|
.getHours()
|
.toString()
|
.padStart(2, "0")}:${date
|
.getMinutes()
|
.toString()
|
.padStart(2, "0")}:${date
|
.getSeconds()
|
.toString()
|
.padStart(2, "0")}`;
|
}
|
}
|
};
|
</script>
|
|
<style scoped>
|
.followup-detail {
|
padding: 20px;
|
}
|
|
.operation-bar {
|
margin-bottom: 20px;
|
display: flex;
|
gap: 10px;
|
align-items: center;
|
}
|
|
.edit-area-card {
|
margin-top: 20px;
|
animation: fadeIn 0.5s;
|
}
|
|
@keyframes fadeIn {
|
from {
|
opacity: 0;
|
transform: translateY(-20px);
|
}
|
to {
|
opacity: 1;
|
transform: translateY(0);
|
}
|
}
|
|
/* 表格选中行样式 */
|
.el-table__row.current-row {
|
background-color: #f0f9ff !important;
|
}
|
|
/* 鼠标悬停行样式 */
|
.el-table__row:hover {
|
cursor: pointer;
|
background-color: #f5f7fa;
|
}
|
</style>
|