blob: acda403d1a83f021b6cabf93831369e6de797376 [file] [log] [blame]
22301115cf6dba22025-03-25 19:06:21 +08001package com.example.myproject.controller;
2
22301126e1131602025-06-04 11:30:10 +08003import cn.dev33.satoken.annotation.SaCheckLogin;
4import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
5import com.example.myproject.common.base.PageUtil;
6import com.example.myproject.dto.param.TorrentParam;
7import com.example.myproject.dto.vo.TorrentVO;
8import com.example.myproject.entity.TorrentEntity;
9import com.example.myproject.mapper.UserMapper;
10import com.example.myproject.mapper.VerificationTokenMapper;
11import com.example.myproject.entity.User;
12import com.example.myproject.entity.VerificationToken;
13import com.example.myproject.service.EmailService;
22301115cf6dba22025-03-25 19:06:21 +080014import com.example.myproject.service.UserService;
22301126e1131602025-06-04 11:30:10 +080015import com.example.myproject.common.base.Result;
16import io.swagger.annotations.Api;
17import io.swagger.annotations.ApiOperation;
18import io.swagger.annotations.ApiParam;
19import io.swagger.v3.oas.annotations.Operation;
20import io.swagger.v3.oas.annotations.media.Content;
21import io.swagger.v3.oas.annotations.media.Schema;
22import io.swagger.v3.oas.annotations.responses.ApiResponse;
23import org.apache.commons.lang3.RandomStringUtils;
24import org.slf4j.Logger;
25import org.slf4j.LoggerFactory;
22301115cf6dba22025-03-25 19:06:21 +080026import org.springframework.beans.factory.annotation.Autowired;
22301126e1131602025-06-04 11:30:10 +080027import org.springframework.http.HttpStatus;
28import org.springframework.http.ResponseEntity;
29import org.springframework.security.authentication.AuthenticationManager;
30import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
31import org.springframework.security.core.Authentication;
32import org.springframework.security.core.AuthenticationException;
33import org.springframework.security.core.context.SecurityContextHolder;
22301115cf6dba22025-03-25 19:06:21 +080034import org.springframework.web.bind.annotation.*;
35
22301126e1131602025-06-04 11:30:10 +080036import javax.annotation.Resource;
37import java.time.Instant;
38import java.time.temporal.ChronoUnit;
YelinCuifdf4ed72025-05-26 11:49:36 +080039import java.util.List;
22301115cf6dba22025-03-25 19:06:21 +080040
41@RestController
22301126e1131602025-06-04 11:30:10 +080042@RequestMapping("/user")
43@Api(value = "用户管理接口", tags = {"用户管理"})
22301115cf6dba22025-03-25 19:06:21 +080044public class UserController {
45
22301126e1131602025-06-04 11:30:10 +080046 @Resource
22301115cf6dba22025-03-25 19:06:21 +080047 private UserService userService;
48
49 @Autowired
22301126e1131602025-06-04 11:30:10 +080050 private AuthenticationManager authenticationManager;
22301115cf6dba22025-03-25 19:06:21 +080051
52 @Autowired
22301126e1131602025-06-04 11:30:10 +080053 private UserMapper userMapper; // 使用 MyBatis-Plus
22301115cf6dba22025-03-25 19:06:21 +080054
22301126e1131602025-06-04 11:30:10 +080055 @Autowired
56 private VerificationTokenMapper verificationTokenMapper; // 替换 JPA
22301115cf6dba22025-03-25 19:06:21 +080057
22301126e1131602025-06-04 11:30:10 +080058 private static final Logger logger = LoggerFactory.getLogger(UserController.class);
22301138f6824512025-06-04 02:03:13 +080059
22301138f6824512025-06-04 02:03:13 +080060 @PostMapping("/login")
22301126e1131602025-06-04 11:30:10 +080061 @ApiOperation(value = "用户登录", notes = "使用用户名和密码进行登录")
62 public Result loginController(@RequestParam @ApiParam(value = "用户名", required = true) String username,
63 @RequestParam @ApiParam(value = "密码", required = true) String password) {
64 try {
65 Authentication authentication = authenticationManager.authenticate(
66 new UsernamePasswordAuthenticationToken(username, password)
67 );
68 SecurityContextHolder.getContext().setAuthentication(authentication);
22301138f6824512025-06-04 02:03:13 +080069
22301126e1131602025-06-04 11:30:10 +080070 // 使用 MyBatis-Plus 查询
71 User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
22301138f6824512025-06-04 02:03:13 +080072
22301126e1131602025-06-04 11:30:10 +080073 System.out.println("Login successful for user: " + username);
74 return Result.ok(user);
75 } catch (AuthenticationException e) {
76 return Result.error("登录失败");
77 }
78 }
79
80 @PostMapping("/register")
81 @ApiOperation(value = "用户注册", notes = "使用用户信息进行注册")
82 public Result registerController(@RequestBody @ApiParam(value = "新用户信息", required = true) User newUser) {
83 if (userService.checkEmailExists(newUser.getEmail())) {
84 return Result.error( "邮箱已被使用,请使用其他邮箱注册或找回密码!");
85 }
86 boolean success = userService.preRegisterUser(newUser);
87 if (success) {
88 User responseUser = new User();
89 responseUser.setEmail(newUser.getEmail());
90 return Result.ok();
22301115cf6dba22025-03-25 19:06:21 +080091 } else {
22301126e1131602025-06-04 11:30:10 +080092 return Result.error("账号已存在或注册失败!");
22301115cf6dba22025-03-25 19:06:21 +080093 }
94 }
95
22301126e1131602025-06-04 11:30:10 +080096 public static class VerificationRequest {
97 private String email;
98 private String code;
22301115cf6dba22025-03-25 19:06:21 +080099
22301126e1131602025-06-04 11:30:10 +0800100 public String getEmail() { return email; }
101 public void setEmail(String email) { this.email = email; }
102 public String getCode() { return code; }
103 public void setCode(String code) { this.code = code; }
22301115cf6dba22025-03-25 19:06:21 +0800104 }
105
22301126e1131602025-06-04 11:30:10 +0800106 @PostMapping("/verify-code")
107 @ApiOperation(value = "验证邮箱验证码", notes = "验证用户邮箱的验证码")
108 public Result verifyEmailCode(@RequestBody @ApiParam(value = "验证请求信息", required = true) VerificationRequest verificationRequest) {
109 String email = verificationRequest.getEmail();
110 String code = verificationRequest.getCode();
111 boolean isVerified = userService.verifyEmail(email, code);
112 if (isVerified) {
113 return Result.ok();
22301115cf6dba22025-03-25 19:06:21 +0800114 } else {
22301126e1131602025-06-04 11:30:10 +0800115 return Result.error( "验证码错误或已过期!");
22301115cf6dba22025-03-25 19:06:21 +0800116 }
117 }
118
22301126e1131602025-06-04 11:30:10 +0800119 @Autowired
120 private EmailService emailService;
121
122 public static class EmailRequest {
123 private String email;
124 public String getEmail() { return email; }
125 public void setEmail(String email) { this.email = email; }
22301115cf6dba22025-03-25 19:06:21 +0800126 }
127
22301126e1131602025-06-04 11:30:10 +0800128 @PostMapping("/get-verification-email")
129 @ApiOperation(value = "发送验证邮件", notes = "通过电子邮件发送验证邮件")
130 public ResponseEntity<Result> sendVerificationEmail(@RequestBody @ApiParam(value = "发送验证请求", required = true) EmailRequest emailVerificationRequest) {
131 String email = emailVerificationRequest.getEmail();
132 User user = userMapper.selectOne(new QueryWrapper<User>().eq("email", email));
133 if (user == null) {
134 logger.error("未找到与该邮箱地址相关联的用户: {}", email);
135 return ResponseEntity.status(HttpStatus.BAD_REQUEST)
136 .body(Result.error("未找到与该邮箱地址相关联的用户"));
22301115cf6dba22025-03-25 19:06:21 +0800137 }
138
22301126e1131602025-06-04 11:30:10 +0800139 // 生成验证码
140 String token = RandomStringUtils.randomNumeric(6);
141 Instant expiryDate = Instant.now().plus(1, ChronoUnit.HOURS);
142 logger.info("生成的验证令牌: {}, 过期时间: {}", token, expiryDate);
143
144 VerificationToken verificationToken = new VerificationToken(token, user.getUsername(), email, user.getPassword(), expiryDate);
145
146 // 保存到 MyBatis-Plus 数据库
147 verificationTokenMapper.insert(verificationToken);
148
149 logger.info("验证令牌已保存,用户: {}", user.getUsername());
150 emailService.sendVerificationEmail(email, token);
151
152 return ResponseEntity.ok(Result.ok());
22301115cf6dba22025-03-25 19:06:21 +0800153 }
22301126e1131602025-06-04 11:30:10 +0800154 @PostMapping("/checkPassword")
155 public Result<String> checkPassword(@RequestParam Long userId, @RequestParam String password) {
156 boolean isPasswordCorrect = userService.checkPassword(userId, password);
157 if (isPasswordCorrect) {
158 return Result.ok();
159 } else {
160 return Result.error("原始密码输入错误");
161 }
162 }
163
164
165// @SaCheckLogin
166// @Operation(summary = "用户收藏列表", description = "获取用户收藏的种子列表-分页-排序")
167// @ApiResponse(responseCode = "0", description = "操作成功",
168// content = {@Content(mediaType = "application/json",
169// schema = @Schema(implementation = TorrentVO.class))
170// })
171// @PostMapping("/favorite/list")
172// public Result listFavorites(@RequestBody FavoriteParam param) {
173// if (param.getUserId() == null) {
174// return Result.error("缺少 userId");
175// }
176//
177// // 校验排序字段是否合理(可选)
178// param.validOrder(param.getOrderKey(TorrentEntity.class));
179//
180// PageUtil.startPage(param);
181//
182// List<TorrentEntity> list = favoriteService.getUserFavoritesPaged(param.getUserId());
183//
184// return Result.ok(list, PageUtil.getPage(list));
185// }
186//
187
YelinCuifdf4ed72025-05-26 11:49:36 +0800188
189
22301115cf6dba22025-03-25 19:06:21 +0800190}