Skip to content

Commit 7b9be78

Browse files
committed
新增功能 - 用户头像信息展示
1 parent 0a83304 commit 7b9be78

File tree

7 files changed

+110
-8
lines changed

7 files changed

+110
-8
lines changed

coder-test-frontend/src/components/GlobalNavbar.vue

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,18 @@
2525
</div>
2626

2727
<el-dropdown>
28-
<span class="user-name">
29-
{{ user?.nickname || user?.username }}
30-
<el-icon class="el-icon--right"><ArrowDown /></el-icon>
28+
<span class="user-info">
29+
<el-avatar
30+
:src="user?.avatar"
31+
:size="32"
32+
class="user-avatar"
33+
>
34+
<el-icon><User /></el-icon>
35+
</el-avatar>
36+
<span class="user-name">
37+
{{ user?.nickname || user?.username }}
38+
<el-icon class="el-icon--right"><ArrowDown /></el-icon>
39+
</span>
3140
</span>
3241
<template #dropdown>
3342
<el-dropdown-menu>
@@ -62,7 +71,8 @@ import {
6271
KnifeFork,
6372
Clock,
6473
SwitchButton,
65-
Coin
74+
Coin,
75+
User
6676
} from '@element-plus/icons-vue'
6777
6878
// Props
@@ -176,24 +186,35 @@ const handleLogout = async () => {
176186
color: var(--accent-gold);
177187
}
178188
179-
.user-name {
189+
.user-info {
180190
cursor: pointer;
181191
display: flex;
182192
align-items: center;
183-
color: var(--bg-card);
184-
font-weight: 500;
193+
gap: 12px;
185194
padding: 8px 16px;
186195
border-radius: 25px;
187196
background: rgba(255, 255, 255, 0.1);
188197
backdrop-filter: blur(10px);
189198
transition: all 0.3s ease;
190199
}
191200
192-
.user-name:hover {
201+
.user-info:hover {
193202
background: rgba(255, 255, 255, 0.2);
194203
transform: translateY(-1px);
195204
}
196205
206+
.user-avatar {
207+
border: 2px solid var(--accent-gold);
208+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
209+
}
210+
211+
.user-name {
212+
display: flex;
213+
align-items: center;
214+
color: var(--bg-card);
215+
font-weight: 500;
216+
}
217+
197218
/* 响应式设计 */
198219
@media (max-width: 768px) {
199220
.navbar-content {

database/add_avatar_column.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- 给用户表添加头像字段的迁移脚本
2+
-- 执行时间:2025-09-16
3+
4+
USE `coder-test`;
5+
6+
-- 添加头像字段
7+
ALTER TABLE `user` ADD COLUMN `avatar` VARCHAR(512) DEFAULT NULL COMMENT '用户头像URL' AFTER `nickname`;
8+
9+
-- 验证字段是否添加成功
10+
DESC `user`;

database/create_tables.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ CREATE TABLE `user`
1515
`username` VARCHAR(50) NOT NULL COMMENT '用户名',
1616
`password` VARCHAR(255) NOT NULL COMMENT '密码(加密存储)',
1717
`nickname` VARCHAR(50) DEFAULT NULL COMMENT '用户昵称',
18+
`avatar` VARCHAR(512) DEFAULT NULL COMMENT '用户头像URL',
1819
`salary` INT DEFAULT 10000 COMMENT '当前薪资(单位:元/月)',
1920
`createTime` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
2021
`updateTime` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

src/main/java/com/yupi/codertestbackend/model/entity/User.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ public class User implements Serializable {
3434
*/
3535
private String nickname;
3636

37+
/**
38+
* 用户头像URL
39+
*/
40+
private String avatar;
41+
3742
/**
3843
* 当前薪资(单位:元/月)
3944
*/

src/main/java/com/yupi/codertestbackend/model/vo/UserVO.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ public class UserVO implements Serializable {
2626
*/
2727
private String nickname;
2828

29+
/**
30+
* 用户头像URL
31+
*/
32+
private String avatar;
33+
2934
/**
3035
* 当前薪资(单位:元/月)
3136
*/

src/main/java/com/yupi/codertestbackend/service/impl/UserServiceImpl.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.yupi.codertestbackend.model.entity.User;
1212
import com.yupi.codertestbackend.model.vo.UserVO;
1313
import com.yupi.codertestbackend.service.UserService;
14+
import com.yupi.codertestbackend.utils.AvatarUtils;
1415
import jakarta.servlet.http.HttpServletRequest;
1516
import lombok.extern.slf4j.Slf4j;
1617
import org.springframework.beans.BeanUtils;
@@ -76,6 +77,11 @@ public String userRegister(UserRegisterRequest userRegisterRequest) {
7677
if (!saveResult) {
7778
throw new RuntimeException("注册失败,数据库错误");
7879
}
80+
81+
// 注册成功后设置默认头像(基于用户ID生成固定头像)
82+
user.setAvatar(AvatarUtils.getDefaultAvatarByUserId(user.getId()));
83+
this.updateById(user);
84+
7985
return user.getId();
8086
}
8187

@@ -140,6 +146,12 @@ public UserVO getLoginUserVO(User user) {
140146
}
141147
UserVO userVO = new UserVO();
142148
BeanUtils.copyProperties(user, userVO);
149+
150+
// 如果用户没有头像,设置默认头像
151+
if (StrUtil.isBlank(userVO.getAvatar())) {
152+
userVO.setAvatar(AvatarUtils.getDefaultAvatarByUserId(user.getId()));
153+
}
154+
143155
return userVO;
144156
}
145157

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.yupi.codertestbackend.utils;
2+
3+
import java.util.Random;
4+
5+
/**
6+
* 头像工具类
7+
*/
8+
public class AvatarUtils {
9+
10+
/**
11+
* 默认头像列表(4个)
12+
*/
13+
private static final String[] DEFAULT_AVATARS = {
14+
"https://img.icons8.com/color/96/000000/user-male-circle--v1.png",
15+
"https://img.icons8.com/color/96/000000/user-female-circle--v1.png",
16+
"https://img.icons8.com/color/96/000000/administrator-male--v1.png",
17+
"https://img.icons8.com/color/96/000000/businesswoman--v1.png"
18+
};
19+
20+
private static final Random random = new Random();
21+
22+
/**
23+
* 获取随机默认头像
24+
*
25+
* @return 默认头像URL
26+
*/
27+
public static String getRandomDefaultAvatar() {
28+
int index = random.nextInt(DEFAULT_AVATARS.length);
29+
return DEFAULT_AVATARS[index];
30+
}
31+
32+
/**
33+
* 根据用户ID生成固定的默认头像(确保同一用户总是获得相同的默认头像)
34+
*
35+
* @param userId 用户ID
36+
* @return 默认头像URL
37+
*/
38+
public static String getDefaultAvatarByUserId(String userId) {
39+
if (userId == null || userId.isEmpty()) {
40+
return getRandomDefaultAvatar();
41+
}
42+
43+
// 使用用户ID的哈希值来确保相同用户ID总是得到相同的头像
44+
int hash = Math.abs(userId.hashCode());
45+
int index = hash % DEFAULT_AVATARS.length;
46+
return DEFAULT_AVATARS[index];
47+
}
48+
}

0 commit comments

Comments
 (0)