refactor: 后端标识统一为 FruitShorts,并落地 05 离线下载
为什么: 1) 产品已定名 FruitShorts,但后端仍是 reelshort 系列标识 —— Java 包 com.reelshort、 模块名与 jar 名 reelshort-*、spring.application.name、配置前缀 reelshort.*, 这些会出现在启动日志、命令行和 IDE 里,与产品名不一致。本次整体替换为 fruitshorts, 数据库连接名上一轮已改名,保持不变。 2) 第一阶段下一批第 1 步(05 离线下载)要求把下载授权(设备绑定/有效期/吊销)、 下载任务与断点续传、配额与过期清理、仅 Wi-Fi 规则做成完整接口,本提交一并落地。 3) 顺带修复:schema-phase1.sql 里 playback_ticket / order_event 仍按普通表定义唯一索引, 表分区化之后重跑脚本必定报错(分区表的唯一索引必须包含分区键)。改为在本脚本里就 按分区表定义,并验证脚本可重复执行。
This commit is contained in:
1 parent
a4aa749cc6
commit
b3179fc836
251 files changed
+7261
-767
No files matched your search
@@ -0,0 +1,39 @@
|
||||
package com.fruitshorts.common.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 全局错误码,详见 docs/architecture-design.md 附录 A。
|
||||
*/
|
||||
@Getter
|
||||
public enum ErrorCode {
|
||||
|
||||
SUCCESS(0, "ok"),
|
||||
|
||||
BAD_REQUEST(400, "参数校验失败"),
|
||||
UNAUTHORIZED(401, "未登录或登录已过期"),
|
||||
FORBIDDEN(403, "无权限"),
|
||||
NOT_FOUND(404, "资源不存在"),
|
||||
TOO_MANY_REQUESTS(429, "请求过于频繁"),
|
||||
INTERNAL_ERROR(500, "系统异常"),
|
||||
|
||||
LOGIN_FAILED(100000, "账号或密码错误"),
|
||||
ACCOUNT_DISABLED(100001, "账号已停用"),
|
||||
COIN_NOT_ENOUGH(100002, "金币余额不足"),
|
||||
EPISODE_NOT_AVAILABLE(100003, "剧集未发布或不存在"),
|
||||
EPISODE_UNLOCKED(100004, "剧集已解锁"),
|
||||
ORDER_STATUS_INVALID(100005, "订单已支付或已关闭"),
|
||||
VIP_EXPIRED(100006, "VIP 已过期"),
|
||||
|
||||
DATA_EXISTS(200001, "数据已存在"),
|
||||
DATA_NOT_FOUND(200002, "数据不存在"),
|
||||
OPERATION_NOT_ALLOWED(200003, "当前状态不允许该操作");
|
||||
|
||||
private final int code;
|
||||
private final String message;
|
||||
|
||||
ErrorCode(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.fruitshorts.common.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 业务异常:带业务错误码,由全局异常处理器转成统一响应。
|
||||
*/
|
||||
@Getter
|
||||
public class ServiceException extends RuntimeException {
|
||||
|
||||
private final int code;
|
||||
|
||||
public ServiceException(ErrorCode errorCode) {
|
||||
super(errorCode.getMessage());
|
||||
this.code = errorCode.getCode();
|
||||
}
|
||||
|
||||
public ServiceException(ErrorCode errorCode, String message) {
|
||||
super(message);
|
||||
this.code = errorCode.getCode();
|
||||
}
|
||||
|
||||
public ServiceException(String message) {
|
||||
super(message);
|
||||
this.code = ErrorCode.INTERNAL_ERROR.getCode();
|
||||
}
|
||||
|
||||
public static ServiceException of(ErrorCode errorCode) {
|
||||
return new ServiceException(errorCode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.fruitshorts.common.pojo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 分页请求参数,pageIndex 从 1 开始,与前端一致。
|
||||
*/
|
||||
@Data
|
||||
public class PageParam {
|
||||
|
||||
private static final int MAX_PAGE_SIZE = 200;
|
||||
|
||||
private Integer pageIndex = 1;
|
||||
private Integer pageSize = 10;
|
||||
|
||||
public long getOffset() {
|
||||
return (long) (getSafePageIndex() - 1) * getSafePageSize();
|
||||
}
|
||||
|
||||
public int getSafePageIndex() {
|
||||
return pageIndex == null || pageIndex < 1 ? 1 : pageIndex;
|
||||
}
|
||||
|
||||
public int getSafePageSize() {
|
||||
if (pageSize == null || pageSize < 1) {
|
||||
return 10;
|
||||
}
|
||||
return Math.min(pageSize, MAX_PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.fruitshorts.common.pojo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分页响应,字段名与前端表格组件(total / list)保持一致。
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class PageResult<T> {
|
||||
|
||||
private final long total;
|
||||
private final List<T> list;
|
||||
|
||||
public static <T> PageResult<T> empty() {
|
||||
return new PageResult<>(0L, List.of());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.fruitshorts.common.pojo;
|
||||
|
||||
import com.fruitshorts.common.exception.ErrorCode;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 统一响应体,与前端 axios 拦截器约定一致:{ code, message, data }。
|
||||
*/
|
||||
@Getter
|
||||
public class Result<T> {
|
||||
|
||||
private final int code;
|
||||
private final String message;
|
||||
private final T data;
|
||||
|
||||
private Result(int code, String message, T data) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static Result<Void> ok() {
|
||||
return new Result<>(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMessage(), null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> ok(T data) {
|
||||
return new Result<>(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMessage(), data);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(ErrorCode errorCode) {
|
||||
return new Result<>(errorCode.getCode(), errorCode.getMessage(), null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(int code, String message) {
|
||||
return new Result<>(code, message, null);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user