diff --git a/pom.xml b/pom.xml
index 8b12ac7..6ab3ae9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,6 +41,11 @@
knife4j-openapi2-spring-boot-starter
4.4.0
+
+
+ org.springframework.security
+ spring-security-crypto
+
com.mysql
mysql-connector-j
diff --git a/sql/create_table.sql b/sql/create_table.sql
new file mode 100644
index 0000000..3718b59
--- /dev/null
+++ b/sql/create_table.sql
@@ -0,0 +1,23 @@
+-- 创建库
+create database if not exists `smile-picture`;
+
+-- 使用库
+use `smile-picture`;
+
+-- 用户表
+create table if not exists user
+(
+ id bigint auto_increment comment 'id' primary key,
+ user_account varchar(256) not null comment '账号',
+ user_password varchar(512) not null comment '密码',
+ user_name varchar(256) null comment '用户昵称',
+ user_avatar varchar(1024) null comment '用户头像',
+ user_profile varchar(512) null comment '用户简介',
+ user_role varchar(256) default 'user' not null comment '用户角色:user/admin',
+ 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)
+ ) comment '用户' collate = utf8mb4_unicode_ci;
diff --git a/src/main/java/edu/whut/smilepicturebackend/SmilePictureBackendApplication.java b/src/main/java/edu/whut/smilepicturebackend/SmilePictureBackendApplication.java
index a1a85ad..b510a0d 100644
--- a/src/main/java/edu/whut/smilepicturebackend/SmilePictureBackendApplication.java
+++ b/src/main/java/edu/whut/smilepicturebackend/SmilePictureBackendApplication.java
@@ -1,9 +1,11 @@
package edu.whut.smilepicturebackend;
+import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
+@MapperScan("edu.whut.smilepicturebackend.mapper")
public class SmilePictureBackendApplication {
public static void main(String[] args) {
diff --git a/src/main/java/edu/whut/smilepicturebackend/config/SecurityConfig.java b/src/main/java/edu/whut/smilepicturebackend/config/SecurityConfig.java
new file mode 100644
index 0000000..f8d36da
--- /dev/null
+++ b/src/main/java/edu/whut/smilepicturebackend/config/SecurityConfig.java
@@ -0,0 +1,13 @@
+package edu.whut.smilepicturebackend.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+
+@Configuration
+public class SecurityConfig {
+ @Bean
+ public BCryptPasswordEncoder passwordEncoder() {
+ return new BCryptPasswordEncoder(12); // 10 是强度
+ }
+}
diff --git a/src/main/java/edu/whut/smilepicturebackend/controller/UserController.java b/src/main/java/edu/whut/smilepicturebackend/controller/UserController.java
new file mode 100644
index 0000000..5fc3493
--- /dev/null
+++ b/src/main/java/edu/whut/smilepicturebackend/controller/UserController.java
@@ -0,0 +1,34 @@
+package edu.whut.smilepicturebackend.controller;
+
+import edu.whut.smilepicturebackend.common.BaseResponse;
+import edu.whut.smilepicturebackend.common.ResultUtils;
+import edu.whut.smilepicturebackend.exception.ErrorCode;
+import edu.whut.smilepicturebackend.exception.ThrowUtils;
+import edu.whut.smilepicturebackend.model.dto.UserRegisterRequest;
+import edu.whut.smilepicturebackend.service.UserService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+@RestController
+@RequestMapping("/user")
+@RequiredArgsConstructor
+public class UserController {
+ private final UserService userService;
+
+ /**
+ * 用户注册
+ */
+ @PostMapping("/register")
+ public BaseResponse userRegister(@RequestBody UserRegisterRequest userRegisterRequest) {
+ ThrowUtils.throwIf(userRegisterRequest == null, ErrorCode.PARAMS_ERROR);
+ String userAccount = userRegisterRequest.getUserAccount();
+ String userPassword = userRegisterRequest.getUserPassword();
+ String checkPassword = userRegisterRequest.getCheckPassword();
+ long result = userService.userRegister(userAccount, userPassword, checkPassword);
+ return ResultUtils.success(result);
+ }
+}
diff --git a/src/main/java/edu/whut/smilepicturebackend/mapper/UserMapper.java b/src/main/java/edu/whut/smilepicturebackend/mapper/UserMapper.java
new file mode 100644
index 0000000..9518645
--- /dev/null
+++ b/src/main/java/edu/whut/smilepicturebackend/mapper/UserMapper.java
@@ -0,0 +1,18 @@
+package edu.whut.smilepicturebackend.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import edu.whut.smilepicturebackend.model.entity.User;
+
+/**
+* @author 张三
+* @description 针对表【user(用户)】的数据库操作Mapper
+* @createDate 2025-06-05 17:43:52
+*/
+
+public interface UserMapper extends BaseMapper {
+
+}
+
+
+
+
diff --git a/src/main/java/edu/whut/smilepicturebackend/model/dto/UserRegisterRequest.java b/src/main/java/edu/whut/smilepicturebackend/model/dto/UserRegisterRequest.java
new file mode 100644
index 0000000..342b386
--- /dev/null
+++ b/src/main/java/edu/whut/smilepicturebackend/model/dto/UserRegisterRequest.java
@@ -0,0 +1,29 @@
+package edu.whut.smilepicturebackend.model.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 用户注册请求
+ */
+@Data
+public class UserRegisterRequest implements Serializable {
+
+ private static final long serialVersionUID = -1321880859645675653L;
+ /**
+ * 账号
+ */
+ private String userAccount;
+
+ /**
+ * 密码
+ */
+ private String userPassword;
+
+ /**
+ * 确认密码
+ */
+ private String checkPassword;
+
+}
diff --git a/src/main/java/edu/whut/smilepicturebackend/model/entity/User.java b/src/main/java/edu/whut/smilepicturebackend/model/entity/User.java
new file mode 100644
index 0000000..be627ab
--- /dev/null
+++ b/src/main/java/edu/whut/smilepicturebackend/model/entity/User.java
@@ -0,0 +1,75 @@
+package edu.whut.smilepicturebackend.model.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 用户
+ * @TableName user
+ */
+@TableName(value ="user")
+@Data
+public class User implements Serializable {
+ /**
+ * id
+ */
+ @TableId(type = IdType.ASSIGN_ID)
+ private Long id;
+
+ /**
+ * 账号
+ */
+ private String userAccount;
+
+ /**
+ * 密码
+ */
+ private String userPassword;
+
+ /**
+ * 用户昵称
+ */
+ private String userName;
+
+ /**
+ * 用户头像
+ */
+ private String userAvatar;
+
+ /**
+ * 用户简介
+ */
+ private String userProfile;
+
+ /**
+ * 用户角色:user/admin
+ */
+ private String userRole;
+
+ /**
+ * 编辑时间
+ */
+ private Date editTime;
+
+ /**
+ * 创建时间
+ */
+ private Date createTime;
+
+ /**
+ * 更新时间
+ */
+ private Date updateTime;
+
+ /**
+ * 是否删除
+ */
+ @TableLogic //标记逻辑删除字段
+ private Integer isDelete;
+
+ @TableField(exist = false)
+ private static final long serialVersionUID = 1L;
+}
\ No newline at end of file
diff --git a/src/main/java/edu/whut/smilepicturebackend/model/enums/UserRoleEnum.java b/src/main/java/edu/whut/smilepicturebackend/model/enums/UserRoleEnum.java
new file mode 100644
index 0000000..20d1822
--- /dev/null
+++ b/src/main/java/edu/whut/smilepicturebackend/model/enums/UserRoleEnum.java
@@ -0,0 +1,42 @@
+package edu.whut.smilepicturebackend.model.enums;
+
+import cn.hutool.core.util.ObjUtil;
+import lombok.Getter;
+
+/**
+ * 用户角色枚举
+ */
+@Getter
+public enum UserRoleEnum {
+
+ USER("用户", "user"),
+ VIP("会员", "vip"),
+ ADMIN("管理员", "admin");
+
+ private final String text;
+
+ private final String value;
+
+ UserRoleEnum(String text, String value) {
+ this.text = text;
+ this.value = value;
+ }
+
+ /**
+ * 根据 value 获取枚举
+ *
+ * @param value 枚举值的 value
+ * @return 枚举值
+ */
+ public static UserRoleEnum getEnumByValue(String value) {
+ if (ObjUtil.isEmpty(value)) {
+ return null;
+ }
+ for (UserRoleEnum userRoleEnum : UserRoleEnum.values()) {
+ if (userRoleEnum.value.equals(value)) {
+ return userRoleEnum;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/edu/whut/smilepicturebackend/service/UserService.java b/src/main/java/edu/whut/smilepicturebackend/service/UserService.java
new file mode 100644
index 0000000..84adb1b
--- /dev/null
+++ b/src/main/java/edu/whut/smilepicturebackend/service/UserService.java
@@ -0,0 +1,30 @@
+package edu.whut.smilepicturebackend.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import edu.whut.smilepicturebackend.model.entity.User;
+
+/**
+* @author 张三
+* @description 针对表【user(用户)】的数据库操作Service
+* @createDate 2025-06-05 17:43:52
+*/
+public interface UserService extends IService {
+ /**
+ * 用户注册
+ *
+ * @param userAccount 用户账户
+ * @param userPassword 用户密码
+ * @param checkPassword 校验密码
+ * @return 新用户 id
+ */
+ long userRegister(String userAccount, String userPassword, String checkPassword);
+ /**
+ * 获取加密后的密码
+ *
+ * @param userPassword
+ * @return
+ */
+
+
+ String getEncryptPassword(String userPassword);
+}
diff --git a/src/main/java/edu/whut/smilepicturebackend/service/impl/UserServiceImpl.java b/src/main/java/edu/whut/smilepicturebackend/service/impl/UserServiceImpl.java
new file mode 100644
index 0000000..443b1ad
--- /dev/null
+++ b/src/main/java/edu/whut/smilepicturebackend/service/impl/UserServiceImpl.java
@@ -0,0 +1,86 @@
+package edu.whut.smilepicturebackend.service.impl;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import edu.whut.smilepicturebackend.exception.BusinessException;
+import edu.whut.smilepicturebackend.exception.ErrorCode;
+import edu.whut.smilepicturebackend.model.entity.User;
+import edu.whut.smilepicturebackend.model.enums.UserRoleEnum;
+import edu.whut.smilepicturebackend.service.UserService;
+import edu.whut.smilepicturebackend.mapper.UserMapper;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.stereotype.Service;
+
+/**
+* @author 张三
+* @description 针对表【user(用户)】的数据库操作Service实现
+* @createDate 2025-06-05 17:43:52
+*/
+@Service
+@RequiredArgsConstructor
+public class UserServiceImpl extends ServiceImpl
+ implements UserService{
+ private final BCryptPasswordEncoder passwordEncoder;
+ /**
+ * 用户注册
+ *
+ * @param userAccount 用户账户
+ * @param userPassword 用户密码
+ * @param checkPassword 校验密码
+ * @return
+ */
+ @Override
+ public long userRegister(String userAccount, String userPassword, String checkPassword) {
+ // 1. 校验参数
+ if (StrUtil.hasBlank(userAccount, userPassword, checkPassword)) {
+ throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
+ }
+ if (userAccount.length() < 4) {
+ throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号过短");
+ }
+ if (userPassword.length() < 8 || checkPassword.length() < 8) {
+ throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码过短");
+ }
+ if (!userPassword.equals(checkPassword)) {
+ throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致");
+ }
+ // 2. 检查用户账号是否和数据库中已有的重复
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("userAccount", userAccount);
+ long count = this.baseMapper.selectCount(queryWrapper);
+ if (count > 0) {
+ throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复");
+ }
+ // 3. 密码一定要加密
+ String encryptPassword = getEncryptPassword(userPassword);
+ // 4. 插入数据到数据库中
+ User user = new User();
+ user.setUserAccount(userAccount);
+ user.setUserPassword(encryptPassword);
+ user.setUserName("无名");
+ user.setUserRole(UserRoleEnum.USER.getValue());
+ boolean saveResult = this.save(user);
+ if (!saveResult) {
+ throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败,数据库错误");
+ }
+ return user.getId();
+ }
+ /**
+ * 获取加密后的密码
+ *
+ * @param userPassword 用户密码
+ * @return 加密后的密码
+ */
+ @Override
+ public String getEncryptPassword(String userPassword) {
+ return passwordEncoder.encode(userPassword);
+// // 加盐,混淆密码
+// final String SALT = "smile12306";
+// return DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
+ }
+}
+
+
+
+
diff --git a/src/main/java/edu/whut/smilepicturebackend/utils/PasswordUtils.java b/src/main/java/edu/whut/smilepicturebackend/utils/PasswordUtils.java
new file mode 100644
index 0000000..c34935c
--- /dev/null
+++ b/src/main/java/edu/whut/smilepicturebackend/utils/PasswordUtils.java
@@ -0,0 +1,23 @@
+package edu.whut.smilepicturebackend.utils;
+
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+
+//BCrypt加密工具类,不如Bean注入效率更高,已废弃。
+public class PasswordUtils {
+
+ private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
+
+ /**
+ * 加密密码
+ */
+ public static String encode(String rawPassword) {
+ return encoder.encode(rawPassword);
+ }
+
+ /**
+ * 校验密码是否匹配
+ */
+ public static boolean matches(String rawPassword, String encodedPassword) {
+ return encoder.matches(rawPassword, encodedPassword);
+ }
+}