初始化前端目录

This commit is contained in:
2025-09-03 21:42:51 +08:00
parent de83878345
commit 31ebed0b5e
68 changed files with 4230 additions and 3461 deletions

View File

@@ -14,12 +14,12 @@ public class AuthInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
// HttpSession session = request.getSession();
// ApiUser apiUser = (ApiUser) session.getAttribute("Authorization");
// if (apiUser == null) {
// response.sendRedirect(request.getContextPath() + "/login");
// return false;
// }
HttpSession session = request.getSession();
ApiUser apiUser = (ApiUser) session.getAttribute("userInfo");
if (apiUser == null) {
response.sendRedirect(request.getContextPath() + "/login");
return false;
}
return true;
}
}

View File

@@ -1,11 +1,17 @@
package com.mini.capi.config;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.PathResourceResolver;
import java.io.IOException;
@Configuration
@RequiredArgsConstructor
@@ -13,35 +19,51 @@ public class WebMvcConfig implements WebMvcConfigurer {
private final AuthInterceptor authInterceptor;
// @Override
// public void addResourceHandlers(ResourceHandlerRegistry registry) {
// registry.addResourceHandler("/cApi/**")
// .addResourceLocations("classpath:/static/")
// .setCachePeriod(0);
// }
//
//
// @Override
// public void addViewControllers(ViewControllerRegistry registry) {
// registry.addViewController("/cApi/**")
// .setViewName("forward:/cApi/index.html");
// }
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("forward:/index.html");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/")
.resourceChain(true)
.addResolver(new PathResourceResolver() {
@Override
protected Resource getResource(String resourcePath, Resource location) throws IOException {
Resource requested = super.getResource(resourcePath, location);
// 文件存在就返回,不存在返回 index.html
return requested != null ? requested : new ClassPathResource("/static/index.html");
}
});
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/**") // 需要拦截的路径
.excludePathPatterns( // 排除的路径
.addPathPatterns("/**") // 拦截所有请求
.excludePathPatterns(
// ① 排除 Vue 静态资源(匹配 static 目录下所有 js/css/img 等)
"/js/**",
"/css/**",
"/img/**",
"/favicon.ico",
"/index.html", // 排除首页Vue 入口)
"/assets/**", // 若 Vue 打包后有 assets 目录,需排除
"/resource/**", // 若有其他静态资源目录,需排除
"/cApi/index/**",
"/login",
"/index.html",
"/assets/**",
"/resource/**",
"/swagger-ui/**",
"/v3/api-docs/**",
"/Sys/jobs/**",
"/Sys/login/**", // 你的登录接口(原 /Sys/login/** 缺少 /cApi 前缀,修复)
"/Sys/jobs/**", // 原路径补充 /cApi 前缀
"/Sys/hosts/**",
"/Sys/dbs/**",
"/Sys/login/**"
"/cApi/swagger-ui/**",
"/cApi/v3/api-docs/**"
);
}
}
}

View File

@@ -1,50 +0,0 @@
package com.mini.capi.job;
import com.mini.capi.model.ApiResult;
import com.mini.capi.sys.service.DbService;
import com.mini.capi.sys.service.DockerService;
import com.mini.capi.utils.*;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/Sys/jobs")
public class taskEnable {
@Resource
private DockerService dockerService;
@Resource
private DbService dbService;
/**
* 获取容器主机的磁盘使用情况
*/
@GetMapping("/getTaskDockerDiskInfo")
public ApiResult<?> jobHostDisk(String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return dockerService.jobHostDisk();
}
/**
* 运行全部任务数据同步
*/
@GetMapping("/getTaskSyncDbInfo")
public ApiResult<?> jobSyncAllTask(String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return dbService.jobSyncAllTask();
}
}

View File

