feat: adding deps and adding base framework

This commit is contained in:
wzp 2024-12-19 12:59:36 +08:00
parent 8a29b3a815
commit 40970c1364
18 changed files with 391 additions and 13 deletions

View File

@ -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")

View File

@ -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);
}

View 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
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View 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> {
}

View 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()));
}
}

View File

@ -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) {
}

View File

@ -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;
}

View 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()));
}
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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);
}
}

View File

@ -1 +1,4 @@
spring.application.name=club
springdoc.swagger-ui.path=/docs
mmga.auth.keySave=DISK
mmga.auth.keySaveFilename=key.pem