fix:优化病历列表显示
This commit is contained in:
parent
ea51cee22a
commit
de468c1acb
@ -30,13 +30,8 @@
|
|||||||
<view class="tabs-area">
|
<view class="tabs-area">
|
||||||
<scroll-view scroll-x class="tabs-scroll" :show-scrollbar="false">
|
<scroll-view scroll-x class="tabs-scroll" :show-scrollbar="false">
|
||||||
<view class="tabs-container">
|
<view class="tabs-container">
|
||||||
<view
|
<view v-for="tab in tabs" :key="tab.key" class="tab-item" :class="{ active: currentTabKey === tab.key }"
|
||||||
v-for="tab in tabs"
|
@click="onTabClick(tab)">
|
||||||
:key="tab.key"
|
|
||||||
class="tab-item"
|
|
||||||
:class="{ active: currentTabKey === tab.key }"
|
|
||||||
@click="onTabClick(tab)"
|
|
||||||
>
|
|
||||||
{{ tab.label }}
|
{{ tab.label }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -47,32 +42,24 @@
|
|||||||
<!-- Main Content -->
|
<!-- Main Content -->
|
||||||
<view class="content-body">
|
<view class="content-body">
|
||||||
<!-- Patient List -->
|
<!-- Patient List -->
|
||||||
<scroll-view
|
<scroll-view scroll-y class="patient-list" :scroll-into-view="scrollIntoId" :scroll-with-animation="true"
|
||||||
scroll-y
|
lower-threshold="80" @scrolltolower="loadMore">
|
||||||
class="patient-list"
|
|
||||||
:scroll-into-view="scrollIntoId"
|
|
||||||
:scroll-with-animation="true"
|
|
||||||
lower-threshold="80"
|
|
||||||
@scrolltolower="loadMore"
|
|
||||||
>
|
|
||||||
<view v-for="group in patientList" :key="group.letter" :id="letterToDomId(group.letter)">
|
<view v-for="group in patientList" :key="group.letter" :id="letterToDomId(group.letter)">
|
||||||
<view class="group-title">{{ group.letter }}</view>
|
<view class="group-title">{{ group.letter }}</view>
|
||||||
|
|
||||||
<view v-for="(patient, pIndex) in group.data" :key="pIndex" class="patient-card" @click="handlePatientClick(patient)">
|
<view v-for="(patient, pIndex) in group.data" :key="pIndex" class="patient-card"
|
||||||
|
@click="handlePatientClick(patient)">
|
||||||
<!-- Checkbox for Batch Mode -->
|
<!-- Checkbox for Batch Mode -->
|
||||||
<view v-if="isBatchMode" class="checkbox-area">
|
<view v-if="isBatchMode" class="checkbox-area">
|
||||||
<uni-icons
|
<uni-icons :type="selectedItems.includes(getSelectId(patient)) ? 'checkbox-filled' : 'checkbox'" size="24"
|
||||||
:type="selectedItems.includes(getSelectId(patient)) ? 'checkbox-filled' : 'checkbox'"
|
:color="selectedItems.includes(getSelectId(patient)) ? '#007aff' : '#ccc'"></uni-icons>
|
||||||
size="24"
|
|
||||||
:color="selectedItems.includes(getSelectId(patient)) ? '#007aff' : '#ccc'"
|
|
||||||
></uni-icons>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="card-content">
|
<view class="card-content">
|
||||||
<!-- Row 1 -->
|
<!-- Row 1 -->
|
||||||
<view class="card-row-top">
|
<view class="card-row-top">
|
||||||
<view class="patient-info">
|
<view class="patient-info">
|
||||||
<text class="patient-name">{{ patient.name }}</text>
|
<text class="patient-name">{{ patient.name }}</text>
|
||||||
<text class="patient-meta">{{ patient.gender }}/{{ patient.age }}岁</text>
|
<text class="patient-meta">{{ patient.gender }}{{ patient.age ? '/' + patient.age + '岁' : '' }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="patient-tags">
|
<view class="patient-tags">
|
||||||
<view v-for="(tag, tIndex) in resolveGroupTags(patient)" :key="tIndex" class="tag">
|
<view v-for="(tag, tIndex) in resolveGroupTags(patient)" :key="tIndex" class="tag">
|
||||||
@ -80,12 +67,21 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- Row 2 / 3 -->
|
<!-- Row 2 -->
|
||||||
|
<view v-if="currentTabKey === 'new'" class="card-row-middle">
|
||||||
|
<text v-if="patient.record" class="record-text record-ellipsis">
|
||||||
|
{{ patient.record.type }} / {{ patient.record.date }} / {{ patient.record.diagnosis }}
|
||||||
|
</text>
|
||||||
|
<text v-else class="no-record">暂无病历记录</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- Row 3 -->
|
||||||
<view class="card-row-bottom">
|
<view class="card-row-bottom">
|
||||||
<template v-if="currentTabKey === 'new'"> <!-- New Patient Tab -->
|
<template v-if="currentTabKey === 'new'"> <!-- New Patient Tab -->
|
||||||
<text class="record-text">
|
<text class="record-text">
|
||||||
{{ patient.createTime || '-' }} / {{ resolveCreatorName(patient) || '-' }}
|
{{ patient.createTime || '-' }} {{ resolveCreatorName(patient) ? resolveCreatorName(patient) +
|
||||||
|
'创建' : '-' }}
|
||||||
</text>
|
</text>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
@ -104,12 +100,7 @@
|
|||||||
|
|
||||||
<!-- Sidebar Index -->
|
<!-- Sidebar Index -->
|
||||||
<view v-if="!isBatchMode" class="sidebar-index">
|
<view v-if="!isBatchMode" class="sidebar-index">
|
||||||
<view
|
<view v-for="letter in indexList" :key="letter" class="index-item" @click="scrollToLetter(letter)">
|
||||||
v-for="letter in indexList"
|
|
||||||
:key="letter"
|
|
||||||
class="index-item"
|
|
||||||
@click="scrollToLetter(letter)"
|
|
||||||
>
|
|
||||||
{{ letter }}
|
{{ letter }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -118,11 +109,9 @@
|
|||||||
<!-- Batch Actions Footer -->
|
<!-- Batch Actions Footer -->
|
||||||
<view v-if="isBatchMode" class="batch-footer">
|
<view v-if="isBatchMode" class="batch-footer">
|
||||||
<view class="left-action" @click="handleSelectAll">
|
<view class="left-action" @click="handleSelectAll">
|
||||||
<uni-icons
|
<uni-icons
|
||||||
:type="selectedItems.length > 0 && selectedItems.length === patientList.flatMap(g => g.data).length ? 'checkbox-filled' : 'checkbox'"
|
:type="selectedItems.length > 0 && selectedItems.length === patientList.flatMap(g => g.data).length ? 'checkbox-filled' : 'checkbox'"
|
||||||
size="24"
|
size="24" color="#666"></uni-icons>
|
||||||
color="#666"
|
|
||||||
></uni-icons>
|
|
||||||
<text class="footer-text">全选 ({{ selectedItems.length }})</text>
|
<text class="footer-text">全选 ({{ selectedItems.length }})</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="right-actions">
|
<view class="right-actions">
|
||||||
@ -202,7 +191,7 @@ const accountStore = useAccountStore();
|
|||||||
const { account, doctorInfo } = storeToRefs(accountStore);
|
const { account, doctorInfo } = storeToRefs(accountStore);
|
||||||
const { getDoctorInfo } = accountStore;
|
const { getDoctorInfo } = accountStore;
|
||||||
|
|
||||||
const teamDisplay = computed(() => `${currentTeam.value?.name || ''}(${managedArchiveCountAllTeams.value})`);
|
const teamDisplay = computed(() => `${currentTeam.value?.name || ''}`);
|
||||||
|
|
||||||
function asArray(value) {
|
function asArray(value) {
|
||||||
return Array.isArray(value) ? value : [];
|
return Array.isArray(value) ? value : [];
|
||||||
@ -246,10 +235,10 @@ async function loadTeamMembers() {
|
|||||||
const members = Array.isArray(t.memberList) ? t.memberList : [];
|
const members = Array.isArray(t.memberList) ? t.memberList : [];
|
||||||
// Update map
|
// Update map
|
||||||
members.forEach(m => {
|
members.forEach(m => {
|
||||||
const uid = String(m?.userid || '');
|
const uid = String(m?.userid || '');
|
||||||
if (uid) {
|
if (uid) {
|
||||||
userNameMap.value[uid] = String(m?.anotherName || m?.name || m?.userid || '') || uid;
|
userNameMap.value[uid] = String(m?.anotherName || m?.name || m?.userid || '') || uid;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('获取团队成员失败', e);
|
console.error('获取团队成员失败', e);
|
||||||
@ -386,7 +375,7 @@ function formatPatient(raw) {
|
|||||||
const rawTags = asArray(raw?.tags).filter((i) => typeof i === 'string' && i.trim());
|
const rawTags = asArray(raw?.tags).filter((i) => typeof i === 'string' && i.trim());
|
||||||
// 最后才使用 tagIds(仅作为兜底,不推荐显示)
|
// 最后才使用 tagIds(仅作为兜底,不推荐显示)
|
||||||
const tagIds = asArray(raw?.tagIds).map(String).filter(Boolean);
|
const tagIds = asArray(raw?.tagIds).map(String).filter(Boolean);
|
||||||
|
|
||||||
// 解析标签:优先 tagNames > tags(字符串) > tagIds
|
// 解析标签:优先 tagNames > tags(字符串) > tagIds
|
||||||
const displayTags = rawTagNames.length ? rawTagNames : (rawTags.length ? rawTags : []);
|
const displayTags = rawTagNames.length ? rawTagNames : (rawTags.length ? rawTags : []);
|
||||||
|
|
||||||
@ -535,11 +524,11 @@ async function reload(reset = true) {
|
|||||||
managedArchiveCountAllTeams.value =
|
managedArchiveCountAllTeams.value =
|
||||||
Number(
|
Number(
|
||||||
payload.totalAllTeams ||
|
payload.totalAllTeams ||
|
||||||
payload.totalAllTeam ||
|
payload.totalAllTeam ||
|
||||||
payload.totalAllTeamsCount ||
|
payload.totalAllTeamsCount ||
|
||||||
managedArchiveCountAllTeams.value ||
|
managedArchiveCountAllTeams.value ||
|
||||||
totalFromApi.value ||
|
totalFromApi.value ||
|
||||||
0
|
0
|
||||||
) || (totalFromApi.value || 0);
|
) || (totalFromApi.value || 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -579,7 +568,7 @@ const patientList = computed(() => {
|
|||||||
.filter((p) => Number(p?.createTimeTs || 0) >= sevenDaysAgo)
|
.filter((p) => Number(p?.createTimeTs || 0) >= sevenDaysAgo)
|
||||||
.slice()
|
.slice()
|
||||||
.sort((a, b) => Number(b?.createTimeTs || 0) - Number(a?.createTimeTs || 0));
|
.sort((a, b) => Number(b?.createTimeTs || 0) - Number(a?.createTimeTs || 0));
|
||||||
return [{ letter: '最近新增', data: flatList }];
|
return [{ letter: '最近7天新增', data: flatList }];
|
||||||
}
|
}
|
||||||
|
|
||||||
return groupByLetter(all);
|
return groupByLetter(all);
|
||||||
@ -587,7 +576,8 @@ const patientList = computed(() => {
|
|||||||
|
|
||||||
const indexList = computed(() => {
|
const indexList = computed(() => {
|
||||||
if (currentTab.value.kind === 'new') return []; // No index bar for new patient
|
if (currentTab.value.kind === 'new') return []; // No index bar for new patient
|
||||||
return 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('').filter(l => patientList.value.some(g => g.letter === l));
|
const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ#'.split('').filter(l => patientList.value.some(g => g.letter === l));
|
||||||
|
return letters;
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalPatients = computed(() => {
|
const totalPatients = computed(() => {
|
||||||
@ -752,7 +742,7 @@ const openCreatePatientEntry = () => {
|
|||||||
// Batch Operations
|
// Batch Operations
|
||||||
const toggleSelect = (patient) => {
|
const toggleSelect = (patient) => {
|
||||||
if (!isBatchMode.value) return; // Should not happen if click handler is correct
|
if (!isBatchMode.value) return; // Should not happen if click handler is correct
|
||||||
|
|
||||||
const id = patient._id || patient.id || patient.phone || patient.mobile; // Prefer server id
|
const id = patient._id || patient.id || patient.phone || patient.mobile; // Prefer server id
|
||||||
const index = selectedItems.value.indexOf(id);
|
const index = selectedItems.value.indexOf(id);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
@ -861,11 +851,11 @@ onShow(async () => {
|
|||||||
height: 100vh;
|
height: 100vh;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
padding-bottom: 0; // Default
|
padding-bottom: 0; // Default
|
||||||
|
|
||||||
// Padding for batch footer
|
// Padding for batch footer
|
||||||
/* &.is-batch {
|
/* &.is-batch {
|
||||||
padding-bottom: 100rpx;
|
padding-bottom: 100rpx;
|
||||||
} */
|
} */
|
||||||
// We can't use &.is-batch because scoped style and root element is tricky depending on uni-app version/style
|
// We can't use &.is-batch because scoped style and root element is tricky depending on uni-app version/style
|
||||||
// Instead we handle it in content-body or separate view
|
// Instead we handle it in content-body or separate view
|
||||||
}
|
}
|
||||||
@ -884,11 +874,11 @@ onShow(async () => {
|
|||||||
font-size: 32rpx;
|
font-size: 32rpx;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #333;
|
color: #333;
|
||||||
|
|
||||||
.team-name {
|
.team-name {
|
||||||
margin-right: 10rpx;
|
margin-right: 10rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.team-icon {
|
.team-icon {
|
||||||
font-size: 32rpx;
|
font-size: 32rpx;
|
||||||
color: #333;
|
color: #333;
|
||||||
@ -898,13 +888,13 @@ onShow(async () => {
|
|||||||
.header-actions {
|
.header-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 30rpx;
|
gap: 30rpx;
|
||||||
|
|
||||||
.action-item {
|
.action-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.action-text {
|
.action-text {
|
||||||
font-size: 20rpx;
|
font-size: 20rpx;
|
||||||
color: #333;
|
color: #333;
|
||||||
@ -925,11 +915,11 @@ onShow(async () => {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.tabs-container {
|
.tabs-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 20rpx 30rpx;
|
padding: 20rpx 30rpx;
|
||||||
|
|
||||||
.tab-item {
|
.tab-item {
|
||||||
padding: 10rpx 30rpx;
|
padding: 10rpx 30rpx;
|
||||||
margin-right: 20rpx;
|
margin-right: 20rpx;
|
||||||
@ -938,7 +928,7 @@ onShow(async () => {
|
|||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-radius: 8rpx;
|
border-radius: 8rpx;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
color: #5d8aff;
|
color: #5d8aff;
|
||||||
background-color: #e6f0ff;
|
background-color: #e6f0ff;
|
||||||
@ -953,7 +943,7 @@ onShow(async () => {
|
|||||||
color: #666;
|
color: #666;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
min-width: 100rpx;
|
min-width: 70rpx;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1022,7 +1012,7 @@ onShow(async () => {
|
|||||||
.patient-tags {
|
.patient-tags {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10rpx;
|
gap: 10rpx;
|
||||||
|
|
||||||
.tag {
|
.tag {
|
||||||
font-size: 20rpx;
|
font-size: 20rpx;
|
||||||
color: #5d8aff;
|
color: #5d8aff;
|
||||||
@ -1035,13 +1025,14 @@ onShow(async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-row-bottom {
|
.card-row-middle {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
|
||||||
.record-text {
|
.record-text {
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
.record-ellipsis {
|
.record-ellipsis {
|
||||||
display: block;
|
display: block;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@ -1049,7 +1040,27 @@ onShow(async () => {
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-record {
|
||||||
|
color: #bdc3c7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-row-bottom {
|
||||||
|
font-size: 28rpx;
|
||||||
|
|
||||||
|
.record-text {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-ellipsis {
|
||||||
|
display: block;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.no-record {
|
.no-record {
|
||||||
color: #bdc3c7;
|
color: #bdc3c7;
|
||||||
}
|
}
|
||||||
@ -1067,12 +1078,13 @@ onShow(async () => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0 30rpx;
|
padding: 0 30rpx;
|
||||||
box-shadow: 0 -4rpx 20rpx rgba(0,0,0,0.05);
|
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.05);
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
|
|
||||||
.left-action {
|
.left-action {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.footer-text {
|
.footer-text {
|
||||||
margin-left: 10rpx;
|
margin-left: 10rpx;
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
@ -1083,7 +1095,7 @@ onShow(async () => {
|
|||||||
.right-actions {
|
.right-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 20rpx;
|
gap: 20rpx;
|
||||||
|
|
||||||
.footer-btn {
|
.footer-btn {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
padding: 0 30rpx;
|
padding: 0 30rpx;
|
||||||
@ -1091,13 +1103,13 @@ onShow(async () => {
|
|||||||
line-height: 64rpx;
|
line-height: 64rpx;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border-radius: 8rpx;
|
border-radius: 8rpx;
|
||||||
|
|
||||||
&.plain {
|
&.plain {
|
||||||
border: 2rpx solid #ddd;
|
border: 2rpx solid #ddd;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.primary {
|
&.primary {
|
||||||
background-color: #5d8aff;
|
background-color: #5d8aff;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@ -1123,7 +1135,7 @@ onShow(async () => {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
|
||||||
.index-item {
|
.index-item {
|
||||||
font-size: 20rpx;
|
font-size: 20rpx;
|
||||||
color: #555;
|
color: #555;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user