8.2 用户资料编辑

This commit is contained in:
zhangsan 2025-08-02 17:47:45 +08:00
parent 2c8fc752ca
commit da05f9ecab
15 changed files with 400 additions and 154 deletions

View File

@ -5,6 +5,9 @@ services:
smile-picture-front:
image: nginx:alpine
container_name: smile-picture-front
depends_on:
smile-picture-backend:
condition: service_started # 明确等待后端启动
restart: unless-stopped
ports:
- "18096:80"

View File

@ -15,12 +15,15 @@ create table if not exists user
user_profile varchar(512) null comment '用户简介',
user_role varchar(256) default 'user' not null comment '用户角色user/admin',
user_email varchar(256) not null COMMENT '用户邮箱',
user_phone VARCHAR(50) NULL DEFAULT NULL COMMENT '用户手机号',
edit_time datetime default CURRENT_TIMESTAMP not null comment '编辑时间',
create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
is_delete tinyint default 0 not null comment '是否删除',
UNIQUE KEY uk_userAccount (user_account),
INDEX idx_userName (user_name)
INDEX idx_userName (user_name),
UNIQUE INDEX uk_user_email (user_email ASC) USING BTREE,
UNIQUE INDEX uk_user_phone (user_phone ASC) USING BTREE,
) comment '用户' collate = utf8mb4_unicode_ci;
-- 图片表

View File

