我的鲜花

This commit is contained in:
haomingming
2026-03-06 10:45:44 +08:00
6 changed files with 94 additions and 61 deletions
+2 -2
View File
@@ -2,8 +2,8 @@
"name" : "肝胆相照专家版", "name" : "肝胆相照专家版",
"appid" : "__UNI__89F511F", "appid" : "__UNI__89F511F",
"description" : "", "description" : "",
"versionName" : "4.2.4", "versionName" : "4.2.5",
"versionCode" : 424, "versionCode" : 425,
"transformPx" : false, "transformPx" : false,
"app-plus" : { "app-plus" : {
/* 5+App特有相关 */ /* 5+App特有相关 */
+1 -1
View File
@@ -1686,7 +1686,7 @@
"list": [ "list": [
{ {
"name": "", "name": "",
"path": "/pages_app/myFlower/myFlower", "path": "pages_app/patientMsg/patientMsg",
"query": "" "query": ""
} }
] ]
+4 -3
View File
@@ -99,7 +99,7 @@
</template> </template>
<script setup> <script setup>
import { ref, computed, onMounted } from 'vue'; import { ref, computed, onMounted,nextTick } from 'vue';
import { onShow,onBackPress,onLoad } from "@dcloudio/uni-app"; import { onShow,onBackPress,onLoad } from "@dcloudio/uni-app";
import upImg from "@/static/triangle_green_theme.png" import upImg from "@/static/triangle_green_theme.png"
import downImg from "@/static/triangle_normal.png" import downImg from "@/static/triangle_normal.png"
@@ -166,8 +166,9 @@ const fetchGroupList = async () => {
openGroups.value = {}; openGroups.value = {};
groupRenderCount.value = {}; groupRenderCount.value = {};
groups.value.forEach((_, idx) => openGroups.value[idx] = false); groups.value.forEach((_, idx) => openGroups.value[idx] = false);
nextTick(() => {
uni.hideLoading(); uni.hideLoading();
});
} }
}; };
+67 -41
View File
@@ -100,7 +100,7 @@
<view class="listbox"> <view class="listbox">
<!-- 使用 up-index-list 索引组件,数据动态渲染 --> <!-- 使用 up-index-list 索引组件,数据动态渲染 -->
<up-index-list :index-list="indexList" v-if="loadFinish" > <up-index-list :index-list="indexList" v-show="loadFinish" >
<!-- 特殊操作项 --> <!-- 特殊操作项 -->
<template #header> <template #header>
@@ -140,7 +140,7 @@
</view> </view>
</template> </template>
<template v-else> <template v-else>
<image class="patient-avatar" :src="docUrl+item.photo" mode="aspectFill" @click="goPatientDetail(item.uuid)"></image> <image class="patient-avatar" :src="item.avatarUrl" mode="aspectFill" @click="goPatientDetail(item.uuid)"></image>
</template> </template>
<view class="patient-info" @click="goPatientDetail(item.uuid)"> <view class="patient-info" @click="goPatientDetail(item.uuid)">
<text class="patient-name">{{ item.realName }}</text> <text class="patient-name">{{ item.realName }}</text>
@@ -150,7 +150,7 @@
</view> </view>
<view class="patient-status"> <view class="patient-status">
<uni-icons type="compose" size="20" color="#8B2316" @click.stop="editPatient(item.uuid)"></uni-icons> <uni-icons type="compose" size="20" color="#8B2316" @click.stop="editPatient(item.uuid)"></uni-icons>
<text class="follow-date">随访于{{ formatYMD(item.join_date) }}</text> <text class="follow-date">随访于{{ item.joinDateYMD }}</text>
</view> </view>
</view> </view>
</view> </view>
@@ -248,14 +248,17 @@
<script setup> <script setup>
import { ref, getCurrentInstance, computed } from 'vue'; import { ref, getCurrentInstance, computed, nextTick, shallowRef } from 'vue';
import { onShow,onLoad,onBackPress} from "@dcloudio/uni-app"; import { onShow,onLoad,onBackPress} from "@dcloudio/uni-app";
import dayImg from "@/static/visit_data11.png" import dayImg from "@/static/visit_data11.png"
import planImg from "@/static/visitplan.png" import planImg from "@/static/visitplan.png"
import api from '@/api/api.js'; import api from '@/api/api.js';
import navTo from '@/utils/navTo.js'; import navTo from '@/utils/navTo.js';
import docUrl from '@/utils/docUrl.js'; import docUrl from '@/utils/docUrl.js';
const patientList = ref([]); const patientList = ref([]);
const patientDataLoaded = ref(false);
const patientDataLoading = ref(false);
const firstLetterCache = new Map();
const navHeight = ref(40); const navHeight = ref(40);
onBackPress(() => { onBackPress(() => {
plus.runtime.quit(); plus.runtime.quit();
@@ -302,7 +305,7 @@
const d = dayjs(input); const d = dayjs(input);
return d.isValid() ? d.format('YYYY年MM月') : ''; return d.isValid() ? d.format('YYYY年MM月') : '';
} }
// 格式化显示日(如:03) // 格式化显示日(如:03)
const formatDay = (input) => { const formatDay = (input) => {
if (!input) return ''; if (!input) return '';
const d = dayjs(input); const d = dayjs(input);
@@ -348,7 +351,7 @@
}; };
// 分组数据(可从接口返回后赋值) // 分组数据(可从接口返回后赋值)
const patientGroups = ref([]); const patientGroups = shallowRef([]);
// 重建索引时保持固定 A-Z // 重建索引时保持固定 A-Z
const rebuildIndexList = () => { const rebuildIndexList = () => {
@@ -359,36 +362,48 @@
// 生成模拟数据 // 生成模拟数据
// 工具:获取首字母 // 工具:获取首字母
const generateMockDate = () => ''; const generateMockDate = () => '';
const getFirstLetter = (chineseName) => { const getFirstLetter = (name = '') => {
// 假设名字由一个或多个汉字组成,我们取第一个汉字的首字母 const firstChar = String(name).trim().charAt(0);
const firstChar = chineseName.charAt(0); // 获取第一个汉字 if (!firstChar) return '#';
const pinyinArray = pinyin(firstChar, { style: pinyin.STYLE_NORMAL }); // 获取拼音数组 if (/^[A-Za-z]$/.test(firstChar)) return firstChar.toUpperCase();
return pinyinArray[0][0].charAt(0); // 返回拼音的第一个字母 if (firstLetterCache.has(firstChar)) {
} return firstLetterCache.get(firstChar);
}
try {
const pinyinArray = pinyin(firstChar, { style: pinyin.STYLE_NORMAL });
const py = pinyinArray?.[0]?.[0] || '';
const letter = py ? py.charAt(0).toUpperCase() : '#';
firstLetterCache.set(firstChar, letter);
return letter;
} catch (error) {
return '#';
}
}
// 根据 patientList 构建按拼音首字母的分组 // 根据 patientList 构建按拼音首字母的分组
const buildGroupsFromPatients = () => { const buildGroupsFromPatients = () => {
const map = new Map(); const map = new Map();
patientList.value.forEach((p) => {
const name = p.realName; const source = patientList.value || [];
const first = name?getFirstLetter(name).toUpperCase():'#'; for (let i = 0; i < source.length; i++) {
const p = source[i] || {};
const normalized = {
...p,
avatarUrl: p.photo ? `${docUrl}${p.photo}` : '',
joinDateYMD: formatYMD(p.join_date)
};
const first = getFirstLetter(normalized.realName || '');
const letter = /^[A-Z]$/.test(first) ? first : '#'; const letter = /^[A-Z]$/.test(first) ? first : '#';
if (!map.has(letter)) map.set(letter, []); if (!map.has(letter)) map.set(letter, []);
map.get(letter).push(p); map.get(letter).push(normalized);
}); }
const letters = Array.from(map.keys()).sort((a,b) => a.localeCompare(b)); const letters = Array.from(map.keys()).sort((a,b) => a.localeCompare(b));
patientGroups.value = letters.map(l => ({ letter: l, items: map.get(l) })); patientGroups.value = letters.map(l => ({ letter: l, items: map.get(l) }));
rebuildIndexList(); rebuildIndexList();
if(patientList.value.length > 4000){ nextTick(() => {
loadFinish.value = true;
setTimeout(() => { setTimeout(() => {
uni.hideLoading(); uni.hideLoading();
},1000);
}, 10000); });
}else{
uni.hideLoading();
loadFinish.value = true;
}
}; };
@@ -469,14 +484,21 @@
} }
}; };
const patientListByGBK = async () => { const patientListByGBK = async () => {
if (patientDataLoading.value) return;
const res = await api.patientListByGBK(); patientDataLoading.value = true;
if(res.code == 1){ try {
patientList.value = res.data; const res = await api.patientListByGBK();
if(res.code == 1){
buildGroupsFromPatients() loadFinish.value = true;
patientList.value = res.data || [];
buildGroupsFromPatients();
patientDataLoaded.value = true;
} else {
uni.hideLoading();
}
} finally {
patientDataLoading.value = false;
} }
}; };
const page=ref(1) const page=ref(1)
const followUpList = ref([]); const followUpList = ref([]);
@@ -594,12 +616,16 @@
// title.value = '患者消息'; // title.value = '患者消息';
break; break;
case 'list': case 'list':
uni.showLoading({ title.value = '患者列表';
title: '加载中...', if (patientDataLoaded.value) {
mask: true loadFinish.value = true;
}); break;
patientListByGBK(); }
title.value = '患者列表'; uni.showLoading({
title: '加载中...',
mask: true
});
patientListByGBK();
// 显示患者列表 // 显示患者列表
break; break;
case 'plan': case 'plan':
@@ -1232,4 +1258,4 @@
} }
} }
</style> </style>
+10 -7
View File
@@ -42,7 +42,7 @@
</template> </template>
<script setup> <script setup>
import { ref, computed } from 'vue' import { ref, computed,nextTick} from 'vue'
import docUrl from '@/utils/docUrl.js' import docUrl from '@/utils/docUrl.js'
import { onShow,onLoad} from "@dcloudio/uni-app"; import { onShow,onLoad} from "@dcloudio/uni-app";
import api from '@/api/api.js' import api from '@/api/api.js'
@@ -63,13 +63,16 @@
if(res.code == 1){ if(res.code == 1){
patientList.value = res.data; patientList.value = res.data;
availablePatientList.value = res.data; availablePatientList.value = res.data;
if(res.data.length > 1000){ nextTick(() => {
setTimeout(() => {
uni.hideLoading();
}, 5000);
}else{
uni.hideLoading(); uni.hideLoading();
} });
// if(res.data.length > 1000){
// setTimeout(() => {
// uni.hideLoading();
// }, 5000);
// }else{
// uni.hideLoading();
// }
} }
}; };
@@ -42,7 +42,7 @@
</template> </template>
<script setup> <script setup>
import { ref, computed } from 'vue' import { ref, computed,nextTick } from 'vue'
import docUrl from '@/utils/docUrl.js' import docUrl from '@/utils/docUrl.js'
import { onShow,onLoad} from "@dcloudio/uni-app"; import { onShow,onLoad} from "@dcloudio/uni-app";
import api from '@/api/api.js' import api from '@/api/api.js'
@@ -62,13 +62,16 @@
if(res.code == 1){ if(res.code == 1){
patientList.value = res.data; patientList.value = res.data;
availablePatientList.value = res.data; availablePatientList.value = res.data;
if(res.data.length > 1000){ nextTick(() => {
setTimeout(() => {
uni.hideLoading();
}, 5000);
}else{
uni.hideLoading(); uni.hideLoading();
} });
// if(res.data.length > 1000){
// setTimeout(() => {
// uni.hideLoading();
// }, 5000);
// }else{
// uni.hideLoading();
// }
} }
}; };