feat: adding deps and adding base framework
This commit is contained in:
parent
8a29b3a815
commit
40970c1364
@ -28,11 +28,11 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
implementation("org.springframework.boot:spring-boot-starter-actuator")
|
||||
implementation("org.springframework.boot:spring-boot-starter-data-redis")
|
||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||
implementation("org.springframework.boot:spring-boot-starter-websocket")
|
||||
implementation("org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.4")
|
||||
implementation("org.mmga:make-minecraft-great-again-spring-boot-starter:0.0.2-20241217.115150-5")
|
||||
implementation("org.mmga:make-minecraft-great-again-spring-boot-starter:0.0.5-20241219.044545-4")
|
||||
implementation("com.mybatis-flex:mybatis-flex-spring-boot-starter:1.10.2")
|
||||
annotationProcessor("com.mybatis-flex:mybatis-flex-processor:1.10.2")
|
||||
// https://mvnrepository.com/artifact/commons-codec/commons-codec
|
||||
implementation("commons-codec:commons-codec:1.16.1")
|
||||
compileOnly("org.projectlombok:lombok")
|
||||
runtimeOnly("com.mysql:mysql-connector-j")
|
||||
annotationProcessor("org.projectlombok:lombok")
|
||||
|
@ -1,5 +1,8 @@
|
||||
package org.blue.club;
|
||||
|
||||
import com.mybatisflex.core.audit.AuditManager;
|
||||
import com.mybatisflex.core.audit.ConsoleMessageCollector;
|
||||
import com.mybatisflex.core.audit.MessageCollector;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@ -7,6 +10,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
public class ClubApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
//开启审计功能
|
||||
AuditManager.setAuditEnable(true);
|
||||
MessageCollector collector = new ConsoleMessageCollector();
|
||||
AuditManager.setMessageCollector(collector);
|
||||
SpringApplication.run(ClubApplication.class, args);
|
||||
}
|
||||
|
||||
|
22
src/main/java/org/blue/club/annotation/Auth.java
Normal file
22
src/main/java/org/blue/club/annotation/Auth.java
Normal file
@ -0,0 +1,22 @@
|
||||
package org.blue.club.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.PARAMETER, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Auth {
|
||||
long[] permissions() default {};
|
||||
|
||||
LogicType permissionType() default LogicType.ANY;
|
||||
|
||||
long[] auths() default {};
|
||||
|
||||
LogicType authType() default LogicType.ANY;
|
||||
|
||||
enum LogicType {
|
||||
ANY, ALL
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package org.blue.club.configuration;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.blue.club.annotation.Auth;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class AuthConfiguration {
|
||||
|
||||
@Bean
|
||||
public Class<? extends Annotation> authAnnotation() {
|
||||
return Auth.class;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package org.blue.club.configuration;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.blue.club.annotation.Auth;
|
||||
import org.blue.club.dao.UserDao;
|
||||
import org.blue.club.entities.dto.User;
|
||||
import org.blue.club.entities.vo.UserVo;
|
||||
import org.mmga.spring.boot.starter.componet.AuthorizationHandler;
|
||||
import org.mmga.spring.boot.starter.componet.JwtUtils;
|
||||
import org.mmga.spring.boot.starter.entities.Result;
|
||||
import org.mmga.spring.boot.starter.exception.AuthorizationException;
|
||||
import org.mmga.spring.boot.starter.utils.VoUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CustomAuthorizationHandler implements AuthorizationHandler<User> {
|
||||
private final JwtUtils jwtUtils;
|
||||
private final UserDao userDao;
|
||||
private final VoUtils voUtils;
|
||||
|
||||
@Override
|
||||
public Optional<User> auth(String token, Annotation ann) {
|
||||
if (ann instanceof Auth auth) {
|
||||
Optional<Long> i = jwtUtils.verifyToken(token);
|
||||
if (i.isEmpty()) throw new AuthorizationException(Result.failed("token错误!"));
|
||||
Long userId = i.get();
|
||||
UserVo userVo = userDao.selectOneWithRelationsById(userId);
|
||||
if (userVo == null) throw new AuthorizationException(Result.failed("用户不存在!"));
|
||||
User user = voUtils.vo2DtoSafe(userVo, User.class);
|
||||
|
||||
return Optional.ofNullable(user);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
@ -1,19 +1,100 @@
|
||||
package org.blue.club.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.mmga.spring.boot.starter.componet.JwtUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.blue.club.annotation.Auth;
|
||||
import org.blue.club.entities.dto.User;
|
||||
import org.blue.club.services.UserServices;
|
||||
import org.mmga.spring.boot.starter.entities.PagerData;
|
||||
import org.mmga.spring.boot.starter.entities.Result;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/user")
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "用户相关接口")
|
||||
public class UserController {
|
||||
private final JwtUtils jwtUtils;
|
||||
private final UserServices userServices;
|
||||
|
||||
@GetMapping("/demo")
|
||||
public String demo() {
|
||||
return jwtUtils.createToken(111);
|
||||
@PostMapping("/login")
|
||||
@Operation(description = "用户登录", responses = {@ApiResponse(description = "返回是否登录成功", responseCode = "200")})
|
||||
public Result<Boolean> login(@RequestBody UserLoginVo user, HttpServletResponse response) {
|
||||
return userServices.login(user, response);
|
||||
}
|
||||
|
||||
@PutMapping("/create")
|
||||
@Operation(description = "创建用户", responses = {@ApiResponse(description = "返回创建后的用户")})
|
||||
public Result<Boolean> createUser(@RequestBody UserRegVo user, HttpServletResponse response) {
|
||||
return userServices.createUser(user, response);
|
||||
}
|
||||
|
||||
@GetMapping("/info")
|
||||
@Operation(description = "获取用户信息")
|
||||
public Result<User> getUserInfo(@RequestAttribute("user") int userId) {
|
||||
return userServices.getUserInfo(userId);
|
||||
}
|
||||
|
||||
@GetMapping("/all")
|
||||
@Operation(description = "获取所有用户信息(分页)")
|
||||
@Auth(permissions = {4})
|
||||
public Result<PagerData<User>> getAllUserInfo(@RequestParam("num") int num, @RequestParam("page") int page) {
|
||||
return userServices.getAllUserInfo(num, page);
|
||||
}
|
||||
|
||||
@PutMapping("/rename")
|
||||
@Operation(description = "修改用户名")
|
||||
@Auth
|
||||
public Result<Boolean> changeUsername(@RequestBody UserRenameVo renameVo, @Auth User user) {
|
||||
return userServices.changeUsername(renameVo, user);
|
||||
}
|
||||
|
||||
@PutMapping("/password")
|
||||
@Operation(description = "修改密码")
|
||||
public Result<Boolean> changePassword(@RequestBody UserChangePasswordVo changePasswordVo, @Auth User user) {
|
||||
return userServices.changePassword(changePasswordVo, user);
|
||||
}
|
||||
|
||||
@PutMapping("/auth")
|
||||
@Operation(description = "修改用户权限组")
|
||||
@Auth(permissions = {4})
|
||||
public Result<Boolean> changeAuth(@RequestBody UserChangeAuthVo userChangeAuthVo) {
|
||||
return userServices.changeAuth(userChangeAuthVo);
|
||||
}
|
||||
|
||||
@PostMapping("/avatar")
|
||||
@Operation(description = "上传头像")
|
||||
public Result<String> changeAvatar(MultipartFile file, @Auth User user) {
|
||||
return userServices.changeAvatar(file, userId);
|
||||
}
|
||||
|
||||
@PutMapping("/avatar")
|
||||
@Operation(description = "修改用户头像")
|
||||
public Result<Boolean> changeAvatar(@RequestParam("code") @Schema(description = "修改头像操作码,可以通过将图片文件上传至") String avatarOperationCode, @Auth User user) {
|
||||
return userServices.changeAvatar(avatarOperationCode, user);
|
||||
}
|
||||
|
||||
@GetMapping("/verify")
|
||||
@Operation(description = "获取验证码")
|
||||
public Result<VerifyResponseVo> generatorVerifyCode() {
|
||||
return userServices.getVerifyCode();
|
||||
}
|
||||
|
||||
@GetMapping("/avatar/{sha1}")
|
||||
@Operation(description = "获取头像文件")
|
||||
public void getAvatar(HttpServletResponse response, @Schema(description = "头像文件SHA1值") @PathVariable("sha1") String sha1) {
|
||||
userServices.getAvatar(response, sha1);
|
||||
}
|
||||
|
||||
@GetMapping("/info/{id}")
|
||||
@Operation(description = "获取简略用户信息")
|
||||
public Result<User> getSimpleInfo(@PathVariable("id") int userId) {
|
||||
return userServices.getUserInfo(userId);
|
||||
}
|
||||
}
|
||||
|
9
src/main/java/org/blue/club/dao/UserDao.java
Normal file
9
src/main/java/org/blue/club/dao/UserDao.java
Normal file
@ -0,0 +1,9 @@
|
||||
package org.blue.club.dao;
|
||||
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.blue.club.entities.vo.UserVo;
|
||||
|
||||
@Mapper
|
||||
public interface UserDao extends BaseMapper<UserVo> {
|
||||
}
|
29
src/main/java/org/blue/club/entities/dto/User.java
Normal file
29
src/main/java/org/blue/club/entities/dto/User.java
Normal file
@ -0,0 +1,29 @@
|
||||
package org.blue.club.entities.dto;
|
||||
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.RelationManyToOne;
|
||||
import jakarta.annotation.Nullable;
|
||||
import lombok.Data;
|
||||
import org.blue.club.entities.vo.AuthVo;
|
||||
import org.blue.club.entities.vo.ClubVo;
|
||||
import org.mmga.spring.boot.starter.interfaces.IdHolder;
|
||||
|
||||
@Data
|
||||
public class User implements IdHolder {
|
||||
@Id
|
||||
private Long id;
|
||||
private String name;
|
||||
@Nullable
|
||||
private String avatar;
|
||||
private AuthVo auths;
|
||||
private ClubVo club;
|
||||
private AuthVo clubAuth;
|
||||
|
||||
public boolean hasPermission(Long permissionId) {
|
||||
return clubAuth.hasPermission(permissionId) || auths.hasPermission(permissionId);
|
||||
}
|
||||
|
||||
public boolean isAuth(Long authId) {
|
||||
return (auths != null && authId.equals(auths.getId())) || (clubAuth != null && authId.equals(clubAuth.getId()));
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package org.blue.club.entities.dto.req;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(name = "登录请求体")
|
||||
public record LoginRequest(@Schema(description = "用户名") String username,
|
||||
@Schema(description = "使用MD5摘要过后的密码hex") String password) {
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package org.blue.club.entities.vo;
|
||||
|
||||
import com.mybatisflex.annotation.Column;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Table("auth_permission")
|
||||
public class AuthPermissionVo extends BaseVo {
|
||||
@Column("auth_id")
|
||||
private Long authId;
|
||||
@Column("permission_id")
|
||||
private Long permissionId;
|
||||
}
|
27
src/main/java/org/blue/club/entities/vo/AuthVo.java
Normal file
27
src/main/java/org/blue/club/entities/vo/AuthVo.java
Normal file
@ -0,0 +1,27 @@
|
||||
package org.blue.club.entities.vo;
|
||||
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.RelationManyToMany;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Table("auth")
|
||||
@Data
|
||||
public class AuthVo extends BaseVo {
|
||||
@Id
|
||||
private Long id;
|
||||
private String name;
|
||||
@RelationManyToMany(joinTable = "auth_permission",
|
||||
selfField = "id", joinSelfColumn = "auth_id",
|
||||
targetField = "id", joinTargetColumn = "permission_id"
|
||||
)
|
||||
private List<PermissionVo> permissions;
|
||||
|
||||
public boolean hasPermission(Long permissionId) {
|
||||
return permissions.stream().anyMatch(p -> permissionId.equals(p.getId()));
|
||||
}
|
||||
}
|
12
src/main/java/org/blue/club/entities/vo/BaseVo.java
Normal file
12
src/main/java/org/blue/club/entities/vo/BaseVo.java
Normal file
@ -0,0 +1,12 @@
|
||||
package org.blue.club.entities.vo;
|
||||
|
||||
import com.mybatisflex.annotation.Column;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class BaseVo {
|
||||
@Column(value = "create_time", onUpdateValue = "now()", onInsertValue = "now()")
|
||||
protected Date createTime;
|
||||
@Column(value = "update_time", onUpdateValue = "now()", onInsertValue = "now()")
|
||||
protected Date updateTime;
|
||||
}
|
18
src/main/java/org/blue/club/entities/vo/ClubUserAuthVo.java
Normal file
18
src/main/java/org/blue/club/entities/vo/ClubUserAuthVo.java
Normal file
@ -0,0 +1,18 @@
|
||||
package org.blue.club.entities.vo;
|
||||
|
||||
import com.mybatisflex.annotation.Column;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Table("club_user_auth")
|
||||
@Data
|
||||
public class ClubUserAuthVo extends BaseVo {
|
||||
@Column("user_id")
|
||||
private Long userId;
|
||||
@Column("club_id")
|
||||
private Long clubId;
|
||||
@Column("auth_id")
|
||||
private Long authId;
|
||||
}
|
16
src/main/java/org/blue/club/entities/vo/ClubVo.java
Normal file
16
src/main/java/org/blue/club/entities/vo/ClubVo.java
Normal file
@ -0,0 +1,16 @@
|
||||
package org.blue.club.entities.vo;
|
||||
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Table("club")
|
||||
public class ClubVo extends BaseVo {
|
||||
@Id
|
||||
private Long id;
|
||||
private String name;
|
||||
private String commit;
|
||||
}
|
15
src/main/java/org/blue/club/entities/vo/PermissionVo.java
Normal file
15
src/main/java/org/blue/club/entities/vo/PermissionVo.java
Normal file
@ -0,0 +1,15 @@
|
||||
package org.blue.club.entities.vo;
|
||||
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Table("permission")
|
||||
@Data
|
||||
public class PermissionVo extends BaseVo {
|
||||
@Id
|
||||
private Long id;
|
||||
private String name;
|
||||
}
|
30
src/main/java/org/blue/club/entities/vo/UserVo.java
Normal file
30
src/main/java/org/blue/club/entities/vo/UserVo.java
Normal file
@ -0,0 +1,30 @@
|
||||
package org.blue.club.entities.vo;
|
||||
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.RelationManyToOne;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import jakarta.annotation.Nullable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.mmga.spring.boot.starter.annotation.VoIgnore;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Table("user")
|
||||
public class UserVo extends BaseVo {
|
||||
@Id
|
||||
private Long id;
|
||||
private String name;
|
||||
@VoIgnore
|
||||
private String password;
|
||||
@VoIgnore
|
||||
private Integer auth;
|
||||
@Nullable
|
||||
private String avatar;
|
||||
@RelationManyToOne(selfField = "auth", targetField = "id")
|
||||
private AuthVo auths;
|
||||
@RelationManyToOne(joinTable = "club_user_auth", selfField = "id", joinSelfColumn = "user_id", targetField = "id", joinTargetColumn = "club_id")
|
||||
private ClubVo club;
|
||||
@RelationManyToOne(joinTable = "club_user_auth", selfField = "id", joinSelfColumn = "user_id", targetField = "id", joinTargetColumn = "auth_id")
|
||||
private AuthVo clubAuth;
|
||||
}
|
28
src/main/java/org/blue/club/services/UserServices.java
Normal file
28
src/main/java/org/blue/club/services/UserServices.java
Normal file
@ -0,0 +1,28 @@
|
||||
package org.blue.club.services;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.blue.club.dao.UserDao;
|
||||
import org.blue.club.entities.dto.User;
|
||||
import org.blue.club.entities.dto.req.LoginRequest;
|
||||
import org.blue.club.entities.vo.UserVo;
|
||||
import org.mmga.spring.boot.starter.entities.Result;
|
||||
import org.mmga.spring.boot.starter.utils.VoUtils;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import static org.blue.club.entities.vo.table.UserVoTableDef.USER_VO;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UserServices {
|
||||
private final UserDao userDao;
|
||||
private final VoUtils voUtils;
|
||||
|
||||
public Result<User> login(LoginRequest loginRequest, String address) {
|
||||
UserVo userVo = userDao.selectOneWithRelationsByCondition(USER_VO.NAME.eq(loginRequest.username()).and(USER_VO.PASSWORD.eq(DigestUtils.sha1Hex(loginRequest.password()))));
|
||||
if (userVo == null) return Result.failed(HttpStatus.NOT_FOUND, "用户不存在!");
|
||||
User user = voUtils.vo2DtoSafe(userVo, User.class);
|
||||
return Result.success(user);
|
||||
}
|
||||
}
|
@ -1 +1,4 @@
|
||||
spring.application.name=club
|
||||
springdoc.swagger-ui.path=/docs
|
||||
mmga.auth.keySave=DISK
|
||||
mmga.auth.keySaveFilename=key.pem
|
Loading…
x
Reference in New Issue
Block a user