更新记录

1.0.0(2026-10-30)

首个版本:两份文本按行做 LCS 对齐,插入一段不让后续行错位;修改行再做字符级拆分,返回 same/del/ins 片段;空白、大小写、中文标点、空行四档忽略规则独立开关;差异带旧行号/新行号,新增与删除的缺失侧为 0;统计一致/修改/新增/删除行数、相似度与字符增删量;差异清单导出 5 列 CSV(带 BOM)与统一视图文本;读文件支持指定编码,GBK 直接传参;行数或 LCS 单元格超限时退化为按行号配对并置 truncated。UTS→Kotlin 编译通过(index.kt 1064 行、classes.dex 45,648 字节),68 项回归测试全部通过;真机未执行(测试机安全锁屏,未提供解锁口令),市场截图为 H5 渲染并标注示例数据。


平台兼容性

uni-app

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× √ × × √ × √ × ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × × × ×

文本版本比对(合同逐字差异)

给要核对合同、条款、说明书、配置文件的你:两份文本进来,逐行对齐、逐字拆开,改哪句、删哪段、多哪一行,带行号说得清清楚楚。

不是「两个输入框贴一下、红绿高亮完事」。真正干活时你需要的四件事,这里都有:

  1. 行对齐不靠行号:旧版中间插入一段,后面 200 行不会被判成「全改了」;
  2. 忽略规则可分开开关:空白、大小写、标点、空行四档独立,避免为一个空格报一堆差异;
  3. 逐字标差异:改了一个数字就只标那个数字,不是整行涂红;
  4. 报告能交出去:差异清单导出 CSV(Excel 双击不乱码),或统一视图文本直接贴进工单。

给谁用

  • 采购/法务:供应商回签版 vs 我方定稿版,核对金额、交期、违约金条款有没有被改;
  • 实施/运维:客户现场改过的配置文件与标准版比对;
  • 质量/体系:作业指导书、检验标准换版时的差异记录;
  • 开发:接口文档、报文样例新旧版本比对,不靠肉眼找。

能做什么

能力 说明
行级对齐 LCS 最长公共子序列对齐,插入/删除一段不会让后续行全部错位
行内拆字 修改行再做一次字符级 LCS,返回 same / del / ins 片段
四档忽略 空白(全忽略)、大小写、中英文标点、空行,各自独立开关
三类差异 新增 / 删除 / 修改,各带旧行号与新行号(不存在的侧为 0)
统计 行数、一致/修改/新增/删除行数、相似度、字符增删量
导出 差异 CSV(5 列固定结构,带 BOM)、统一视图文本(- + ~)
编码 读文件时可指定编码,老系统导出的 GBK 文本直接传 GBK
大文本 行数或 LCS 单元格超限自动退化为按行号配对,置 truncated,不崩

快速接入

import { diffPlain, diffFiles, toCsv } from '@/uni_modules/szhzy-text-diff'

// 1. 两段文本直接比(粘贴比对、预览都用它)
const r = diffPlain({
  textA: oldText,
  textB: newText,
  ignoreWhitespace: true,   // 默认开
  ignorePunct: false,
  maxItems: 500
})
// r.stats  { linesA, linesB, same, added, removed, changed, similarity, charsAdded, charsRemoved }
// r.items  [{ kind, title, lineA, lineB, textA, textB, segs: [{ t, v }] }]

// 2. 两个文件比,顺手把差异报告写出去
const f = diffFiles({
  pathA: '/storage/emulated/0/Download/合同-定稿.txt',
  pathB: '/storage/emulated/0/Download/合同-回签.txt',
  charset: 'UTF-8',
  writeCsv: true,
  fileName: '合同差异.csv'
})
// f.path 是写出的绝对路径,f.bytes 是字节数

// 3. 只要 CSV 文本,自己安排落盘
const c = toCsv({ textA: a, textB: b })

所有接口返回统一信封 { ok, code, message, ... },不抛异常。code 取值:SUCCESS、IDENTICAL(在忽略规则下完全一致)、EMPTY、READ_FAILED、CHARSET_UNSUPPORTED 等。

segs 怎么用

