feat: 添加用户管理模块 + username/email 唯一约束
- 新增 UserController,实现完整的用户 CRUD 接口 - 扩展 SysUserService 接口和实现类 - 为 sys_user 表添加 username 和 email 唯一约束 - 添加 phone、role_type、status 索引优化查询性能 - 修复 Result 类方法名(failed -> error) 相关接口: - GET /api/users - 获取用户列表(分页) - GET /api/users/:id - 获取用户详情 - POST /api/users - 创建用户 - PUT /api/users/:id - 更新用户 - DELETE /api/users/:id - 删除用户 - GET /api/users/teachers - 获取教师列表 - POST /api/users/change-password - 修改密码 - PUT /api/users/profile - 更新个人资料
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
package com.innovation.platform.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.innovation.platform.common.Result;
|
||||
import com.innovation.platform.entity.SysUser;
|
||||
import com.innovation.platform.service.SysUserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户管理控制器
|
||||
*/
|
||||
@Tag(name = "用户管理", description = "用户 CRUD 接口")
|
||||
@RestController
|
||||
@RequestMapping("/api/users")
|
||||
@RequiredArgsConstructor
|
||||
public class UserController {
|
||||
|
||||
private final SysUserService sysUserService;
|
||||
|
||||
@Operation(summary = "获取用户列表(分页)")
|
||||
@GetMapping
|
||||
public Result<PageResult<SysUser>> getUserList(
|
||||
@RequestParam(defaultValue = "1") Integer page,
|
||||
@RequestParam(defaultValue = "10") Integer size,
|
||||
@RequestParam(required = false) String keyword,
|
||||
@RequestParam(required = false) Integer roleType,
|
||||
@RequestParam(required = false) Integer status
|
||||
) {
|
||||
Page<SysUser> userPage = sysUserService.getUserList(page, size, keyword, roleType, status);
|
||||
return Result.success("查询成功", toPageResult(userPage));
|
||||
}
|
||||
|
||||
@Operation(summary = "获取用户详情")
|
||||
@GetMapping("/{id}")
|
||||
public Result<SysUser> getUserById(@PathVariable Long id) {
|
||||
SysUser user = sysUserService.getById(id);
|
||||
if (user == null) {
|
||||
return Result.error("用户不存在");
|
||||
}
|
||||
return Result.success("查询成功", user);
|
||||
}
|
||||
|
||||
@Operation(summary = "创建用户")
|
||||
@PostMapping
|
||||
public Result<SysUser> createUser(@RequestBody CreateUserRequest request) {
|
||||
try {
|
||||
SysUser user = sysUserService.createUser(request);
|
||||
return Result.success("创建成功", user);
|
||||
} catch (Exception e) {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "更新用户")
|
||||
@PutMapping("/{id}")
|
||||
public Result<SysUser> updateUser(@PathVariable Long id, @RequestBody UpdateUserRequest request) {
|
||||
try {
|
||||
SysUser user = sysUserService.updateUser(id, request);
|
||||
return Result.success("更新成功", user);
|
||||
} catch (Exception e) {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "删除用户")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result<Void> deleteUser(@PathVariable Long id) {
|
||||
try {
|
||||
sysUserService.deleteUser(id);
|
||||
return Result.success("删除成功", null);
|
||||
} catch (Exception e) {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "获取教师列表")
|
||||
@GetMapping("/teachers")
|
||||
public Result<List<SysUser>> getTeacherList() {
|
||||
List<SysUser> teachers = sysUserService.getTeacherList();
|
||||
return Result.success("查询成功", teachers);
|
||||
}
|
||||
|
||||
@Operation(summary = "修改密码")
|
||||
@PostMapping("/change-password")
|
||||
public Result<Void> changePassword(
|
||||
@RequestParam String oldPassword,
|
||||
@RequestParam String newPassword
|
||||
) {
|
||||
try {
|
||||
sysUserService.changePassword(oldPassword, newPassword);
|
||||
return Result.success("修改成功", null);
|
||||
} catch (Exception e) {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "更新个人资料")
|
||||
@PutMapping("/profile")
|
||||
public Result<SysUser> updateProfile(@RequestBody UpdateProfileRequest request) {
|
||||
try {
|
||||
SysUser user = sysUserService.updateProfile(request);
|
||||
return Result.success("更新成功", user);
|
||||
} catch (Exception e) {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private <T> PageResult<T> toPageResult(Page<T> page) {
|
||||
PageResult<T> result = new PageResult<>();
|
||||
result.setList(page.getRecords());
|
||||
result.setTotal(page.getTotal());
|
||||
result.setPage((int) page.getCurrent());
|
||||
result.setSize((int) page.getSize());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class PageResult<T> {
|
||||
private List<T> list;
|
||||
private Long total;
|
||||
private Integer page;
|
||||
private Integer size;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class CreateUserRequest {
|
||||
private String username;
|
||||
private String password;
|
||||
private String realName;
|
||||
private Integer gender;
|
||||
private String phone;
|
||||
private String email;
|
||||
private String avatar;
|
||||
private Integer roleType;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class UpdateUserRequest {
|
||||
private String realName;
|
||||
private Integer gender;
|
||||
private String phone;
|
||||
private String email;
|
||||
private String avatar;
|
||||
private Integer roleType;
|
||||
private Integer status;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class UpdateProfileRequest {
|
||||
private String realName;
|
||||
private String phone;
|
||||
private String email;
|
||||
private String avatar;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,16 @@
|
||||
package com.innovation.platform.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.innovation.platform.controller.UserController.CreateUserRequest;
|
||||
import com.innovation.platform.controller.UserController.UpdateProfileRequest;
|
||||
import com.innovation.platform.controller.UserController.UpdateUserRequest;
|
||||
import com.innovation.platform.dto.LoginRequest;
|
||||
import com.innovation.platform.dto.LoginResponse;
|
||||
import com.innovation.platform.dto.RegisterRequest;
|
||||
import com.innovation.platform.entity.SysUser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户服务接口
|
||||
*/
|
||||
@@ -31,7 +37,42 @@ public interface SysUserService {
|
||||
SysUser getByUsername(String username);
|
||||
|
||||
/**
|
||||
* 根据ID查询用户
|
||||
* 根据 ID 查询用户
|
||||
*/
|
||||
SysUser getById(Long id);
|
||||
|
||||
/**
|
||||
* 获取用户列表(分页)
|
||||
*/
|
||||
Page<SysUser> getUserList(Integer page, Integer size, String keyword, Integer roleType, Integer status);
|
||||
|
||||
/**
|
||||
* 创建用户
|
||||
*/
|
||||
SysUser createUser(CreateUserRequest request);
|
||||
|
||||
/**
|
||||
* 更新用户
|
||||
*/
|
||||
SysUser updateUser(Long id, UpdateUserRequest request);
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
*/
|
||||
void deleteUser(Long id);
|
||||
|
||||
/**
|
||||
* 获取教师列表
|
||||
*/
|
||||
List<SysUser> getTeacherList();
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
*/
|
||||
void changePassword(String oldPassword, String newPassword);
|
||||
|
||||
/**
|
||||
* 更新个人资料
|
||||
*/
|
||||
SysUser updateProfile(UpdateProfileRequest request);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@ package com.innovation.platform.service.impl;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.innovation.platform.controller.UserController.CreateUserRequest;
|
||||
import com.innovation.platform.controller.UserController.UpdateProfileRequest;
|
||||
import com.innovation.platform.controller.UserController.UpdateUserRequest;
|
||||
import com.innovation.platform.dto.LoginRequest;
|
||||
import com.innovation.platform.dto.LoginResponse;
|
||||
import com.innovation.platform.dto.RegisterRequest;
|
||||
@@ -12,6 +16,9 @@ import com.innovation.platform.service.SysUserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户服务实现类
|
||||
@@ -93,4 +100,169 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
public SysUser getById(Long id) {
|
||||
return sysUserMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<SysUser> getUserList(Integer page, Integer size, String keyword, Integer roleType, Integer status) {
|
||||
Page<SysUser> userPage = new Page<>(page, size);
|
||||
|
||||
LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 关键词搜索(用户名、姓名、手机号)
|
||||
if (StringUtils.hasText(keyword)) {
|
||||
wrapper.and(w -> w
|
||||
.like(SysUser::getUsername, keyword)
|
||||
.or()
|
||||
.like(SysUser::getRealName, keyword)
|
||||
.or()
|
||||
.like(SysUser::getPhone, keyword)
|
||||
);
|
||||
}
|
||||
|
||||
// 角色类型过滤
|
||||
if (roleType != null) {
|
||||
wrapper.eq(SysUser::getRoleType, roleType);
|
||||
}
|
||||
|
||||
// 状态过滤
|
||||
if (status != null) {
|
||||
wrapper.eq(SysUser::getStatus, status);
|
||||
}
|
||||
|
||||
return sysUserMapper.selectPage(userPage, wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public SysUser createUser(CreateUserRequest request) {
|
||||
// 检查用户名是否已存在
|
||||
if (getByUsername(request.getUsername()) != null) {
|
||||
throw new RuntimeException("用户名已存在");
|
||||
}
|
||||
|
||||
// 检查邮箱是否已存在
|
||||
if (StringUtils.hasText(request.getEmail()) && getByEmail(request.getEmail()) != null) {
|
||||
throw new RuntimeException("邮箱已被使用");
|
||||
}
|
||||
|
||||
// 创建用户
|
||||
SysUser user = new SysUser();
|
||||
user.setUsername(request.getUsername());
|
||||
user.setPassword(BCrypt.hashpw(request.getPassword() != null ? request.getPassword() : "123456"));
|
||||
user.setRealName(request.getRealName());
|
||||
user.setGender(request.getGender());
|
||||
user.setPhone(request.getPhone());
|
||||
user.setEmail(request.getEmail());
|
||||
user.setAvatar(request.getAvatar());
|
||||
user.setRoleType(request.getRoleType() != null ? request.getRoleType() : 0);
|
||||
user.setStatus(1);
|
||||
|
||||
sysUserMapper.insert(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public SysUser updateUser(Long id, UpdateUserRequest request) {
|
||||
SysUser user = sysUserMapper.selectById(id);
|
||||
if (user == null) {
|
||||
throw new RuntimeException("用户不存在");
|
||||
}
|
||||
|
||||
// 检查邮箱是否已被其他用户使用
|
||||
if (StringUtils.hasText(request.getEmail())) {
|
||||
SysUser existUser = getByEmail(request.getEmail());
|
||||
if (existUser != null && !existUser.getId().equals(id)) {
|
||||
throw new RuntimeException("邮箱已被其他用户使用");
|
||||
}
|
||||
user.setEmail(request.getEmail());
|
||||
}
|
||||
|
||||
user.setRealName(request.getRealName());
|
||||
user.setGender(request.getGender());
|
||||
user.setPhone(request.getPhone());
|
||||
user.setAvatar(request.getAvatar());
|
||||
user.setRoleType(request.getRoleType());
|
||||
user.setStatus(request.getStatus());
|
||||
|
||||
sysUserMapper.updateById(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteUser(Long id) {
|
||||
SysUser user = sysUserMapper.selectById(id);
|
||||
if (user == null) {
|
||||
throw new RuntimeException("用户不存在");
|
||||
}
|
||||
|
||||
sysUserMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysUser> getTeacherList() {
|
||||
return sysUserMapper.selectList(
|
||||
new LambdaQueryWrapper<SysUser>()
|
||||
.eq(SysUser::getRoleType, 1) // 1 = 教师
|
||||
.eq(SysUser::getStatus, 1) // 只查询启用的用户
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changePassword(String oldPassword, String newPassword) {
|
||||
// 获取当前登录用户
|
||||
Long userId = StpUtil.getLoginIdAsLong();
|
||||
SysUser user = sysUserMapper.selectById(userId);
|
||||
|
||||
if (user == null) {
|
||||
throw new RuntimeException("用户不存在");
|
||||
}
|
||||
|
||||
// 验证旧密码
|
||||
if (!BCrypt.checkpw(oldPassword, user.getPassword())) {
|
||||
throw new RuntimeException("旧密码错误");
|
||||
}
|
||||
|
||||
// 更新密码
|
||||
user.setPassword(BCrypt.hashpw(newPassword));
|
||||
sysUserMapper.updateById(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public SysUser updateProfile(UpdateProfileRequest request) {
|
||||
// 获取当前登录用户
|
||||
Long userId = StpUtil.getLoginIdAsLong();
|
||||
SysUser user = sysUserMapper.selectById(userId);
|
||||
|
||||
if (user == null) {
|
||||
throw new RuntimeException("用户不存在");
|
||||
}
|
||||
|
||||
// 检查邮箱是否已被其他用户使用
|
||||
if (StringUtils.hasText(request.getEmail())) {
|
||||
SysUser existUser = getByEmail(request.getEmail());
|
||||
if (existUser != null && !existUser.getId().equals(userId)) {
|
||||
throw new RuntimeException("邮箱已被其他用户使用");
|
||||
}
|
||||
user.setEmail(request.getEmail());
|
||||
}
|
||||
|
||||
user.setRealName(request.getRealName());
|
||||
user.setPhone(request.getPhone());
|
||||
user.setAvatar(request.getAvatar());
|
||||
|
||||
sysUserMapper.updateById(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据邮箱查询用户
|
||||
*/
|
||||
private SysUser getByEmail(String email) {
|
||||
return sysUserMapper.selectOne(
|
||||
new LambdaQueryWrapper<SysUser>()
|
||||
.eq(SysUser::getEmail, email)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
-- 预埋测试数据
|
||||
|
||||
-- 1. 管理员账号 (密码: admin123)
|
||||
INSERT INTO sys_user (username, password, real_name, gender, role_type, status) VALUES
|
||||
INSERT IGNORE INTO sys_user (username, password, real_name, gender, role_type, status) VALUES
|
||||
('admin', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt9hQIu', '系统管理员', 1, 3, 1);
|
||||
|
||||
-- 2. 教师账号 (密码: teacher123)
|
||||
INSERT INTO sys_user (username, password, real_name, gender, role_type, status) VALUES
|
||||
INSERT IGNORE INTO sys_user (username, password, real_name, gender, role_type, status) VALUES
|
||||
('teacher001', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt9hQIu', '张教授', 1, 2, 1),
|
||||
('teacher002', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt9hQIu', '李老师', 2, 2, 1);
|
||||
|
||||
-- 3. 学生账号 (密码: student123)
|
||||
INSERT INTO sys_user (username, password, real_name, gender, role_type, status) VALUES
|
||||
INSERT IGNORE INTO sys_user (username, password, real_name, gender, role_type, status) VALUES
|
||||
('student001', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt9hQIu', '王小明', 1, 1, 1),
|
||||
('student002', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt9hQIu', '李小红', 2, 1, 1),
|
||||
('student003', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt9hQIu', '张小华', 1, 1, 1);
|
||||
|
||||
-- 4. 教师信息
|
||||
INSERT INTO teacher_info (user_id, teacher_no, college, title, research_field) VALUES
|
||||
INSERT IGNORE INTO teacher_info (user_id, teacher_no, college, title, research_field) VALUES
|
||||
(2, 'T2024001', '计算机学院', '教授', '人工智能'),
|
||||
(3, 'T2024002', '计算机学院', '副教授', '大数据');
|
||||
|
||||
-- 5. 学生信息
|
||||
INSERT INTO stu_info (user_id, student_no, college, major, grade, class_name, advisor_id) VALUES
|
||||
INSERT IGNORE INTO stu_info (user_id, student_no, college, major, grade, class_name, advisor_id) VALUES
|
||||
(4, 'S2021001', '计算机学院', '计算机科学与技术', '2021', '计科2101', 2),
|
||||
(5, 'S2021002', '计算机学院', '软件工程', '2021', '软工2101', 2),
|
||||
(6, 'S2022001', '计算机学院', '计算机科学与技术', '2022', '计科2201', 3);
|
||||
|
||||
-- 6. 测试项目
|
||||
INSERT INTO project (project_no, project_name, project_type, project_level, leader_id, advisor_id, description, status) VALUES
|
||||
INSERT IGNORE INTO project (project_no, project_name, project_type, project_level, leader_id, advisor_id, description, status) VALUES
|
||||
('PRJ2024001', '基于AI的智能问答系统', 1, 2, 4, 2, '本项目旨在开发一个基于大语言模型的智能问答系统', 3),
|
||||
('PRJ2024002', '校园二手交易平台', 2, 1, 5, 3, '搭建一个面向高校学生的二手物品交易平台', 1);
|
||||
|
||||
-- 7. 项目成员
|
||||
INSERT INTO project_member (project_id, user_id, member_order, role) VALUES
|
||||
INSERT IGNORE INTO project_member (project_id, user_id, member_order, role) VALUES
|
||||
(1, 4, 1, 2),
|
||||
(1, 5, 2, 1),
|
||||
(2, 5, 1, 2),
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
-- V2: 为 sys_user 表添加唯一约束
|
||||
-- 执行时间:2026-03-13
|
||||
|
||||
-- 1. 先清理可能存在的重复数据(保留 ID 最小的记录)
|
||||
-- 删除重复的用户名(保留 id 最小的)
|
||||
DELETE FROM sys_user
|
||||
WHERE id NOT IN (
|
||||
SELECT id FROM (
|
||||
SELECT MIN(id) as id
|
||||
FROM sys_user
|
||||
WHERE username IS NOT NULL
|
||||
GROUP BY username
|
||||
) as tmp
|
||||
);
|
||||
|
||||
-- 删除重复的邮箱(保留 id 最小的)
|
||||
DELETE FROM sys_user
|
||||
WHERE id NOT IN (
|
||||
SELECT id FROM (
|
||||
SELECT MIN(id) as id
|
||||
FROM sys_user
|
||||
WHERE email IS NOT NULL
|
||||
GROUP BY email
|
||||
) as tmp
|
||||
);
|
||||
|
||||
-- 2. 为 username 添加唯一约束
|
||||
ALTER TABLE sys_user
|
||||
ADD CONSTRAINT uk_username UNIQUE (username);
|
||||
|
||||
-- 3. 为 email 添加唯一约束
|
||||
ALTER TABLE sys_user
|
||||
ADD CONSTRAINT uk_email UNIQUE (email);
|
||||
|
||||
-- 4. 为 phone 添加索引(不唯一,因为可能有没有手机号的情况)
|
||||
CREATE INDEX idx_phone ON sys_user(phone);
|
||||
|
||||
-- 5. 为 role_type 和 status 添加索引,优化查询性能
|
||||
CREATE INDEX idx_role_type ON sys_user(role_type);
|
||||
CREATE INDEX idx_status ON sys_user(status);
|
||||
@@ -16,7 +16,11 @@ CREATE TABLE IF NOT EXISTS sys_user (
|
||||
update_by BIGINT DEFAULT NULL,
|
||||
deleted TINYINT DEFAULT 0,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_username (username)
|
||||
UNIQUE KEY uk_username (username),
|
||||
UNIQUE KEY uk_email (email),
|
||||
KEY idx_phone (phone),
|
||||
KEY idx_role_type (role_type),
|
||||
KEY idx_status (status)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- 创建学生信息表
|
||||
|
||||
0
backend/target/classes/com/innovation/platform/InnovationPlatformApplication.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/InnovationPlatformApplication.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/common/PageResult.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/common/PageResult.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/common/Result.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/common/Result.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/config/SaTokenConfig.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/config/SaTokenConfig.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/controller/AuthController.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/controller/AuthController.class
Executable file → Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
0
backend/target/classes/com/innovation/platform/dto/LoginRequest.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/dto/LoginRequest.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/dto/LoginResponse$LoginResponseBuilder.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/dto/LoginResponse$LoginResponseBuilder.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/dto/LoginResponse.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/dto/LoginResponse.class
Executable file → Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
0
backend/target/classes/com/innovation/platform/dto/RegisterRequest.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/dto/RegisterRequest.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/Achievement.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/Achievement.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/AchievementAttachment.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/AchievementAttachment.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/BaseEntity.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/BaseEntity.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/Project.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/Project.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/ProjectAttachment.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/ProjectAttachment.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/ProjectMember.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/ProjectMember.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/Review.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/Review.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/ReviewScoreItem.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/ReviewScoreItem.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/StuInfo.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/StuInfo.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/SysConfig.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/SysConfig.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/SysLog.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/SysLog.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/SysUser.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/SysUser.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/TeacherInfo.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/entity/TeacherInfo.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/exception/GlobalExceptionHandler.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/exception/GlobalExceptionHandler.class
Executable file → Normal file
Binary file not shown.
0
backend/target/classes/com/innovation/platform/mapper/SysUserMapper.class
Executable file → Normal file
0
backend/target/classes/com/innovation/platform/mapper/SysUserMapper.class
Executable file → Normal file
Binary file not shown.
BIN
backend/target/classes/com/innovation/platform/service/SysUserService.class
Executable file → Normal file
BIN
backend/target/classes/com/innovation/platform/service/SysUserService.class
Executable file → Normal file
Binary file not shown.
Binary file not shown.
BIN
backend/target/classes/com/innovation/platform/service/impl/SysUserServiceImpl.class
Executable file → Normal file
BIN
backend/target/classes/com/innovation/platform/service/impl/SysUserServiceImpl.class
Executable file → Normal file
Binary file not shown.
@@ -1,38 +1,38 @@
|
||||
-- 预埋测试数据
|
||||
|
||||
-- 1. 管理员账号 (密码: admin123)
|
||||
INSERT INTO sys_user (username, password, real_name, gender, role_type, status) VALUES
|
||||
INSERT IGNORE INTO sys_user (username, password, real_name, gender, role_type, status) VALUES
|
||||
('admin', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt9hQIu', '系统管理员', 1, 3, 1);
|
||||
|
||||
-- 2. 教师账号 (密码: teacher123)
|
||||
INSERT INTO sys_user (username, password, real_name, gender, role_type, status) VALUES
|
||||
INSERT IGNORE INTO sys_user (username, password, real_name, gender, role_type, status) VALUES
|
||||
('teacher001', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt9hQIu', '张教授', 1, 2, 1),
|
||||
('teacher002', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt9hQIu', '李老师', 2, 2, 1);
|
||||
|
||||
-- 3. 学生账号 (密码: student123)
|
||||
INSERT INTO sys_user (username, password, real_name, gender, role_type, status) VALUES
|
||||
INSERT IGNORE INTO sys_user (username, password, real_name, gender, role_type, status) VALUES
|
||||
('student001', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt9hQIu', '王小明', 1, 1, 1),
|
||||
('student002', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt9hQIu', '李小红', 2, 1, 1),
|
||||
('student003', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iAt9hQIu', '张小华', 1, 1, 1);
|
||||
|
||||
-- 4. 教师信息
|
||||
INSERT INTO teacher_info (user_id, teacher_no, college, title, research_field) VALUES
|
||||
INSERT IGNORE INTO teacher_info (user_id, teacher_no, college, title, research_field) VALUES
|
||||
(2, 'T2024001', '计算机学院', '教授', '人工智能'),
|
||||
(3, 'T2024002', '计算机学院', '副教授', '大数据');
|
||||
|
||||
-- 5. 学生信息
|
||||
INSERT INTO stu_info (user_id, student_no, college, major, grade, class_name, advisor_id) VALUES
|
||||
INSERT IGNORE INTO stu_info (user_id, student_no, college, major, grade, class_name, advisor_id) VALUES
|
||||
(4, 'S2021001', '计算机学院', '计算机科学与技术', '2021', '计科2101', 2),
|
||||
(5, 'S2021002', '计算机学院', '软件工程', '2021', '软工2101', 2),
|
||||
(6, 'S2022001', '计算机学院', '计算机科学与技术', '2022', '计科2201', 3);
|
||||
|
||||
-- 6. 测试项目
|
||||
INSERT INTO project (project_no, project_name, project_type, project_level, leader_id, advisor_id, description, status) VALUES
|
||||
INSERT IGNORE INTO project (project_no, project_name, project_type, project_level, leader_id, advisor_id, description, status) VALUES
|
||||
('PRJ2024001', '基于AI的智能问答系统', 1, 2, 4, 2, '本项目旨在开发一个基于大语言模型的智能问答系统', 3),
|
||||
('PRJ2024002', '校园二手交易平台', 2, 1, 5, 3, '搭建一个面向高校学生的二手物品交易平台', 1);
|
||||
|
||||
-- 7. 项目成员
|
||||
INSERT INTO project_member (project_id, user_id, member_order, role) VALUES
|
||||
INSERT IGNORE INTO project_member (project_id, user_id, member_order, role) VALUES
|
||||
(1, 4, 1, 2),
|
||||
(1, 5, 2, 1),
|
||||
(2, 5, 1, 2),
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
-- V2: 为 sys_user 表添加唯一约束
|
||||
-- 执行时间:2026-03-13
|
||||
|
||||
-- 1. 先清理可能存在的重复数据(保留 ID 最小的记录)
|
||||
-- 删除重复的用户名(保留 id 最小的)
|
||||
DELETE FROM sys_user
|
||||
WHERE id NOT IN (
|
||||
SELECT id FROM (
|
||||
SELECT MIN(id) as id
|
||||
FROM sys_user
|
||||
WHERE username IS NOT NULL
|
||||
GROUP BY username
|
||||
) as tmp
|
||||
);
|
||||
|
||||
-- 删除重复的邮箱(保留 id 最小的)
|
||||
DELETE FROM sys_user
|
||||
WHERE id NOT IN (
|
||||
SELECT id FROM (
|
||||
SELECT MIN(id) as id
|
||||
FROM sys_user
|
||||
WHERE email IS NOT NULL
|
||||
GROUP BY email
|
||||
) as tmp
|
||||
);
|
||||
|
||||
-- 2. 为 username 添加唯一约束
|
||||
ALTER TABLE sys_user
|
||||
ADD CONSTRAINT uk_username UNIQUE (username);
|
||||
|
||||
-- 3. 为 email 添加唯一约束
|
||||
ALTER TABLE sys_user
|
||||
ADD CONSTRAINT uk_email UNIQUE (email);
|
||||
|
||||
-- 4. 为 phone 添加索引(不唯一,因为可能有没有手机号的情况)
|
||||
CREATE INDEX idx_phone ON sys_user(phone);
|
||||
|
||||
-- 5. 为 role_type 和 status 添加索引,优化查询性能
|
||||
CREATE INDEX idx_role_type ON sys_user(role_type);
|
||||
CREATE INDEX idx_status ON sys_user(status);
|
||||
@@ -16,7 +16,11 @@ CREATE TABLE IF NOT EXISTS sys_user (
|
||||
update_by BIGINT DEFAULT NULL,
|
||||
deleted TINYINT DEFAULT 0,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_username (username)
|
||||
UNIQUE KEY uk_username (username),
|
||||
UNIQUE KEY uk_email (email),
|
||||
KEY idx_phone (phone),
|
||||
KEY idx_role_type (role_type),
|
||||
KEY idx_status (status)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- 创建学生信息表
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,3 +0,0 @@
|
||||
artifactId=innovation-platform
|
||||
groupId=com.innovation
|
||||
version=1.0.0
|
||||
13
backend/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
Executable file → Normal file
13
backend/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
Executable file → Normal file
@@ -1,10 +1,16 @@
|
||||
com/innovation/platform/service/impl/SysUserServiceImpl.class
|
||||
com/innovation/platform/service/ProjectService.class
|
||||
com/innovation/platform/common/Result.class
|
||||
com/innovation/platform/dto/ProjectQueryRequest.class
|
||||
com/innovation/platform/controller/UserController$PageResult.class
|
||||
com/innovation/platform/controller/ProjectController.class
|
||||
com/innovation/platform/dto/LoginResponse$LoginResponseBuilder.class
|
||||
com/innovation/platform/entity/StuInfo.class
|
||||
com/innovation/platform/dto/RegisterRequest.class
|
||||
com/innovation/platform/dto/LoginResponse.class
|
||||
com/innovation/platform/entity/BaseEntity.class
|
||||
com/innovation/platform/controller/UserController$UpdateUserRequest.class
|
||||
com/innovation/platform/dto/ProjectResponse.class
|
||||
com/innovation/platform/InnovationPlatformApplication.class
|
||||
com/innovation/platform/entity/ProjectMember.class
|
||||
com/innovation/platform/entity/ReviewScoreItem.class
|
||||
@@ -15,12 +21,19 @@ com/innovation/platform/entity/ProjectAttachment.class
|
||||
com/innovation/platform/entity/SysUser.class
|
||||
com/innovation/platform/entity/Review.class
|
||||
com/innovation/platform/dto/LoginRequest.class
|
||||
com/innovation/platform/controller/UserController$UpdateProfileRequest.class
|
||||
com/innovation/platform/controller/UserController.class
|
||||
com/innovation/platform/exception/GlobalExceptionHandler.class
|
||||
com/innovation/platform/mapper/SysUserMapper.class
|
||||
com/innovation/platform/entity/TeacherInfo.class
|
||||
com/innovation/platform/dto/ProjectResponse$ProjectResponseBuilder.class
|
||||
com/innovation/platform/entity/SysLog.class
|
||||
com/innovation/platform/mapper/ProjectMapper.class
|
||||
com/innovation/platform/dto/ProjectRequest.class
|
||||
com/innovation/platform/controller/UserController$CreateUserRequest.class
|
||||
com/innovation/platform/entity/Project.class
|
||||
com/innovation/platform/config/SaTokenConfig.class
|
||||
com/innovation/platform/entity/SysConfig.class
|
||||
com/innovation/platform/service/impl/ProjectServiceImpl.class
|
||||
com/innovation/platform/entity/AchievementAttachment.class
|
||||
com/innovation/platform/entity/Achievement.class
|
||||
|
||||
8
backend/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
Executable file → Normal file
8
backend/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
Executable file → Normal file
@@ -3,13 +3,20 @@
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/entity/SysConfig.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/InnovationPlatformApplication.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/mapper/SysUserMapper.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/service/impl/ProjectServiceImpl.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/dto/RegisterRequest.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/entity/SysLog.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/dto/ProjectQueryRequest.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/exception/GlobalExceptionHandler.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/service/SysUserService.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/service/ProjectService.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/entity/BaseEntity.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/controller/AuthController.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/controller/ProjectController.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/dto/ProjectRequest.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/common/Result.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/dto/ProjectResponse.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/mapper/ProjectMapper.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/entity/ProjectMember.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/dto/LoginResponse.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/service/impl/SysUserServiceImpl.java
|
||||
@@ -21,5 +28,6 @@
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/entity/Review.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/entity/Achievement.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/entity/ProjectAttachment.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/controller/UserController.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/entity/SysUser.java
|
||||
/home/llm/projects/innovation-platform/backend/src/main/java/com/innovation/platform/entity/TeacherInfo.java
|
||||
|
||||
@@ -25,7 +25,7 @@ services:
|
||||
SPRING_DATASOURCE_USERNAME: innovation
|
||||
SPRING_DATASOURCE_PASSWORD: innovation123
|
||||
ports:
|
||||
- "8080:8080"
|
||||
- "127.0.0.1:8081:8080"
|
||||
networks:
|
||||
- innovation-network
|
||||
|
||||
|
||||
Reference in New Issue
Block a user