新增转码模式支持转到核心以及sql语法转换

This commit is contained in:
taocong
2026-09-30 10:47:14 +08:00
committed by taocong45644
parent 43e184bffb
commit e7030a6dbf
14 changed files with 573 additions and 193 deletions
+38 -15
View File
@@ -86,9 +86,11 @@ Uft30ChangeCode 是一款桌面端 UF20 → UFT3 代码转码工具,主要提
**说明**:全量转码仅支持 **LS_ 开头**的功能("内存交易"改造范围),按清单对功能进行整体转码。清单保存在 `cust.json` 的 `convert.dir` 节点(见 §6.1)。
**表格列**:`UF20函数名` | `是否存在` | `操作`(行尾编辑按钮)。
**表格列**:`UF20函数名` | `是否存在` | `核心` | `是否柜面接口`(**双击函数名所在行**可在弹窗中修改函数名)。
- "是否存在"显示 **否**:说明元数据未更新或该功能在 UF20 元数据中检索不到(见 §7 FAQ);
- **核心**:下拉选择该功能转码后归属的核心,可选 **ucbp**(默认)/ **uses** / **uarg** / **usms**;SQL 方言由核心自动派生——ucbp/uses 对应 mdb,uarg/usms 对应 db;
- **是否柜面接口**:下拉选择 **否**(默认)/ **是**,标识该功能是否为柜面接口;
- 每次显示页面时自动刷新"是否存在"列。
**操作步骤:**
@@ -96,7 +98,7 @@ Uft30ChangeCode 是一款桌面端 UF20 → UFT3 代码转码工具,主要提
1. 切到 **全量转码** Tab;
2. 点击 **添加**,弹窗内**每行输入一个** LS_ 函数名(支持批量粘贴);输入非 LS 函数将被拒绝,并提示切换到"按需转码";
3. 也可在 **UF20功能查询** 中双击或右键选中 LS_ 功能直接加入(见 §5.3.1);
4. 点击行尾编辑按钮可修改函数名;**删除选中** / **清空列表**(二次确认)维护清单;
4. **双击函数名所在行**可在弹窗中修改函数名;**删除选中** / **清空列表**(二次确认)维护清单;
5. 点击 **开始转换**,进度条与状态文字显示转换进度;转换中按钮变为 **停止转换**,可随时点击终止任务。
**清单同步**:手工编辑 `cust.json` 保存后约 0.3 秒内界面自动刷新(文件监视 + 防抖),程序与手工编辑双向同步。
@@ -114,14 +116,15 @@ Uft30ChangeCode 是一款桌面端 UF20 → UFT3 代码转码工具,主要提
- **方式二**:按需转码 Tab 点击 **添加**,弹窗内每行输入一个函数短名(如 `AS_xxx`);误带 `.service_design` 等后缀会自动剥离;新增功能递归模式默认 **否**;若输入 LS_ 开头函数仅给出提示(建议放入全量转码),不会拦截;
- **方式三**:手工编辑配置文件 `cust_nonls.json`(见 §6.2),保存后程序自动检测并刷新界面。
**表格列**:`UF20函数名` | `是否存在` | `是否递归` | `操作`(行尾编辑按钮)。
**表格列**:`UF20函数名` | `是否存在` | `是否递归` | `db模式`(**双击函数名所在行**可在弹窗中修改函数名)。
- LS_ 开头的函数名以橙色字体显示提醒(不拦截)。
**设置递归模式:**
**设置递归模式与 db 模式:**
1. 在目标行的 **是否递归** 下拉框选择 **否**(单文件)或 **是**(递归);
2. 选择后立即写入 `cust_nonls.json` 并生效,无需额外点击。
2. 在 **db模式** 下拉框选择 SQL 语法转换方言:**否** = mdb(默认)、**是** = db;
3. 选择后立即写入 `cust_nonls.json` 并生效,无需额外点击。
**执行转码:** 点击 **开始转换**,进度显示与停止方式同全量转码;任务互斥规则相同。
@@ -256,19 +259,38 @@ Uft30ChangeCode 是一款桌面端 UF20 → UFT3 代码转码工具,主要提
| 节点 | 结构 | 用途 |
| --- | --- | --- |
| `convert.dir` | 数组,元素为 `"函数名.service_design"` | 全量转码清单 |
| `convert.dir` | 对象数组,元素 `{name, core, viaUmgr, dialect}` | 全量转码清单(含核心、柜面接口配置) |
| `tableCompareUf2_Uf3` | 对象 `{UF20表名: UFT3表名}` | 表替换映射 |
| `functionReplace` | 对象 `{UF20函数名: UFT3函数名}` | 函数替换映射 |
| `noChangeFullNameCode` | 字符串数组 | 不转码功能函数清单,转码时跳过这些函数名的替换 |
`convert.dir` 元素字段说明(详见 `docs/转码配置格式契约.md`):
| 字段 | 说明 |
| --- | --- |
| `name` | 功能名(含 `.service_design` 后缀) |
| `core` | 归属核心:`ucbp`(默认)/ `uses` / `uarg` / `usms` |
| `viaUmgr` | 是否柜面接口:`false`(默认)/ `true` |
| `dialect` | SQL 方言,由 core 派生:`ucbp`/`uses` → `mdb`,`uarg`/`usms` → `db`(程序保存时自动生成,无需手工填写) |
**手工编辑示例(以实际文件结构为准):**
```json
{
"convert": {
"dir": [
"LS_CustQry.service_design",
"LS_AcctChk.service_design"
{
"name": "LS_CustQry.service_design",
"core": "ucbp",
"viaUmgr": false,
"dialect": "mdb"
},
{
"name": "LS_AcctChk.service_design",
"core": "uarg",
"viaUmgr": true,
"dialect": "db"
}
]
},
"tableCompareUf2_Uf3": {
@@ -288,17 +310,18 @@ Uft30ChangeCode 是一款桌面端 UF20 → UFT3 代码转码工具,主要提
- 程序内修改(全量转码 / 表替换 / 函数替换 / 不转码功能函数页)会自动写回该文件;
- 手工编辑保存后各页面自动检测并刷新;
- 全量转码清单函数名可省略 `.service_design` 后缀展示,`dir` 为数组结构,程序保存时保留文件其余内容与格式。
- 全量转码清单函数名可省略 `.service_design` 后缀展示,`dir` 为对象数组结构,程序保存时保留文件其余内容与格式;
- 兼容旧版 `dir` 为字符串数组(仅函数名)的格式,旧条目按 core=ucbp、viaUmgr=false、dialect=mdb 加载。
### 6.2 cust_nonls.json(按需转码清单)
- **路径**:`bin\uf2touft3\config\cust_nonls.json`
- **作用**:保存按需转码功能清单及每项的递归标志,供界面与转码引擎共用。
- **作用**:保存按需转码功能清单及每项的递归标志与 SQL 方言(db 模式),供界面与转码引擎共用。
| 节点 | 结构 | 说明 |
| --- | --- | --- |
| `convert.dir` | 对象 `{功能名: 0 或 -1}` | `0` = 否(单文件转码),`-1` = 是(递归转码) |
| `convert.dir["*"]` | 引擎兜底键 | 非清单功能,界面不展示、保存时自动保留 |
| `convert.dir[功能名]` | 对象 `{depth, dialect}` | `depth`: `0` = 否(单文件转码)、`-1` = 是(递归转码);`dialect`: `mdb` = 否(默认)、`db` = 是 |
| `convert.dir["*"]` | 引擎兜底键(数值) | 非清单功能,界面不展示、保存时原样保留 |
| `convert.ext` | 后缀数组 | 引擎识别的功能文件后缀,程序保存时自动维护 |
**手工编辑示例(以实际文件结构为准):**
@@ -308,8 +331,8 @@ Uft30ChangeCode 是一款桌面端 UF20 → UFT3 代码转码工具,主要提
"convert": {
"dir": {
"*": -1,
"AS_CustQry": 0,
"LF_AcctChk": -1
"AS_CustQry": { "depth": 0, "dialect": "mdb" },
"LF_AcctChk": { "depth": -1, "dialect": "db" }
},
"ext": [
".service_design",
@@ -325,7 +348,7 @@ Uft30ChangeCode 是一款桌面端 UF20 → UFT3 代码转码工具,主要提
**编辑注意:**
- 保持 JSON 格式合法(逗号、引号完整);若格式非法,程序将保留内存中的现有清单并在日志中记录警告;
- 兼容旧版 `dir` 为数组的格式(无递归标志,一律按"否"加载);
- 兼容旧版格式:`dir` 值为数值(`0`/`-1`,无方言,按"否/mdb"加载)或为数组(无递归标志,一律按"否/mdb"加载);
- 外部编辑保存后约 0.3 秒内界面自动刷新;程序自身写入该文件时不会触发重复刷新,可放心与手工编辑混用。
### 6.3 config.ini 与 change_code.ini
+22 -15
View File
@@ -32,7 +32,8 @@ Uft30ChangeCode 是一款桌面端 **UF20 → UFT3 代码转码工具**,提供
| --- | --- |
| UF20 / UFT3 | 新旧两代系统版本,转码即将 UF20 风格代码转换为 UFT3 风格 |
| LS 功能 | "内存交易"改造范围的功能类别;**全量转码仅支持 LS_ 开头功能**,按需转码仅针对非 LS 功能 |
| 递归标志 | `cust_nonls.json` 中 `convert.dir` 的取值:`0`=否(不递归),`-1`=是(递归) |
| 递归标志 | `cust_nonls.json` 中 `convert.dir` 条目 `depth` 的取值:`0`=否(不递归),`-1`=是(递归) |
| SQL 方言(dialect) | 转码引擎 SQL 语法转换目标:`mdb` / `db`。全量转码由核心派生(ucbp/uses→mdb,uarg/usms→db);按需转码由"db模式"列选择(否=mdb,是=db) |
| 元数据 | 从源码解析出的功能/函数索引信息,存于 SQLite 缓存库 |
| 调用链路 | 某功能的向上调用方(谁调用了它)与向下被调(它调用了谁)构成的关系树 |
@@ -161,8 +162,8 @@ Uft30ChangeCode/
| --- | --- | --- | --- |
| 主窗口导航 | `MainWindow` | — | ElaWindow 容器、页面注册、**转码任务调度与互斥**、引擎进程管理 |
| 业务转码容器 | `BusinessConvertPage` | — | ElaPivot 承载全量/按需两个工作台 |
| 全量转码 | `BatchConvertPage` | — | `cust.json` 的 `convert.dir` 清单管理(仅 LS_ 功能)、触发转码 |
| 按需转码 | `NonLsConvertPage` | — | 非 LS 功能清单管理、递归模式选择、外部修改同步 |
| 全量转码 | `BatchConvertPage` | — | `cust.json` 的 `convert.dir` 清单管理(仅 LS_ 功能,含核心/是否柜面接口配置)、触发转码 |
| 按需转码 | `NonLsConvertPage` | — | 非 LS 功能清单管理、递归模式与 db 模式(SQL 方言)选择、外部修改同步 |
| 功能查询 | `FunctionSearchPage`(基类)、`UF20/UFT3FunctionSearchPage` | 模板方法(基类复用) | 元数据检索(多关键词批量查询);UF20 双击/右键一键分流加入转码清单(合并单次提示),UFT3 纯查询 |
| 代码检索 | `CodeSearchPage`、`CallChainAnalyzer` | — | 调用链路查询、索引构建与缓存、导出 |
| 数据映射 | `TableMappingPage`、`FunctionMappingPage`、`NoChangeFullNamePage` | — | `cust.json` 表替换/函数替换映射维护、不转码功能函数清单维护(增删改查) |
@@ -316,8 +317,8 @@ sequenceDiagram
**要点:**
- **全量转码**:引擎读取 `cust.json` 的 `convert.dir` 清单,对清单内 LS_ 功能整体转码;
- **按需转码**:`NonLsConvertPage::buildArguments()` 组装引擎参数(含 `-m 2` 模式标识),功能清单与递归标志由 `cust_nonls.json` 提供,引擎按映射关系(`cust.json`)完成表名/函数名替换;
- **全量转码**:引擎读取 `cust.json` 的 `convert.dir` 清单(V2 对象数组 `{name, core, viaUmgr, dialect}`),对清单内 LS_ 功能整体转码,核心/柜面接口/SQL 方言随清单下发(契约见 `docs/转码配置格式契约.md`);
- **按需转码**:`NonLsConvertPage::buildArguments()` 组装引擎参数(含 `-m 2` 模式标识),功能清单、递归标志(depth)与 SQL 方言(dialect)由 `cust_nonls.json` 提供,引擎按映射关系(`cust.json`)完成表名/函数名替换;
- **成败判定**:引擎在个别文件转码失败时退出码仍可能为 0,因此 `MainWindow` 在输出解析链最前端检测 `FAIL` 行(`[N/M] FAIL 函数名`)与汇总行(`批量转码完成: X/Y 通过, Z 失败`)累计 `m_failCount`;收尾按 `正常退出 && 退出码==0 && m_failCount==0` 判定成功,失败时页面调用 `onConvertFailed`——进度条**保持当前进度**(不置 100%)、状态文字"转换失败(N 个文件转换失败)"(详见 §8.7);
- **转码后联动**:任务成功后自动静默刷新代码检索索引,保证调用链路反映最新代码。
@@ -334,11 +335,11 @@ sequenceDiagram
### 5.2 全量转码模块(BatchConvertPage)
**职责**:维护 LS_ 功能转码清单并对功能执行整体转码,表格展示"UF20函数名 / 是否存在 / 操作"。
**职责**:维护 LS_ 功能转码清单(含核心、是否柜面接口配置)并对功能执行整体转码,表格展示"UF20函数名 / 是否存在 / 核心 / 是否柜面接口"(无操作列,双击函数名所在行触发编辑)。
```mermaid
flowchart TD
A([进入全量转码页]) --> B["加载清单<br/>cust.json → convert.dir 数组"]
A([进入全量转码页]) --> B["加载清单<br/>cust.json → convert.dir 对象数组<br/>(V2: {name, core, viaUmgr, dialect})"]
B --> C[updateTable 渲染 ElaTableView]
C --> D{逐行判断}
D --> E["checkUF20CnameExists(函数名)<br/>查询 DataCache"]
@@ -353,21 +354,22 @@ flowchart TD
**要点:**
- 清单**仅允许 LS_ 开头**的功能(`validateLsFunctionNames` 校验),非 LS 输入被拒绝并提示切换到按需转码;
- 清单持久化于 `cust.json` 的 `convert.dir` 数组(元素为 `"函数名.service_design"`);保存时用**正则定位数组做局部替换**,保留文件其余内容与格式;
- 清单持久化于 `cust.json` 的 `convert.dir` 对象数组(V2 元素 `{name, core, viaUmgr, dialect}`,dialect 由 core 派生:ucbp/uses→mdb、uarg/usms→db);保存时用**正则定位数组做局部替换**,保留文件其余内容与格式;加载兼容 V1 字符串数组(按 core=ucbp、viaUmgr=false、dialect=mdb 兜底);
- `QFileSystemWatcher + QTimer`(300ms 防抖)监听 `cust.json` 外部修改,与手工编辑双向同步;
- "是否存在"列依赖元数据缓存;**首次运行若未执行元数据更新,可能整列显示"否"**(详见 §8.2)。
### 5.3 按需转码模块(NonLsConvertPage)
**职责**:管理"非 LS 功能"的按需转码清单,支持**单文件转码**与**递归转码**两种模式(下拉选择),转码范围不包含核心文件、module 模块文件。清单持久化于 `bin/uf2touft3/config/cust_nonls.json`,并监听外部修改。
**职责**:管理"非 LS 功能"的按需转码清单,支持**单文件转码**与**递归转码**两种模式(下拉选择),并为每项功能选择 **db 模式**(SQL 方言:否=mdb,是=db),转码范围不包含核心文件、module 模块文件。清单持久化于 `bin/uf2touft3/config/cust_nonls.json`,并监听外部修改。
#### 5.3.1 数据结构
| 成员 | 类型 | 说明 |
| --- | --- | --- |
| `m_funcList` | `QStringList` | 功能名有序清单(与表格行序一致) |
| `m_recursionMap` | `QMap<QString,int>` | 功能名 → 递归标志(`0`=否,`-1`=是),与 json 的 `convert.dir` 同值 |
| `m_tableModel` | `QStandardItemModel` | 表格模型,列:`UF20函数名 / 是否存在 / 是否递归 / 操作` |
| `m_recursionMap` | `QMap<QString,int>` | 功能名 → 递归标志(`0`=否,`-1`=是),对应 json 的 `convert.dir[名].depth` |
| `m_dialectMap` | `QMap<QString,QString>` | 功能名 → SQL 方言(`mdb`=否/默认,`db`=是),对应 json 的 `convert.dir[名].dialect` |
| `m_tableModel` | `QStandardItemModel` | 表格模型,列:`UF20函数名 / 是否存在 / 是否递归 / db模式`(双击函数名所在行触发编辑) |
| `m_configWatcher` | `QFileSystemWatcher` | 监听 `cust_nonls.json` 文件与其所在目录 |
| `m_reloadTimer` | `QTimer` | 防抖定时器,外部修改后延迟重载 |
| `m_lastFileMtime` | `QDateTime` | 上次已处理的文件修改时间,用于过滤自身写入触发的变更 |
@@ -400,7 +402,7 @@ flowchart TD
B --> C{遍历 m_funcList}
C --> D[构建行: 函数名 / 是否存在<br/>存在性查询 DataCache]
D --> E["是否递归列: setIndexWidget<br/>放置 ElaComboBox(否/是)"]
E --> F["操作列: setIndexWidget<br/>放置编辑按钮"]
E --> F["双击函数名所在行触发编辑<br/>(基类统一接线, 以函数名为稳定键)"]
F --> G{还有下一行?}
G -- 是 --> D
G -- 否 --> H["viewport()->update()<br/>resizeRowsToContents()<br/>scrollToTop() / clearSelection()"]
@@ -448,7 +450,7 @@ flowchart TD
- `fileChanged` 在部分编辑器保存时会**移除监听**,回调中检测到即对路径重新 `addPath`,保证持续监听;
- 目录监听用于捕获"文件被删除重建"的场景;
- mtime 比较过滤掉程序自身写盘引发的回环刷新;
- **兼容旧版格式**:旧版 `convert.dir` 为数组(无递归标志),加载时自动兼容、一律按"否"处理;新版为对象 `{功能名: 0|-1}`,引擎兜底键 `"*"` 由程序保存时自动保留。
- **兼容旧版格式**:旧版 `convert.dir` 为数组(无递归标志与方言)或值为数值(`0`/`-1`,无方言)均可自动兼容,均按"否/mdb"兜底加载;新版为对象 `{功能名: {depth, dialect}}`,引擎兜底键 `"*"`(数值)由程序保存时原样保留。
#### 5.3.6 按需转码执行模式
@@ -724,6 +726,7 @@ flowchart TD
| `tableCompareUf2_Uf3` | UF20→UFT3 表名映射 | 全量/按需转码的表替换 |
| `functionReplace` | 函数替换规则 | 转码的函数替换 |
| `noChangeFullNameCode` | 字符串数组(功能函数全名清单) | 转码引擎对清单内功能函数名不做全名替换 |
| `convert.dir` | 对象数组 `{name, core, viaUmgr, dialect}`(全量转码清单,V2 格式,见 `docs/转码配置格式契约.md`) | 全量转码页维护、引擎读取 |
| 其余键 | 引擎自身配置 | 原样透传 |
- 数据映射三页各自只读写所属顶层键(键名统一引用 `Constants::CustKeys`,见 §6.4),其余内容原样保留;
@@ -734,13 +737,17 @@ flowchart TD
```json
{
"convert": {
"dir": { "功能名": 0, "另一功能": -1, "*": 0 },
"dir": {
"功能名": { "depth": 0, "dialect": "mdb" },
"另一功能": { "depth": -1, "dialect": "db" },
"*": 0
},
"ext": ["c", "h"]
}
}
```
- `dir.<功能名>`:`0` 纳入转码、`-1` 不纳入;`"*"` 为兜底键;
- `dir.<功能名>`:对象 `{depth, dialect}`——`depth` 为 `0` 纳入转码(单文件)、`-1` 递归转码;`dialect` 为 SQL 方言(`mdb` 默认 / `db`),对应界面"db模式"列(否=mdb、是=db);`"*"` 为兜底键(数值,程序保存时原样透传);
- `ext`:纳入转码的扩展名白名单;
- 兼容旧版数组格式(仅扩展名列表),读取时自动转换。