@@ -1,9 +1,11 @@
package com.mini.capi.model;
import com.mini.capi.biz.domain.SyncTablesView;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
@Data
public class ApiResult<T> implements Serializable {
@@ -37,6 +39,7 @@ public class ApiResult<T> implements Serializable {
this.result = data;
}
/* ---------------- 静态工厂方法 ---------------- */
/**

View File

@@ -0,0 +1,124 @@
package com.mini.capi.sys.Api;
import com.mini.capi.model.ApiResult;
import com.mini.capi.model.TabResult;
import com.mini.capi.sys.service.DbService;
import com.mini.capi.sys.service.DockerService;
import com.mini.capi.sys.service.HostService;
import com.mini.capi.utils.vToken;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/Sys/api")
public class apiController {
@Resource
private DbService dbService;
@Resource
private HostService hostService;
@Resource
private DockerService dockerService;
/**
* 获取MySQL的当前连接下的所有数据表
*/
@GetMapping("/getApiSourceTables")
public ApiResult<List<TabResult>> listSourceTables(String token, String dbId) {
// 1. 验证token有效性
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return dbService.listSourceTables(dbId);
}
@GetMapping("/getApiInfo")
public ApiResult<List<HostService.SnapshotDTO>> getApiInfo(String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return hostService.getApiInfo();
}
/**
* 获取容器列表
*/
@GetMapping("/getApiDockerInfo")
public ApiResult<?> getDockerInfo(String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return hostService.getDockerInfo();
}
/**
* 启动容器
*/
@GetMapping("/getApiStartDockerInfo")
public ApiResult<?> startDockerInfo(String id, String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return hostService.startDockerInfo(id);
}
/**
* 停止容器
*/
@GetMapping("/getApiStopDockerInfo")
public ApiResult<?> stopDockerInfo(String id, String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return hostService.stopDockerInfo(id);
}
/**
* 获取容器主机的磁盘使用情况
*/
@GetMapping("/getTaskDockerDiskInfo")
public ApiResult<?> jobHostDisk(String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return dockerService.jobHostDisk();
}
/**
* 运行全部任务数据同步
*/
@GetMapping("/getTaskSyncDbInfo")
public ApiResult<?> jobSyncAllTask(String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return dbService.jobSyncAllTask();
}
/**
* 运行单个任务
*/
@GetMapping("/getTaskSyncDbByInfo")
public ApiResult<?> jobSyncOneTask(String token, String taskId) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return dbService.jobSyncOneTask(taskId);
}
}

View File

