98 lines
2.9 KiB
JavaScript
98 lines
2.9 KiB
JavaScript
/** 统一头像 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 });
|
||
}
|