feat: 默认头像根据用户名绘制svg (#132)

This commit is contained in:
nsnail 2024-05-31 16:48:11 +08:00 committed by GitHub
parent d1951dbcb5
commit 127f6e9f6c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 91 additions and 13 deletions

View File

@ -2,7 +2,7 @@
<el-table-column :label="label" :prop="prop" sortable="custom">
<template #default="scope">
<div class="avatar">
<el-avatar :src="getAvatar(scope)" size="small"></el-avatar>
<el-avatar :src="getAvatar(scope, prop)" size="small"></el-avatar>
<span>{{ tool.getNestedProperty(scope.row, prop) }}</span>
</div>
</template>
@ -36,8 +36,8 @@ export default {
},
methods: {
//
getAvatar(scope) {
return scope.row.avatar ? scope.row.avatar : this.$CONFIG.DEFAULT_AVATAR
getAvatar(scope, prop) {
return scope.row.avatar ? scope.row.avatar : this.$CONFIG.DEFAULT_AVATAR(tool.getNestedProperty(scope.row, prop))
},
},
}

View File

@ -2,7 +2,10 @@
<el-table-column v-bind="$attrs">
<template #default="scope">
<div @click="click(tool.getNestedProperty(scope.row, $attrs.prop))" class="avatar">
<el-avatar v-if="tool.getNestedProperty(scope.row, $attrs.nestProp)" :src="getAvatar(scope)" size="small"></el-avatar>
<el-avatar
v-if="tool.getNestedProperty(scope.row, $attrs.nestProp)"
:src="getAvatar(scope, $attrs.nestProp)"
size="small"></el-avatar>
<div>
<p>{{ tool.getNestedProperty(scope.row, $attrs.nestProp) }}</p>
<p v-if="$attrs.nestProp2">{{ tool.getNestedProperty(scope.row, $attrs.nestProp2) }}</p>
@ -54,8 +57,8 @@ export default {
await this.$refs.saveDialog.open('view', { id: id })
},
//
getAvatar(scope) {
return scope.row.avatar ? scope.row.avatar : this.$CONFIG.DEFAULT_AVATAR
getAvatar(scope, prop) {
return scope.row.avatar ? scope.row.avatar : this.$CONFIG.DEFAULT_AVATAR(tool.getNestedProperty(scope.row, prop))
},
},
}

View File

@ -1,5 +1,7 @@
import MY_CONFIG from './myConfig'
import APP_CONFIG from './appConfig'
import avatar from '@/utils/avatar'
import tool from '@/utils/tool'
const DEFAULT_CONFIG = {
//标题
@ -74,8 +76,14 @@ const DEFAULT_CONFIG = {
},
//默认头像
DEFAULT_AVATAR:
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAflJREFUeNqs1u1P2kAYAHB6B+21UmZbatEAki2+MKIR42TGaHRLjBr/Yj/7wWRb3If5gjHbfIlBjIqCUCq0PmaJLqG9IwdP+qV3vV+v1/Z5Ttg/Ke39tm+q7VD/wlBx/j0J7xzWbccL9TVgosCivrv/Atgw8yI9JuZGVXNQjCkROL2tOpc39q8/D7bj0gcy6NSQvDoTR4LwdidVhOPDyMD29/Jd9YkyFlH6pAhanjb+d19DFvHSlOHX0x09kYpGcOAFMPf0kMxJJ02ZvlyWRjhpWcJ0moiIk240Gf9Rw2lz0o92i04/Nnhpl/Hhhtqux0mnLcZrzCQUTrrV9lh/M++CFM9rtOXyvL+lOif98+T++r4Z1Ht0Vju9anDSEKXbQBqSFH0sgz6+qMGDd7Y/1J96pav1FuTPzvZvxYrrej3REOWK09l4XWkyB7Jp30RBRNwH2jf/MZMimzZi/kk5l1HFMOKnFYK/zMaDqsxqPo6QwENDtd2YtwakwOI5rJO1OZOS0/3p8VR0s2CpMqMoJzSytWAldKmrig7cQk4fMUiX+w14rPVPVvGi9qNYcVpuIP1xVM2PvaOU2sACnYwmTbJ7cHdefssqSJFeXkUYCysz8flJjcN9nf7XvFnIahi/gMCiwphMROFzVstYSu/7sWxaXczpAAL7LMAA6FWV/DBrhrIAAAAASUVORK5CYII=',
DEFAULT_AVATAR(name) {
return (
'data:image/svg+xml,' +
encodeURIComponent(
avatar.createSVG(`#${Math.abs(tool.crypto.hashCode(name)).toString(16).substring(0, 6)}`, name.slice(0, 1).toUpperCase()).outerHTML,
)
)
},
}
//合并业务配置

