mirror of
https://github.com/nsnail/NetAdmin.git
synced 2025-06-17 01:13:22 +08:00
feat: ✨ 默认头像根据用户名绘制svg (#132)
This commit is contained in:
parent
d1951dbcb5
commit
127f6e9f6c
@ -2,7 +2,7 @@
|
|||||||
<el-table-column :label="label" :prop="prop" sortable="custom">
|
<el-table-column :label="label" :prop="prop" sortable="custom">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div class="avatar">
|
<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>
|
<span>{{ tool.getNestedProperty(scope.row, prop) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -36,8 +36,8 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
//获取头像
|
//获取头像
|
||||||
getAvatar(scope) {
|
getAvatar(scope, prop) {
|
||||||
return scope.row.avatar ? scope.row.avatar : this.$CONFIG.DEFAULT_AVATAR
|
return scope.row.avatar ? scope.row.avatar : this.$CONFIG.DEFAULT_AVATAR(tool.getNestedProperty(scope.row, prop))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
<el-table-column v-bind="$attrs">
|
<el-table-column v-bind="$attrs">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div @click="click(tool.getNestedProperty(scope.row, $attrs.prop))" class="avatar">
|
<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>
|
<div>
|
||||||
<p>{{ tool.getNestedProperty(scope.row, $attrs.nestProp) }}</p>
|
<p>{{ tool.getNestedProperty(scope.row, $attrs.nestProp) }}</p>
|
||||||
<p v-if="$attrs.nestProp2">{{ tool.getNestedProperty(scope.row, $attrs.nestProp2) }}</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 })
|
await this.$refs.saveDialog.open('view', { id: id })
|
||||||
},
|
},
|
||||||
//获取头像
|
//获取头像
|
||||||
getAvatar(scope) {
|
getAvatar(scope, prop) {
|
||||||
return scope.row.avatar ? scope.row.avatar : this.$CONFIG.DEFAULT_AVATAR
|
return scope.row.avatar ? scope.row.avatar : this.$CONFIG.DEFAULT_AVATAR(tool.getNestedProperty(scope.row, prop))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import MY_CONFIG from './myConfig'
|
import MY_CONFIG from './myConfig'
|
||||||
import APP_CONFIG from './appConfig'
|
import APP_CONFIG from './appConfig'
|
||||||
|
import avatar from '@/utils/avatar'
|
||||||
|
import tool from '@/utils/tool'
|
||||||
|
|
||||||
const DEFAULT_CONFIG = {
|
const DEFAULT_CONFIG = {
|
||||||
//标题
|
//标题
|
||||||
@ -74,8 +76,14 @@ const DEFAULT_CONFIG = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
//默认头像
|
//默认头像
|
||||||
DEFAULT_AVATAR:
|
DEFAULT_AVATAR(name) {
|
||||||
'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=',
|
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,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
//合并业务配置
|
//合并业务配置
|
||||||
|
@ -39,7 +39,20 @@
|
|||||||
</div>
|
</div>
|
||||||
<el-dropdown @command="handleUser" class="user panel-item" trigger="click">
|
<el-dropdown @command="handleUser" class="user panel-item" trigger="click">
|
||||||
<div class="user-avatar">
|
<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>
|
<label>{{ user.userName }}</label>
|
||||||
<el-icon class="el-icon--right">
|
<el-icon class="el-icon--right">
|
||||||
<el-icon-arrow-down />
|
<el-icon-arrow-down />
|
||||||
@ -68,7 +81,14 @@
|
|||||||
import search from './search.vue'
|
import search from './search.vue'
|
||||||
import tasks from './tasks.vue'
|
import tasks from './tasks.vue'
|
||||||
import message from '@/views/profile/message/components/list.vue'
|
import message from '@/views/profile/message/components/list.vue'
|
||||||
|
import avatar from '../../utils/avatar'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
computed: {
|
||||||
|
avatar() {
|
||||||
|
return avatar
|
||||||
|
},
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
search,
|
search,
|
||||||
tasks,
|
tasks,
|
||||||
|
42
src/frontend/admin/src/utils/avatar.js
Normal file
42
src/frontend/admin/src/utils/avatar.js
Normal 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
|
||||||
|
},
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
<el-container>
|
<el-container>
|
||||||
<el-header>
|
<el-header>
|
||||||
<div class="user-info-top">
|
<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>
|
<h2>{{ user.userName }}</h2>
|
||||||
<p>
|
<p>
|
||||||
<el-tag v-for="(item, i) in user.roles" :key="i" effect="dark" round size="large">{{ item.name }}</el-tag>
|
<el-tag v-for="(item, i) in user.roles" :key="i" effect="dark" round size="large">{{ item.name }}</el-tag>
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
<template>
|
<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>
|
<template v-else>
|
||||||
<el-container v-if="msgList.length > 0" class="nopadding">
|
<el-container v-if="msgList.length > 0" class="nopadding">
|
||||||
<el-header style="border: none">
|
<el-header style="border: none">
|
||||||
@ -30,9 +32,12 @@
|
|||||||
<div class="msg-title">
|
<div class="msg-title">
|
||||||
<div>
|
<div>
|
||||||
<el-badge v-if="msg.myFlags.userSiteMsgStatus === 0" is-dot type="primary">
|
<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-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>
|
||||||
<div>
|
<div>
|
||||||
<h2>{{ msg.title }}</h2>
|
<h2>{{ msg.title }}</h2>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user