feat(auth): 新增 Apple 登录并集成 Sa-Token 鉴权

- AppleServiceImpl:返回完整用户信息并签发 Sa-Token
- 新增 KeyboardUser 实体、Mapper、Service,支持按 subjectId 查询与创建
- GlobalExceptionHandler 统一处理 Sa-Token 未登录异常
- 补充 APPLE_LOGIN_ERROR 等错误码
- 配置文件增加 Sa-Token 相关参数
This commit is contained in:
2025-12-02 16:47:01 +08:00
parent bcbb623ee4
commit fdc024e58f
25 changed files with 575 additions and 30 deletions

View File

@@ -17,8 +17,17 @@ public enum ErrorCode {
NOT_FOUND_ERROR(40400, "请求数据不存在"),
FORBIDDEN_ERROR(40300, "禁止访问"),
SYSTEM_ERROR(50000, "系统内部异常"),
OPERATION_ERROR(50001, "操作失败");
OPERATION_ERROR(50001, "操作失败"),
APPLE_LOGIN_ERROR(40003, "Apple登录失败"),
FILE_IS_EMPTY(40001, "上传文件为空"),
TOKEN_NOT_FOUND(40102, "未能读取到有效用户令牌"),
TOKEN_INVALID(40103, "令牌无效"),
TOKEN_TIMEOUT(40104, "令牌已过期"),
TOKEN_BE_REPLACED(40105, "令牌已被顶下线"),
TOKEN_KICK_OUT(40107, "令牌已被踢下线"),
TOKEN_FREEZE(40108, "令牌已被冻结"),
TOKEN_NO_PREFIX(40109, "未按照指定前缀提交令牌"),
FILE_NAME_ERROR(40002, "文件名错误");
/**
* 状态码
*/

View File

@@ -0,0 +1,35 @@
package com.yolo.keyborad.common.xfile;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.dromara.x.file.storage.core.file.FileWrapper;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
@Getter
@Setter
@NoArgsConstructor
public class ByteFileWrapper implements FileWrapper {
private byte[] bytes;
private String name;
private String contentType;
private InputStream inputStream;
private Long size;
public ByteFileWrapper(byte[] bytes,String name,String contentType,Long size) {
this.bytes = bytes;
this.name = name;
this.contentType = contentType;
this.size = size;
}
@Override
public InputStream getInputStream() {
if (inputStream == null) {
inputStream = new ByteArrayInputStream(bytes);
}
return inputStream;
}
}

View File

@@ -0,0 +1,41 @@
package com.yolo.keyborad.common.xfile;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.dromara.x.file.storage.core.file.FileWrapper;
import org.dromara.x.file.storage.core.file.FileWrapperAdapter;
import org.dromara.x.file.storage.core.tika.ContentTypeDetect;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class ByteFileWrapperAdapter implements FileWrapperAdapter {
private ContentTypeDetect contentTypeDetect;
/**
* 是否支持此资源文件
*/
@Override
public boolean isSupport(Object source) {
return source instanceof byte[] || source instanceof ByteFileWrapper;
}
/**
* 对资源文件进行包装
*/
@Override
public FileWrapper getFileWrapper(Object source, String name, String contentType, Long size) {
if (source instanceof ByteFileWrapper) {
return updateFileWrapper((ByteFileWrapper) source,name,contentType,size);
} else {
byte[] bytes = (byte[]) source;
if (name == null) name = "";
if (contentType == null) contentType = contentTypeDetect.detect(bytes,name);
if (size == null) size = (long) bytes.length;
return new ByteFileWrapper(bytes,name,contentType,size);
}
}
}