View File

@ -39,7 +39,20 @@
</div>
<el-dropdown @command="handleUser" class="user panel-item" trigger="click">
<div class="user-avatar">
<el-avatar :size="30" :src="user.avatar ? user.avatar : $CONFIG.DEFAULT_AVATAR"></el-avatar>
<el-avatar
:size="30"
:src="
user.avatar
? user.avatar
: 'data:image/svg+xml,' +
encodeURIComponent(
avatar.createSVG(
`#${Math.abs(this.$TOOL.crypto.hashCode(user.userName)).toString(16).substring(0, 6)}`,
user.userName.slice(0, 1).toUpperCase(),
).outerHTML,
)
"></el-avatar>
<label>{{ user.userName }}</label>
<el-icon class="el-icon--right">
<el-icon-arrow-down />
@ -68,7 +81,14 @@
import search from './search.vue'
import tasks from './tasks.vue'
import message from '@/views/profile/message/components/list.vue'
import avatar from '../../utils/avatar'
export default {
computed: {
avatar() {
return avatar
},
},
components: {
search,
tasks,

View File

@ -0,0 +1,42 @@
export default {
//生成svg矩形
createSVG(color, name) {
const svg = document.createElement('svg')
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg')
svg.setAttribute('width', 50)
svg.setAttribute('height', 50)
// <rect> background
const rect = document.createElement('rect')
rect.setAttribute('fill', color)
rect.setAttribute('x', 0)
rect.setAttribute('y', 0)
rect.setAttribute('width', '100%')
rect.setAttribute('height', '100%')
svg.appendChild(rect)
// <text> name
const text = document.createElement('text')
text.setAttribute('fill', '#fff')
text.setAttribute('x', '50%')
text.setAttribute('y', '50%')
text.setAttribute('text-anchor', 'middle')
text.setAttribute('font-size', '16')
text.setAttribute('font-weight', '900')
text.setAttribute('font-family', 'monospace')
// IE/Edge don't support alignment-baseline
// @see https://msdn.microsoft.com/en-us/library/gg558060(v=vs.85).aspx
if (document.documentMode || /Edge/.test(navigator.userAgent)) {
text.setAttribute('dy', '0.35em')
} else {
text.setAttribute('alignment-baseline', 'middle')
}
text.textContent = name
svg.appendChild(text)
return svg
},
}

View File

@ -4,7 +4,7 @@
<el-container>
<el-header>
<div class="user-info-top">
<el-avatar :size="70" :src="user.avatar ? user.avatar : $CONFIG.DEFAULT_AVATAR"></el-avatar>
<el-avatar :size="70" :src="user.avatar ? user.avatar : $CONFIG.DEFAULT_AVATAR(user.userName)"></el-avatar>
<h2>{{ user.userName }}</h2>
<p>
<el-tag v-for="(item, i) in user.roles" :key="i" effect="dark" round size="large">{{ item.name }}</el-tag>

View File

@ -1,5 +1,7 @@
<template>
<el-skeleton v-if="loading" :rows="5" animated />
<div v-if="loading" style="padding: 1rem">
<el-skeleton :rows="5" animated />
</div>
<template v-else>
<el-container v-if="msgList.length > 0" class="nopadding">
<el-header style="border: none">
@ -30,9 +32,12 @@
<div class="msg-title">
<div>
<el-badge v-if="msg.myFlags.userSiteMsgStatus === 0" is-dot type="primary">
<el-avatar :size="40" :src="msg.sender.avatar ?? $CONFIG.DEFAULT_AVATAR"></el-avatar>
<el-avatar :size="40" :src="msg.sender.avatar ?? $CONFIG.DEFAULT_AVATAR(msg.sender.userName)"></el-avatar>
</el-badge>
<el-avatar v-else :size="40" :src="msg.sender.avatar ?? $CONFIG.DEFAULT_AVATAR"></el-avatar>
<el-avatar
v-else
:size="40"
:src="msg.sender.avatar ?? $CONFIG.DEFAULT_AVATAR(msg.sender.userName)"></el-avatar>
</div>
<div>
<h2>{{ msg.title }}</h2>