重写复现方法

This commit is contained in:
2025-09-05 16:25:53 +08:00
parent 89ed87e362
commit 09cd62efd7
9 changed files with 110 additions and 348 deletions

View File

@@ -2,6 +2,8 @@ package com.mini.capi.sys.Api;
import com.mini.capi.model.ApiResult;
import com.mini.capi.model.TabResult;
import com.mini.capi.sys.domain.TableInfo;
import com.mini.capi.sys.service.DataService;
import com.mini.capi.sys.service.DbService;
import com.mini.capi.sys.service.DockerService;
import com.mini.capi.sys.service.HostService;
@@ -24,15 +26,29 @@ public class apiController {
@Resource
private HostService hostService;
@Resource
private DataService dataService;
@Resource
private DockerService dockerService;
/**
* 获取表的结构和字段
*/
@GetMapping("/getTableDetail")
public ApiResult<TableInfo> getTableDetail(String token, String taskId) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return dataService.getTableDetail(taskId);
}
/**
* 获取MySQL的当前连接下的所有数据表
*/
@GetMapping("/getApiSourceTables")
@GetMapping("/getSourceTables")
public ApiResult<List<TabResult>> listSourceTables(String token, String dbId) {
// 1. 验证token有效性
if (vToken.isValidToken(token)) {
@@ -42,7 +58,7 @@ public class apiController {
}
@GetMapping("/getApiInfo")
@GetMapping("/getInfo")
public ApiResult<List<HostService.SnapshotDTO>> getApiInfo(String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
@@ -54,7 +70,7 @@ public class apiController {
/**
* 获取容器列表
*/
@GetMapping("/getApiDockerInfo")
@GetMapping("/getDockerInfo")
public ApiResult<?> getDockerInfo(String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
@@ -66,7 +82,7 @@ public class apiController {
/**
* 启动容器
*/
@GetMapping("/getApiStartDockerInfo")
@GetMapping("/getStartDockerInfo")
public ApiResult<?> startDockerInfo(String id, String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
@@ -78,7 +94,7 @@ public class apiController {
/**
* 停止容器
*/
@GetMapping("/getApiStopDockerInfo")
@GetMapping("/getStopDockerInfo")
public ApiResult<?> stopDockerInfo(String id, String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
@@ -91,7 +107,7 @@ public class apiController {
* 获取容器主机的磁盘使用情况
*/
@GetMapping("/getTaskDockerDiskInfo")
public ApiResult<?> jobHostDisk(String token) {
public ApiResult<?> getTaskDockerDiskInfo(String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
@@ -103,7 +119,7 @@ public class apiController {
* 运行全部任务数据同步
*/
@GetMapping("/getTaskSyncDbInfo")
public ApiResult<?> jobSyncAllTask(String token) {
public ApiResult<?> getTaskSyncDbInfo(String token) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
@@ -114,11 +130,10 @@ public class apiController {
* 运行单个任务
*/
@GetMapping("/getTaskSyncDbByInfo")
public ApiResult<?> jobSyncOneTask(String token, String taskId) {
public ApiResult<?> getTaskSyncDbByInfo(String token, String taskId) {
if (vToken.isValidToken(token)) {
return ApiResult.error(401, "无效的访问令牌");
}
return dbService.jobSyncOneTask(taskId);
}
}

View File

@@ -1,9 +0,0 @@
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,134 +0,0 @@
package com.mini.capi.sys.App;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mini.capi.biz.domain.ApiMenus;
import com.mini.capi.biz.domain.ApiModule;
import com.mini.capi.biz.domain.ApiUser;
import com.mini.capi.biz.service.ApiMenusService;
import com.mini.capi.biz.service.ApiModuleService;
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;
import org.springframework.web.bind.annotation.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@RestController
@RequestMapping("/Sys/login")
public class loginController {
@Resource
private ApiUserService userService;
@Resource
private ApiModuleService moduleService;
@Resource
private ApiMenusService menusService;
@Data
public static class LoginParams implements Serializable {
private String account;
private String password;
}
@Data
public static class ApiUserDTO implements Serializable {
private String userId;
/**
* 登录名称
*/
private String username;
/**
* 用户名称
*/
private String uname;
private String token;
// 构造方法(从实体类转换)
public ApiUserDTO(ApiUser apiUser, String token) {
this.userId = apiUser.getUserId();
this.username = apiUser.getApiUser();
this.uname = apiUser.getUname();
this.token = token;
}
}
/**
* 密码校验(生产环境需替换为加密比对)
*/
private boolean verifyPassword(String rawPassword, String encodedPassword) {
return Objects.equals(rawPassword, encodedPassword);
}
/**
* 用户登录
*/
@PostMapping("/userLogin")
public Result login(@RequestBody LoginParams user, HttpSession session) {
try {
QueryWrapper<ApiUser> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("api_user", user.getAccount())
.eq("ustatus", 1);
ApiUser apiUser = userService.getOne(queryWrapper);
if (apiUser == null) {
return Result.error(101, "账户不存在");
}
if (!verifyPassword(user.getPassword(), apiUser.getApiPswd())) {
// 可记录登录失败日志,用于后续风控
return Result.error(102, "账户或密码错误");
}
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() {
List<ApiModule> apiModules = moduleService.list();
List<ModuleMenuDTO> menuDTOList = new ArrayList<>();
for (ApiModule apiModule : apiModules) {
ModuleMenuDTO menuDTO = new ModuleMenuDTO(apiModule.getModuleName(), apiModule.getModuleCode(), apiModule.getCIcon(), apiModule.getCHref(), getMenus(apiModule.getModuleCode()));
menuDTOList.add(menuDTO);
}
return ApiResult.success(menuDTOList);
}
public List<ApiMenus> getMenus(String moduleCode) {
QueryWrapper<ApiMenus> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("module_code", moduleCode);
return menusService.list(queryWrapper);
}
}

View File

@@ -1,31 +0,0 @@
package com.mini.capi.sys.domain;
import com.mini.capi.biz.domain.ApiMenus;
import com.mini.capi.biz.domain.ApiModule;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@Data
public class ModuleMenuDTO implements Serializable {
private String moduleName;
private String moduleCode;
private String icon;
private String href;
List<ApiMenus> menus = new ArrayList<>();
public ModuleMenuDTO() {
}
public ModuleMenuDTO(String moduleName,String moduleCode,String icon,String href,List<ApiMenus> menus){
this.moduleName = moduleName;
this.moduleCode = moduleCode;
this.icon = icon;
this.href = href;
this.menus = menus;
}
}

View File

@@ -1,28 +0,0 @@
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

@@ -0,0 +1,24 @@
package com.mini.capi.sys.domain;
import lombok.Data;
import java.io.Serializable;
@Data
public class TabColumns implements Serializable {
private String tableName;
private Integer sort;
private String colName;
private String colType;
private String colDesc;
private String keyType;
public TabColumns(String tableName, Integer sort, String colName, String colType, String colDesc, String keyType) {
this.tableName = tableName;
this.sort = sort;
this.colName = colName;
this.colType = colType;
this.colDesc = colDesc;
this.keyType = keyType;
}
}

View File

@@ -0,0 +1,24 @@
package com.mini.capi.sys.domain;
import lombok.Data;
import java.io.Serializable;
@Data
public class TabDetail implements Serializable {
private String createTime;
private String dbName;
private String tableName;
private String tableDesc;
private String dataLength;
private String updateTime;
public TabDetail(String createTime, String dbName, String tableName, String tableDesc, String dataLength, String updateTime) {
this.createTime = createTime;
this.dbName = dbName;
this.tableName = tableName;
this.tableDesc = tableDesc;
this.dataLength = dataLength;
this.updateTime = updateTime;
}
}

View File

@@ -0,0 +1,27 @@
package com.mini.capi.sys.domain;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public 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;
}
}

View File

@@ -1,33 +1,26 @@
package com.mini.capi.sys.App;
package com.mini.capi.sys.service;
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 com.mini.capi.sys.domain.TabColumns;
import com.mini.capi.sys.domain.TabDetail;
import com.mini.capi.sys.domain.TableInfo;
import jakarta.annotation.Resource;
import lombok.Data;
import org.springframework.jdbc.core.JdbcTemplate;
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.ArrayList;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/Sys/data")
public class dataController {
@Service
public class DataService {
@Resource
@@ -38,70 +31,6 @@ public class dataController {
private DbConfigService configService;
@Resource
private SyncTablesViewService tablesViewService;
@Data
static class TabDetail implements Serializable {
private String createTime;
private String dbName;
private String tableName;
private String tableDesc;
private String dataLength;
private String updateTime;
public TabDetail(String createTime, String dbName, String tableName, String tableDesc, String dataLength, String updateTime) {
this.createTime = createTime;
this.dbName = dbName;
this.tableName = tableName;
this.tableDesc = tableDesc;
this.dataLength = dataLength;
this.updateTime = updateTime;
}
}
@Data
static class TabColumns implements Serializable {
private String tableName;
private Integer sort;
private String colName;
private String colType;
private String colDesc;
private String keyType;
public TabColumns(String tableName, Integer sort, String colName, String colType, String colDesc, String keyType) {
this.tableName = tableName;
this.sort = sort;
this.colName = colName;
this.colType = colType;
this.colDesc = colDesc;
this.keyType = keyType;
}
}
@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) {
@@ -128,7 +57,6 @@ public class dataController {
return sb.toString();
}
/* ---------- 生成 CREATE TABLE ---------- */
public static String buildDDL(List<TabColumns> columns, TabDetail table) {
if (columns == null || columns.isEmpty() || table == null) {
return "-- no columns or table info";
@@ -190,58 +118,10 @@ public class dataController {
}
/**
* 获取数据配置表
*
* @return
*/
@GetMapping("/getDbList")
public ApiResult<List<SelectOption>> getDbList() {
try {
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);
@@ -253,7 +133,6 @@ public class dataController {
} catch (Exception e) {
return ApiResult.error(401, e.getMessage());
}
// 查询表基本信息
List<TabDetail> data;
try {
@@ -275,7 +154,6 @@ public class dataController {
);
data.sort(Comparator.comparing(TabDetail::getTableName));
} catch (Exception e) {
return ApiResult.error(401, e.getMessage());
}
// 查询表列信息
@@ -301,7 +179,6 @@ public class dataController {
} catch (Exception e) {
return ApiResult.error(401, e.getMessage());
}
// 计算表结构统计信息
long primaryKeyCnt = columns.stream()
.filter(c -> "PRI".equalsIgnoreCase(c.getKeyType()))
@@ -310,7 +187,6 @@ public class dataController {
.filter(c -> !"PRI".equalsIgnoreCase(c.getKeyType()) && !c.getKeyType().isBlank())
.count() + 1; // 包含主键索引
long colCnt = columns.size();
// 构建返回结果
TableInfo tableInfo = new TableInfo(
data.get(0),
@@ -323,6 +199,4 @@ public class dataController {
);
return ApiResult.success(tableInfo);
}
}