This commit is contained in:
huxuejian 2026-02-11 17:24:50 +08:00
commit cc58301191
3 changed files with 226 additions and 10 deletions

View File

@ -279,6 +279,8 @@ const typeOptions = [
];
const teamOptions = ref([{ label: "全部", value: "ALL" }]);
const teamNameMap = ref({});
const loadedTeamNameIds = new Set();
const query = reactive({
isMy: false,
@ -401,6 +403,89 @@ function getExecuteTeamId(todo) {
.trim();
}
function resolveTeamName(id) {
const tid = String(id || "").trim();
if (!tid) return "";
const cached = teamNameMap.value?.[tid];
if (cached) return String(cached);
const list = teamOptions.value || [];
const hit = list.find((i) => i && i.value === tid);
if (hit?.label && hit.label !== "全部") return String(hit.label);
return "";
}
let teamNameBatchInflight = null;
async function batchLoadTeamNames(teamIds) {
const ids = Array.isArray(teamIds)
? teamIds.map((v) => String(v || "").trim()).filter(Boolean)
: [];
if (!ids.length) return;
const uniq = Array.from(new Set(ids));
const unknown = uniq.filter((tid) => {
if (loadedTeamNameIds.has(tid)) return false;
const cached = teamNameMap.value?.[tid];
if (cached) return false;
const list = teamOptions.value || [];
const hit = list.find((i) => i && i.value === tid);
return !hit?.label;
});
if (!unknown.length) return;
if (teamNameBatchInflight) return teamNameBatchInflight;
await ensureDoctor();
const corpId = getCorpId();
if (!corpId) return;
unknown.forEach((tid) => loadedTeamNameIds.add(tid));
teamNameBatchInflight = (async () => {
try {
const res = await api("getTeamById", { corpId, teamIds: unknown }, false);
if (res?.success) {
const rows = Array.isArray(res?.data) ? res.data : Array.isArray(res?.data?.data) ? res.data.data : [];
const patch = rows.reduce((acc, t) => {
const id = String(t?.teamId || t?.id || t?._id || "").trim();
if (!id) return acc;
const name = String(t?.name || t?.teamName || t?.team || "").trim();
if (!name) return acc;
const existing = teamNameMap.value?.[id];
if (existing) return acc;
acc[id] = name;
return acc;
}, {});
if (Object.keys(patch).length) teamNameMap.value = { ...(teamNameMap.value || {}), ...patch };
return;
}
} catch {
// ignore
}
// fallback
const limit = 4;
let idx = 0;
const workers = Array.from({ length: Math.min(limit, unknown.length) }, async () => {
while (idx < unknown.length) {
const tid = unknown[idx++];
try {
const res = await api("getTeamData", { corpId, teamId: tid }, false);
if (!res?.success) continue;
const data = res?.data && typeof res.data === "object" ? res.data : {};
const name = String(data?.name || data?.teamName || data?.team || "").trim();
if (!name) continue;
if (!teamNameMap.value?.[tid]) teamNameMap.value = { ...(teamNameMap.value || {}), [tid]: name };
} catch {
// ignore
}
}
});
await Promise.allSettled(workers);
})().finally(() => {
teamNameBatchInflight = null;
});
return teamNameBatchInflight;
}
const loadedTeamMemberIds = new Set();
const teamMemberInflight = new Map();
async function loadTeamMembers(teamId) {
@ -572,14 +657,38 @@ async function ensureTodoNames(todos) {
});
await Promise.allSettled(workers);
await batchLoadTeamNames(teamIds);
await batchLoadCorpMembers(unknownUserIds);
//
list.value = (Array.isArray(list.value) ? list.value : []).map((t) => ({
...t,
executorName: normalizeName(t?.executorName) || resolveUserName(t?.executorUserId),
creatorName: normalizeName(t?.creatorName) || resolveUserName(t?.creatorUserId),
}));
list.value = (Array.isArray(list.value) ? list.value : []).map((t) => {
const uId = t?.executorUserId;
const uName = resolveUserName(uId);
const finalExecutorName =
uName && uName !== String(uId || "")
? uName
: normalizeName(t?.executorName) || uName;
const cId = t?.creatorUserId;
const cName = resolveUserName(cId);
const finalCreatorName =
cName && cName !== String(cId || "")
? cName
: normalizeName(t?.creatorName) || cName;
const tid = getExecuteTeamId(t);
const tName = resolveTeamName(tid);
const finalTeamName = tName
? tName
: normalizeName(t?.executeTeamName || t?.teamName) || tName;
return {
...t,
executorName: finalExecutorName,
creatorName: finalCreatorName,
executeTeamName: finalTeamName,
};
});
})().finally(() => {
ensureNamesInflight = null;
});
@ -631,6 +740,22 @@ function formatTodo(todo) {
const status = getStatus(todo);
const plannedExecutionTime = todo?.plannedExecutionTime;
const createTime = todo?.createTime;
const teamId = getExecuteTeamId(todo);
const uId = todo?.executorUserId;
const uName = resolveUserName(uId);
const finalExecutorName =
uName && uName !== String(uId || "")
? uName
: normalizeName(todo?.executorName) || uName;
const cId = todo?.creatorUserId;
const cName = resolveUserName(cId);
const finalCreatorName =
cName && cName !== String(cId || "")
? cName
: normalizeName(todo?.creatorName) || cName;
return {
...todo,
status,
@ -644,8 +769,12 @@ function formatTodo(todo) {
createTime && dayjs(createTime).isValid()
? dayjs(createTime).format("YYYY-MM-DD HH:mm")
: "",
executorName: resolveUserName(todo?.executorUserId),
creatorName: resolveUserName(todo?.creatorUserId),
executorName: finalExecutorName,
creatorName: finalCreatorName,
executeTeamId: teamId,
executeTeamName:
normalizeName(todo?.executeTeamName || todo?.teamName) ||
resolveTeamName(teamId),
};
}

View File

@ -72,8 +72,10 @@
<script setup>
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
import { storeToRefs } from 'pinia';
import dayjs from 'dayjs';
import api from '@/utils/api';
import useAccountStore from '@/store/account';
import { loading, hideLoading, toast } from '@/utils/widget';
import { normalizeTemplate } from '../../utils/template';
import { normalizeVisitRecordFormData } from '../../utils/visit-record';
@ -85,6 +87,10 @@ const props = defineProps({
floatingBottom: { type: Number, default: 16 },
});
const accountStore = useAccountStore();
const { account, doctorInfo } = storeToRefs(accountStore);
const { getDoctorInfo } = accountStore;
const FALLBACK_TEMPLATE_TYPES = ['outpatient', 'inhospital', 'preConsultationRecord', 'physicalExaminationTemplate'];
const templates = ref([]);
const selectableTemplates = computed(() => templates.value.filter((i) => i && i.templateType && typeof i.name === 'string' && i.name.trim()));
@ -134,7 +140,77 @@ const shareAllTeamsForQuery = computed(() => {
function getCorpId() {
const team = uni.getStorageSync('ykt_case_current_team') || {};
return team?.corpId ? String(team.corpId) : '';
const d = doctorInfo.value || {};
const a = account.value || {};
return String(team.corpId || d.corpId || a.corpId || '') || '';
}
async function ensureDoctor() {
if (doctorInfo.value) return;
if (!account.value?.openid) return;
try {
await getDoctorInfo();
} catch {
// ignore
}
}
let corpMemberBatchInflight = null;
async function batchLoadCorpMembers(userIds) {
const ids = Array.isArray(userIds) ? userIds.map((v) => String(v || '').trim()).filter(Boolean) : [];
if (!ids.length) return;
const uniq = Array.from(new Set(ids));
const unknown = uniq.filter((id) => {
const existing = userNameMap.value?.[id];
return !existing || existing === id;
});
if (!unknown.length) return;
if (corpMemberBatchInflight) return corpMemberBatchInflight;
await ensureDoctor();
const corpId = getCorpId();
if (!corpId) return;
corpMemberBatchInflight = (async () => {
try {
const res = await api(
'getCorpMember',
{
page: 1,
pageSize: Math.min(Math.max(unknown.length, 10), 500),
params: {
corpId,
memberList: unknown,
},
},
false
);
if (!res?.success) return;
const rows = Array.isArray(res?.data) ? res.data : Array.isArray(res?.data?.data) ? res.data.data : [];
if (!rows.length) return;
const patch = rows.reduce((acc, m) => {
const id = String(m?.userid || m?.userId || m?.corpUserId || '').trim();
if (!id) return acc;
const existing = userNameMap.value?.[id];
if (existing && existing !== id) return acc;
const display = String(m?.anotherName || m?.name || '').trim();
if (!display || display === id) return acc;
acc[id] = display;
return acc;
}, {});
if (Object.keys(patch).length) userNameMap.value = { ...(userNameMap.value || {}), ...patch };
} catch {
// ignore
}
})().finally(() => {
corpMemberBatchInflight = null;
});
return corpMemberBatchInflight;
}
const loadedCorpId = ref('');
@ -386,6 +462,18 @@ async function refreshList() {
records.value = !shareAllTeamsForQuery.value && teamId.value
? mapped.filter((i) => String(i?.teamId || '') === String(teamId.value))
: mapped;
const creatorIds = mapped
.map(
(i) =>
i.creator ||
i.creatorUserId ||
i.createUserId ||
i.executor ||
i.executorUserId
)
.filter(Boolean);
void batchLoadCorpMembers(creatorIds);
} else {
records.value = [];
}
@ -460,7 +548,7 @@ function getCreateFooter(r) {
const byCustomer = r?.ignore === 'checkIn';
if (byCustomer) return time ? `${time} 患者自建` : '患者自建';
const creatorId = String(r?.creator || '');
const creatorId = String(r?.creator || r?.creatorUserId || r?.createUserId || r?.executor || r?.executorUserId || '');
if (!creatorId) return time ? `创建时间:${time}` : '';
const name = resolveUserName(creatorId);
return time ? `${time} ${name}代建` : `${name}代建`;

View File

@ -1125,7 +1125,6 @@ async function reload(reset = true, opts = {}) {
const corpId = getCorpId();
const teamId = getTeamId();
if (!corpId || !teamId || !userId) {
toast('缺少用户/团队信息,请先完成登录与个人信息');
return;
}