feat: 完善范式润色功能和相关组件
- 新增范式选择模态框 (ParadigmSelectorModal) - 新增差异标注面板 (DiffAnnotationPanel) - 新增精确差异处理工具 (preciseDiff.js) - 更新各面板组件支持范式润色功能 - 更新范式配置文件 (paradigms.js) - 更新依赖配置 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
114
src/utils/preciseDiff.js
Normal file
114
src/utils/preciseDiff.js
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* 精确文本差异计算工具
|
||||
* 使用 diff-match-patch 算法实现字符级别的精确对比
|
||||
*/
|
||||
|
||||
import DiffMatchPatch from 'diff-match-patch'
|
||||
|
||||
const dmp = new DiffMatchPatch()
|
||||
|
||||
/**
|
||||
* 计算两段文本的精确差异(字符级别)
|
||||
* @param {string} original - 原文
|
||||
* @param {string} rewritten - 修改后的文本
|
||||
* @returns {Array<{type: 'unchanged'|'modified'|'added'|'removed', original: string, rewritten: string}>}
|
||||
*/
|
||||
export const computePreciseDiff = (original, rewritten) => {
|
||||
if (!original && !rewritten) return []
|
||||
if (!original) {
|
||||
return [{ type: 'added', original: '', rewritten: rewritten }]
|
||||
}
|
||||
if (!rewritten) {
|
||||
return [{ type: 'removed', original: original, rewritten: '' }]
|
||||
}
|
||||
|
||||
// 使用 diff-match-patch 计算差异
|
||||
const diffs = dmp.diff_main(original, rewritten)
|
||||
dmp.diff_cleanupSemantic(diffs) // 语义清理,让差异更可读
|
||||
|
||||
const result = []
|
||||
|
||||
for (const [op, text] of diffs) {
|
||||
if (op === 0) {
|
||||
// 相同部分
|
||||
result.push({
|
||||
type: 'unchanged',
|
||||
original: text,
|
||||
rewritten: text
|
||||
})
|
||||
} else if (op === -1) {
|
||||
// 删除
|
||||
result.push({
|
||||
type: 'removed',
|
||||
original: text,
|
||||
rewritten: ''
|
||||
})
|
||||
} else if (op === 1) {
|
||||
// 新增
|
||||
result.push({
|
||||
type: 'added',
|
||||
original: '',
|
||||
rewritten: text
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 合并相邻的删除和新增为修改
|
||||
return mergeAdjacentChanges(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并相邻的删除和新增为修改
|
||||
* @param {Array} diffs - 差异数组
|
||||
* @returns {Array} - 合并后的差异数组
|
||||
*/
|
||||
const mergeAdjacentChanges = (diffs) => {
|
||||
const merged = []
|
||||
let i = 0
|
||||
|
||||
while (i < diffs.length) {
|
||||
const current = diffs[i]
|
||||
const next = diffs[i + 1]
|
||||
|
||||
// 如果当前是删除,下一个是新增,合并为修改
|
||||
if (current.type === 'removed' && next?.type === 'added') {
|
||||
merged.push({
|
||||
type: 'modified',
|
||||
original: current.original,
|
||||
rewritten: next.rewritten
|
||||
})
|
||||
i += 2
|
||||
}
|
||||
// 如果当前是新增,下一个是删除,也合并为修改
|
||||
else if (current.type === 'added' && next?.type === 'removed') {
|
||||
merged.push({
|
||||
type: 'modified',
|
||||
original: next.original,
|
||||
rewritten: current.rewritten
|
||||
})
|
||||
i += 2
|
||||
}
|
||||
else {
|
||||
merged.push(current)
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
return merged
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取精确差异统计
|
||||
* @param {Array} diffSegments - 差异片段
|
||||
* @returns {{total: number, modified: number, added: number, removed: number, unchanged: number}}
|
||||
*/
|
||||
export const getPreciseDiffStats = (diffSegments) => {
|
||||
const nonUnchanged = diffSegments.filter(s => s.type !== 'unchanged')
|
||||
return {
|
||||
total: nonUnchanged.length,
|
||||
modified: diffSegments.filter(s => s.type === 'modified').length,
|
||||
added: diffSegments.filter(s => s.type === 'added').length,
|
||||
removed: diffSegments.filter(s => s.type === 'removed').length,
|
||||
unchanged: diffSegments.filter(s => s.type === 'unchanged').length
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user