segs 是行内片段数组,按顺序拼起来就是新版(去掉 del)或旧版(去掉 ins):

// 旧版:一、合同金额:人民币 128,000 元(含税 13%)
// 新版:一、合同金额:人民币 136,000 元(含税 13%)
segs = [
  { t: 'same', v: '一、合同金额:人民币 1' },
  { t: 'del',  v: '28' },
  { t: 'ins',  v: '36' },
  { t: 'same', v: ',000 元(含税 13%)' }
]

参数

参数 类型 默认 说明
ignoreWhitespace boolean true 忽略全部空白字符(含全角空格、制表符)
ignoreCase boolean false 忽略英文大小写
ignorePunct boolean false 忽略中英文标点,全角 ASCII 先转半角再比
ignoreBlankLines boolean false 空行不参与比对
charLevel boolean true 修改行是否拆到字符级
maxItems number 500 差异条目上限,0 表示不限
charset string UTF-8 读文件时使用的编码
writeCsv boolean false 是否把差异报告写成 CSV
bom boolean true 写 CSV 时是否带 UTF-8 BOM(Excel 需要)

和同系列插件怎么分工

插件 比什么 怎么对
本插件 文本版本比对 自由文本(合同、条款、文档) 逐行 LCS + 逐字
表格差异比对 结构化表格(CSV/TSV) 按主键对齐,字段级
Word 表格提取 Word → 结构化 抽取,不比对

合同正文用本插件;对账台账用表格差异比对;Word 里的表格先抽出来再比。

购买前必读

  • 只比纯文本。Word / PDF 不是纯文本,先用 szhzy-docx-read 抽成文本再进来;
  • 单行超过约 500 字时,字符级比对会退化为整行替换(保证长合同不卡界面),差异仍然完整,只是不够细;
  • 相似度是「一致行数 ÷ 两侧较多行数」的粗略指标,给人看的,不是法律意义上的文本同一性判定;
  • 行被整体搬家(同一行从第 3 行挪到第 30 行)会呈现为一次删除 + 一次新增,这是所有行级 diff 的常规表现;
  • 大文件会退化:行数超过 4000 行或 LCS 单元格超过上限时按行号配对,结果置 truncated。

验证状态

项 结果
UTS → Kotlin 编译 通过(项目 demo-text-diff 编译成功,index.kt 1064 行,classes.dex 45,648 字节)
纯逻辑回归测试 68 项全部通过(dev-tools-uts/verify/text-diff/run-tests.mjs)
真机运行 未执行。本版开发时测试机处于安全锁屏且未提供解锁口令,无法操作界面,因此文件选择、content:// 读取、写出目录三条链路只有编译期保证
真机截图 未取得。市场截图为 H5 渲染(同一份演示工程、同一份示例数据),页面标注「示例数据」

未验证的部分我没有写成「已支持」:文件读写链路请在自定义基座上自行验收一次再上线。

平台支持

  • uni-app(Vue3)+ Android 6.0 及以上:支持
  • iOS / 鸿蒙 / 小程序 / H5:不支持(本版只有 Android 平台实现)
  • 需要打自定义基座:标准基座不含 UTS 插件

权限与隐私

不申请任何系统权限,不联网,不上传,不写日志。读取走调用方用系统文件选择器交过来的路径或 content:// 授权;写出默认落应用外部私有目录(Android/data/<包名>/files/documents)。

常见问题

Q:为什么两份一模一样,返回 IDENTICAL 但 items 是空的? A:一致就没有差异条目,code 会明确告诉你 IDENTICAL,不用靠 items.length === 0 猜。

Q:CSV 里为什么带 BOM? A:不带 BOM 的 UTF-8 CSV 在中文 Windows 的 Excel 里双击会乱码。要喂给程序就传 bom: false。

Q:能比多少次? A:本地计算,不限制次数,不消耗任何额度。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无系统权限。读取调用方用系统文件选择器交过来的文件(路径或 content:// 授权),写出走应用外部私有目录。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集、不上传任何数据,不访问网络,不写日志。两份文本只在本机内存中比对;差异报告由调用方决定是否落盘,默认写应用外部私有目录。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。