首次提交后端接口

This commit is contained in:
super
2026-01-27 20:48:47 +08:00
commit 40db55e85d
177 changed files with 18905 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
package com.nanxiislet.admin.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
/**
* 证书申请请求DTO
*
* @author NanxiIslet
* @since 2026-01-13
*/
@Data
@Schema(description = "证书申请请求")
public class CertificateApplyRequest {
@NotNull(message = "服务器ID不能为空")
@Schema(description = "服务器ID")
private Long serverId;
@NotBlank(message = "主域名不能为空")
@Schema(description = "主域名")
private String primaryDomain;
@Schema(description = "其他域名(逗号分隔)")
private String otherDomains;
@NotNull(message = "Acme账户ID不能为空")
@Schema(description = "Acme账户ID")
private Long acmeAccountId;
@NotNull(message = "DNS账户ID不能为空")
@Schema(description = "DNS账户ID")
private Long dnsAccountId;
@Schema(description = "密钥算法 P256/P384/RSA2048/RSA4096")
private String keyType = "P256";
@Schema(description = "自动续签")
private Boolean autoRenew = true;
@Schema(description = "备注")
private String description;
}

View File

@@ -0,0 +1,80 @@
package com.nanxiislet.admin.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 证书申请结果DTO
*
* @author NanxiIslet
* @since 2026-01-13
*/
@Data
@Schema(description = "证书申请结果")
public class CertificateApplyResult {
@Schema(description = "是否成功")
private Boolean success;
@Schema(description = "结果消息")
private String message;
@Schema(description = "1Panel证书ID")
private Long panelSslId;
@Schema(description = "本地证书记录ID")
private Long certificateId;
@Schema(description = "申请步骤")
private List<ApplyStep> steps = new ArrayList<>();
@Data
@Schema(description = "申请步骤")
public static class ApplyStep {
@Schema(description = "步骤名称")
private String step;
@Schema(description = "状态 success/failed/skipped")
private String status;
@Schema(description = "消息")
private String message;
public ApplyStep() {}
public ApplyStep(String step, String status, String message) {
this.step = step;
this.status = status;
this.message = message;
}
}
public static CertificateApplyResult success(String message) {
CertificateApplyResult result = new CertificateApplyResult();
result.setSuccess(true);
result.setMessage(message);
return result;
}
public static CertificateApplyResult failed(String message) {
CertificateApplyResult result = new CertificateApplyResult();
result.setSuccess(false);
result.setMessage(message);
return result;
}
public void addSuccessStep(String step, String message) {
this.steps.add(new ApplyStep(step, "success", message));
}
public void addFailedStep(String step, String message) {
this.steps.add(new ApplyStep(step, "failed", message));
}
public void addSkippedStep(String step, String message) {
this.steps.add(new ApplyStep(step, "skipped", message));
}
}

View File

@@ -0,0 +1,30 @@
package com.nanxiislet.admin.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 部署请求DTO
*
* @author NanxiIslet
* @since 2024-01-10
*/
@Data
@Schema(description = "部署请求")
public class DeployRequest {
@Schema(description = "项目ID", required = true)
private Long projectId;
@Schema(description = "是否启用HTTPS")
private Boolean enableHttps = true;
@Schema(description = "Acme账户ID启用HTTPS时需要")
private Long acmeAccountId;
@Schema(description = "DNS账户ID启用HTTPS时需要")
private Long dnsAccountId;
@Schema(description = "如果网站不存在是否自动创建")
private Boolean createIfNotExist = true;
}

View File

