fix:修复userid显示问题
This commit is contained in:
parent
1018707e25
commit
69a0c83311
@ -34,7 +34,7 @@
|
|||||||
<view class="head">
|
<view class="head">
|
||||||
<view class="dot"></view>
|
<view class="dot"></view>
|
||||||
<view class="time">{{ i.timeStr }}</view>
|
<view class="time">{{ i.timeStr }}</view>
|
||||||
<view v-if="i.hasFile" class="file-link" @click.stop="viewFile(i)">
|
<view v-if="showFileEntry && i.hasFile" class="file-link" @click.stop="viewFile(i)">
|
||||||
{{ i.fileType === 'article' ? '查看文章' : '查看问卷' }}
|
{{ i.fileType === 'article' ? '查看文章' : '查看问卷' }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -137,6 +137,11 @@ const loading = ref(false);
|
|||||||
const list = ref([]);
|
const list = ref([]);
|
||||||
const expandMap = ref({});
|
const expandMap = ref({});
|
||||||
const userNameMap = ref({});
|
const userNameMap = ref({});
|
||||||
|
const teamNameMap = ref({});
|
||||||
|
const loadedTeamNameIds = new Set();
|
||||||
|
|
||||||
|
// 先隐藏“查看问卷/文章”入口(保留相关代码,后续可随时打开)
|
||||||
|
const showFileEntry = ref(false);
|
||||||
|
|
||||||
const accountStore = useAccountStore();
|
const accountStore = useAccountStore();
|
||||||
const { account, doctorInfo } = storeToRefs(accountStore);
|
const { account, doctorInfo } = storeToRefs(accountStore);
|
||||||
@ -183,6 +188,7 @@ function getExecutorId(r) {
|
|||||||
const row = r && typeof r === 'object' ? r : {};
|
const row = r && typeof r === 'object' ? r : {};
|
||||||
return String(
|
return String(
|
||||||
row.executorUserId ||
|
row.executorUserId ||
|
||||||
|
row.executorUserID ||
|
||||||
row.executorId ||
|
row.executorId ||
|
||||||
row.executor ||
|
row.executor ||
|
||||||
row.creatorUserId ||
|
row.creatorUserId ||
|
||||||
@ -194,11 +200,11 @@ function getExecutorId(r) {
|
|||||||
|
|
||||||
function executorText(r) {
|
function executorText(r) {
|
||||||
const row = r && typeof r === 'object' ? r : {};
|
const row = r && typeof r === 'object' ? r : {};
|
||||||
const fromRow = normalizeName(row.executorName || row.executorUserName || row.creatorName || row.updateUserName || '');
|
|
||||||
if (fromRow) return fromRow;
|
|
||||||
const uid = getExecutorId(row);
|
const uid = getExecutorId(row);
|
||||||
const mapped = normalizeName(resolveUserName(uid));
|
const mapped = normalizeName(resolveUserName(uid));
|
||||||
return mapped || (uid ? uid : '--');
|
const fromRow = normalizeName(row.executorName || row.executorUserName || row.creatorName || row.updateUserName || '');
|
||||||
|
if (mapped && uid && mapped !== uid && (!fromRow || fromRow === uid)) return mapped;
|
||||||
|
return fromRow || mapped || (uid ? uid : '--');
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExecuteTeamId(r) {
|
function getExecuteTeamId(r) {
|
||||||
@ -209,9 +215,46 @@ function getExecuteTeamId(r) {
|
|||||||
function resolveTeamName(teamId) {
|
function resolveTeamName(teamId) {
|
||||||
const tid = String(teamId || '') || '';
|
const tid = String(teamId || '') || '';
|
||||||
if (!tid) return '';
|
if (!tid) return '';
|
||||||
|
const cached = teamNameMap.value?.[tid];
|
||||||
|
if (cached) return String(cached);
|
||||||
const list = teamList.value || [];
|
const list = teamList.value || [];
|
||||||
const hit = list.find((i) => i && i.value === tid);
|
const hit = list.find((i) => i && i.value === tid);
|
||||||
return hit?.label ? String(hit.label) : '';
|
if (hit?.label) return String(hit.label);
|
||||||
|
// 不阻塞渲染:后台补齐团队名
|
||||||
|
void loadTeamName(tid);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadTeamName(teamId) {
|
||||||
|
const tid = String(teamId || '') || '';
|
||||||
|
if (!tid) return;
|
||||||
|
if (loadedTeamNameIds.has(tid)) return;
|
||||||
|
const corpId = getCorpId();
|
||||||
|
if (!corpId) return;
|
||||||
|
|
||||||
|
loadedTeamNameIds.add(tid);
|
||||||
|
try {
|
||||||
|
const res = await api('getTeamBaseInfo', { corpId, teamId: tid });
|
||||||
|
if (res?.success) {
|
||||||
|
const data = res?.data && typeof res.data === 'object' ? res.data : {};
|
||||||
|
const name = String(data?.name || data?.teamName || data?.team || '').trim();
|
||||||
|
if (name) teamNameMap.value = { ...(teamNameMap.value || {}), [tid]: name };
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
// 兜底:用 getTeamData 再试一次
|
||||||
|
try {
|
||||||
|
const res = await api('getTeamData', { corpId, teamId: tid });
|
||||||
|
if (!res?.success) return;
|
||||||
|
const data = res?.data && typeof res.data === 'object' ? res.data : {};
|
||||||
|
const name = String(data?.name || data?.teamName || data?.team || '').trim();
|
||||||
|
if (name) teamNameMap.value = { ...(teamNameMap.value || {}), [tid]: name };
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function executeTeamText(r) {
|
function executeTeamText(r) {
|
||||||
@ -264,21 +307,110 @@ async function loadTeamMembers(teamId) {
|
|||||||
const tid = String(teamId || '') || '';
|
const tid = String(teamId || '') || '';
|
||||||
if (!tid) return;
|
if (!tid) return;
|
||||||
if (loadedTeamMemberIds.has(tid)) return;
|
if (loadedTeamMemberIds.has(tid)) return;
|
||||||
loadedTeamMemberIds.add(tid);
|
|
||||||
await ensureDoctor();
|
await ensureDoctor();
|
||||||
const corpId = getCorpId();
|
const corpId = getCorpId();
|
||||||
if (!corpId) return;
|
if (!corpId) return;
|
||||||
const res = await api('getTeamData', { corpId, teamId: tid });
|
loadedTeamMemberIds.add(tid);
|
||||||
if (!res?.success) return;
|
|
||||||
const t = res?.data && typeof res.data === 'object' ? res.data : {};
|
// 以 getTeamData 为准(getTeamMemberAvatarsAndName 存在不全/不准的情况)
|
||||||
|
const fallback = await api('getTeamData', { corpId, teamId: tid });
|
||||||
|
if (!fallback?.success) {
|
||||||
|
loadedTeamMemberIds.delete(tid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const t = fallback?.data && typeof fallback.data === 'object' ? fallback.data : {};
|
||||||
const members = Array.isArray(t.memberList) ? t.memberList : [];
|
const members = Array.isArray(t.memberList) ? t.memberList : [];
|
||||||
const map = members.reduce((acc, m) => {
|
const map = members.reduce((acc, m) => {
|
||||||
const uid = String(m?.userid || '');
|
if (typeof m === 'string') {
|
||||||
|
const id = String(m || '');
|
||||||
|
if (id) acc[id] = id;
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
const uid = String(m?.userid || m?.userId || m?.corpUserId || m?._id || m?.id || '');
|
||||||
if (!uid) return acc;
|
if (!uid) return acc;
|
||||||
acc[uid] = String(m?.anotherName || m?.name || m?.userid || '') || uid;
|
acc[uid] = String(m?.anotherName || m?.name || m?.userid || m?.userId || '') || uid;
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
userNameMap.value = { ...(userNameMap.value || {}), ...map };
|
userNameMap.value = { ...(userNameMap.value || {}), ...map };
|
||||||
|
|
||||||
|
// 补缺:仅当当前没有映射时才用 avatars 接口补齐,避免覆盖正确姓名
|
||||||
|
try {
|
||||||
|
const res = await api('getTeamMemberAvatarsAndName', { corpId, teamId: tid });
|
||||||
|
if (res?.success && res?.data && typeof res.data === 'object') {
|
||||||
|
const raw = res.data;
|
||||||
|
const patch = Object.keys(raw).reduce((acc, uid) => {
|
||||||
|
const id = String(uid || '');
|
||||||
|
if (!id) return acc;
|
||||||
|
const existing = userNameMap.value?.[id];
|
||||||
|
if (existing && existing !== id) return acc;
|
||||||
|
const name = String(raw?.[uid]?.name || raw?.[uid]?.anotherName || '').trim();
|
||||||
|
if (!name || name === id) return acc;
|
||||||
|
acc[id] = name;
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
if (Object.keys(patch).length) userNameMap.value = { ...(userNameMap.value || {}), ...patch };
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let corpMemberBatchInflight = null; // Promise | 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 moreStatus = computed(() => {
|
const moreStatus = computed(() => {
|
||||||
@ -375,6 +507,10 @@ async function getMore() {
|
|||||||
// 尽量加载记录所属团队成员,用于执行人展示
|
// 尽量加载记录所属团队成员,用于执行人展示
|
||||||
const teamIds = mapped.map((i) => i.executeTeamId).filter(Boolean);
|
const teamIds = mapped.map((i) => i.executeTeamId).filter(Boolean);
|
||||||
Array.from(new Set(teamIds)).forEach((tid) => loadTeamMembers(tid));
|
Array.from(new Set(teamIds)).forEach((tid) => loadTeamMembers(tid));
|
||||||
|
|
||||||
|
// 补齐非团队成员执行人姓名(例如其他团队创建/操作)
|
||||||
|
const executorIds = mapped.map((i) => i.executorUserId).filter(Boolean);
|
||||||
|
void batchLoadCorpMembers(executorIds);
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
@ -669,6 +805,7 @@ watch(
|
|||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
-webkit-line-clamp: 3;
|
-webkit-line-clamp: 3;
|
||||||
|
line-clamp: 3;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.pen {
|
.pen {
|
||||||
|
|||||||
@ -163,6 +163,10 @@ const groupNameMap = computed(() => {
|
|||||||
|
|
||||||
// Team Members Map
|
// Team Members Map
|
||||||
const userNameMap = ref({});
|
const userNameMap = ref({});
|
||||||
|
const loadedMembersTeamId = ref('');
|
||||||
|
const corpMemberNameInflight = new Map(); // userId -> Promise
|
||||||
|
const corpMemberNameTried = new Set(); // avoid retry storms on failures
|
||||||
|
let corpMemberBatchInflight = null; // Promise | null
|
||||||
|
|
||||||
// 新增流程所需状态(认证相关)
|
// 新增流程所需状态(认证相关)
|
||||||
const managedArchiveCountAllTeams = ref(0); // 在管档案数(所有团队)
|
const managedArchiveCountAllTeams = ref(0); // 在管档案数(所有团队)
|
||||||
@ -196,6 +200,272 @@ function asArray(value) {
|
|||||||
return Array.isArray(value) ? value : [];
|
return Array.isArray(value) ? value : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeUserId(value) {
|
||||||
|
if (value === null || value === undefined) return '';
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
const obj = value;
|
||||||
|
const picked =
|
||||||
|
obj.userid ||
|
||||||
|
obj.userId ||
|
||||||
|
obj.userID ||
|
||||||
|
obj.corpUserId ||
|
||||||
|
obj.corpUserID ||
|
||||||
|
obj._id ||
|
||||||
|
obj.id ||
|
||||||
|
'';
|
||||||
|
return String(picked || '').trim();
|
||||||
|
}
|
||||||
|
return String(value || '').trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveUserName(userId) {
|
||||||
|
const id = normalizeUserId(userId);
|
||||||
|
if (!id) return '';
|
||||||
|
// 优先使用当前登录人的信息(避免映射未命中时只显示 userid)
|
||||||
|
const d = doctorInfo.value || {};
|
||||||
|
const doctorId = normalizeUserId(d.userid || d.userId || d.corpUserId || '');
|
||||||
|
if (doctorId && doctorId === id) {
|
||||||
|
const display = String(d.anotherName || d.name || d.username || d.userid || '').trim();
|
||||||
|
if (display) return display;
|
||||||
|
}
|
||||||
|
const mapped = userNameMap.value[id] || userNameMap.value[id.toLowerCase()];
|
||||||
|
if (mapped) return mapped;
|
||||||
|
// 不阻塞渲染:后台补齐非团队成员姓名(例如其他团队成员创建)
|
||||||
|
if (isLikelyUserId(id)) void fetchCorpMemberDisplayName(id).catch(() => {});
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLikelyUserId(value) {
|
||||||
|
const id = normalizeUserId(value);
|
||||||
|
if (!id) return false;
|
||||||
|
if (/[\u4e00-\u9fa5]/.test(id)) return false; // already looks like a name
|
||||||
|
if (/\s/.test(id)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractDisplayNameFromAny(payload) {
|
||||||
|
if (!payload) return '';
|
||||||
|
if (typeof payload === 'string') return payload.trim();
|
||||||
|
if (Array.isArray(payload)) return extractDisplayNameFromAny(payload[0]);
|
||||||
|
if (typeof payload !== 'object') return '';
|
||||||
|
const obj = payload;
|
||||||
|
const candidate =
|
||||||
|
obj.anotherName ||
|
||||||
|
obj.name ||
|
||||||
|
obj.realName ||
|
||||||
|
obj.username ||
|
||||||
|
obj.nickName ||
|
||||||
|
obj.nickname ||
|
||||||
|
obj.displayName ||
|
||||||
|
obj.userName ||
|
||||||
|
obj.userid ||
|
||||||
|
obj.userId ||
|
||||||
|
obj.corpUserId ||
|
||||||
|
'';
|
||||||
|
return String(candidate || '').trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractDisplayNameFromCorpMember(row) {
|
||||||
|
const m = row && typeof row === 'object' ? row : {};
|
||||||
|
const name = String(m.anotherName || m.name || '').trim();
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function batchFetchCorpMemberDisplayNames(userIds) {
|
||||||
|
const ids = Array.isArray(userIds) ? userIds.map(normalizeUserId).filter(Boolean) : [];
|
||||||
|
if (!ids.length) return;
|
||||||
|
const uniq = Array.from(new Set(ids));
|
||||||
|
|
||||||
|
const unresolved = uniq.filter((id) => {
|
||||||
|
if (!isLikelyUserId(id)) return false;
|
||||||
|
const cached = userNameMap.value?.[id] || userNameMap.value?.[id.toLowerCase()];
|
||||||
|
return !cached || cached === id;
|
||||||
|
});
|
||||||
|
if (!unresolved.length) return;
|
||||||
|
|
||||||
|
if (corpMemberBatchInflight) return corpMemberBatchInflight;
|
||||||
|
|
||||||
|
const corpId = getCorpId() || String(account.value?.corpId || doctorInfo.value?.corpId || '');
|
||||||
|
if (!corpId) return;
|
||||||
|
|
||||||
|
corpMemberBatchInflight = (async () => {
|
||||||
|
try {
|
||||||
|
const res = await api(
|
||||||
|
'getCorpMember',
|
||||||
|
{
|
||||||
|
page: 1,
|
||||||
|
pageSize: Math.min(Math.max(unresolved.length, 10), 500),
|
||||||
|
params: {
|
||||||
|
corpId,
|
||||||
|
memberList: unresolved,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
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 next = { ...(userNameMap.value || {}) };
|
||||||
|
rows.forEach((m) => {
|
||||||
|
const id = normalizeUserId(m?.userid || m?.userId || m?.corpUserId || '');
|
||||||
|
if (!id) return;
|
||||||
|
const display = extractDisplayNameFromCorpMember(m) || id;
|
||||||
|
const existing = next[id] || next[id.toLowerCase()];
|
||||||
|
// 仅补缺:不覆盖已有的非空/非同值映射
|
||||||
|
if (existing && existing !== id) return;
|
||||||
|
if (display && display !== id) {
|
||||||
|
next[id] = display;
|
||||||
|
next[id.toLowerCase()] = display;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
userNameMap.value = next;
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
})().finally(() => {
|
||||||
|
corpMemberBatchInflight = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return corpMemberBatchInflight;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchCorpMemberDisplayName(userId) {
|
||||||
|
const id = normalizeUserId(userId);
|
||||||
|
if (!id) return '';
|
||||||
|
if (!isLikelyUserId(id)) return '';
|
||||||
|
|
||||||
|
const cached = userNameMap.value[id] || userNameMap.value[id.toLowerCase()];
|
||||||
|
if (cached && cached !== id) return cached;
|
||||||
|
|
||||||
|
if (corpMemberNameInflight.has(id)) return corpMemberNameInflight.get(id);
|
||||||
|
if (corpMemberNameTried.has(id)) return '';
|
||||||
|
|
||||||
|
const corpId = getCorpId() || String(account.value?.corpId || doctorInfo.value?.corpId || '');
|
||||||
|
if (!corpId) return '';
|
||||||
|
|
||||||
|
const p = (async () => {
|
||||||
|
corpMemberNameTried.add(id);
|
||||||
|
|
||||||
|
// 1) 首选:企业成员主页信息(更可能支持用 userid 查询)
|
||||||
|
try {
|
||||||
|
const res = await api('getCorpMemberHomepageInfo', { corpId, corpUserId: id }, false);
|
||||||
|
if (res?.success) {
|
||||||
|
const name =
|
||||||
|
extractDisplayNameFromAny(res?.data) ||
|
||||||
|
extractDisplayNameFromAny(res?.data?.data) ||
|
||||||
|
extractDisplayNameFromAny(res?.data?.member) ||
|
||||||
|
'';
|
||||||
|
if (name) return name;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1.1) 有的后端参数名为 userId
|
||||||
|
try {
|
||||||
|
const res = await api('getCorpMemberHomepageInfo', { corpId, userId: id }, false);
|
||||||
|
if (res?.success) {
|
||||||
|
const name =
|
||||||
|
extractDisplayNameFromAny(res?.data) ||
|
||||||
|
extractDisplayNameFromAny(res?.data?.data) ||
|
||||||
|
extractDisplayNameFromAny(res?.data?.member) ||
|
||||||
|
'';
|
||||||
|
if (name) return name;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) 兜底:成员数据接口(部分环境可能支持 corpUserId)
|
||||||
|
try {
|
||||||
|
const res = await api('getCorpMemberData', { corpId, corpUserId: id }, false);
|
||||||
|
if (res?.success) {
|
||||||
|
const name =
|
||||||
|
extractDisplayNameFromAny(res?.data) ||
|
||||||
|
extractDisplayNameFromAny(res?.data?.data) ||
|
||||||
|
'';
|
||||||
|
if (name) return name;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.1) 同样尝试 userId
|
||||||
|
try {
|
||||||
|
const res = await api('getCorpMemberData', { corpId, userId: id }, false);
|
||||||
|
if (res?.success) {
|
||||||
|
const name =
|
||||||
|
extractDisplayNameFromAny(res?.data) ||
|
||||||
|
extractDisplayNameFromAny(res?.data?.data) ||
|
||||||
|
'';
|
||||||
|
if (name) return name;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
})()
|
||||||
|
.then((name) => {
|
||||||
|
const display = String(name || '').trim();
|
||||||
|
if (display) {
|
||||||
|
const next = { ...(userNameMap.value || {}) };
|
||||||
|
next[id] = display;
|
||||||
|
next[id.toLowerCase()] = display;
|
||||||
|
userNameMap.value = next;
|
||||||
|
}
|
||||||
|
return display;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
corpMemberNameInflight.delete(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
corpMemberNameInflight.set(id, p);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function prefetchUserNamesFromPatients(patients) {
|
||||||
|
const list = Array.isArray(patients) ? patients : [];
|
||||||
|
if (!list.length) return;
|
||||||
|
|
||||||
|
const ids = new Set();
|
||||||
|
list.forEach((p) => {
|
||||||
|
const u1 = normalizeUserId(p?.recentAddOperatorUserId);
|
||||||
|
const u2 = normalizeUserId(p?.creator);
|
||||||
|
if (u1) ids.add(u1);
|
||||||
|
if (u2) ids.add(u2);
|
||||||
|
});
|
||||||
|
|
||||||
|
const targets = Array.from(ids).filter((id) => {
|
||||||
|
if (!isLikelyUserId(id)) return false;
|
||||||
|
const cached = userNameMap.value[id] || userNameMap.value[id.toLowerCase()];
|
||||||
|
return !cached || cached === id;
|
||||||
|
});
|
||||||
|
if (!targets.length) return;
|
||||||
|
|
||||||
|
// 优先批量补齐(现成后端接口 getCorpMember 支持 memberList)
|
||||||
|
await batchFetchCorpMemberDisplayNames(targets);
|
||||||
|
|
||||||
|
const limit = 6;
|
||||||
|
let idx = 0;
|
||||||
|
const workers = Array.from({ length: Math.min(limit, targets.length) }, async () => {
|
||||||
|
while (idx < targets.length) {
|
||||||
|
const cur = targets[idx++];
|
||||||
|
try {
|
||||||
|
const cached = userNameMap.value?.[cur] || userNameMap.value?.[cur.toLowerCase()];
|
||||||
|
if (cached && cached !== cur) continue;
|
||||||
|
await fetchCorpMemberDisplayName(cur);
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.allSettled(workers);
|
||||||
|
}
|
||||||
|
|
||||||
function normalizeTeam(raw) {
|
function normalizeTeam(raw) {
|
||||||
if (!raw || typeof raw !== 'object') return null;
|
if (!raw || typeof raw !== 'object') return null;
|
||||||
const teamId = raw.teamId || raw.id || raw._id || '';
|
const teamId = raw.teamId || raw.id || raw._id || '';
|
||||||
@ -235,23 +505,76 @@ function ensureUserInfoForFeature() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function ensureDoctorForQuery() {
|
||||||
|
if (account.value?.openid) {
|
||||||
|
try {
|
||||||
|
const a = account.value || {};
|
||||||
|
const accountId = normalizeUserId(a.userid || a.userId || a.corpUserId || '');
|
||||||
|
const d = doctorInfo.value || {};
|
||||||
|
const doctorId = normalizeUserId(d.userid || d.userId || d.corpUserId || '');
|
||||||
|
// doctorInfo 可能是旧缓存:当与当前账号不一致时强制刷新
|
||||||
|
if (!doctorId || (accountId && doctorId && accountId !== doctorId)) {
|
||||||
|
await getDoctorInfo();
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Boolean(getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
async function loadTeamMembers() {
|
async function loadTeamMembers() {
|
||||||
const corpId = getCorpId();
|
const corpId = getCorpId();
|
||||||
const teamId = getTeamId();
|
const teamId = getTeamId();
|
||||||
if (!corpId || !teamId) return;
|
if (!corpId || !teamId) return;
|
||||||
|
if (loadedMembersTeamId.value === teamId && Object.keys(userNameMap.value || {}).length > 0) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const nextMap = { ...(userNameMap.value || {}) };
|
||||||
|
|
||||||
|
// 以团队详情为准(getTeamMemberAvatarsAndName 存在不全/不准的情况)
|
||||||
const res = await api('getTeamData', { corpId, teamId });
|
const res = await api('getTeamData', { corpId, teamId });
|
||||||
if (!res?.success) return;
|
if (res?.success) {
|
||||||
const t = res?.data && typeof res.data === 'object' ? res.data : {};
|
const t = res?.data && typeof res.data === 'object' ? res.data : {};
|
||||||
const members = Array.isArray(t.memberList) ? t.memberList : [];
|
const members = Array.isArray(t.memberList) ? t.memberList : [];
|
||||||
// Update map
|
members.forEach((m) => {
|
||||||
members.forEach(m => {
|
if (typeof m === 'string') {
|
||||||
const uid = String(m?.userid || '');
|
const k = normalizeUserId(m);
|
||||||
if (uid) {
|
if (k) {
|
||||||
userNameMap.value[uid] = String(m?.anotherName || m?.name || m?.userid || '') || uid;
|
nextMap[k] = nextMap[k] || k;
|
||||||
}
|
nextMap[k.toLowerCase()] = nextMap[k.toLowerCase()] || nextMap[k] || k;
|
||||||
});
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const display = String(m?.anotherName || m?.name || m?.userid || m?.userId || m?.corpUserId || '').trim();
|
||||||
|
const keys = [m?.userid, m?.userId, m?.corpUserId].map(normalizeUserId).filter(Boolean);
|
||||||
|
keys.forEach((k) => {
|
||||||
|
nextMap[k] = display || nextMap[k] || k;
|
||||||
|
nextMap[String(k).toLowerCase()] = display || nextMap[String(k).toLowerCase()] || k;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 补缺:仅当当前没有映射时才用 avatars 接口补齐,避免覆盖正确姓名
|
||||||
|
try {
|
||||||
|
const avatarRes = await api('getTeamMemberAvatarsAndName', { corpId, teamId });
|
||||||
|
const mapObj = avatarRes?.success && avatarRes?.data && typeof avatarRes.data === 'object' ? avatarRes.data : {};
|
||||||
|
Object.entries(mapObj).forEach(([uid, info]) => {
|
||||||
|
const k = normalizeUserId(uid);
|
||||||
|
if (!k) return;
|
||||||
|
const existing = nextMap[k] || nextMap[k.toLowerCase()];
|
||||||
|
if (existing && existing !== k) return;
|
||||||
|
const display = String(info?.name || info?.anotherName || info?.userid || '').trim();
|
||||||
|
if (!display || display === k) return;
|
||||||
|
nextMap[k] = display;
|
||||||
|
nextMap[k.toLowerCase()] = display;
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
userNameMap.value = nextMap;
|
||||||
|
loadedMembersTeamId.value = teamId;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('获取团队成员失败', e);
|
console.error('获取团队成员失败', e);
|
||||||
}
|
}
|
||||||
@ -260,7 +583,7 @@ async function loadTeamMembers() {
|
|||||||
function resolveCreatorName(patient) {
|
function resolveCreatorName(patient) {
|
||||||
const val = patient.creator;
|
const val = patient.creator;
|
||||||
if (!val) return '';
|
if (!val) return '';
|
||||||
return userNameMap.value[val] || val;
|
return resolveUserName(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveRecentAddTime(patient) {
|
function resolveRecentAddTime(patient) {
|
||||||
@ -268,9 +591,12 @@ function resolveRecentAddTime(patient) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function resolveRecentAddOperatorName(patient) {
|
function resolveRecentAddOperatorName(patient) {
|
||||||
const uid = patient?.recentAddOperatorUserId || patient?.creator || '';
|
const nameFromApi = String(patient?.recentAddOperatorName || '').trim();
|
||||||
|
// 后端部分场景会把 userid 填到 name 字段里,此时仍需通过 userid 解析姓名
|
||||||
|
if (nameFromApi && !isLikelyUserId(nameFromApi)) return nameFromApi;
|
||||||
|
const uid = patient?.recentAddOperatorUserId || nameFromApi || patient?.creator || '';
|
||||||
if (!uid) return '';
|
if (!uid) return '';
|
||||||
return userNameMap.value[uid] || uid;
|
return resolveUserName(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveRecentAddAction(patient) {
|
function resolveRecentAddAction(patient) {
|
||||||
@ -396,6 +722,123 @@ function parseCreateTime(value) {
|
|||||||
return d2.isValid() ? d2 : null;
|
return d2.isValid() ? d2 : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeMedicalType(raw) {
|
||||||
|
const s = String(raw || '').trim();
|
||||||
|
if (!s) return '';
|
||||||
|
const lower = s.toLowerCase();
|
||||||
|
// 中文兜底(部分接口返回展示名)
|
||||||
|
if (s.includes('门诊')) return 'outpatient';
|
||||||
|
if (s.includes('住院') || s.includes('入院')) return 'inhospital';
|
||||||
|
if (s.includes('预问诊') || s.includes('问诊')) return 'preConsultation';
|
||||||
|
if (s.includes('体检')) return 'physicalExaminationTemplate';
|
||||||
|
if (lower.includes('preconsult') || (lower.includes('pre') && lower.includes('consult'))) return 'preConsultation';
|
||||||
|
if (lower === 'outpatient' || lower === 'out_patient' || lower === 'out-patient') return 'outpatient';
|
||||||
|
if (lower === 'inhospital' || lower === 'in_hospital' || lower === 'in-hospital' || lower === 'inpatient') return 'inhospital';
|
||||||
|
if (lower === 'physicalexaminationtemplate' || lower === 'physicalexamination' || lower === 'physical_examination') return 'physicalExaminationTemplate';
|
||||||
|
if (s === 'outPatient') return 'outpatient';
|
||||||
|
if (s === 'inHospital') return 'inhospital';
|
||||||
|
if (s === 'preConsultation') return 'preConsultation';
|
||||||
|
if (s === 'physicalExaminationTemplate') return 'physicalExaminationTemplate';
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeText(v) {
|
||||||
|
if (Array.isArray(v)) {
|
||||||
|
const parts = v
|
||||||
|
.map((i) => normalizeText(i))
|
||||||
|
.filter((i) => i !== null && i !== undefined && String(i).trim());
|
||||||
|
return parts.join(',');
|
||||||
|
}
|
||||||
|
if (v === 0) return '0';
|
||||||
|
if (v && typeof v === 'object') {
|
||||||
|
const o = v;
|
||||||
|
const candidate = o.label ?? o.name ?? o.text ?? o.title ?? o.value ?? o.diseaseName ?? o.code ?? '';
|
||||||
|
return candidate ? String(candidate) : '';
|
||||||
|
}
|
||||||
|
return v ? String(v) : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatAnyDate(value, fmt = 'YYYY-MM-DD') {
|
||||||
|
const d = parseCreateTime(value);
|
||||||
|
return d ? d.format(fmt) : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveLatestRecord(lr) {
|
||||||
|
if (!lr || typeof lr !== 'object') return null;
|
||||||
|
|
||||||
|
const formData = lr?.formData && typeof lr.formData === 'object' ? lr.formData : null;
|
||||||
|
const recordData = lr?.recordData && typeof lr.recordData === 'object' ? lr.recordData : null;
|
||||||
|
const data = lr?.data && typeof lr.data === 'object' ? lr.data : null;
|
||||||
|
|
||||||
|
const hasValue = (v) => {
|
||||||
|
if (v === 0) return true;
|
||||||
|
if (Array.isArray(v)) return v.length > 0;
|
||||||
|
if (v && typeof v === 'object') return Object.keys(v).length > 0;
|
||||||
|
return v !== null && v !== undefined && String(v).trim() !== '';
|
||||||
|
};
|
||||||
|
|
||||||
|
const pick = (...keys) => {
|
||||||
|
for (const k of keys) {
|
||||||
|
const v0 = lr?.[k];
|
||||||
|
if (hasValue(v0)) return v0;
|
||||||
|
const v1 = formData?.[k];
|
||||||
|
if (hasValue(v1)) return v1;
|
||||||
|
const v2 = recordData?.[k];
|
||||||
|
if (hasValue(v2)) return v2;
|
||||||
|
const v3 = data?.[k];
|
||||||
|
if (hasValue(v3)) return v3;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const rawType = String(pick('medicalType', 'templateType') || '').trim();
|
||||||
|
const uiType = normalizeMedicalType(rawType || pick('type'));
|
||||||
|
const typeLabel = String(pick('tempName', 'templateName', 'name', 'type') || '').trim();
|
||||||
|
|
||||||
|
const rawDate = pick('date', 'visitTime', 'inhosDate', 'consultDate', 'inspectDate', 'sortTime');
|
||||||
|
const rawDateStr = String(rawDate ?? '').trim();
|
||||||
|
const date = (/^\d{10,13}$/.test(rawDateStr) ? (formatAnyDate(rawDateStr, 'YYYY-MM-DD') || rawDateStr) : rawDateStr)
|
||||||
|
|| formatAnyDate(pick('visitTime', 'inhosDate', 'consultDate', 'inspectDate', 'sortTime'), 'YYYY-MM-DD')
|
||||||
|
|| '-';
|
||||||
|
|
||||||
|
let third = '';
|
||||||
|
if (uiType === 'outpatient' || uiType === 'inhospital') {
|
||||||
|
third = normalizeText(pick(
|
||||||
|
'diagnosisName',
|
||||||
|
'diagnosis',
|
||||||
|
'diagnosisList',
|
||||||
|
'diagnosisNames',
|
||||||
|
'mainDiagnosis',
|
||||||
|
'admissionDiagnosis',
|
||||||
|
'inDiagnosis',
|
||||||
|
'outDiagnosis',
|
||||||
|
'outPatientDiagnosis',
|
||||||
|
'inHospitalDiagnosis'
|
||||||
|
));
|
||||||
|
} else if (uiType === 'preConsultation') {
|
||||||
|
third = normalizeText(pick('chiefComplaint', 'complaint', 'mainComplaint', 'mainSuit', 'chief'));
|
||||||
|
} else if (uiType === 'physicalExaminationTemplate') {
|
||||||
|
third = normalizeText(pick('summary', 'inspectSummary', 'conclusion', 'inspectConclusion', 'inspectResult', 'finalConclusion'));
|
||||||
|
} else {
|
||||||
|
third = normalizeText(pick('diagnosis', 'diagnosisName', 'summary', 'chiefComplaint'));
|
||||||
|
}
|
||||||
|
third = String(third || '').replace(/\s+/g, ' ').trim();
|
||||||
|
if (!third) {
|
||||||
|
// 最后的兜底:避免经常展示为 '-'
|
||||||
|
third = normalizeText(pick('summary', 'inspectSummary', 'chiefComplaint', 'presentIllness', 'treatmentPlan', 'abstract', 'brief'));
|
||||||
|
third = String(third || '').replace(/\s+/g, ' ').trim();
|
||||||
|
}
|
||||||
|
if (!String(third || '').trim()) third = '-';
|
||||||
|
|
||||||
|
const type = typeLabel || (uiType === 'outpatient' ? '门诊记录'
|
||||||
|
: uiType === 'inhospital' ? '住院记录'
|
||||||
|
: uiType === 'preConsultation' ? '预问诊记录'
|
||||||
|
: uiType === 'physicalExaminationTemplate' ? '体检档案'
|
||||||
|
: '-');
|
||||||
|
|
||||||
|
return { type, date, diagnosis: third };
|
||||||
|
}
|
||||||
|
|
||||||
function formatPatient(raw) {
|
function formatPatient(raw) {
|
||||||
const name = raw?.name || raw?.customerName || '';
|
const name = raw?.name || raw?.customerName || '';
|
||||||
const sex = raw?.sex || raw?.gender || '';
|
const sex = raw?.sex || raw?.gender || '';
|
||||||
@ -427,20 +870,16 @@ function formatPatient(raw) {
|
|||||||
|
|
||||||
// 解析病历信息
|
// 解析病历信息
|
||||||
let record = null;
|
let record = null;
|
||||||
if (raw?.latestRecord && typeof raw.latestRecord === 'object') {
|
const latestRaw =
|
||||||
const lr = raw.latestRecord;
|
raw?.latestRecord ??
|
||||||
const type = lr.type || '';
|
raw?.latestMedicalRecord ??
|
||||||
const date = lr.date || '';
|
raw?.latestMedicalCase ??
|
||||||
const diagnosis = lr.diagnosis || '';
|
raw?.lastRecord ??
|
||||||
// 只有存在有效信息时才设置 record
|
raw?.lastMedicalRecord ??
|
||||||
if (type || date || diagnosis) {
|
raw?.recentRecord ??
|
||||||
record = {
|
null;
|
||||||
type: type || '-',
|
const latest = Array.isArray(latestRaw) ? latestRaw[0] : latestRaw;
|
||||||
date: date || '-',
|
if (latest && typeof latest === 'object') record = resolveLatestRecord(latest);
|
||||||
diagnosis: diagnosis || '-'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...raw,
|
...raw,
|
||||||
@ -457,6 +896,14 @@ function formatPatient(raw) {
|
|||||||
recentAddTimeTs,
|
recentAddTimeTs,
|
||||||
recentAddType,
|
recentAddType,
|
||||||
recentAddOperatorUserId,
|
recentAddOperatorUserId,
|
||||||
|
recentAddOperatorName: String(
|
||||||
|
raw?.recentAddOperatorName
|
||||||
|
|| raw?.recentAddOperatorAnotherName
|
||||||
|
|| raw?.recentAddOperatorUserName
|
||||||
|
|| raw?.recentAddOperatorRealName
|
||||||
|
|| raw?.recentAddOperatorDisplayName
|
||||||
|
|| ''
|
||||||
|
).trim(),
|
||||||
creator: raw?.creatorName || raw?.creator || '',
|
creator: raw?.creatorName || raw?.creator || '',
|
||||||
hospitalId: raw?.customerNumber || raw?.hospitalId || '',
|
hospitalId: raw?.customerNumber || raw?.hospitalId || '',
|
||||||
record,
|
record,
|
||||||
@ -518,6 +965,7 @@ async function reload(reset = true) {
|
|||||||
if (!currentTeam.value) return;
|
if (!currentTeam.value) return;
|
||||||
if (loading.value) return;
|
if (loading.value) return;
|
||||||
|
|
||||||
|
await ensureDoctorForQuery();
|
||||||
const userId = getUserId();
|
const userId = getUserId();
|
||||||
const corpId = getCorpId();
|
const corpId = getCorpId();
|
||||||
const teamId = getTeamId();
|
const teamId = getTeamId();
|
||||||
@ -571,6 +1019,8 @@ async function reload(reset = true) {
|
|||||||
const list = Array.isArray(payload.list) ? payload.list : Array.isArray(payload.data) ? payload.data : [];
|
const list = Array.isArray(payload.list) ? payload.list : Array.isArray(payload.data) ? payload.data : [];
|
||||||
const next = list.map(formatPatient);
|
const next = list.map(formatPatient);
|
||||||
rawPatients.value = page.value === 1 ? next : [...rawPatients.value, ...next];
|
rawPatients.value = page.value === 1 ? next : [...rawPatients.value, ...next];
|
||||||
|
// 补齐创建人/新增人姓名(部分创建人不在当前团队成员列表中)
|
||||||
|
void prefetchUserNamesFromPatients(next).catch(() => {});
|
||||||
pages.value = Number(payload.pages || 0) || 0;
|
pages.value = Number(payload.pages || 0) || 0;
|
||||||
totalFromApi.value = Number(payload.total || 0) || rawPatients.value.length;
|
totalFromApi.value = Number(payload.total || 0) || rawPatients.value.length;
|
||||||
managedArchiveCountAllTeams.value =
|
managedArchiveCountAllTeams.value =
|
||||||
@ -665,13 +1115,13 @@ const toggleTeamPopup = () => {
|
|||||||
}
|
}
|
||||||
uni.showActionSheet({
|
uni.showActionSheet({
|
||||||
itemList: teams.value.map((i) => i.name),
|
itemList: teams.value.map((i) => i.name),
|
||||||
success: function (res) {
|
success: async (res) => {
|
||||||
currentTeam.value = teams.value[res.tapIndex] || teams.value[0] || null;
|
currentTeam.value = teams.value[res.tapIndex] || teams.value[0] || null;
|
||||||
if (currentTeam.value) uni.setStorageSync(CURRENT_TEAM_STORAGE_KEY, currentTeam.value);
|
if (currentTeam.value) uni.setStorageSync(CURRENT_TEAM_STORAGE_KEY, currentTeam.value);
|
||||||
currentTabKey.value = 'all';
|
currentTabKey.value = 'all';
|
||||||
loadGroups();
|
await loadGroups();
|
||||||
loadTeamMembers();
|
await loadTeamMembers();
|
||||||
reload(true);
|
await reload(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -1016,6 +1466,7 @@ watch(currentTeam, (t) => {
|
|||||||
|
|
||||||
watch(currentTabKey, () => {
|
watch(currentTabKey, () => {
|
||||||
if (!currentTeam.value) return;
|
if (!currentTeam.value) return;
|
||||||
|
loadTeamMembers();
|
||||||
reload(true);
|
reload(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1032,7 +1483,7 @@ onLoad(async () => {
|
|||||||
await loadTeams();
|
await loadTeams();
|
||||||
if (currentTeam.value) {
|
if (currentTeam.value) {
|
||||||
await loadGroups();
|
await loadGroups();
|
||||||
loadTeamMembers();
|
await loadTeamMembers();
|
||||||
await reload(true);
|
await reload(true);
|
||||||
}
|
}
|
||||||
await refreshVerifyStatus();
|
await refreshVerifyStatus();
|
||||||
@ -1056,7 +1507,7 @@ onShow(async () => {
|
|||||||
} else {
|
} else {
|
||||||
await loadGroups();
|
await loadGroups();
|
||||||
}
|
}
|
||||||
loadTeamMembers();
|
await loadTeamMembers();
|
||||||
await refreshVerifyStatus();
|
await refreshVerifyStatus();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,8 @@ import request from "./http";
|
|||||||
const urlsConfig = {
|
const urlsConfig = {
|
||||||
corp: {
|
corp: {
|
||||||
getCorpMemberHomepageInfo: 'getCorpMemberHomepageInfo',
|
getCorpMemberHomepageInfo: 'getCorpMemberHomepageInfo',
|
||||||
|
getCorpMember: 'getCorpMember',
|
||||||
|
getCorpMemberOptions: 'getCorpMemberOptions',
|
||||||
// 企业信息/标签
|
// 企业信息/标签
|
||||||
getCorpInfo: 'getCorpInfo',
|
getCorpInfo: 'getCorpInfo',
|
||||||
getCorpTags: 'getCorpTags',
|
getCorpTags: 'getCorpTags',
|
||||||
|
|||||||
@ -6,6 +6,38 @@ import { globalTimChatManager } from './tim-chat.js';
|
|||||||
import api from './api.js';
|
import api from './api.js';
|
||||||
import { toast } from './widget.js';
|
import { toast } from './widget.js';
|
||||||
const env = __VITE_ENV__;
|
const env = __VITE_ENV__;
|
||||||
|
|
||||||
|
function nowTs() {
|
||||||
|
return Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function tryAddServiceRecord(payload) {
|
||||||
|
try {
|
||||||
|
const res = await api('addServiceRecord', payload);
|
||||||
|
if (!res?.success) {
|
||||||
|
console.warn('写入服务记录失败:', res?.message || res);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('写入服务记录异常:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function canWriteServiceRecord(options = {}) {
|
||||||
|
return Boolean(options?.corpId && options?.userId && options?.customerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeServiceRecordBase(options = {}) {
|
||||||
|
return {
|
||||||
|
corpId: options.corpId,
|
||||||
|
executorUserId: String(options.userId || ''),
|
||||||
|
creatorUserId: String(options.userId || ''),
|
||||||
|
customerId: String(options.customerId || ''),
|
||||||
|
customerName: String(options.customerName || ''),
|
||||||
|
executeTeamId: String(options.teamId || options.executeTeamId || ''),
|
||||||
|
executionTime: nowTs(),
|
||||||
|
externalUserId: String(options.externalUserId || options.customerUserId || ''),
|
||||||
|
};
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 发送文字消息
|
* 发送文字消息
|
||||||
* @param {string} content - 文字内容
|
* @param {string} content - 文字内容
|
||||||
@ -168,6 +200,24 @@ export async function sendArticleMessage(article, options = {}) {
|
|||||||
console.error('记录文章发送失败:', err);
|
console.error('记录文章发送失败:', err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 写入服务记录留痕(异步,不阻塞)
|
||||||
|
if (canWriteServiceRecord(options)) {
|
||||||
|
const base = normalizeServiceRecordBase(options);
|
||||||
|
tryAddServiceRecord({
|
||||||
|
...base,
|
||||||
|
eventType: 'ContentReminder',
|
||||||
|
taskContent: `推送文章:${article.title || '宣教文章'}`,
|
||||||
|
pannedEventSendFile: {
|
||||||
|
type: 'article',
|
||||||
|
articleId: article._id || options.articleId || '',
|
||||||
|
title: article.title || '',
|
||||||
|
url: article.url || '',
|
||||||
|
},
|
||||||
|
pannedEventName: '宣教发送',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
toast(result?.error || '发送文章消息失败');
|
toast(result?.error || '发送文章消息失败');
|
||||||
@ -243,6 +293,22 @@ export async function sendSurveyMessage(survey, options = {}) {
|
|||||||
const result = await globalTimChatManager.sendCustomMessage(customMessageData);
|
const result = await globalTimChatManager.sendCustomMessage(customMessageData);
|
||||||
|
|
||||||
if (result?.success) {
|
if (result?.success) {
|
||||||
|
// 写入服务记录留痕(异步,不阻塞)
|
||||||
|
if (canWriteServiceRecord(options)) {
|
||||||
|
const base = normalizeServiceRecordBase(options);
|
||||||
|
tryAddServiceRecord({
|
||||||
|
...base,
|
||||||
|
eventType: 'questionnaire',
|
||||||
|
taskContent: `推送问卷:${survey.name || '问卷'}`,
|
||||||
|
pannedEventSendFile: {
|
||||||
|
type: 'questionnaire',
|
||||||
|
surveryId: survey._id || survey.surveryId || '',
|
||||||
|
name: survey.name || '',
|
||||||
|
url: surveyLink || '',
|
||||||
|
},
|
||||||
|
pannedEventName: '问卷调查',
|
||||||
|
});
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
toast(result?.error || '发送问卷消息失败');
|
toast(result?.error || '发送问卷消息失败');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user