提交 e18356b6 authored 作者: Matrix's avatar Matrix

fix(用户模块): 将用户模块添加到项目中

上级 0c932748
......@@ -6,4 +6,5 @@ import lombok.Data;
public class Hello {
private String name;
}
package org.matrix.database.controller;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.matrix.actuators.usecase.CaseActuator;
import org.matrix.actuators.usecase.TestCaseExecuteResult;
import org.matrix.database.entity.ExecutionRecord;
import org.matrix.database.entity.TestCase;
import org.matrix.database.entity.TestCaseBTO;
import org.matrix.database.entity.TestData;
import org.matrix.database.mapper.ExecutionHistoryMapper;
import org.matrix.database.service.IExecutionHistoryService;
import org.matrix.database.vo.ExecutionHistoryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static java.util.stream.Collectors.groupingBy;
/**
* TestController. 用于测试的控制器
*
......@@ -32,6 +35,15 @@ public class TestController {
@Autowired
IExecutionHistoryService executionHistoryService;
public String treeTest() {
List<ExecutionRecord> recordList = new ArrayList<>();
Map<Long, Map<Long, Map<Long, List<ExecutionRecord>>>> map = recordList.stream().collect(
groupingBy(ExecutionRecord::getTestJobId,
groupingBy(ExecutionRecord::getTestCaseId,
groupingBy(ExecutionRecord::getTestDataId))));
return "";
}
/**
* 获得表名,用于测试http执行器的调用
*/
......@@ -83,8 +95,8 @@ public class TestController {
@GetMapping("/sendMessage")
public ResponseEntity sendMessage(String tableName) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("message",String.format("你好: %s",tableName));
JSONObject jsonObject = new JSONObject();
jsonObject.put("message", String.format("你好: %s", tableName));
return ResponseEntity.ok(jsonObject);
}
......@@ -121,7 +133,7 @@ public class TestController {
TestCaseBTO testCaseBTO = new TestCaseBTO();
testCaseBTO.setTestCase(testCase);
testCaseBTO.setTestData(testData);
TestCaseExecuteResult testCaseExecuteResult = caseActuator.executeTestCase(testCaseBTO,1L,1L);
TestCaseExecuteResult testCaseExecuteResult = caseActuator.executeTestCase(testCaseBTO, 1L, 1L);
System.out.println(testCaseExecuteResult);
}
}
package org.matrix.database.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.matrix.database.entity.ExecutionHistory;
import org.matrix.database.vo.ExecutionHisVo;
import org.matrix.database.vo.ExecutionHistoryVo;
import org.springframework.web.bind.annotation.RequestParam;
......
package org.matrix.database.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.matrix.enums.ExecutionHistoryStatus;
import org.matrix.enums.ExecutionType;
import java.time.LocalDateTime;
/**
* ExecutionHisVo.
*
* @author Matrix <xhyrzldf@gmail.com>
* @since 2022/3/16 at 4:16 PM
* Suffering is the most powerful teacher of life.
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ExecutionHisVo {
/**
* 调试/执行的类型 - 1 = 接口case 2 = 测试任务job
*/
private ExecutionType type;
/**
* 主键id type 1 = case(接口)主键id , 2 = job(测试任务)主键id
*/
private Long id;
/**
* uniqueKey 独立key
*/
private String uniqueKey;
/**
* 调试/执行的顺序号
*/
private Long executionOrder;
/**
* 调试/执行的开始时间
*/
private LocalDateTime startTime;
/**
* 调试/执行 锁消耗的时间
*/
private Long costMills;
/**
* 状态
*/
private ExecutionHistoryStatus status;
}
......@@ -12,10 +12,17 @@ import java.time.LocalDateTime;
@Data
public class ExecutionHistoryVo extends ExecutionHistory {
/**
* 名称(case-caseName , job - jobName)
*/
private String caseName;
private String dataName;
/**
* caseId -> 这一条用例运行时的开始时间 startTime最小值
* jobId -> 这一个测试任务的开始时间 startTime最小值
*/
private LocalDateTime startTime;
private LocalDateTime endTime;
......
package org.matrix.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
......@@ -33,6 +34,7 @@ public enum ExecutionHistoryStatus {
/**
* 数据库里记录的字段使用该字段来记录
*/
@JsonValue
@EnumValue
private final int code;
......
package org.matrix.enums;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
/**
* ExecutionType.
*
* @author Matrix <xhyrzldf@gmail.com>
* @since 2022/3/16 at 4:35 PM
* Suffering is the most powerful teacher of life.
*/
@AllArgsConstructor
public enum ExecutionType {
/**
* 接口类的执行记录,2层数据结构
*/
TEST_CASE(1,"接口类的执行记录,2层数据结构"),
/**
* "测试任务类的执行记录,3层数据结构"
*/
TEST_JOB(2,"测试任务类的执行记录,3层数据结构");
/**
* 1,2
*/
private final int code;
/**
* 描述
*/
private final String des;
@JsonValue
public int getCode() {
return code;
}
public String getDes() {
return des;
}
}
......@@ -26,6 +26,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> errorMessage(Exception e) {
log.error("[其他异常] {}", e.toString());
e.printStackTrace();
return ResponseEntity.status(500).body("服务器异常" + e.getMessage());
}
......@@ -38,6 +39,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(GlobalException.class)
public ResponseEntity<String> errorMessage(GlobalException e) {
log.warn("[自定义异常]" + e.toString());
e.printStackTrace();
return ResponseEntity.status(400).body(e.getMessage());
}
......
package org.matrix.util;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.testng.Assert;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* TreeUtils.
*
* @author Matrix <xhyrzldf@gmail.com>
* @since 2022/3/16 at 8:24 PM
* Suffering is the most powerful teacher of life.
*/
public class TreeUtils {
Map<Long, OrgNode> orgNodeMap = new HashMap<>();
{
//初始化测试用的数据
orgNodeMap.put(1L, new OrgNode(1, "Jack", 4));
orgNodeMap.put(2L, new OrgNode(2, "Rose", 4));
orgNodeMap.put(3L, new OrgNode(3, "Lucy", 0));
orgNodeMap.put(4L, new OrgNode(4, "Alice", 3));
orgNodeMap.put(5L, new OrgNode(5, "Tom", 3));
orgNodeMap.put(6L, new OrgNode(6, "Jason", 8));
orgNodeMap.put(7L, new OrgNode(7, "Emma", 5));
orgNodeMap.put(8L, new OrgNode(8, "Brown", 5));
}
public Optional<OrgNode> getParentOrgNode(long parentId) {
return Optional.ofNullable(orgNodeMap.get(parentId));
}
public void parseTree() {
//1.从DB中查询出List<OrgNode>
List<OrgNode> orgNodeList = new ArrayList<>(orgNodeMap.values());
//2.将List<OrgNode>解析并转化为Node<OrgNodeVo>对象
List<OrgNodeVo> rootNodeList = parseTreeFromDown(orgNodeList,
OrgNode::getId,
orgNode -> getParentOrgNode(orgNode.getParentId()),
OrgNode::toVo,
OrgNodeVo::addChildNode);
Assert.assertTrue(rootNodeList.size() >= 1);
//打印出结果
for (OrgNodeVo root : rootNodeList) {
printTreeNode(root, OrgNodeVo::getName, OrgNodeVo::getChildNodes, 0);
}
}
/**
* 自底向上整理出树结构,并存放在Node对象中
* 利用Map将原始List的对象的位置重新整理,并将所有的指针都设置好
*
* @param originList 原始待整理的列表
* @param getId 列表里每个对象获取自身id的方法,用于避免重复计算
* @param getParent 列表里每个对象获取父对象的方法
* @param mapToTargetNode 列表里的原始对象转化为最终对象的方法,默认为t->t,即不变(传入null即可)
* @param targetSetChild 用于最终对象设置子节点的方法,形如R.setChild(R),或者R.addChildList(R)
* @param <R> 最终对象
* @param <V> 原始对象
* @param <T> 主键类型
* @return 根节点对象集合
*/
public static <R, V, T extends Number> List<R> parseTreeFromDown(List<V> originList,
Function<V, T> getId,
Function<V, Optional<V>> getParent,
Function<V, R> mapToTargetNode,
BiConsumer<R, R> targetSetChild) {
//K为主键id , Value 为最终对象
Map<T, R> map = new HashMap<>(32);
List<T> rootIds = new ArrayList<>();
for (V originNode : originList) {
//对于所有节点,如果已经遍历过了则直接取已经设置过子节点的引用
R targetNode = map.getOrDefault(getId.apply(originNode), mapToTargetNode.apply(originNode));
Optional<V> parentNode = getParent.apply(originNode);
//查询父节点,如果不存在父节点则证明该节点为根节点,直接放入map中
if (parentNode.isPresent()) {
//否则查询该父节点是否已经已经被连接过指针,如果连接过则取出连接过的继续连接,否则进行第一次连接并存入map
V parent = parentNode.get();
T parentId = getId.apply(parent);
R parentInMap = map.get(parentId);
if (parentInMap == null) {
R newNode = mapToTargetNode.apply(parent);
targetSetChild.accept(newNode, targetNode);
map.put(parentId, newNode);
} else {
targetSetChild.accept(parentInMap, targetNode);
}
//连接完处理之后还需要将自身这个节点存入map
map.put(getId.apply(originNode), targetNode);
} else {
//root node
map.put(getId.apply(originNode), targetNode);
rootIds.add(getId.apply(originNode));
}
}
//根据rootIds返回所有的顶层节点
return rootIds.stream().map(map::get).collect(Collectors.toList());
}
/**
* 打印出树状对象结构
*
* @param rootNode 树的根节点
* @param printProperty 想打印的属性
* @param getChild 子节点
* @param stackDepth 栈深度
* @param <T> 节点对象类型
* @param <R> 要打印的属性类型
*/
public <T, R> void printTreeNode(T rootNode,
Function<T, R> printProperty,
Function<T, List<T>> getChild,
int stackDepth) {
StringJoiner joiner = new StringJoiner("\t");
IntStream.range(0, stackDepth).mapToObj(i -> "").forEach(joiner::add);
joiner.add(printProperty.apply(rootNode).toString());
System.out.println(joiner.toString());
for (T childNode : getChild.apply(rootNode)) {
int currentLevel = stackDepth + 1;
printTreeNode(childNode, printProperty, getChild, currentLevel);
}
}
/**
* data struct
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
class OrgNode {
public long id;
public String name;
public long parentId;
public OrgNodeVo toVo() {
return new OrgNodeVo(id, name, new ArrayList<>(4));
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString(exclude = "childNodes")
class OrgNodeVo {
public long id;
public String name;
public List<OrgNodeVo> childNodes = new ArrayList<>(4);
public void addChildNode(OrgNodeVo orgNodeVo) {
childNodes.add(orgNodeVo);
}
}
}
package org.matrix.local.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
/**
* ScheduledConfig.
*
* @author Matrix <xhyrzldf@gmail.com>
* @since 2022/3/16 at 8:05 PM
* Suffering is the most powerful teacher of life.
*/
@Configuration
public class ScheduledConfig {
@Bean
public TaskScheduler taskScheduler(){
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(10);
taskScheduler.initialize();
return taskScheduler;
}
}
......@@ -18,7 +18,12 @@
<groupId>org.matrix</groupId>
<artifactId>kt-base</artifactId>
</dependency>
<dependency>
<groupId>org.matrix</groupId>
<artifactId>kt-user</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
......
package org.matrix;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Hello world!
*
* @author 27795
*/
@EnableSwagger2
@EnableCaching
@EnableScheduling
@SpringBootApplication
@MapperScan(basePackages = {"org.matrix.database.mapper", "org.matrix.zentao.mapper","org.matrix.remote.mapper","org.matrix.local.mapper"})
@ComponentScan(basePackages = {"org.matrix.local","org.matrix.remote","org.matrix"})
public class WebBootApplication {
public static void main(String[] args) {
SpringApplication.run(BaseBootApplication.class);
......
......@@ -5,6 +5,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
......@@ -14,7 +15,6 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
* @author mry
*/
@Configuration
@EnableSwagger2
public class SwaggerConfigApi {
@Bean
......@@ -24,6 +24,7 @@ public class SwaggerConfigApi {
.apiInfo(apiInfo())
//选择哪些接口作为swagger的doc发布
.select()
.apis(RequestHandlerSelectors.basePackage("org.matrix"))
//不显示错误的接口地址
.paths(Predicates.not(PathSelectors.regex("/error.*")))
.paths(PathSelectors.any())
......
......@@ -11,6 +11,7 @@ import org.matrix.database.service.ITestJobService;
import org.matrix.database.vo.CommonResult;
import org.matrix.database.vo.CommonResultObj;
import org.matrix.database.vo.TestJobVo;
import org.matrix.exception.GlobalException;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
......
package org.matrix.autotest.pojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* LoginQuery.
*
* @author Matrix <xhyrzldf@gmail.com>
* @since 2022/3/15 at 8:47 PM
* Suffering is the most powerful teacher of life.
*/
@Data
@ApiModel("用于登录的查询类")
public class LoginQuery {
@ApiModelProperty("用户名")
private String username;
@ApiModelProperty("密码")
private String password;
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论