Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
xiaofang li
MeterSphere
Commits
bd2558c0
Commit
bd2558c0
authored
3 years ago
by
chenjianxing
Committed by
jianxing
3 years ago
Browse files
Options
Download
Email Patches
Plain Diff
fix: 关系图保存时检测环并且合并图
parent
03d3dceb
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
backend/src/main/java/io/metersphere/base/mapper/ext/ExtRelationshipEdgeMapper.java
+10
-0
...etersphere/base/mapper/ext/ExtRelationshipEdgeMapper.java
backend/src/main/java/io/metersphere/base/mapper/ext/ExtRelationshipEdgeMapper.xml
+17
-0
...metersphere/base/mapper/ext/ExtRelationshipEdgeMapper.xml
backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml
+1
-1
...java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml
backend/src/main/java/io/metersphere/service/RelationshipEdgeService.java
+87
-27
.../java/io/metersphere/service/RelationshipEdgeService.java
frontend/src/business/components/track/case/components/TestCaseList.vue
+1
-2
...usiness/components/track/case/components/TestCaseList.vue
with
116 additions
and
30 deletions
+116
-30
backend/src/main/java/io/metersphere/base/mapper/ext/ExtRelationshipEdgeMapper.java
0 → 100644
+
10
-
0
View file @
bd2558c0
package
io.metersphere.base.mapper.ext
;
import
org.apache.ibatis.annotations.Param
;
import
java.util.List
;
public
interface
ExtRelationshipEdgeMapper
{
List
<
String
>
getGraphIdsByNodeIds
(
@Param
(
"ids"
)
List
<
String
>
ids
);
}
This diff is collapsed.
Click to expand it.
backend/src/main/java/io/metersphere/base/mapper/ext/ExtRelationshipEdgeMapper.xml
0 → 100644
+
17
-
0
View file @
bd2558c0
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"io.metersphere.base.mapper.ext.ExtRelationshipEdgeMapper"
>
<select
id=
"getGraphIdsByNodeIds"
resultType=
"java.lang.String"
>
select distinct graph_id
from relationship_edge
where source_id in
<foreach
collection=
"ids"
item=
"id"
open=
"("
close=
")"
separator=
","
>
#{id}
</foreach>
or target_id in
<foreach
collection=
"ids"
item=
"id"
open=
"("
close=
")"
separator=
","
>
#{id}
</foreach>
</select>
</mapper>
This diff is collapsed.
Click to expand it.
backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestCaseMapper.xml
+
1
-
1
View file @
bd2558c0
...
...
@@ -563,7 +563,7 @@
<foreach
collection=
"ids"
item=
"id"
separator=
","
open=
"("
close=
")"
>
#{id}
</foreach>
and test_case.status != 'Trash';
and
(
test_case.status != 'Trash'
or test_case.status is NULL)
;
</select>
<update
id=
"deleteToGc"
>
...
...
This diff is collapsed.
Click to expand it.
backend/src/main/java/io/metersphere/service/RelationshipEdgeService.java
+
87
-
27
View file @
bd2558c0
...
...
@@ -4,6 +4,8 @@ package io.metersphere.service;
import
io.metersphere.base.domain.RelationshipEdge
;
import
io.metersphere.base.domain.RelationshipEdgeExample
;
import
io.metersphere.base.mapper.RelationshipEdgeMapper
;
import
io.metersphere.base.mapper.ext.ExtRelationshipEdgeMapper
;
import
io.metersphere.commons.exception.MSException
;
import
io.metersphere.commons.utils.SessionUtils
;
import
io.metersphere.controller.request.RelationshipEdgeRequest
;
import
org.apache.commons.collections.CollectionUtils
;
...
...
@@ -15,9 +17,7 @@ import org.springframework.stereotype.Service;
import
org.springframework.transaction.annotation.Transactional
;
import
javax.annotation.Resource
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.UUID
;
import
java.util.*
;
import
java.util.stream.Collectors
;
/**
...
...
@@ -31,6 +31,8 @@ public class RelationshipEdgeService {
@Resource
private
RelationshipEdgeMapper
relationshipEdgeMapper
;
@Resource
private
ExtRelationshipEdgeMapper
extRelationshipEdgeMapper
;
@Resource
private
SqlSessionFactory
sqlSessionFactory
;
public
void
delete
(
String
sourceId
,
String
targetId
)
{
...
...
@@ -95,29 +97,51 @@ public class RelationshipEdgeService {
return
relationshipEdgeMapper
.
selectByExample
(
example
);
}
/**
* 保存新的边
* 校验是否存在环
* 同时将两个不连通的图合并成一个图
* @param request
*/
public
void
saveBatch
(
RelationshipEdgeRequest
request
)
{
SqlSession
sqlSession
=
sqlSessionFactory
.
openSession
(
ExecutorType
.
BATCH
);
RelationshipEdgeMapper
batchMapper
=
sqlSession
.
getMapper
(
RelationshipEdgeMapper
.
class
);
String
graphId
=
getGraphId
(
request
);
// todo 检验是否有环
String
graphId
=
UUID
.
randomUUID
().
toString
(
);
List
<
RelationshipEdge
>
relationshipEdges
=
getEdgesBySaveRequest
(
request
);
Set
<
String
>
addEdgesIds
=
new
HashSet
<>();
if
(
CollectionUtils
.
isNotEmpty
(
request
.
getTargetIds
()))
{
for
(
String
targetId
:
request
.
getTargetIds
()
)
{
request
.
getTargetIds
()
.
forEach
(
targetId
->
{
RelationshipEdge
edge
=
getNewRelationshipEdge
(
graphId
,
request
.
getId
(),
targetId
,
request
.
getType
());
batchMapper
.
insert
(
edge
);
}
relationshipEdges
.
add
(
edge
);
addEdgesIds
.
add
(
edge
.
getSourceId
()
+
edge
.
getTargetId
());
});
}
if
(
CollectionUtils
.
isNotEmpty
(
request
.
getSourceIds
()))
{
for
(
String
sourceId
:
request
.
getSourceIds
()
)
{
request
.
getSourceIds
()
.
forEach
(
sourceId
->
{
RelationshipEdge
edge
=
getNewRelationshipEdge
(
graphId
,
sourceId
,
request
.
getId
(),
request
.
getType
());
batchMapper
.
insert
(
edge
);
}
relationshipEdges
.
add
(
edge
);
addEdgesIds
.
add
(
edge
.
getSourceId
()
+
edge
.
getTargetId
());
});
}
// 判断是否有环, 两个方向都搜索一遍
if
(
directedCycle
(
request
.
getId
(),
relationshipEdges
,
new
HashSet
<>(),
true
)
||
directedCycle
(
request
.
getId
(),
relationshipEdges
,
new
HashSet
<>(),
false
))
{
MSException
.
throwException
(
"关联后存在循环依赖,请检查依赖关系"
);
};
relationshipEdges
.
forEach
(
item
->
{
if
(
addEdgesIds
.
contains
(
item
.
getSourceId
()
+
item
.
getTargetId
()))
{
batchMapper
.
insert
(
item
);
}
else
{
item
.
setGraphId
(
graphId
);
// 把原来图的id设置成合并后新的图的id
batchMapper
.
updateByPrimaryKey
(
item
);
}
});
sqlSession
.
flushStatements
();
}
...
...
@@ -133,15 +157,11 @@ public class RelationshipEdgeService {
}
/**
*
获取当前节点
所在
的
图的
id
*
查找要关联的边
所在图的
所有的边
* @param request
* @return
*/
private
String
getGraphId
(
RelationshipEdgeRequest
request
)
{
// 判断这些顶点是否已经和其他顶点连通
// 连通的话,加到同一个图中,否则新建一个图,即 graphId
String
graphId
=
UUID
.
randomUUID
().
toString
();
public
List
<
RelationshipEdge
>
getEdgesBySaveRequest
(
RelationshipEdgeRequest
request
)
{
List
<
String
>
graphNodes
=
new
ArrayList
<>();
graphNodes
.
add
(
request
.
getId
());
if
(
request
.
getTargetIds
()
!=
null
)
{
...
...
@@ -150,18 +170,58 @@ public class RelationshipEdgeService {
if
(
request
.
getSourceIds
()
!=
null
)
{
graphNodes
.
addAll
(
request
.
getSourceIds
());
}
List
<
String
>
graphIds
=
extRelationshipEdgeMapper
.
getGraphIdsByNodeIds
(
graphNodes
);
if
(
CollectionUtils
.
isEmpty
(
graphIds
))
{
return
new
ArrayList
<>();
}
RelationshipEdgeExample
example
=
new
RelationshipEdgeExample
();
example
.
createCriteria
()
.
andSourceIdIn
(
graphNodes
);
example
.
or
(
example
.
createCriteria
()
.
andTargetIdIn
(
graphNodes
)
);
List
<
RelationshipEdge
>
relationshipEdges
=
relationshipEdgeMapper
.
selectByExample
(
example
);
if
(
CollectionUtils
.
isNotEmpty
(
relationshipEdges
))
{
return
relationshipEdges
.
get
(
0
).
getGraphId
();
.
andGraphIdIn
(
graphIds
);
return
relationshipEdgeMapper
.
selectByExample
(
example
);
}
/**
* 给定一点,深度搜索该连通图中是否存在环
* @param id
* @param edges
* @param markSet
* @param isForwardDirection
* @return
*/
public
boolean
directedCycle
(
String
id
,
List
<
RelationshipEdge
>
edges
,
Set
<
String
>
markSet
,
Boolean
isForwardDirection
)
{
if
(
markSet
.
contains
(
id
))
{
// 如果已经访问过该节点,则说明存在环
return
true
;
}
return
graphId
;
markSet
.
add
(
id
);
ArrayList
<
String
>
nextLevelNodes
=
new
ArrayList
();
for
(
RelationshipEdge
relationshipEdge
:
edges
)
{
if
(
isForwardDirection
)
{
// 正向则搜索 sourceId 是当前节点的边
if
(
id
.
equals
(
relationshipEdge
.
getSourceId
()))
{
nextLevelNodes
.
add
(
relationshipEdge
.
getTargetId
());
}
}
else
{
if
(
id
.
equals
(
relationshipEdge
.
getTargetId
()))
{
nextLevelNodes
.
add
(
relationshipEdge
.
getSourceId
());
}
}
}
for
(
String
nextNode
:
nextLevelNodes
)
{
if
(
directedCycle
(
nextNode
,
edges
,
markSet
,
isForwardDirection
))
{
return
true
;
};
}
// 关键,递归完这一条路径要把这个标记去掉,否则会误判为有环
// 比如 1->3, 1->2->3 , 3 经过多次但是无环
markSet
.
remove
(
id
);
return
false
;
}
/**
...
...
This diff is collapsed.
Click to expand it.
frontend/src/business/components/track/case/components/TestCaseList.vue
+
1
-
2
View file @
bd2558c0
...
...
@@ -446,7 +446,6 @@ export default {
activated
()
{
this
.
getTemplateField
();
this
.
condition
.
filters
=
{
reviewStatus
:
[
"
Prepare
"
,
"
Pass
"
,
"
UnPass
"
]};
this
.
condition
.
filters
=
{
status
:
[
"
Prepare
"
,
"
Underway
"
,
"
Completed
"
]}
let
ids
=
this
.
$route
.
params
.
ids
;
if
(
ids
)
{
this
.
condition
.
ids
=
ids
;
...
...
@@ -458,7 +457,7 @@ export default {
selectNodeIds
()
{
this
.
page
.
currentPage
=
1
;
if
(
!
this
.
trashEnable
){
this
.
condition
.
filters
.
status
=
[
"
Prepare
"
,
"
Underway
"
,
"
Completed
"
];
this
.
condition
.
filters
.
status
=
[];
}
initCondition
(
this
.
condition
,
false
);
this
.
initTableData
();
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment