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

283 lines
8.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>