Files
zgty-mas-m/sheep/utils/avatar.js
2025-09-30 00:08:23 +08:00

205 lines
4.5 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 头像工具函数
* 参考 zt-vue-element 实现,提供默认头像逻辑
*/
/**
* 获取用户头像显示信息
* @param {Object} userInfo - 用户信息
* @param {string} userInfo.avatar - 头像URL
* @param {string} userInfo.nickname - 用户昵称
* @param {string} userInfo.username - 用户名
* @param {string} userInfo.name - 姓名
* @returns {Object} 头像显示信息
*/
export function getAvatarInfo(userInfo = {}) {
const { avatar, nickname, username, name } = userInfo
return {
// 头像URL有则使用
src: avatar || '',
// 初始字符,用于无头像时显示
initial: getInitialChar(nickname || username || name || ''),
// 显示名称
displayName: nickname || username || name || '用户',
// 是否有头像
hasAvatar: !!avatar
}
}
/**
* 生成初始字符
* @param {string} name - 名称
* @returns {string} 首字母或首字
*/
export function getInitialChar(name) {
if (!name || typeof name !== 'string') {
return '用'
}
const trimmedName = name.trim()
if (!trimmedName) {
return '用'
}
const firstChar = trimmedName.charAt(0)
// 如果是中文字符,直接返回
if (/[\u4e00-\u9fa5]/.test(firstChar)) {
return firstChar
}
// 如果是英文字符,转大写
if (/[a-zA-Z]/.test(firstChar)) {
return firstChar.toUpperCase()
}
// 如果是数字或其他字符,返回默认
return '用'
}
/**
* 生成头像背景色
* 根据用户名生成一致的背景色
* @param {string} name - 用户名
* @returns {string} 十六进制颜色值
*/
export function getAvatarBgColor(name) {
// 预设颜色数组,都是比较柔和的颜色
const colors = [
'#0055A2', // 主题蓝
'#337AB7', // 浅蓝
'#5cb85c', // 绿色
'#f0ad4e', // 橙色
'#d9534f', // 红色
'#5bc0de', // 青色
'#9b59b6', // 紫色
'#34495e', // 深灰蓝
'#1abc9c', // 青绿
'#e67e22' // 深橙
]
if (!name) {
return colors[0] // 默认使用主题色
}
// 根据名称生成一致的索引
let hash = 0
for (let i = 0; i < name.length; i++) {
hash = name.charCodeAt(i) + ((hash << 5) - hash)
hash = hash & hash // 转换为32位整数
}
const index = Math.abs(hash) % colors.length
return colors[index]
}
/**
* 头像尺寸预设
*/
export const AVATAR_SIZES = {
xs: 32,
sm: 48,
md: 64,
lg: 80,
xl: 120,
xxl: 160
}
/**
* 获取标准化的头像尺寸
* @param {string|number} size - 尺寸
* @returns {number} 标准化后的尺寸
*/
export function normalizeAvatarSize(size) {
// 如果是预设尺寸名称
if (typeof size === 'string' && AVATAR_SIZES[size]) {
return AVATAR_SIZES[size]
}
// 如果是数字
if (typeof size === 'number') {
return size
}
// 如果是字符串数字
if (typeof size === 'string') {
const num = parseInt(size, 10)
if (!isNaN(num)) {
return num
}
}
// 默认返回中等尺寸
return AVATAR_SIZES.md
}
/**
* 验证头像URL是否有效
* @param {string} url - 头像URL
* @returns {Promise<boolean>} 是否有效
*/
export function validateAvatarUrl(url) {
return new Promise((resolve) => {
if (!url || typeof url !== 'string') {
resolve(false)
return
}
// 在uni-app中使用网络状态检查
uni.getImageInfo({
src: url,
success: () => {
resolve(true)
},
fail: () => {
resolve(false)
}
})
})
}
/**
* 头像默认配置
*/
export const DEFAULT_AVATAR_CONFIG = {
size: AVATAR_SIZES.md,
bgColor: '#0055A2',
textColor: '#ffffff',
shape: 'circle', // circle | square
editable: false,
readonly: false
}
/**
* 创建头像组件的props
* @param {Object} userInfo - 用户信息
* @param {Object} options - 选项
* @returns {Object} 组件props
*/
export function createAvatarProps(userInfo = {}, options = {}) {
const avatarInfo = getAvatarInfo(userInfo)
const config = { ...DEFAULT_AVATAR_CONFIG, ...options }
return {
src: avatarInfo.src,
nickname: avatarInfo.displayName,
initial: avatarInfo.initial,
size: normalizeAvatarSize(config.size),
bgColor: config.bgColor || getAvatarBgColor(avatarInfo.displayName),
textColor: config.textColor,
editable: config.editable,
readonly: config.readonly
}
}
export default {
getAvatarInfo,
getInitialChar,
getAvatarBgColor,
normalizeAvatarSize,
validateAvatarUrl,
createAvatarProps,
AVATAR_SIZES,
DEFAULT_AVATAR_CONFIG
}