add Notebook
This commit is contained in:
parent
f46f6d97e1
commit
717c3509b4
@ -87,6 +87,7 @@ public class AopLog {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取方法参数名和参数值
|
* 获取方法参数名和参数值
|
||||||
|
*
|
||||||
* @param joinPoint 切入点
|
* @param joinPoint 切入点
|
||||||
* @return 接口参数和参数值
|
* @return 接口参数和参数值
|
||||||
*/
|
*/
|
||||||
@ -112,6 +113,7 @@ public class AopLog {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取ip地址
|
* 获取ip地址
|
||||||
|
*
|
||||||
* @param request 请求体
|
* @param request 请求体
|
||||||
* @return 返回ip地址
|
* @return 返回ip地址
|
||||||
*/
|
*/
|
||||||
@ -150,6 +152,7 @@ public class AopLog {
|
|||||||
private static boolean isInvalidIp(String ip) {
|
private static boolean isInvalidIp(String ip) {
|
||||||
return ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip);
|
return ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@Builder
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
|||||||
@ -60,6 +60,7 @@ public class SecurityConfig {
|
|||||||
.authorizeHttpRequests(auth -> auth
|
.authorizeHttpRequests(auth -> auth
|
||||||
.requestMatchers("/auth/**").permitAll()
|
.requestMatchers("/auth/**").permitAll()
|
||||||
.requestMatchers("/auth/register").permitAll()
|
.requestMatchers("/auth/register").permitAll()
|
||||||
|
.requestMatchers("/api/**").permitAll()
|
||||||
// .requestMatchers("/user/**").permitAll()
|
// .requestMatchers("/user/**").permitAll()
|
||||||
.anyRequest().access((authenticationSupplier, requestAuthorizationContext) -> {
|
.anyRequest().access((authenticationSupplier, requestAuthorizationContext) -> {
|
||||||
HttpServletRequest request = requestAuthorizationContext.getRequest();
|
HttpServletRequest request = requestAuthorizationContext.getRequest();
|
||||||
|
|||||||
@ -63,6 +63,12 @@ public enum Status {
|
|||||||
/** 无法手动踢出自己,请尝试退出登录操作! */
|
/** 无法手动踢出自己,请尝试退出登录操作! */
|
||||||
KICKOUT_SELF(5004, "无法手动踢出自己,请尝试退出登录操作!"),
|
KICKOUT_SELF(5004, "无法手动踢出自己,请尝试退出登录操作!"),
|
||||||
|
|
||||||
|
/** 账号密码错误 */
|
||||||
|
USERNAME_OR_PASSWORD_ERROR(200, "账号密码错误"),
|
||||||
|
|
||||||
|
/** 账户已被锁定 */
|
||||||
|
ACCOUNT_LOCKED(200, "账户已被锁定"),
|
||||||
|
|
||||||
/** 注册成功! */
|
/** 注册成功! */
|
||||||
REGISTER_SUCCESS(200, "注册成功");
|
REGISTER_SUCCESS(200, "注册成功");
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,25 @@
|
|||||||
package asia.yulinling.workflow.controller;
|
package asia.yulinling.workflow.controller;
|
||||||
|
|
||||||
|
import asia.yulinling.workflow.constant.Status;
|
||||||
import asia.yulinling.workflow.dto.request.LoginRequest;
|
import asia.yulinling.workflow.dto.request.LoginRequest;
|
||||||
import asia.yulinling.workflow.dto.request.RegisterRequest;
|
import asia.yulinling.workflow.dto.request.RegisterRequest;
|
||||||
import asia.yulinling.workflow.model.ApiResponse;
|
import asia.yulinling.workflow.model.ApiResponse;
|
||||||
import asia.yulinling.workflow.model.vo.LoginVO;
|
import asia.yulinling.workflow.model.vo.LoginVO;
|
||||||
import asia.yulinling.workflow.model.vo.RegisterVO;
|
import asia.yulinling.workflow.model.vo.RegisterVO;
|
||||||
import asia.yulinling.workflow.service.AuthService;
|
import asia.yulinling.workflow.service.AuthService;
|
||||||
|
import asia.yulinling.workflow.utils.JwtUtil;
|
||||||
|
import com.alibaba.druid.support.spring.stat.annotation.Stat;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
import org.springframework.security.authentication.LockedException;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@ -27,15 +39,33 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
public class AuthController {
|
public class AuthController {
|
||||||
|
|
||||||
private final AuthService authService;
|
private final AuthService authService;
|
||||||
|
private final JwtUtil jwtUtil;
|
||||||
|
private final AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
public ApiResponse<LoginVO> login(@RequestBody LoginRequest loginRequest) {
|
public ResponseEntity<ApiResponse<LoginVO>> login(@Valid @RequestBody LoginRequest loginRequest) {
|
||||||
return authService.login(loginRequest);
|
try {
|
||||||
|
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
|
||||||
|
loginRequest.getUsername(), loginRequest.getPassword()
|
||||||
|
));
|
||||||
|
|
||||||
|
LoginVO loginVO = authService.login(authentication, loginRequest.getRememberMe());
|
||||||
|
return ResponseEntity.ok().body(ApiResponse.ofStatus(Status.LOGIN_SUCCESS, loginVO));
|
||||||
|
} catch (BadCredentialsException e) {
|
||||||
|
return ResponseEntity.ok().body(ApiResponse.ofStatus(Status.USERNAME_PASSWORD_ERROR));
|
||||||
|
} catch (LockedException e) {
|
||||||
|
return ResponseEntity.ok().body(ApiResponse.ofStatus(Status.ACCOUNT_LOCKED));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/logout")
|
@PostMapping("/logout")
|
||||||
public ApiResponse<?> logout(HttpServletRequest request) throws SecurityException {
|
public ApiResponse<?> logout(HttpServletRequest request) {
|
||||||
return authService.logout(request);
|
String token = jwtUtil.getTokenFromRequest(request);
|
||||||
|
if (token == null || token.isBlank()) {
|
||||||
|
return ApiResponse.ofStatus(Status.TOKEN_EXPIRED);
|
||||||
|
}
|
||||||
|
authService.logout(token);
|
||||||
|
return ApiResponse.ofStatus(Status.SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/register")
|
@PostMapping("/register")
|
||||||
|
|||||||
@ -0,0 +1,10 @@
|
|||||||
|
package asia.yulinling.workflow.controller;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RequestMapping("/api22")
|
||||||
|
public class NoteController {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package asia.yulinling.workflow.controller;
|
||||||
|
|
||||||
|
import asia.yulinling.workflow.constant.Status;
|
||||||
|
import asia.yulinling.workflow.dto.request.NotebookRequest;
|
||||||
|
import asia.yulinling.workflow.model.ApiResponse;
|
||||||
|
import asia.yulinling.workflow.model.entity.Notebook;
|
||||||
|
import asia.yulinling.workflow.service.NotebookService;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RequestMapping("/api")
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class NotebookController {
|
||||||
|
private final NotebookService notebookService;
|
||||||
|
|
||||||
|
@PostMapping("/notebooks")
|
||||||
|
public ApiResponse<?> notebooks(@Valid @RequestBody NotebookRequest notebookRequest) {
|
||||||
|
Notebook notebook = new Notebook();
|
||||||
|
BeanUtils.copyProperties(notebookRequest, notebook);
|
||||||
|
notebookService.addNotebook(notebook);
|
||||||
|
return ApiResponse.ofStatus(Status.SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/notebooks")
|
||||||
|
public void notebooksGet() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/notebooks/{id}")
|
||||||
|
public void notebooksGet(@PathVariable String id) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/notebooks/{id}")
|
||||||
|
public void notebooksPut(@PathVariable String id) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/notebooks/{id}")
|
||||||
|
public void notebooksDelete(@PathVariable String id) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -37,6 +37,7 @@ public class TestController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试方法 GET
|
* 测试方法 GET
|
||||||
|
*
|
||||||
* @param who 测试参数
|
* @param who 测试参数
|
||||||
* @return {@link Dict}
|
* @return {@link Dict}
|
||||||
*/
|
*/
|
||||||
@ -47,6 +48,7 @@ public class TestController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试方法 POST
|
* 测试方法 POST
|
||||||
|
*
|
||||||
* @param map 请求的json参数
|
* @param map 请求的json参数
|
||||||
* @return {@link Dict}
|
* @return {@link Dict}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -0,0 +1,29 @@
|
|||||||
|
package asia.yulinling.workflow.dto.request;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class NotebookRequest {
|
||||||
|
/**
|
||||||
|
* 用户id,外键
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "创建用户为空")
|
||||||
|
Long userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 笔记本名称
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "笔记本名称为空")
|
||||||
|
String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 笔记本颜色标识
|
||||||
|
*/
|
||||||
|
String color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 笔记本图标标识
|
||||||
|
*/
|
||||||
|
String icon;
|
||||||
|
}
|
||||||
16
src/main/java/asia/yulinling/workflow/mapper/NoteMapper.java
Normal file
16
src/main/java/asia/yulinling/workflow/mapper/NoteMapper.java
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package asia.yulinling.workflow.mapper;
|
||||||
|
|
||||||
|
import asia.yulinling.workflow.model.entity.Note;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 笔记本Mapper
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author YLL
|
||||||
|
* @since 2025/7/23
|
||||||
|
*/
|
||||||
|
public interface NoteMapper extends BaseMapper<Note> {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package asia.yulinling.workflow.mapper;
|
||||||
|
|
||||||
|
import asia.yulinling.workflow.model.entity.Notebook;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 笔记本集合Mapper
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author YLL
|
||||||
|
* @since 2025/6/13
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
@Component
|
||||||
|
public interface NotebookMapper extends BaseMapper<Notebook> {
|
||||||
|
}
|
||||||
99
src/main/java/asia/yulinling/workflow/model/entity/Note.java
Normal file
99
src/main/java/asia/yulinling/workflow/model/entity/Note.java
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
package asia.yulinling.workflow.model.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Note {
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户id,外键
|
||||||
|
*/
|
||||||
|
@TableField("user_id")
|
||||||
|
Long userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 笔记本id,外键
|
||||||
|
*/
|
||||||
|
@TableField("notebook_id")
|
||||||
|
Long notebookId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 笔记标题
|
||||||
|
*/
|
||||||
|
String title;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 笔记本内容
|
||||||
|
*/
|
||||||
|
String content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 笔记本内容预览,截取前200字符
|
||||||
|
*/
|
||||||
|
@TableField("preview_text")
|
||||||
|
String previewText;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 笔记内容字数统计
|
||||||
|
*/
|
||||||
|
@TableField("word_count")
|
||||||
|
Integer wordCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否置顶显示
|
||||||
|
*/
|
||||||
|
@TableField("is_pinned")
|
||||||
|
Boolean isPinned;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否归档(不显示在默认列表中)
|
||||||
|
*/
|
||||||
|
@TableField("is_archived")
|
||||||
|
Boolean isArchived;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否标记为收藏
|
||||||
|
*/
|
||||||
|
@TableField("is_favorite")
|
||||||
|
Boolean isFavorite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否需要密码查看
|
||||||
|
*/
|
||||||
|
@TableField("password_protected")
|
||||||
|
Boolean passwordProtected;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@TableField("create_time")
|
||||||
|
Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@TableField("update_time")
|
||||||
|
Date updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提醒时间
|
||||||
|
*/
|
||||||
|
@TableField("reminder")
|
||||||
|
Date reminderTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 笔记封面图片url
|
||||||
|
*/
|
||||||
|
@TableField("cover_image")
|
||||||
|
String coverImage;
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
package asia.yulinling.workflow.model.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("wk_notebooks")
|
||||||
|
public class Notebook {
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户id,外键
|
||||||
|
*/
|
||||||
|
@TableField("user_id")
|
||||||
|
Long userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 笔记本名称
|
||||||
|
*/
|
||||||
|
String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 笔记本颜色标识
|
||||||
|
*/
|
||||||
|
String color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 笔记本图标标识
|
||||||
|
*/
|
||||||
|
String icon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@TableField("created_at")
|
||||||
|
Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@TableField("update_at")
|
||||||
|
Date updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 笔记本内的笔记数量
|
||||||
|
*/
|
||||||
|
Integer notesCount;
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@ import asia.yulinling.workflow.model.ApiResponse;
|
|||||||
import asia.yulinling.workflow.model.vo.LoginVO;
|
import asia.yulinling.workflow.model.vo.LoginVO;
|
||||||
import asia.yulinling.workflow.model.vo.RegisterVO;
|
import asia.yulinling.workflow.model.vo.RegisterVO;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@ -19,18 +20,16 @@ public interface AuthService {
|
|||||||
/**
|
/**
|
||||||
* 登录系统
|
* 登录系统
|
||||||
*
|
*
|
||||||
* @param loginRequest 登录请求
|
* @param authentication 登录信息
|
||||||
* @return token
|
|
||||||
*/
|
*/
|
||||||
ApiResponse<LoginVO> login(LoginRequest loginRequest);
|
LoginVO login(Authentication authentication, boolean rememberMe);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 退出登录
|
* 退出登录
|
||||||
*
|
*
|
||||||
* @param request 退出登录请求
|
* @param token 登录信息
|
||||||
* @return 请求结果
|
|
||||||
*/
|
*/
|
||||||
ApiResponse<?> logout(HttpServletRequest request) throws SecurityException;
|
void logout(String token) throws SecurityException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册
|
* 注册
|
||||||
|
|||||||
@ -0,0 +1,5 @@
|
|||||||
|
package asia.yulinling.workflow.service;
|
||||||
|
|
||||||
|
public interface NoteService {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package asia.yulinling.workflow.service;
|
||||||
|
|
||||||
|
import asia.yulinling.workflow.model.entity.Notebook;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public interface NotebookService {
|
||||||
|
/**
|
||||||
|
* 添加笔记本
|
||||||
|
*
|
||||||
|
* @param notebook 笔记本
|
||||||
|
*/
|
||||||
|
void addNotebook(Notebook notebook);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除笔记本
|
||||||
|
*
|
||||||
|
* @param id 笔记本id
|
||||||
|
*/
|
||||||
|
void deleteNotebook(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新笔记本
|
||||||
|
*
|
||||||
|
* @param notebook 笔记本
|
||||||
|
*/
|
||||||
|
void updateNotebook(Notebook notebook);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取笔记本内容
|
||||||
|
*
|
||||||
|
* @param id 笔记本id
|
||||||
|
* @return 笔记本
|
||||||
|
*/
|
||||||
|
Notebook getNotebook(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取笔记本列表
|
||||||
|
*
|
||||||
|
* @return 笔记本列表
|
||||||
|
*/
|
||||||
|
List<Notebook> getNotebookList();
|
||||||
|
}
|
||||||
@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -47,46 +48,36 @@ public class AuthServiceImpl implements AuthService {
|
|||||||
/**
|
/**
|
||||||
* 登录系统
|
* 登录系统
|
||||||
*
|
*
|
||||||
* @param loginRequest 登录请求
|
* @param authentication 登录信息
|
||||||
* @return token
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<LoginVO> login(LoginRequest loginRequest) {
|
public LoginVO login(Authentication authentication, boolean rememberMe) {
|
||||||
|
|
||||||
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
|
|
||||||
loginRequest.getUsername(), loginRequest.getPassword()
|
|
||||||
));
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
|
||||||
|
|
||||||
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
|
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
|
||||||
|
|
||||||
String accessToken = jwtUtil.generateToken(authentication, false);
|
String accessToken = jwtUtil.generateToken(authentication, rememberMe);
|
||||||
Long expiresIn = jwtUtil.getExpiresIn(loginRequest.getRememberMe());
|
Long expiresIn = jwtUtil.getExpiresIn(rememberMe);
|
||||||
|
|
||||||
LoginVO loginVO = LoginVO.builder()
|
log.info("用户登录成功: {}", userPrincipal.getUsername());
|
||||||
|
return LoginVO.builder()
|
||||||
.userId(userPrincipal.getId())
|
.userId(userPrincipal.getId())
|
||||||
.username(userPrincipal.getUsername())
|
.username(userPrincipal.getUsername())
|
||||||
.accessToken(accessToken)
|
.accessToken(accessToken)
|
||||||
.expiresIn(expiresIn)
|
.expiresIn(expiresIn)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return ApiResponse.ofStatus(Status.LOGIN_SUCCESS, loginVO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 退出登录
|
* 退出登录
|
||||||
*
|
*
|
||||||
* @param request 退出登录请求
|
* @param token 登录信息
|
||||||
* @return 请求结果
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<?> logout(HttpServletRequest request) throws SecurityException {
|
public void logout(String token) throws SecurityException {
|
||||||
try {
|
try {
|
||||||
jwtUtil.invalidateToken(request);
|
jwtUtil.invalidateToken(token);
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
log.info("invalidateToken: {}", e.getMessage());
|
log.info("invalidateToken: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
return ApiResponse.ofStatus(Status.LOGOUT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -0,0 +1,10 @@
|
|||||||
|
package asia.yulinling.workflow.service.impl;
|
||||||
|
|
||||||
|
import asia.yulinling.workflow.service.NoteService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class NoteServiceImpl implements NoteService {
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package asia.yulinling.workflow.service.impl;
|
||||||
|
|
||||||
|
import asia.yulinling.workflow.mapper.NotebookMapper;
|
||||||
|
import asia.yulinling.workflow.model.entity.Notebook;
|
||||||
|
import asia.yulinling.workflow.service.NotebookService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class NotebookServiceImpl implements NotebookService {
|
||||||
|
private final NotebookMapper notebookMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addNotebook(Notebook notebook) {
|
||||||
|
if (notebook == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
notebookMapper.insert(notebook);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteNotebook(Long id) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNotebook(Notebook notebook) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Notebook getNotebook(Long id) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Notebook> getNotebookList() {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -214,10 +214,9 @@ public class JwtUtil {
|
|||||||
/**
|
/**
|
||||||
* 设置Token过期
|
* 设置Token过期
|
||||||
*
|
*
|
||||||
* @param request 请求
|
* @param token 登录信息
|
||||||
*/
|
*/
|
||||||
public void invalidateToken(HttpServletRequest request) {
|
public void invalidateToken(String token) {
|
||||||
String token = getTokenFromRequest(request);
|
|
||||||
String username = parseToken(token).getSubject();
|
String username = parseToken(token).getSubject();
|
||||||
stringRedisTemplate.delete(Const.REDIS_JWT_KEY_PREFIX + username);
|
stringRedisTemplate.delete(Const.REDIS_JWT_KEY_PREFIX + username);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,7 +86,7 @@ CREATE TABLE `wk_role_user`
|
|||||||
DROP TABLE IF EXISTS `wk_notebooks`;
|
DROP TABLE IF EXISTS `wk_notebooks`;
|
||||||
CREATE TABLE `wk_notebooks`
|
CREATE TABLE `wk_notebooks`
|
||||||
(
|
(
|
||||||
id VARCHAR(36) PRIMARY KEY, -- 笔记本唯一标识
|
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '笔记本主键', -- 笔记本唯一标识
|
||||||
user_id bigint(64) NOT NULL COMMENT '所属用户ID', -- 笔记本所有者
|
user_id bigint(64) NOT NULL COMMENT '所属用户ID', -- 笔记本所有者
|
||||||
name VARCHAR(100) NOT NULL COMMENT '笔记本名称', -- 显示名称
|
name VARCHAR(100) NOT NULL COMMENT '笔记本名称', -- 显示名称
|
||||||
color VARCHAR(20) COMMENT '笔记本颜色标记,用于UI显示', -- 如#FF0000
|
color VARCHAR(20) COMMENT '笔记本颜色标记,用于UI显示', -- 如#FF0000
|
||||||
@ -96,14 +96,14 @@ CREATE TABLE `wk_notebooks`
|
|||||||
notes_count INT DEFAULT 0 COMMENT '包含的笔记数量', -- 用于快速统计
|
notes_count INT DEFAULT 0 COMMENT '包含的笔记数量', -- 用于快速统计
|
||||||
FOREIGN KEY (user_id) REFERENCES wk_user (id) ON DELETE CASCADE,
|
FOREIGN KEY (user_id) REFERENCES wk_user (id) ON DELETE CASCADE,
|
||||||
CONSTRAINT chk_notebook_name CHECK (name <> '') -- 名称不能为空
|
CONSTRAINT chk_notebook_name CHECK (name <> '') -- 名称不能为空
|
||||||
) COMMENT '用户笔记本分类表,用于组织管理笔记';
|
) COMMENT '用户笔记本';
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `wk_notes`;
|
DROP TABLE IF EXISTS `wk_notes`;
|
||||||
CREATE TABLE `wk_notes`
|
CREATE TABLE `wk_notes`
|
||||||
(
|
(
|
||||||
id VARCHAR(36) PRIMARY KEY COMMENT '笔记唯一标识',
|
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '笔记唯一标识',
|
||||||
user_id bigint(64) NOT NULL COMMENT '作者用户ID',
|
user_id bigint(64) NOT NULL COMMENT '作者用户ID',
|
||||||
notebook_id VARCHAR(36) COMMENT '所属笔记本ID,可为空',
|
notebook_id BIGINT COMMENT '所属笔记本ID,可为空',
|
||||||
title VARCHAR(255) COMMENT '笔记标题,可为空(自动提取内容首行)',
|
title VARCHAR(255) COMMENT '笔记标题,可为空(自动提取内容首行)',
|
||||||
content TEXT NOT NULL COMMENT '笔记正文内容,支持Markdown格式',
|
content TEXT NOT NULL COMMENT '笔记正文内容,支持Markdown格式',
|
||||||
preview_text VARCHAR(200) COMMENT '内容预览,自动提取前200字符',
|
preview_text VARCHAR(200) COMMENT '内容预览,自动提取前200字符',
|
||||||
@ -124,7 +124,7 @@ CREATE TABLE `wk_notes`
|
|||||||
DROP TABLE IF EXISTS `wk_tags`;
|
DROP TABLE IF EXISTS `wk_tags`;
|
||||||
CREATE TABLE `wk_tags`
|
CREATE TABLE `wk_tags`
|
||||||
(
|
(
|
||||||
id VARCHAR(36) PRIMARY KEY COMMENT '标签唯一标识',
|
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '标签唯一标识',
|
||||||
user_id bigint(64) NOT NULL COMMENT '所属用户ID',
|
user_id bigint(64) NOT NULL COMMENT '所属用户ID',
|
||||||
name VARCHAR(50) NOT NULL COMMENT '标签名称',
|
name VARCHAR(50) NOT NULL COMMENT '标签名称',
|
||||||
color VARCHAR(20) COMMENT '标签颜色,用于UI显示',
|
color VARCHAR(20) COMMENT '标签颜色,用于UI显示',
|
||||||
@ -138,8 +138,8 @@ CREATE TABLE `wk_tags`
|
|||||||
DROP TABLE IF EXISTS `wk_note_tags`;
|
DROP TABLE IF EXISTS `wk_note_tags`;
|
||||||
CREATE TABLE `wk_note_tags`
|
CREATE TABLE `wk_note_tags`
|
||||||
(
|
(
|
||||||
note_id VARCHAR(36) NOT NULL COMMENT '关联的笔记ID',
|
note_id BIGINT NOT NULL COMMENT '关联的笔记ID',
|
||||||
tag_id VARCHAR(36) NOT NULL COMMENT '关联的标签ID',
|
tag_id BIGINT NOT NULL COMMENT '关联的标签ID',
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '关联创建时间',
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '关联创建时间',
|
||||||
PRIMARY KEY (note_id, tag_id) COMMENT '联合主键,防止重复关联',
|
PRIMARY KEY (note_id, tag_id) COMMENT '联合主键,防止重复关联',
|
||||||
FOREIGN KEY (note_id) REFERENCES wk_notes (id) ON DELETE CASCADE,
|
FOREIGN KEY (note_id) REFERENCES wk_notes (id) ON DELETE CASCADE,
|
||||||
@ -149,8 +149,8 @@ CREATE TABLE `wk_note_tags`
|
|||||||
DROP TABLE IF EXISTS `wk_attachments`;
|
DROP TABLE IF EXISTS `wk_attachments`;
|
||||||
CREATE TABLE wk_attachments
|
CREATE TABLE wk_attachments
|
||||||
(
|
(
|
||||||
id VARCHAR(36) PRIMARY KEY COMMENT '附件唯一标识',
|
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '附件唯一标识',
|
||||||
note_id VARCHAR(36) NOT NULL COMMENT '所属笔记ID',
|
note_id BIGINT NOT NULL COMMENT '所属笔记ID',
|
||||||
file_path VARCHAR(255) NOT NULL COMMENT '文件存储路径',
|
file_path VARCHAR(255) NOT NULL COMMENT '文件存储路径',
|
||||||
file_type VARCHAR(50) NOT NULL COMMENT '文件MIME类型,如image/png',
|
file_type VARCHAR(50) NOT NULL COMMENT '文件MIME类型,如image/png',
|
||||||
file_name VARCHAR(255) NOT NULL COMMENT '原始文件名',
|
file_name VARCHAR(255) NOT NULL COMMENT '原始文件名',
|
||||||
|
|||||||
@ -1 +1,6 @@
|
|||||||
SELECT * FROM wk_notes;
|
SELECT * FROM wk_notes;
|
||||||
|
SELECT * FROM wk_attachments;
|
||||||
|
SELECT * FROM wk_note_tags;
|
||||||
|
SELECT * FROM wk_tags;
|
||||||
|
SELECT * FROM wk_notebooks;
|
||||||
|
|
||||||
|
|||||||
5
src/main/resources/mapper/NoteMapper.xml
Normal file
5
src/main/resources/mapper/NoteMapper.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="asia.yulinling.workflow.mapper.NoteMapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
5
src/main/resources/mapper/NotebookMapper.xml
Normal file
5
src/main/resources/mapper/NotebookMapper.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="asia.yulinling.workflow.mapper.NotebookMapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
Loading…
Reference in New Issue
Block a user