/** 统一头像 URL:无有效头像时始终返回 ossImageUrl + morentouxiang(后端配置) */ function isBlankPath(p) { if (p == null) return true; if (typeof p !== 'string') return true; const s = p.trim(); return !s || s === 'null' || s === 'undefined' || s === 'none'; } function readConfigFallback(app) { if (!app || typeof app.readConfigFromStorage !== 'function') return null; try { return app.readConfigFromStorage(); } catch (e) { return null; } } function getOssBase(app) { let oss = app.globalData?.ossImageUrl || ''; if (!oss) { const cfg = readConfigFallback(app); oss = cfg?.cos?.ossImageUrl || ''; } return oss; } function getDefaultRelative(app) { let def = app.globalData?.morentouxiang || ''; if (!def) { const cfg = readConfigFallback(app); def = cfg?.otherConfig?.morentouxiang || ''; } return def || 'avatar/default.jpg'; } export function getDefaultAvatarUrl(app) { return resolveAvatarUrl('', app); } export function resolveAvatarUrl(rawPath, app) { app = app || getApp(); const oss = getOssBase(app); const def = getDefaultRelative(app); if (!isBlankPath(rawPath)) { if (rawPath.startsWith('http://') || rawPath.startsWith('https://')) { return rawPath; } const path = rawPath.startsWith('/') ? rawPath : `/${rawPath}`; if (oss) return oss + path; return path; } if (def.startsWith('http://') || def.startsWith('https://')) { return def; } const defPath = def.startsWith('/') ? def : `/${def}`; if (oss) return oss + defPath; // 配置未就绪时仍返回相对路径,由 binderror 回退;有 oss 时必须拼完整 URL return defPath; } /** 是否已是可加载的完整头像 URL */ export function isUsableAvatarUrl(url) { return url && (url.startsWith('http://') || url.startsWith('https://')); } export function ensureAvatarUrl(rawPath, app) { app = app || getApp(); const resolved = resolveAvatarUrl(rawPath, app); if (isUsableAvatarUrl(resolved)) return resolved; const def = getDefaultAvatarUrl(app); return isUsableAvatarUrl(def) ? def : resolved; } export function resolveAvatarFromStorage(app) { app = app || getApp(); const tx = wx.getStorageSync('touxiang') || ''; return resolveAvatarUrl(tx, app); } /** 配置加载后刷新页面头像(聊天页等订阅 configApplied) */ export function subscribeConfigAvatarRefresh(page, refreshFn) { const app = getApp(); if (!app || typeof refreshFn !== 'function') return null; const handler = () => refreshFn(); if (app.on) app.on('configApplied', handler); return () => { if (app.off) app.off('configApplied', handler); }; } /** 消息列表/聊天页 image 加载失败时回退默认头像 */ export function onAvatarImageError(page, dataKey, app) { if (!page || !dataKey) return; const def = getDefaultAvatarUrl(app || getApp()); page.setData({ [dataKey]: def }); }