@@ -1,23 +1,32 @@
package com.mini.capi.sys.controller;
package com.mini.capi.sys.App;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mini.capi.biz.domain.DbConfig;
import com.mini.capi.biz.domain.SyncTablesView;
import com.mini.capi.biz.domain.SyncTask;
import com.mini.capi.biz.service.DbConfigService;
import com.mini.capi.biz.service.SyncTablesViewService;
import com.mini.capi.biz.service.SyncTaskService;
import com.mini.capi.config.DataSourceConfig;
import com.mini.capi.model.ApiResult;
import com.mini.capi.sys.domain.SelectOption;
import jakarta.annotation.Resource;
import lombok.Data;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.Serializable;
import java.util.Collections;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
@Controller
@RestController
@RequestMapping("/Sys/data")
public class dataController {
@@ -26,12 +35,11 @@ public class dataController {
@Resource
private DbConfigService dbConfigService;
private DbConfigService configService;
@GetMapping("/Sys/data/list")
public String listPage() {
return "views/data/list";
}
@Resource
private SyncTablesViewService tablesViewService;
@Data
@@ -73,6 +81,28 @@ public class dataController {
}
@Data
static class TableInfo implements Serializable {
private TabDetail tabDetail;
private List<TabColumns> tabColumns;
private long pkCnt;
private long idxCnt;
private long colCnt;
private String ddlSql;
private String selectSql;
public TableInfo(TabDetail tabDetail, List<TabColumns> tabColumns, long pkCnt, long idxCnt, long colCnt, String ddlSql, String selectSql) {
this.tabDetail = tabDetail;
this.tabColumns = tabColumns;
this.pkCnt = pkCnt;
this.idxCnt = idxCnt;
this.colCnt = colCnt;
this.ddlSql = ddlSql;
this.selectSql = selectSql;
}
}
public static String buildSelect(List<TabColumns> columns, TabDetail table) {
if (columns == null || columns.isEmpty() || table == null) {
return "-- no columns or table info";
@@ -160,18 +190,78 @@ public class dataController {
}
@GetMapping("/Sys/data/getTableDetail")
public String getTableDetail(String taskId, Model model) {
SyncTask task = syncTaskService.getById(taskId);
DbConfig dbConfig = dbConfigService.getById(task.getSourceDbId());
List<TabDetail> data;
List<TabColumns> columns;
/**
* 获取数据配置表
*
* @return
*/
@GetMapping("/getDbList")
public ApiResult<List<SelectOption>> getDbList() {
try {
JdbcTemplate jdbcTemplate = DataSourceConfig.createJdbcTemplate(dbConfig);
// 补充参数传递
String querySql = "SELECT CREATE_TIME,TABLE_NAME,TABLE_COMMENT,MAX_DATA_LENGTH,UPDATE_TIME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?";
List<DbConfig> configs = configService.list();
List<SelectOption> selectOptions = configs.stream()
.map(config -> new SelectOption(
config.getDbId(), // 下拉框value绑定值
config.getDbName(), // 下拉框label显示文本
false // 关键注释说明禁用原因所有数据库默认禁用选择需申请后启用
))
.collect(Collectors.toList());
return ApiResult.success(selectOptions);
} catch (Exception e) {
return ApiResult.error(401, e.getMessage());
}
}
/**
* 获取数据字段表
*
* @return
*/
@GetMapping("/getTableList")
public ApiResult<List<SyncTablesView>> getTableList(String dbId, String targetTable) {
try {
List<SyncTablesView> tablesViews = tablesViewService.list(
new QueryWrapper<SyncTablesView>()
.eq(StringUtils.hasText(dbId), "db_id", dbId)
.and(StringUtils.hasText(targetTable),
w -> w.like("target_table", targetTable)
.or()
.like("task_name", targetTable))
.orderByDesc("create_time")
);
return ApiResult.success(tablesViews);
} catch (Exception e) {
return ApiResult.error(401, e.getMessage());
}
}
/**
* 获取数据表属性
*
* @param taskId
* @return
*/
@GetMapping("/Sys/data/getTableDetail")
public ApiResult<TableInfo> getTableDetail(String taskId) {
// 获取基础数据
SyncTask task = syncTaskService.getById(taskId);
DbConfig dbConfig = configService.getById(task.getSourceDbId());
JdbcTemplate jdbcTemplate;
try {
// 统一创建JdbcTemplate避免重复初始化
jdbcTemplate = DataSourceConfig.createJdbcTemplate(dbConfig);
} catch (Exception e) {
return ApiResult.error(401, e.getMessage());
}
// 查询表基本信息
List<TabDetail> data;
try {
String tableQuerySql = "SELECT CREATE_TIME,TABLE_NAME,TABLE_COMMENT,MAX_DATA_LENGTH,UPDATE_TIME " +
"FROM information_schema.TABLES " +
"WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?";
data = jdbcTemplate.query(
querySql,
tableQuerySql,
(rs, rowNum) -> new TabDetail(
rs.getString("CREATE_TIME"),
dbConfig.getDbName(),
@@ -185,16 +275,17 @@ public class dataController {
);
data.sort(Comparator.comparing(TabDetail::getTableName));
} catch (Exception e) {
data = Collections.emptyList();
System.out.println(e.getMessage());
}
return ApiResult.error(401, e.getMessage());
}
// 查询表列信息
List<TabColumns> columns;
try {
JdbcTemplate jdbcTemplate = DataSourceConfig.createJdbcTemplate(dbConfig);
// 补充参数传递
String querySql = "SELECT TABLE_NAME,ORDINAL_POSITION,COLUMN_NAME,COLUMN_TYPE,COLUMN_COMMENT,COLUMN_KEY FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?";
String columnQuerySql = "SELECT TABLE_NAME,ORDINAL_POSITION,COLUMN_NAME,COLUMN_TYPE,COLUMN_COMMENT,COLUMN_KEY " +
"FROM information_schema.COLUMNS " +
"WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?";
columns = jdbcTemplate.query(
querySql,
columnQuerySql,
(rs, rowNum) -> new TabColumns(
rs.getString("TABLE_NAME"),
rs.getInt("ORDINAL_POSITION"),
@@ -208,26 +299,29 @@ public class dataController {
);
columns.sort(Comparator.comparing(TabColumns::getSort));
} catch (Exception e) {
columns = Collections.emptyList();
System.out.println(e.getMessage());
return ApiResult.error(401, e.getMessage());
}
// 在查询完表结构后
// 计算表结构统计信息
long primaryKeyCnt = columns.stream()
.filter(c -> "PRI".equalsIgnoreCase(c.getKeyType()))
.count();
long indexCnt = columns.stream()
.filter(c -> !"PRI".equalsIgnoreCase(c.getKeyType()) && !c.getKeyType().isBlank())
.count()
+ 1; // 主键索引也算 1
.count() + 1; // 包含主键索引
long colCnt = columns.size();
model.addAttribute("pkCnt", primaryKeyCnt);
model.addAttribute("idxCnt", indexCnt);
model.addAttribute("colCnt", colCnt);
model.addAttribute("data", data);
model.addAttribute("columns", columns);
model.addAttribute("ddlSql", buildDDL(columns, data.get(0)));
model.addAttribute("selectSql", buildSelect(columns, data.get(0)));
return "views/data/detail";
// 构建返回结果
TableInfo tableInfo = new TableInfo(
data.get(0),
columns,
primaryKeyCnt,
indexCnt,
colCnt,
buildDDL(columns, data.get(0)),
buildSelect(columns, data.get(0))
);
return ApiResult.success(tableInfo);
}

View File

@@ -0,0 +1,9 @@
package com.mini.capi.sys.App;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/Sys/hosts")
public class hostController {
}

View File

@@ -1,4 +1,4 @@
package com.mini.capi.sys.pageController;
package com.mini.capi.sys.App;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mini.capi.biz.domain.ApiMenus;
@@ -10,6 +10,7 @@ import com.mini.capi.biz.service.ApiUserService;
import com.mini.capi.model.ApiResult;
import com.mini.capi.model.auth.Result;
import com.mini.capi.sys.domain.ModuleMenuDTO;
import com.mini.capi.utils.KeyUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpSession;
import lombok.Data;
@@ -20,10 +21,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@RestController
@RequestMapping("/Sys/login")
public class loginPageController {
public class loginController {
@Resource
@@ -58,11 +58,14 @@ public class loginPageController {
*/
private String uname;
private String token;
// 构造方法从实体类转换
public ApiUserDTO(ApiUser apiUser) {
public ApiUserDTO(ApiUser apiUser, String token) {
this.userId = apiUser.getUserId();
this.username = apiUser.getApiUser();
this.uname = apiUser.getUname();
this.token = token;
}
}
@@ -91,14 +94,25 @@ public class loginPageController {
// 可记录登录失败日志用于后续风控
return Result.error(102, "账户或密码错误");
}
session.setAttribute("token", apiUser);
ApiUserDTO userDTO = new ApiUserDTO(apiUser);
session.setAttribute("userInfo", apiUser);
ApiUserDTO userDTO = new ApiUserDTO(apiUser, KeyUtil.ObjKey(32, 0));
return Result.success("登录成功", userDTO);
} catch (Exception e) {
return Result.error(103, "登录失败,请稍后重试");
}
}
@PostMapping("/userLogout")
public Result loginOut(HttpSession session) {
try {
session.removeAttribute("userInfo"); // 只清 token
session.invalidate();
return Result.error(200, "退出成功");
} catch (Exception e) {
return Result.error(500, "退出失败");
}
}
@GetMapping("/getModules")
public ApiResult<List<ModuleMenuDTO>> getModules() {

View File

@@ -1,31 +1,40 @@
package com.mini.capi.sys.controller;
import jakarta.servlet.http.HttpServletRequest; // 注意这里
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.HashMap;
import java.util.Map;
@Controller
public class CustomErrorController implements ErrorController {
@RequestMapping("/error")
public ResponseEntity<Map<String, Object>> handleError(HttpServletRequest request) {
public Object handleError(HttpServletRequest request) {
String uri = request.getRequestURI();
// 1. 前端路由:统一转发到 index.html
if (uri.startsWith("/cApi/index/")) {
return "forward:/index.html";
}
// 2. 其他 404返回 JSON
HttpStatus status = getStatus(request);
Map<String, Object> body = new HashMap<>();
body.put("status", status.value());
body.put("error", status.getReasonPhrase());
body.put("message", "访问的资源不存在");
body.put("path", request.getRequestURI());
return ResponseEntity.status(status).body(body);
return ResponseEntity
.status(status)
.body(Map.of(
"status", status.value(),
"error", status.getReasonPhrase(),
"message", "访问的资源不存在",
"path", uri
));
}
private HttpStatus getStatus(HttpServletRequest request) {
Integer code = (Integer) request.getAttribute("jakarta.servlet.error.status_code");
return (code != null) ? HttpStatus.valueOf(code) : HttpStatus.INTERNAL_SERVER_ERROR;
return code != null ? HttpStatus.valueOf(code) : HttpStatus.INTERNAL_SERVER_ERROR;
}
}
}

View File

@@ -1,19 +0,0 @@
package com.mini.capi.sys.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class hostController {
/**
* 主机登录
*
* @return
*/
@GetMapping("/Sys/app/host")
public String listPage() {
return "views/ssh/index";
}
}

View File

@@ -1,40 +0,0 @@
package com.mini.capi.sys.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class loginController {
@GetMapping("/login")
public String loginPage() {
return "forward:/index.html";
}
//
// /**
// * 退出登录:清空 session 并返回到退出成功页面
// */
// @GetMapping("/userLogout")
// public String logout(HttpSession session) {
// session.invalidate();
// return "index";
// }
//
//
// /**
// * 主页
// */
// @GetMapping("/welcome")
// public String welcomePage() {
// return "views/demo";
// }
//
// /**
// * 系统首页-控制台
// */
// @GetMapping("/home")
// public String homePage() {
// return "views/home";
// }
}

View File

@@ -1,15 +0,0 @@
package com.mini.capi.sys.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class sysController {
@GetMapping("/Sys/sys/icon")
public String getIcon() {
return "views/icon";
}
}

View File

@@ -0,0 +1,28 @@
package com.mini.capi.sys.domain;
import lombok.Data;
import java.io.Serializable;
@Data
public class SelectOption implements Serializable {
private String value;
private String label;
private boolean disabled;
public SelectOption() {
}
// 全参构造函数
public SelectOption(String value, String label, boolean disabled) {
this.value = value;
this.label = label;
this.disabled = disabled;
}
}

View File

@@ -1,46 +0,0 @@
package com.mini.capi.sys.pageController;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mini.capi.biz.domain.DbConfig;
import com.mini.capi.biz.domain.SyncTablesView;
import com.mini.capi.biz.service.DbConfigService;
import com.mini.capi.biz.service.SyncTablesViewService;
import jakarta.annotation.Resource;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController // ← 关键
@RequestMapping("/Sys/data")
public class dataPageController {
@Resource
private DbConfigService configService;
@Resource
private SyncTablesViewService tablesViewService;
@GetMapping("/getDbList")
public List<DbConfig> getDbList() {
return configService.list();
}
@GetMapping("/getTableList")
public List<SyncTablesView> getTableList(String dbId, String targetTable) {
return tablesViewService.list(
new QueryWrapper<SyncTablesView>()
.eq(StringUtils.hasText(dbId), "db_id", dbId)
.and(StringUtils.hasText(targetTable),
w -> w.like("target_table", targetTable)
.or()
.like("task_name", targetTable))
.orderByDesc("create_time")
);
}
}

View File

@@ -1,45 +0,0 @@
package com.mini.capi.sys.pageController;
import com.mini.capi.model.ApiResult;
import com.mini.capi.model.TabResult;
import com.mini.capi.sys.service.DbService;
import com.mini.capi.utils.vToken;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/Sys/dbs")
public class dbPageController {
@Resource
private DbService dbService;
/**
* 获取MySQL的当前连接下的所有数据表
*/
@GetMapping("/getApiSourceTables")
public ApiResult<List<TabResult>> listSourceTables(String token, String dbId) {
// 1. 验证token有效性
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return dbService.listSourceTables(dbId);
}
/**
* 运行单个任务
*/
@GetMapping("/getTaskSyncDbByInfo")
public ApiResult<?> jobSyncOneTask(String token, String taskId) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return dbService.jobSyncOneTask(taskId);
}
}

View File

@@ -1,70 +0,0 @@
package com.mini.capi.sys.pageController;
import com.mini.capi.model.ApiResult;
import com.mini.capi.sys.service.HostService;
import com.mini.capi.utils.vToken;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
@RestController
@RequestMapping("/Sys/hosts")
public class hostPageController {
@Resource
private HostService hostService;
@GetMapping("/getApiInfo")
public ApiResult<List<HostService.SnapshotDTO>> getApiInfo(String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return hostService.getApiInfo();
}
/**
* 获取容器列表
*/
@GetMapping("/getApiDockerInfo")
public ApiResult<?> getDockerInfo(String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return hostService.getDockerInfo();
}
/**
* 启动容器
*/
@GetMapping("/getApiStartDockerInfo")
public ApiResult<?> startDockerInfo(String id, String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return hostService.startDockerInfo(id);
}
/**
* 停止容器
*/
@GetMapping("/getApiStopDockerInfo")
public ApiResult<?> stopDockerInfo(String id, String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return hostService.stopDockerInfo(id);
}
}

View File

@@ -0,0 +1,81 @@
package com.mini.capi.utils;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.net.util.Base64;
public class AESUtil {
public static String key = "AD42F6697B035B7580E4FEF93BE20BAD";
private static String charset = "utf-8";
// 偏移量
private static int offset = 16;
private static String transformation = "AES/CBC/PKCS5Padding";
private static String algorithm = "AES";
/**
* 加密
*
* @param content
* @return
*/
public static String encrypt(String content) {
return encrypt(content, key);
}
/**
* 解密
*
* @param content
* @return
*/
public static String decrypt(String content) {
return decrypt(content, key);
}
/**
* 加密
*
* @param content 需要加密的内容
* @param key 加密密码
* @return
*/
public static String encrypt(String content, String key) {
try {
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), algorithm);
IvParameterSpec iv = new IvParameterSpec(key.getBytes(), 0, offset);
Cipher cipher = Cipher.getInstance(transformation);
byte[] byteContent = content.getBytes(charset);
cipher.init(Cipher.ENCRYPT_MODE, skey, iv);// 初始化
byte[] result = cipher.doFinal(byteContent);
return new Base64().encodeToString(result).replaceAll("[\\s*\t\n\r]", ""); // 加密
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* AES256解密
*
* @param content 待解密内容
* @param key 解密密钥
* @return 解密之后
* @throws Exception
*/
public static String decrypt(String content, String key) {
try {
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), algorithm);
IvParameterSpec iv = new IvParameterSpec(key.getBytes(charset), 0, offset);
Cipher cipher = Cipher.getInstance(transformation);
cipher.init(Cipher.DECRYPT_MODE, skey, iv);// 初始化
byte[] result = cipher.doFinal(new Base64().decode(content));
return new String(result).replaceAll("[\\s*\t\n\r]", ""); // 解密
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
}

View File

@@ -0,0 +1,48 @@
package com.mini.capi.utils;
import java.util.Random;
public class KeyUtil {
public static String ObjKey(int length, int type) {
Random random = new Random();
StringBuffer key = new StringBuffer();
if (type == 1) {
String str = "0123456789";
for (int i = 0; i < length; ++i) {
//从62个的数字或字母中选择
int number = random.nextInt(10);
//将产生的数字通过length次承载到key中
key.append(str.charAt(number));
}
return key.toString();
} else if (type == 2) {
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for (int i = 0; i < length; ++i) {
//从62个的数字或字母中选择
int number = random.nextInt(36);
//将产生的数字通过length次承载到key中
key.append(str.charAt(number));
}
return key.toString();
} else if (type == 3) {
String str = "abcdefghijklmnopqrstuvwxyz0123456789";
for (int i = 0; i < length; ++i) {
//从62个的数字或字母中选择
int number = random.nextInt(36);
//将产生的数字通过length次承载到key中
key.append(str.charAt(number));
}
return key.toString();
} else {
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (int i = 0; i < length; ++i) {
//从62个的数字或字母中选择
int number = random.nextInt(62);
//将产生的数字通过length次承载到key中
key.append(str.charAt(number));
}
return key.toString();
}
}
}