@@ -0,0 +1,114 @@
package com.nanxiislet.admin.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import java.util.ArrayList;
import java.util.List;
/**
* 部署结果DTO
*
* @author NanxiIslet
* @since 2024-01-10
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "部署结果")
public class DeployResult {
@Schema(description = "是否成功")
private Boolean success;
@Schema(description = "结果消息")
private String message;
@Schema(description = "1Panel网站ID")
private Long websiteId;
@Schema(description = "1Panel证书ID")
private Long sslCertificateId;
@Schema(description = "部署步骤详情")
@Builder.Default
private List<DeployStep> steps = new ArrayList<>();
/**
* 部署步骤
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class DeployStep {
@Schema(description = "步骤名称")
private String step;
@Schema(description = "步骤状态 success/failed/skipped")
private String status;
@Schema(description = "步骤消息")
private String message;
}
/**
* 添加成功步骤
*/
public void addSuccessStep(String stepName, String message) {
this.steps.add(DeployStep.builder()
.step(stepName)
.status("success")
.message(message)
.build());
}
/**
* 添加失败步骤
*/
public void addFailedStep(String stepName, String message) {
this.steps.add(DeployStep.builder()
.step(stepName)
.status("failed")
.message(message)
.build());
}
/**
* 添加跳过步骤
*/
public void addSkippedStep(String stepName, String message) {
this.steps.add(DeployStep.builder()
.step(stepName)
.status("skipped")
.message(message)
.build());
}
/**
* 创建成功结果
*/
public static DeployResult success(String message) {
return DeployResult.builder()
.success(true)
.message(message)
.steps(new ArrayList<>())
.build();
}
/**
* 创建失败结果
*/
public static DeployResult failed(String message) {
return DeployResult.builder()
.success(false)
.message(message)
.steps(new ArrayList<>())
.build();
}
}

View File

@@ -0,0 +1,33 @@
package com.nanxiislet.admin.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotNull;
/**
* 域名部署请求DTO
*
* @author NanxiIslet
* @since 2026-01-13
*/
@Data
@Schema(description = "域名部署请求")
public class DomainDeployRequest {
@NotNull(message = "域名ID不能为空")
@Schema(description = "域名ID")
private Long domainId;
@Schema(description = "是否启用HTTPS")
private Boolean enableHttps;
@Schema(description = "Acme账户ID申请SSL证书时需要")
private Long acmeAccountId;
@Schema(description = "DNS账户ID申请SSL证书时需要")
private Long dnsAccountId;
@Schema(description = "如果网站不存在是否自动创建")
private Boolean createIfNotExist = true;
}

View File

@@ -0,0 +1,80 @@
package com.nanxiislet.admin.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 域名部署结果DTO
*
* @author NanxiIslet
* @since 2026-01-13
*/
@Data
@Schema(description = "域名部署结果")
public class DomainDeployResult {
@Schema(description = "是否成功")
private Boolean success;
@Schema(description = "结果消息")
private String message;
@Schema(description = "1Panel网站ID")
private Long websiteId;
@Schema(description = "1Panel证书ID")
private Long sslCertificateId;
@Schema(description = "部署步骤列表")
private List<DeployStep> steps = new ArrayList<>();
@Data
@Schema(description = "部署步骤")
public static class DeployStep {
@Schema(description = "步骤名称")
private String step;
@Schema(description = "状态 success/failed/skipped")
private String status;
@Schema(description = "消息")
private String message;
public DeployStep() {}
public DeployStep(String step, String status, String message) {
this.step = step;
this.status = status;
this.message = message;
}
}
public static DomainDeployResult success(String message) {
DomainDeployResult result = new DomainDeployResult();
result.setSuccess(true);
result.setMessage(message);
return result;
}
public static DomainDeployResult failed(String message) {
DomainDeployResult result = new DomainDeployResult();
result.setSuccess(false);
result.setMessage(message);
return result;
}
public void addSuccessStep(String step, String message) {
this.steps.add(new DeployStep(step, "success", message));
}
public void addFailedStep(String step, String message) {
this.steps.add(new DeployStep(step, "failed", message));
}
public void addSkippedStep(String step, String message) {
this.steps.add(new DeployStep(step, "skipped", message));
}
}

View File

@@ -0,0 +1,26 @@
package com.nanxiislet.admin.dto;
import com.nanxiislet.admin.common.base.BasePageQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 域名查询参数
*
* @author NanxiIslet
* @since 2026-01-13
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class DomainQueryDTO extends BasePageQuery {
@Schema(description = "服务器ID")
private Long serverId;
@Schema(description = "域名状态")
private String status;
@Schema(description = "SSL状态")
private String sslStatus;
}

View File

@@ -0,0 +1,30 @@
package com.nanxiislet.admin.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 域名统计DTO
*
* @author NanxiIslet
* @since 2026-01-13
*/
@Data
@Schema(description = "域名统计信息")
public class DomainStatsDTO {
@Schema(description = "总计")
private Long total;
@Schema(description = "正常数量")
private Long active;
@Schema(description = "待配置数量")
private Long pending;
@Schema(description = "SSL即将过期数量")
private Long sslExpiring;
@Schema(description = "已部署数量")
private Long deployed;
}

View File

