ykt-wxapp/components/archive-detail/health-profile-tab.vue

312 lines
7.8 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>
<!-- Mobile 来源: ykt-management-mobile/src/pages/customer/customer-detail/health-profile/health-profile.vue -->
<view class="wrap">
<view class="filters">
<picker mode="selector" :range="typeRange" range-key="name" @change="pickType">
<view class="filter-pill">
<view class="pill-text" :class="{ muted: currentType.value === 'ALL' }">{{ currentType.value === 'ALL' ? '档案类型' : currentType.name }}</view>
<uni-icons type="arrowdown" size="12" color="#666" />
</view>
</picker>
<view class="filter-pill">
<picker mode="date" @change="pickDate">
<view class="pill-text" :class="{ muted: !date }">{{ date || '时间筛选' }}</view>
</picker>
<view class="pill-icon" @click.stop="clearDate">
<uni-icons v-if="date" type="closeempty" size="14" color="#666" />
<uni-icons v-else type="arrowdown" size="12" color="#666" />
</view>
</view>
</view>
<view class="list">
<view v-for="r in records" :key="r._id" class="card record" @click="edit(r)">
<view class="record-head">
<view class="record-date">{{ r.dateStr }}</view>
<view class="record-tag" :class="tagClass[r.templateType] || 'bg-blue'">{{ r.tempName }}</view>
<view v-if="r.corpName === '其他'" class="record-tag bg-rose">外院</view>
</view>
<view class="record-body">
<view v-for="row in buildSummaryRows(r)" :key="row.k" class="kv">
<view class="k">{{ row.k }}</view>
<view class="v">{{ row.v }}</view>
</view>
<view v-if="!buildSummaryRows(r).length" class="kv">
<view class="k">摘要</view>
<view class="v">{{ r.summary || '暂无内容' }}</view>
</view>
</view>
<view class="record-foot">
<view class="foot-left">创建时间{{ r.createTimeStr }}</view>
<view class="foot-right">记录人{{ r.creatorName || '—' }}</view>
</view>
</view>
<view v-if="records.length === 0" class="empty">暂无数据</view>
</view>
<view class="fab" :style="{ bottom: `${floatingBottom}px` }" @click="add">
<uni-icons type="plusempty" size="24" color="#fff" />
</view>
</view>
</template>
<script setup>
import { computed, onMounted, onUnmounted, ref } from 'vue';
import dayjs from 'dayjs';
import { ensureSeed, getVisitRecordTemplates, queryVisitRecords } from './mock';
const props = defineProps({
data: { type: Object, default: () => ({}) },
archiveId: { type: String, default: '' },
floatingBottom: { type: Number, default: 16 },
});
const date = ref('');
const templates = ref(getVisitRecordTemplates());
const typeRange = computed(() => [{ name: '全部', value: 'ALL' }, ...templates.value.map((t) => ({ name: t.name, value: t.templateType }))]);
const currentType = ref({ name: '全部', value: 'ALL' });
const records = ref([]);
function refreshList() {
if (!props.archiveId) return;
records.value = queryVisitRecords({
archiveId: props.archiveId,
medicalType: currentType.value.value,
date: date.value,
}).map((r) => ({
...r,
createTimeStr: r.createTime ? dayjs(r.createTime).format('YYYY-MM-DD') : '',
}));
}
const tagClass = {
outpatient: 'bg-amber',
inhospital: 'bg-teal',
physicalExaminationTemplate: 'bg-green',
};
function buildSummaryRows(r) {
const rows = [];
if (r.templateType === 'outpatient') {
if (r.corpName) rows.push({ k: '机构', v: r.corpName });
if (r.deptName) rows.push({ k: '科室', v: r.deptName });
if (r.doctor) rows.push({ k: '医生', v: r.doctor });
if (r.diagnosisName) rows.push({ k: '诊断', v: r.diagnosisName });
if (r.summary) rows.push({ k: '摘要', v: r.summary });
return rows;
}
if (r.templateType === 'inhospital') {
if (r.corpName) rows.push({ k: '机构', v: r.corpName });
if (r.diagnosisName) rows.push({ k: '诊断', v: r.diagnosisName });
if (r.summary) rows.push({ k: '摘要', v: r.summary });
return rows;
}
if (r.templateType === 'physicalExaminationTemplate') {
if (r.corpName) rows.push({ k: '机构', v: r.corpName });
if (r.inspectPakageName) rows.push({ k: '套餐', v: r.inspectPakageName });
if (r.positiveFind) rows.push({ k: '阳性', v: r.positiveFind });
if (r.summary) rows.push({ k: '摘要', v: r.summary });
return rows;
}
if (r.summary) rows.push({ k: '摘要', v: r.summary });
return rows;
}
function pickType(e) {
currentType.value = typeRange.value[e.detail.value] || { name: '全部', value: 'ALL' };
refreshList();
}
function pickDate(e) {
date.value = e.detail.value || '';
refreshList();
}
function clearDate() {
if (!date.value) return;
date.value = '';
refreshList();
}
function add() {
uni.showActionSheet({
itemList: templates.value.map((i) => i.name),
success: ({ tapIndex }) => {
const t = templates.value[tapIndex];
uni.navigateTo({
url: `/pages/case/visit-record-detail?archiveId=${encodeURIComponent(props.archiveId)}&type=${encodeURIComponent(t.templateType)}&name=${encodeURIComponent(props.data?.name || '')}`,
});
},
});
}
function edit(record) {
uni.navigateTo({
url: `/pages/case/visit-record-detail?archiveId=${encodeURIComponent(props.archiveId)}&id=${encodeURIComponent(record._id)}&type=${encodeURIComponent(record.templateType || record.medicalType || '')}`,
});
}
onMounted(() => {
ensureSeed(props.archiveId, props.data);
refreshList();
uni.$on('archive-detail:visit-record-changed', refreshList);
});
onUnmounted(() => {
uni.$off('archive-detail:visit-record-changed', refreshList);
});
</script>
<style scoped>
.wrap {
padding: 12px 0 96px;
}
.filters {
display: flex;
gap: 10px;
padding: 10px 14px;
background: #f5f6f8;
border-bottom: 1px solid #f2f2f2;
}
.filter-pill {
background: #fff;
border: 1px solid #e6e6e6;
border-radius: 6px;
padding: 10px 10px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
min-width: 110px;
}
.pill-text {
font-size: 13px;
color: #333;
max-width: 140px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.pill-text.muted {
color: #999;
}
.pill-icon {
padding-left: 8px;
}
.list {
padding: 0 14px;
}
.card {
background: #fff;
border-radius: 10px;
margin-top: 10px;
overflow: hidden;
box-shadow: 0 6px 14px rgba(0, 0, 0, 0.06);
}
.record {
padding: 0;
}
.record-head {
display: flex;
align-items: center;
padding: 12px 12px 10px;
gap: 8px;
}
.record-title {
font-size: 15px;
font-weight: 600;
color: #1f1f1f;
}
.record-date {
font-size: 14px;
font-weight: 600;
color: #333;
}
.record-body {
padding: 0 12px 12px;
}
.kv {
display: flex;
padding-top: 10px;
font-size: 13px;
color: #333;
line-height: 18px;
}
.k {
flex-shrink: 0;
color: #666;
}
.v {
flex: 1;
color: #333;
word-break: break-all;
}
.record-foot {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 12px;
border-top: 1px solid #f2f2f2;
font-size: 12px;
color: #999;
}
.foot-left {
flex-shrink: 0;
margin-right: 10px;
}
.foot-right {
flex: 1;
text-align: right;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.record-tag {
font-size: 12px;
color: #fff;
padding: 4px 8px;
border-radius: 8px;
}
.bg-blue {
background: #4f6ef7;
}
.bg-amber {
background: #d97706;
}
.bg-teal {
background: #0f766e;
}
.bg-green {
background: #16a34a;
}
.bg-rose {
background: #f43f5e;
}
.empty {
padding: 120px 0;
text-align: center;
color: #9aa0a6;
font-size: 13px;
}
.fab {
position: fixed;
right: 16px;
width: 52px;
height: 52px;
border-radius: 26px;
background: #4f6ef7;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 10px 18px rgba(79, 110, 247, 0.35);
z-index: 20;
}
</style>