Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
V
vue3_onlineEditor
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
pangchong
vue3_onlineEditor
Commits
ca450b0c
Commit
ca450b0c
authored
Apr 07, 2025
by
qlintonger xeno
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 使用LCS对比
parent
50112533
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
83 additions
and
107 deletions
+83
-107
components.d.ts
+0
-1
src/assets/file/Trans-Convert.xml
+3
-2
src/configs/node.config.ts
+3
-0
src/lib/XMLProcessor/src/core/Processing.ts
+16
-97
src/lib/XMLProcessor/src/core/dualCompare.ts
+57
-0
src/lib/XMLProcessor/src/index.ts
+2
-2
src/lib/XMLProcessor/src/typing/index.d.ts
+0
-3
src/views/editor/functions/index.ts
+2
-2
No files found.
components.d.ts
View file @
ca450b0c
...
...
@@ -20,7 +20,6 @@ declare module 'vue' {
NLayoutHeader
:
typeof
import
(
'naive-ui'
)[
'NLayoutHeader'
]
NMessageProvider
:
typeof
import
(
'naive-ui'
)[
'NMessageProvider'
]
NModalProvider
:
typeof
import
(
'naive-ui'
)[
'NModalProvider'
]
NResult
:
typeof
import
(
'naive-ui'
)[
'NResult'
]
NSpace
:
typeof
import
(
'naive-ui'
)[
'NSpace'
]
NTree
:
typeof
import
(
'naive-ui'
)[
'NTree'
]
RouterLink
:
typeof
import
(
'vue-router'
)[
'RouterLink'
]
...
...
src/assets/file/Trans-Convert.xml
View file @
ca450b0c
...
...
@@ -2,17 +2,18 @@
<!--Arbortext, Inc., 1988-2013, v.4002-->
<!DOCTYPE JOBCARD PUBLIC "-//CEA-TEXT//DTD JOBCARD-VER1//EN" "JOBCARD.dtd" [
<!ENTITY nbsp " ">
<!ENTITY rsquo "’">
<!ENTITY rsquo "’">
]>
<JOBCARD>
<EOTK-HEADER></EOTK-HEADER>
<CEP>
<EFFECT
EFFRG=
"001999"
></EFFECT>
<TITLEC>
发动机QEC拆卸(V2500-A5系列)
</TITLEC>
<TITLE>
Remove the Engine's QEC(V2500-A5 series)
测试修改
</TITLE>
<TITLE>
Remove the Engine's QEC(V2500-A5 series)
</TITLE>
<TOPIC
CK-LEVEL=
"C"
>
<TITLEC>
飞机/发动机基本信息
</TITLEC>
<TITLE>
AIRCRAFT/ENGINE INFORMATION
</TITLE>
<TITLE>
AIRCRAFT/ENGINE INFORMATION
</TITLE>
<STEP
CK-LEVEL=
"C"
>
<EFFECT
EFFRG=
"001999"
></EFFECT>
<RECORD-LINE>
...
...
src/configs/node.config.ts
View file @
ca450b0c
...
...
@@ -24,3 +24,5 @@ export const nodeSet = [
'STEP'
,
'RECORD-LINE'
]
export
const
contentHoldNode
=
[
'PARA'
,
'TITLE'
]
\ No newline at end of file
src/lib/XMLProcessor/src/core/Processing.ts
View file @
ca450b0c
...
...
@@ -2,7 +2,7 @@
import
{
NewTreeModification
,
OldTreeModification
,
TreeRenderResult
,
TreeRenderResultFlatted
}
from
'@/lib/XMLProcessor/src/typing'
import
{
md5
}
from
'js-md5'
import
{
getUUID
}
from
'../utils/uuid.ts'
import
{
cloneDeep
}
from
'lodash
'
import
{
dualCompare
}
from
'@/lib/XMLProcessor/src/core/dualCompare.ts
'
// 定义 Processing 类,用于处理 XML 数据
export
class
Processing
{
...
...
@@ -41,7 +41,8 @@ export class Processing {
dualCompareFromString
(
xmlStringOld
:
string
,
xmlStringNew
:
string
,
bothHandledNode
:
string
[]
bothHandledNode
:
string
[],
contentHoldNode
:
string
[]
):
{
dataForNew
:
NewTreeModification
dataForOld
:
OldTreeModification
...
...
@@ -59,106 +60,24 @@ export class Processing {
treeA
.
documentElement
.
querySelectorAll
(
':not([data-key])'
).
forEach
((
node
)
=>
node
.
remove
())
treeB
.
documentElement
.
querySelectorAll
(
':not([data-key])'
).
forEach
((
node
)
=>
node
.
remove
())
// 扁平化所有节点
const
resultAFlatted
=
this
.
flattenTree
(
resultA
)
const
resultBFlatted
=
this
.
flattenTree
(
resultB
)
const
dataForOld
:
OldTreeModification
=
{
Changed
:
[],
Deleted
:
[]
}
const
dataForNew
:
NewTreeModification
=
{
Changed
:
[],
Added
:
[]
}
// 获取序列号、hash以及标签中任一不相同的节点
const
nonSameInOld
=
resultAFlatted
.
filter
(
a
=>
{
return
!
resultBFlatted
.
find
(
v
=>
v
.
chained
.
join
(
'$'
)
===
a
.
chained
.
join
(
'$'
)
&&
v
.
hash
===
a
.
hash
&&
a
.
label
===
v
.
label
);
});
const
nonSameInNew
=
resultBFlatted
.
filter
(
a
=>
{
return
!
resultAFlatted
.
find
(
v
=>
v
.
chained
.
join
(
'$'
)
===
a
.
chained
.
join
(
'$'
)
&&
v
.
hash
===
a
.
hash
&&
a
.
label
===
v
.
label
);
});
// 如果标签和序列号相同,但是hash不同,则视为修改
const
nodeChangedInOld
=
nonSameInOld
.
filter
(
a
=>
{
return
nonSameInNew
.
find
(
v
=>
v
.
chained
.
join
(
'$'
)
===
a
.
chained
.
join
(
'$'
)
&&
a
.
label
===
v
.
label
);
});
const
nodeChangedInNew
=
nonSameInNew
.
filter
(
a
=>
{
return
nonSameInOld
.
find
(
v
=>
v
.
chained
.
join
(
'$'
)
===
a
.
chained
.
join
(
'$'
)
&&
a
.
label
===
v
.
label
);
});
const
resultAFlatted
=
this
.
flattenTree
(
resultA
).
filter
((
item
)
=>
{
return
contentHoldNode
.
includes
(
item
.
label
)
})
const
resultBFlatted
=
this
.
flattenTree
(
resultB
).
filter
((
item
)
=>
{
return
contentHoldNode
.
includes
(
item
.
label
)
})
// 再获取剩下来不同的节点
const
stillDiffInOld
=
nonSameInOld
.
filter
(
a
=>
{
return
!
nodeChangedInOld
.
find
(
v
=>
v
.
key
===
a
.
key
);
});
const
results
=
dualCompare
(
resultAFlatted
,
resultBFlatted
)
.
filter
(
a
=>
a
.
type
!==
'same'
);
let
stillDiffInNew
=
nonSameInNew
.
filter
(
a
=>
{
return
!
nodeChangedInNew
.
find
(
v
=>
v
.
key
===
a
.
key
);
});
console
.
log
(
'results here'
,
results
)
// 以PARA和TITLE构建一组树,只追踪到上一级父节点即可,仅对新增节点有效
// 首先筛选出基层节点PARA和TITLE即可
let
allBaseNodeInNew
=
stillDiffInNew
.
filter
(
a
=>
{
return
a
.
label
===
'PARA'
||
a
.
label
===
'TITLE'
;
});
// 构建树节点
let
newDom
=
allBaseNodeInNew
.
map
(
a
=>
{
let
chainedParentNode
:
TreeRenderResultFlatted
[]
=
[
a
];
let
currentA
=
treeB
.
documentElement
.
querySelector
(
`[data-key="
${
a
.
key
}
"]`
)
while
(
currentA
)
{
currentA
=
currentA
.
parentElement
if
(
!
currentA
||
currentA
.
tagName
===
'JOBCARD'
)
{
break
}
let
keyVal
=
currentA
.
getAttribute
(
'data-key'
);
let
foundParentInNew
=
stillDiffInNew
.
find
(
v
=>
v
.
key
===
keyVal
);
if
(
foundParentInNew
)
{
chainedParentNode
.
push
(
foundParentInNew
)
}
const
dataForOld
:
OldTreeModification
=
{
Deleted
:
results
.
filter
(
item
=>
item
.
type
===
'deleted'
).
map
(
a
=>
a
.
item
)
}
chainedParentNode
.
reverse
();
let
targetChildren
=
null
return
chainedParentNode
.
reduce
((
acc
,
cur
)
=>
{
if
(
!
acc
)
{
// @ts-ignore
cur
.
children
=
[]
acc
=
cur
}
else
{
targetChildren
.
push
(
cur
)
// @ts-ignore
cur
.
children
=
[]
const
dataForNew
:
NewTreeModification
=
{
Added
:
results
.
filter
(
item
=>
item
.
type
===
'added'
).
map
(
a
=>
a
.
item
)
}
// @ts-ignore
targetChildren
=
cur
.
children
return
acc
;
},
null
as
null
|
TreeRenderResult
);
});
// 将修改的节点添加到结果中
dataForOld
.
Changed
.
push
(...
nodeChangedInOld
);
dataForNew
.
Changed
.
push
(...
nodeChangedInNew
);
// 将删除的节点添加到结果中
dataForOld
.
Deleted
.
push
(...
stillDiffInOld
);
// 将新增的节点添加到结果中
// @ts-ignore
dataForNew
.
Added
.
push
(...
newDom
);
return
{
dataForNew
,
...
...
src/lib/XMLProcessor/src/core/dualCompare.ts
0 → 100644
View file @
ca450b0c
import
{
TreeRenderResultFlatted
}
from
'@/lib/XMLProcessor/src/typing'
import
{
cloneDeep
}
from
'lodash'
export
function
dualCompare
(
oldItems
:
TreeRenderResultFlatted
[],
newItems
:
TreeRenderResultFlatted
[])
{
const
oldItemsCount
=
oldItems
.
length
const
newItemsCount
=
newItems
.
length
const
dp
:
number
[][]
=
Array
.
from
({
length
:
oldItemsCount
+
1
},
()
=>
Array
(
newItemsCount
+
1
).
fill
(
0
))
for
(
let
i
=
1
;
i
<=
oldItemsCount
;
i
++
)
{
for
(
let
j
=
1
;
j
<=
newItemsCount
;
j
++
)
{
if
(
oldItems
[
i
-
1
].
hash
===
newItems
[
j
-
1
].
hash
&&
oldItems
[
i
-
1
].
label
===
newItems
[
j
-
1
].
label
)
{
dp
[
i
][
j
]
=
dp
[
i
-
1
][
j
-
1
]
+
1
}
else
{
dp
[
i
][
j
]
=
Math
.
max
(
dp
[
i
-
1
][
j
],
dp
[
i
][
j
-
1
])
}
}
}
let
i
=
oldItemsCount
,
j
=
newItemsCount
const
result
:
Array
<
{
type
:
'same'
|
'deleted'
|
'added'
;
item
:
TreeRenderResultFlatted
}
>
=
[]
while
(
i
>
0
&&
j
>
0
)
{
if
(
oldItems
[
i
-
1
].
hash
===
newItems
[
j
-
1
].
hash
&&
oldItems
[
i
-
1
].
label
===
newItems
[
j
-
1
].
label
)
{
result
.
unshift
({
type
:
'same'
,
item
:
cloneDeep
(
oldItems
[
i
-
1
])
})
i
--
j
--
}
else
if
(
dp
[
i
-
1
][
j
]
>
dp
[
i
][
j
-
1
])
{
result
.
unshift
({
type
:
'deleted'
,
item
:
cloneDeep
(
oldItems
[
i
-
1
])
})
i
--
}
else
{
result
.
unshift
({
type
:
'added'
,
item
:
cloneDeep
(
newItems
[
j
-
1
])
})
j
--
}
}
while
(
i
>
0
)
{
result
.
unshift
({
type
:
'deleted'
,
item
:
cloneDeep
(
oldItems
[
i
-
1
])
})
i
--
}
while
(
j
>
0
)
{
result
.
unshift
({
type
:
'added'
,
item
:
cloneDeep
(
newItems
[
j
-
1
])
})
j
--
}
return
result
}
src/lib/XMLProcessor/src/index.ts
View file @
ca450b0c
...
...
@@ -2,12 +2,12 @@ import { Processing } from '@/lib/XMLProcessor/src/core/Processing.ts'
import
{
Plugin
,
getCurrentInstance
}
from
'vue'
import
TextA
from
'@/assets/file/CES-QEC-V250-A.xml?raw'
import
TextB
from
'@/assets/file/Trans-Convert.xml?raw'
import
{
nodeSet
}
from
'@/configs/node.config'
import
{
nodeSet
,
contentHoldNode
}
from
'@/configs/node.config'
const
p
=
new
Processing
()
// @ts-ignore
window
.
$p
=
function
()
{
let
nodeV
=
p
.
dualCompareFromString
(
TextA
,
TextB
,
nodeSet
)
let
nodeV
=
p
.
dualCompareFromString
(
TextA
,
TextB
,
nodeSet
,
contentHoldNode
)
console
.
log
(
'v-h'
,
nodeV
)
}
export
const
XMLProcessing
:
Plugin
=
function
(
app
)
{
...
...
src/lib/XMLProcessor/src/typing/index.d.ts
View file @
ca450b0c
...
...
@@ -18,11 +18,9 @@ export type TreeRenderResultFlatted = {
}
export
type
OldTreeModification
=
{
Changed
:
TreeRenderResultFlatted
[],
Deleted
:
TreeRenderResultFlatted
[]
}
export
type
NewTreeModification
=
{
Added
:
TreeRenderResultFlatted
[],
Changed
:
TreeRenderResultFlatted
[],
}
\ No newline at end of file
src/views/editor/functions/index.ts
View file @
ca450b0c
...
...
@@ -6,7 +6,7 @@ import { getUUID } from '@/utils'
import
{
compareLeftData
,
compareRightData
,
showCompare
}
from
'../constants/compare'
import
TextA
from
'@/assets/file/CES-QEC-V250-A.xml?raw'
import
TextB
from
'@/assets/file/Trans-Convert.xml?raw'
import
{
nodeSet
}
from
'@/configs/node.config'
import
{
nodeSet
,
contentHoldNode
}
from
'@/configs/node.config'
import
{
handleLeftDifferent
,
handleRightDifferent
}
from
'./compare'
export
const
handleCreated
=
(
editor
:
IDomEditor
)
=>
{
...
...
@@ -100,7 +100,7 @@ export const uploadXml = async () => {
export
const
compareXml
=
()
=>
{
showCompare
.
value
=
true
const
xmlProcessing
=
useXMLProcessing
()
const
res
=
xmlProcessing
.
dualCompareFromString
(
TextA
,
TextB
,
nodeSet
)
const
res
=
xmlProcessing
.
dualCompareFromString
(
TextA
,
TextB
,
nodeSet
,
contentHoldNode
)
console
.
log
(
res
)
//渲染数据
compareLeftData
.
value
=
res
.
xmlContentOld
...
...
Write
Preview
Markdown
is supported
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