@@ -0,0 +1,130 @@
package com.nanxiislet.admin.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import java.time.LocalDateTime;
import java.util.List;
/**
* 服务器信息DTO包含实时资源使用情况
*
* @author NanxiIslet
* @since 2024-01-10
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "服务器信息DTO")
public class ServerInfoDto {
@Schema(description = "服务器ID")
private Long id;
@Schema(description = "服务器名称")
private String name;
@Schema(description = "公网IP")
private String ip;
@Schema(description = "内网IP")
private String internalIp;
@Schema(description = "SSH端口")
private Integer port;
@Schema(description = "服务器类型 physical/virtual/cloud")
private String type;
@Schema(description = "状态 online/offline/warning/maintenance")
private String status;
@Schema(description = "操作系统")
private String os;
@Schema(description = "标签")
private List<String> tags;
@Schema(description = "1Panel面板地址")
private String panelUrl;
@Schema(description = "1Panel面板端口")
private Integer panelPort;
@Schema(description = "描述")
private String description;
@Schema(description = "创建时间")
private LocalDateTime createdAt;
@Schema(description = "更新时间")
private LocalDateTime updatedAt;
// ==================== 资源使用情况从1Panel获取 ====================
@Schema(description = "CPU信息")
private CpuInfo cpu;
@Schema(description = "内存信息")
private MemoryInfo memory;
@Schema(description = "磁盘信息")
private DiskInfo disk;
/**
* CPU信息
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class CpuInfo {
@Schema(description = "CPU核心数")
private Integer cores;
@Schema(description = "CPU使用率(%)")
private Double usage;
}
/**
* 内存信息
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class MemoryInfo {
@Schema(description = "总内存(GB)")
private Double total;
@Schema(description = "已用内存(GB)")
private Double used;
@Schema(description = "内存使用率(%)")
private Double usage;
}
/**
* 磁盘信息
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class DiskInfo {
@Schema(description = "总磁盘(GB)")
private Double total;
@Schema(description = "已用磁盘(GB)")
private Double used;
@Schema(description = "磁盘使用率(%)")
private Double usage;
}
}

View File

@@ -0,0 +1,24 @@
package com.nanxiislet.admin.dto.approval;
import com.nanxiislet.admin.entity.SysApprovalInstance;
import com.nanxiislet.admin.entity.SysApprovalRecord;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
* 审批实例VO包含审批记录
*
* @author NanxiIslet
* @since 2026-01-09
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class ApprovalInstanceVO extends SysApprovalInstance {
/**
* 审批记录列表
*/
private List<SysApprovalRecord> records;
}

View File

@@ -0,0 +1,48 @@
package com.nanxiislet.admin.dto.approval;
import lombok.Data;
/**
* 审批统计数据
*
* @author NanxiIslet
* @since 2026-01-09
*/
@Data
public class ApprovalStats {
/**
* 模板总数
*/
private Long totalTemplates;
/**
* 已启用模板数
*/
private Long enabledTemplates;
/**
* 实例总数
*/
private Long totalInstances;
/**
* 待处理实例数
*/
private Long pendingInstances;
/**
* 审批中实例数
*/
private Long inProgressInstances;
/**
* 已通过实例数
*/
private Long approvedInstances;
/**
* 已拒绝实例数
*/
private Long rejectedInstances;
}

View File

@@ -0,0 +1,46 @@
package com.nanxiislet.admin.dto.approval;
import com.nanxiislet.admin.entity.SysApprovalNode;
import lombok.Data;
import java.util.List;
/**
* 创建/更新审批模板请求
*
* @author NanxiIslet
* @since 2026-01-09
*/
@Data
public class ApprovalTemplateRequest {
/**
* 模板ID更新时需要
*/
private Long id;
/**
* 模板名称
*/
private String name;
/**
* 描述
*/
private String description;
/**
* 适用场景
*/
private String scenario;
/**
* 是否启用
*/
private Boolean enabled;
/**
* 审批节点列表
*/
private List<SysApprovalNode> nodes;
}

View File

@@ -0,0 +1,24 @@
package com.nanxiislet.admin.dto.approval;
import com.nanxiislet.admin.entity.SysApprovalNode;
import com.nanxiislet.admin.entity.SysApprovalTemplate;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
* 审批模板VO包含节点信息
*
* @author NanxiIslet
* @since 2026-01-09
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class ApprovalTemplateVO extends SysApprovalTemplate {
/**
* 审批节点列表
*/
private List<SysApprovalNode> nodes;
}

View File

