ykt-wxapp/pages/case/visit-record-view.vue

283 lines
8.0 KiB
Vue
Raw Normal View History

2026-01-22 17:39:23 +08:00
<template>
<!-- 详情页参考截图顶部蓝条显示创建信息支持编辑/删除黄底提示不渲染 -->
<view class="page">
<view class="topbar">
<view class="topbar-text">{{ topText }}</view>
</view>
<view class="content">
<view class="section">
<view class="row">
<view class="label">病历类型</view>
<view class="value">{{ typeLabel }}</view>
</view>
<view class="row">
<view class="label">就诊日期</view>
<view class="value">{{ visitDate || '--' }}</view>
</view>
<view class="row">
<view class="label">诊断</view>
<view class="value">{{ diagnosisText }}</view>
</view>
<view v-if="templateType === 'inhospital' && record.surgeryName" class="row">
<view class="label">手术名称</view>
<view class="value">{{ record.surgeryName }}</view>
</view>
</view>
<view v-for="(s, idx) in sections" :key="idx" class="section">
<view class="h2">{{ s.title }}</view>
<view class="p">{{ s.value }}</view>
</view>
<view class="section">
<view class="h2">文件上传</view>
<view v-if="files.length" class="files">
<view v-for="(f, idx) in files" :key="idx" class="file" @click="preview(idx)">
<image class="thumb" :src="f.url" mode="aspectFill" />
</view>
</view>
<view v-else class="files-empty">暂无附件</view>
</view>
</view>
<view class="footer">
<button class="btn danger" @click="remove">删除</button>
<button class="btn primary" @click="edit">编辑</button>
</view>
</view>
</template>
<script setup>
import { computed, ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import dayjs from 'dayjs';
import { getVisitRecord, removeVisitRecord } from '@/components/archive-detail/mock';
const archiveId = ref('');
const id = ref('');
const record = ref({});
const files = computed(() => {
const arr = record.value?.files;
return Array.isArray(arr) ? arr.filter((i) => i && i.url) : [];
});
const templateType = computed(() => record.value?.templateType || record.value?.medicalType || '');
const typeLabel = computed(() => record.value?.tempName || '病历');
const visitDate = computed(() => {
const t = templateType.value;
if (t === 'outpatient') return record.value?.visitTime || '';
if (t === 'inhospital') return record.value?.inhosDate || '';
if (t === 'preConsultation') return record.value?.consultDate || '';
if (t === 'physicalExaminationTemplate') return record.value?.inspectDate || '';
return record.value?.dateStr || '';
});
const diagnosisText = computed(() => {
const t = templateType.value;
if (t === 'preConsultation') return record.value?.chiefComplaint || record.value?.summary || '--';
if (t === 'physicalExaminationTemplate') return record.value?.positiveFind || record.value?.summary || '--';
return record.value?.diagnosisName || record.value?.summary || '--';
});
const sections = computed(() => {
const t = templateType.value;
const push = (title, value) => {
const v = value === 0 ? '0' : value ? String(value) : '';
if (!v.trim()) return;
return { title, value: v };
};
const list = [];
if (t === 'outpatient') {
const corp = push('就诊机构', record.value?.corpName);
const dept = push('科室', record.value?.deptName);
const doctor = push('医生', record.value?.doctor);
const treatment = push('治疗方案', record.value?.treatmentPlan);
const dispose = push('处置计划', record.value?.disposePlan);
const summary = push('备注/摘要', record.value?.summary);
[corp, dept, doctor, treatment, dispose, summary].forEach((i) => i && list.push(i));
return list;
}
if (t === 'inhospital') {
const corp = push('住院机构', record.value?.corpName);
const summary = push('摘要', record.value?.summary);
[corp, summary].forEach((i) => i && list.push(i));
return list;
}
if (t === 'preConsultation') {
const illness = push('现病史', record.value?.presentIllness);
const past = push('既往史', record.value?.pastHistory);
const allergy = push('过敏史', record.value?.allergyHistory);
const summary = push('摘要', record.value?.summary);
[illness, past, allergy, summary].forEach((i) => i && list.push(i));
return list;
}
if (t === 'physicalExaminationTemplate') {
const corp = push('体检机构', record.value?.corpName);
const pkg = push('体检套餐', record.value?.inspectPakageName);
const positive = push('阳性发现', record.value?.positiveFind);
const summary = push('摘要', record.value?.summary);
[corp, pkg, positive, summary].forEach((i) => i && list.push(i));
return list;
}
const summary = push('摘要', record.value?.summary);
if (summary) list.push(summary);
return list;
});
const topText = computed(() => {
const time = record.value?.createTime ? dayjs(record.value.createTime).format('YYYY-MM-DD HH:mm') : '';
const name = record.value?.creatorName ? String(record.value.creatorName) : '';
return `${time || '--'} ${name || '--'}创建`;
});
onLoad((opt) => {
archiveId.value = opt?.archiveId ? String(opt.archiveId) : '';
id.value = opt?.id ? String(opt.id) : '';
if (!archiveId.value || !id.value) {
uni.showToast({ title: '参数缺失', icon: 'none' });
setTimeout(() => uni.navigateBack(), 300);
return;
}
const r = getVisitRecord({ archiveId: archiveId.value, id: id.value });
if (!r) {
uni.showToast({ title: '记录不存在', icon: 'none' });
setTimeout(() => uni.navigateBack(), 300);
return;
}
record.value = r;
uni.setNavigationBarTitle({ title: r?.tempName ? String(r.tempName) : '病历详情' });
});
function preview(idx) {
const urls = files.value.map((i) => i.url);
uni.previewImage({ urls, current: urls[idx] });
}
function edit() {
const type = record.value?.templateType || record.value?.medicalType || '';
uni.navigateTo({
url: `/pages/case/visit-record-detail?archiveId=${encodeURIComponent(archiveId.value)}&id=${encodeURIComponent(id.value)}&type=${encodeURIComponent(type)}`,
});
}
function remove() {
uni.showModal({
title: '提示',
content: '确定删除当前记录?',
success: (res) => {
if (!res.confirm) return;
removeVisitRecord({ archiveId: archiveId.value, id: id.value });
uni.$emit('archive-detail:visit-record-changed');
uni.showToast({ title: '已删除', icon: 'success' });
setTimeout(() => uni.navigateBack(), 300);
},
});
}
</script>
<style scoped>
.page {
min-height: 100vh;
background: #fff;
padding-bottom: calc(76px + env(safe-area-inset-bottom));
}
.topbar {
background: #5d6df0;
padding: 10px 14px;
}
.topbar-text {
color: #fff;
font-size: 14px;
text-align: center;
}
.content {
padding: 14px 14px 0;
}
.section {
margin-bottom: 14px;
}
.row {
display: flex;
padding: 10px 0;
}
.label {
width: 90px;
font-size: 14px;
font-weight: 600;
color: #111827;
}
.value {
flex: 1;
font-size: 14px;
color: #111827;
word-break: break-all;
}
.h2 {
font-size: 14px;
font-weight: 700;
color: #111827;
padding: 8px 0;
}
.p {
font-size: 14px;
color: #111827;
line-height: 20px;
white-space: pre-wrap;
}
.files {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.file {
width: 90px;
height: 70px;
border: 1px solid #d1d5db;
background: #f9fafb;
}
.thumb {
width: 90px;
height: 70px;
}
.files-empty {
font-size: 13px;
color: #9aa0a6;
padding: 8px 0;
}
.footer {
position: fixed;
left: 0;
right: 0;
bottom: 0;
background: #fff;
padding: 12px 14px calc(12px + env(safe-area-inset-bottom));
display: flex;
justify-content: flex-end;
gap: 14px;
box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.06);
}
.btn {
width: 120px;
height: 44px;
line-height: 44px;
border-radius: 6px;
font-size: 15px;
}
.btn::after {
border: none;
}
.btn.danger {
background: #fff;
color: #ff4d4f;
border: 1px solid #ff4d4f;
}
.btn.primary {
background: #4f6ef7;
color: #fff;
}
</style>