205 lines
4.5 KiB
JavaScript
205 lines
4.5 KiB
JavaScript
/**
|
||
* 头像工具函数
|
||
* 参考 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
|
||
} |