@@ -0,0 +1,27 @@
package com.nanxiislet.admin.dto.auth;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 验证码响应DTO
*
* @author NanxiIslet
* @since 2024-01-06
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "验证码响应")
public class CaptchaResponse {
@Schema(description = "验证码Key")
private String captchaKey;
@Schema(description = "验证码图片Base64")
private String captchaImage;
}

View File

@@ -0,0 +1,32 @@
package com.nanxiislet.admin.dto.auth;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
* 登录请求DTO
*
* @author NanxiIslet
* @since 2024-01-06
*/
@Data
@Schema(description = "登录请求")
public class LoginRequest {
@Schema(description = "用户名", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "用户名不能为空")
private String username;
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "密码不能为空")
private String password;
@Schema(description = "验证码", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "验证码不能为空")
private String captcha;
@Schema(description = "验证码Key", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "验证码Key不能为空")
private String captchaKey;
}

View File

@@ -0,0 +1,33 @@
package com.nanxiislet.admin.dto.auth;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 登录响应DTO
*
* @author NanxiIslet
* @since 2024-01-06
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "登录响应")
public class LoginResponse {
@Schema(description = "访问令牌")
private String token;
@Schema(description = "刷新令牌")
private String refreshToken;
@Schema(description = "过期时间(秒)")
private long expires;
@Schema(description = "用户信息")
private UserInfoVO userInfo;
}

View File

@@ -0,0 +1,56 @@
package com.nanxiislet.admin.dto.auth;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 用户信息VO
*
* @author NanxiIslet
* @since 2024-01-06
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "用户信息")
public class UserInfoVO {
@Schema(description = "用户ID")
private Long id;
@Schema(description = "用户名")
private String username;
@Schema(description = "昵称")
private String nickname;
@Schema(description = "头像")
private String avatar;
@Schema(description = "邮箱")
private String email;
@Schema(description = "手机号")
private String phone;
@Schema(description = "角色")
private String role;
@Schema(description = "权限列表")
private List<String> permissions;
@Schema(description = "菜单列表")
private List<com.nanxiislet.admin.entity.SysMenu> menus;
@Schema(description = "创建时间")
private String createTime;
@Schema(description = "最后登录时间")
private String lastLoginTime;
}

View File

@@ -0,0 +1,36 @@
package com.nanxiislet.admin.dto.query;
import com.nanxiislet.admin.common.base.BasePageQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 支出查询条件
*
* @author NanxiIslet
* @since 2024-01-06
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "支出查询条件")
public class ExpenseQuery extends BasePageQuery {
@Schema(description = "支出类型")
private String type;
@Schema(description = "项目ID")
private Long projectId;
@Schema(description = "部门ID")
private Long departmentId;
@Schema(description = "状态")
private String status;
@Schema(description = "开始日期")
private String startDate;
@Schema(description = "结束日期")
private String endDate;
}

View File

@@ -0,0 +1,36 @@
package com.nanxiislet.admin.dto.query;
import com.nanxiislet.admin.common.base.BasePageQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 收入查询条件
*
* @author NanxiIslet
* @since 2024-01-06
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "收入查询条件")
public class IncomeQuery extends BasePageQuery {
@Schema(description = "收入类型")
private String type;
@Schema(description = "客户ID")
private Long customerId;
@Schema(description = "项目ID")
private Long projectId;
@Schema(description = "状态")
private String status;
@Schema(description = "开始日期")
private String startDate;
@Schema(description = "结束日期")
private String endDate;
}

View File

@@ -0,0 +1,27 @@
package com.nanxiislet.admin.dto.query;
import com.nanxiislet.admin.common.base.BasePageQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 项目查询条件
*
* @author NanxiIslet
* @since 2024-01-06
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "项目查询条件")
public class ProjectQuery extends BasePageQuery {
@Schema(description = "项目类型")
private String type;
@Schema(description = "服务器ID")
private Long serverId;
@Schema(description = "状态")
private String status;
}

View File

@@ -0,0 +1,26 @@
package com.nanxiislet.admin.dto.system;
import com.nanxiislet.admin.common.base.BasePageQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 用户查询参数
*
* @author NanxiIslet
* @since 2026-01-09
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class UserQuery extends BasePageQuery {
@Schema(description = "角色编码")
private String role;
@Schema(description = "部门ID")
private Long deptId;
@Schema(description = "状态 0-禁用 1-正常")
private Integer status;
}