@ -1 +1 @@
import{_ as o,c as s,a as t,o as a}from"./index-D10z2Ner.js";const n={},c={class:"about"};function r(_,e){return a(),s("div",c,e[0]||(e[0]=[t("h1",null,"This is an about page",-1)]))}const l=o(n,[["render",r]]);export{l as default};
import{_ as o,c as s,a as t,o as a}from"./index-CrUyCRGJ.js";const n={},c={class:"about"};function r(_,e){return a(),s("div",c,e[0]||(e[0]=[t("h1",null,"This is an about page",-1)]))}const l=o(n,[["render",r]]);export{l as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6,8 +6,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Smile云图库</title>
<meta name="description" content="Smile云图库海量图片素材免费获取">
<script type="module" crossorigin src="/assets/index-D10z2Ner.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DlRSOPH_.css">
<script type="module" crossorigin src="/assets/index-Wpj-tH9k.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-D39s5k2B.css">
</head>
<body>
<div id="app"></div>

View File

@ -1,6 +1,7 @@
package edu.whut.smilepicturebackend.controller;
import cn.hutool.core.lang.RegexPool;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -20,6 +21,7 @@ import edu.whut.smilepicturebackend.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@ -52,6 +54,25 @@ public class UserController {
return ResultUtils.success();
}
/**
* 用户修改密码
*
* @return 是否成功
*/
@PostMapping("/password")
public BaseResponse<Boolean> editUserPassword(@RequestBody UserEditPasswordRequest userEditPasswordRequest,HttpServletRequest request) {
ThrowUtils.throwIf(userEditPasswordRequest == null, ErrorCode.PARAMS_ERROR);
if (StrUtil.hasBlank(userEditPasswordRequest.getOriginPassword(), userEditPasswordRequest.getNewPassword(),
userEditPasswordRequest.getConfirmPassword())) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码不能为空");
}
if (!userEditPasswordRequest.getNewPassword().equals(userEditPasswordRequest.getConfirmPassword())) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次新密码不一致");
}
userService.editUserPassword(userEditPasswordRequest,request);
return ResultUtils.success();
}
/**
* 发送邮箱验证码
*
@ -138,6 +159,8 @@ public class UserController {
return ResultUtils.success(user);
}
/**
* 根据 id 获取包装类(脱敏)
*/
@ -161,6 +184,27 @@ public class UserController {
return ResultUtils.success(b);
}
/**
* 编辑用户
*
* @return 是否成功
*/
@PostMapping("/edit")
public BaseResponse<Boolean> editUser(@RequestBody UserEditRequest userEditRequest,HttpServletRequest request) {
ThrowUtils.throwIf(userEditRequest == null, ErrorCode.PARAMS_ERROR);
ThrowUtils.throwIf(ObjectUtil.isEmpty(userEditRequest.getId()), ErrorCode.PARAMS_ERROR);
String userPhone = userEditRequest.getUserPhone();
if (StrUtil.isNotEmpty(userPhone) && userPhone.length() > 11) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号过长");
}
String userProfile = userEditRequest.getUserProfile();
if (StrUtil.isNotEmpty(userProfile) && userProfile.length() > 500) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户简介过长");
}
userService.editUser(userEditRequest,request);
return ResultUtils.success();
}
/**
* 更新用户
*/
@ -177,6 +221,18 @@ public class UserController {
return ResultUtils.success(true);
}
/**
* 上传头像
*
* @param avatarFile 头像文件
* @return 头像地址
*/
@PostMapping("/uploadAvatar")
public BaseResponse<String> uploadAvatar(@RequestParam("file") MultipartFile avatarFile) {
ThrowUtils.throwIf(avatarFile == null, ErrorCode.PARAMS_ERROR);
return ResultUtils.success(userService.uploadAvatar(avatarFile));
}
/**
* 分页获取用户封装列表仅管理员
*

View File

@ -0,0 +1,27 @@
package edu.whut.smilepicturebackend.model.dto.user;
import lombok.Data;
import java.io.Serializable;
/**
* 用户编辑请求
*/
@Data
public class UserEditPasswordRequest implements Serializable {
/**
* 原密码
*/
private String originPassword;
/**
* 新密码
*/
private String newPassword;
/**
* 确认密码
*/
private String confirmPassword;
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,55 @@
package edu.whut.smilepicturebackend.model.dto.user;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 用户编辑请求
*/
@Data
public class UserEditRequest implements Serializable {
/**
* 用户ID
*/
private Long Id;
/**
* 账号
*/
private String userAccount;
/**
* 用户手机号
*/
private String userPhone;
/**
* 用户昵称
*/
private String userName;
/**
* 用户头像
*/
private String userAvatar;
/**
* 用户简介
*/
private String userProfile;
/**
* 出生日期
*/
private Date birthday;
/**
* 分享码
*/
private String shareCode;
private static final long serialVersionUID = 1L;
}

View File

@ -39,6 +39,11 @@ public class User implements Serializable {
*/
private String userName;
/**
* 用户手机号
*/
private String userPhone;
/**
* 用户头像
*/

View File

@ -21,6 +21,16 @@ public class UserVO implements Serializable {
*/
private String userAccount;
/**
* 用户邮箱
*/
private String userEmail;
/**
* 用户手机号
*/
private String userPhone;
/**
* 用户昵称
*/

View File

@ -4,10 +4,13 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import edu.whut.smilepicturebackend.model.dto.user.UserAddRequest;
import edu.whut.smilepicturebackend.model.dto.user.UserEditPasswordRequest;
import edu.whut.smilepicturebackend.model.dto.user.UserEditRequest;
import edu.whut.smilepicturebackend.model.dto.user.UserQueryRequest;
import edu.whut.smilepicturebackend.model.entity.User;
import edu.whut.smilepicturebackend.model.vo.LoginUserVO;
import edu.whut.smilepicturebackend.model.vo.UserVO;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@ -110,4 +113,15 @@ public interface UserService extends IService<User> {
*/
String sendEmailCode(String userEmail);
void editUserPassword(UserEditPasswordRequest userEditPasswordRequest,HttpServletRequest request);
void editUser(UserEditRequest userEditRequest,HttpServletRequest request);
/**
* 上传头像
*
* @param avatarFile 头像文件
* @return 头像地址
*/
String uploadAvatar(MultipartFile avatarFile);
}

View File

@ -1,4 +1,5 @@
package edu.whut.smilepicturebackend.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.RegexPool;
@ -17,9 +18,13 @@ import edu.whut.smilepicturebackend.exception.ErrorCode;
import edu.whut.smilepicturebackend.exception.ThrowUtils;
import edu.whut.smilepicturebackend.manager.auth.StpKit;
import edu.whut.smilepicturebackend.manager.email.EmailManager;
import edu.whut.smilepicturebackend.manager.upload.FilePictureUpload;
import edu.whut.smilepicturebackend.model.dto.user.UserEditPasswordRequest;
import edu.whut.smilepicturebackend.model.dto.user.UserEditRequest;
import edu.whut.smilepicturebackend.model.dto.user.UserQueryRequest;
import edu.whut.smilepicturebackend.model.entity.User;
import edu.whut.smilepicturebackend.model.enums.UserRoleEnum;
import edu.whut.smilepicturebackend.model.file.UploadPictureResult;
import edu.whut.smilepicturebackend.model.vo.LoginUserVO;
import edu.whut.smilepicturebackend.model.vo.UserVO;
import edu.whut.smilepicturebackend.service.UserService;
@ -29,6 +34,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
@ -53,6 +59,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
private final StringRedisTemplate stringRedisTemplate;
private final FilePictureUpload uploadPictureFile;
/**
* 用户注册
@ -255,6 +262,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
return user != null && UserRoleEnum.ADMIN.getValue().equals(user.getUserRole());
}
@Override
public String sendEmailCode(String userEmail) {
boolean existed = existedUserByEmail(userEmail);
@ -271,6 +279,70 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
return key;
}
/**
* 用户修改密码
*/
@Override
public void editUserPassword(UserEditPasswordRequest userEditPasswordRequest,HttpServletRequest request) {
User loginUser = this.getLoginUser(request);
if (!passwordEncoder.matches(loginUser.getUserPassword(), userEditPasswordRequest.getOriginPassword())) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "原密码错误");
}
User user=new User();
user.setId(loginUser.getId());
user.setUserPassword(getEncryptPassword(userEditPasswordRequest.getNewPassword()));
boolean result = this.updateById(user);
if (result) {
// 移除登录态
request.getSession().removeAttribute(UserConstant.USER_LOGIN_STATE);
return;
}
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "密码修改失败!");
}
@Override
public void editUser(UserEditRequest userEditRequest,HttpServletRequest request) {
boolean existed= this.getBaseMapper()
.exists(new QueryWrapper<User>()
.eq("id", userEditRequest.getId())
);
if (!existed) {
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "用户不存在!");
}
User user=new User();
BeanUtil.copyProperties(userEditRequest,user);
boolean result = this.updateById(user);
if (result) {
// 移除登录态
request.getSession().removeAttribute(UserConstant.USER_LOGIN_STATE);
return;
}
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "编辑失败!");
}
@Override
public String uploadAvatar(MultipartFile avatarFile) {
long userId = StpUtil.getLoginIdAsLong();
String pathPrefix = "avatar/" + userId + "/";
// 调用上传图片
UploadPictureResult uploadPictureResult = uploadPictureFile.uploadPicture(avatarFile, pathPrefix);
String avatarUrl = uploadPictureResult.getUrl();
if (StrUtil.isEmpty(avatarUrl)) {
throw new BusinessException(ErrorCode.OPERATION_ERROR, "头像上传失败");
}
User user=new User();
user.setId(userId);
user.setUserAvatar(avatarUrl);
boolean result = this.updateById(user);
if (!result) {
throw new BusinessException(ErrorCode.OPERATION_ERROR, "头像更新失败");
}
// 移除登录态
// request.getSession().removeAttribute(UserConstant.USER_LOGIN_STATE);
return avatarUrl;
}
public boolean existedUserByEmail(String userEmail) {
return this.getBaseMapper()

View File

@ -8,6 +8,7 @@
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="userAccount" column="user_account" jdbcType="VARCHAR"/>
<result property="userPassword" column="user_password" jdbcType="VARCHAR"/>
<result property="userPhone" column="user_phone" jdbcType="VARCHAR"/>
<result property="userName" column="user_name" jdbcType="VARCHAR"/>
<result property="userEmail" column="user_email" jdbcType="VARCHAR"/>
<result property="userAvatar" column="user_avatar" jdbcType="VARCHAR"/>
@ -20,7 +21,7 @@
</resultMap>
<sql id="Base_Column_List">
id,user_account,user_password,
id,user_account,user_password,user_phone,
user_name,user_emial,user_avatar,user_profile,
user_role,edit_time,create_time,
update_time,is_delete